Sunichi's Blog

sunichi@DUBHE | Linux & Pwn & Fuzz

0%

Pwnable.tw start writeup

使用ida查看程序,首先保存esp和_exit地址,随后将输出的字符串压栈:

1
2
3
4
5
6
7
8
9
push esp
push offset _exit
xor eax, eax ; ebx, ecx, edx
push 'Let's start the CTF:'
mov ecx esp ; addr
mov dl, 14h ; len
mov bl, 1 ; fd
mov al, 4 ; syscall num, write
int 80h

随后执行输入函数:

1
2
3
4
xor ebx, ebx ; fd
mov dl, 3Ch ; len
mov al, 3 ; syscall num, put
int 80h

由于ecx在之前已经被赋值为esp,所以put函数仍是对同一个变量(输出的字符串)进行输入。使用gdb-pedachecksec查看,虽然显示NX: enable,但是通过vmmap执行,发现栈是可执行的。使用pattern createpattern offset获取偏移量为20。因此构造的payload结构如下:

1
'a' * 20 + [ret addr] + getshell

因为要获取栈的地址来达到ret2shellcode的目的,所以需要通过write泄漏栈地址。在程序运行的开始,执行了:

1
2
push esp
push offset _exit

在put函数后,执行:

1
2
add esp, 14h
ret ;pop esp

使得字符串参数、_exit被移出栈、pop,栈顶从而变为之前储存的esp。因此在第一个put函数执行时,输入:

1
'a' * 20 + 0x8048087

便可以打印出esp的地址。获取esp的地址后,将会继续再次执行put函数(此时ecx仍为字符串参数的地址),此时输入:

1
'a' * 20 + [ret addr] + getshell

即可。需要注意shellcode长度以满足输入的条件(3Ch)。