[编程相关] PWN PWN PWN!
作者:CC下载站 日期:2022-01-30 04:13:15 浏览:5 分类:编程开发
写在前面
作为一个半退役的CTF web选手,在大三上学习了编译原理和操作系统原理之后,感觉可以学习pwn了!下面写一下在buu和攻防世界上pwn专题的刷题记录。
攻防世界
1.CGfsb
作为攻防世界pwn新手区的第一题,它的考点是printf函数的格式化字符串漏洞。
利用IDA64进行反编译后,在main函数中,我们发现了以下代码。
只要pwnme为8,我们就能获得flag。而在该题中,我们传入的一个参数s将直接作为printf的参数。
实际上我们可以往s这个字符串里输入一个格式化的内容,比如 %s
之类的,在c提供的一些格式化符号中,利用 %n
可以实现内存任意写,理论上代码里定义的变量,我们都可以进行修改。
但是由于我十分菜,还不太会写payload,但是pwntools中提供了一个函数fmtstr_payload
,只要我们输入一些参数,pwntools就能帮助我们快速构建payload。
fmstr_payload
需要传递的参数主要是 偏移量offset 和一个字典,字典内部的key表示你要修改的变量的内存地址,value则表示修改后的值。
而这个offset是一个神秘的值,我不太理解它到底是什么,但是能够模仿大佬们的wp知道怎么求出这个值。
实际情况下,%08x或者%p的数量可以多一些,这样某个神秘的指针就会在一次次调用中不断往后,直到找到41414141,即AAAA的ascii值,你就获得了你能够控制的格式化字符串的offset 偏移量。
然后第二个参数字典就非常容易了,在这道题中我们需要改变的pwnme变量的地址是 0x0804A068,然后想要改变为的值是8,我们就这样写来构造payload。
最终的payload如下。
payload代码
2.level0
最简单的栈溢出。
栈溢出的思想就是通过程序中没有控制输入的长度,从而超出了某个变量应该限制的范围,影响到了外面的return之类的东西,从而进行程序流的劫持,比如我们把本来return后程序就结束了,然后我们把return的返回地址指导了一个backdoor函数,而这个后门函数一般就是一个shell,我们可以用来 cat flag。
在这道题中,我们利用IDA64可以看到一个vulnerable_function
按理说buf字符串的长度应该只有128,但是这个程序却用read读了0x200这么长,即512的长度。
所以我们在把正常buf的内容用随便一些字符覆盖完后,我们就可以进行一些劫持工作了。
在IDA64中双击buf变量,我们可以看到buf的栈使用情况。
我们可以看到buf 有0x80个空间,然后就是一个s和r。
这两个具体是啥我也不太懂,但是我们可以通过覆盖r中的值从而改变程序流向。
该程序中还存在一个callsystem
函数,很显然,这就是我们期盼的后门函数了。
然后我们很容易写出payload脚本如下。
payload代码
3.level2
这道题便是ctfwiki pwn中basic rop中的ret2libc例1的情况。
链接:基本 ROP - CTF Wiki (ctf-wiki.org)
该题首先对由于read函数读取的字符个数大于变量本身的限制,存在栈溢出。
这道题中和level0不同,level0属于 ret2txt,即return回到已有的代码上,因为上题中的callsystem函数能够直接get shell,我们直接返回到它的地址即可。可惜这道题里没有这样成品的后门函数。
但是从IDA中我们可以看到代码有system函数,也有/bin/sh
这个字符串,我们可以将他们进行按照函数调用的规则入栈,从而get shell。
入栈规则 首先传入system函数的plt地址,然后传入一个返回地址,最后传参数的地址。
这个返回地址我们可以随便写,为了凑足一个字(这道题是32位的,即4个字节),我们可以传4个字符作为返回地址。
这道题的payload代码里,我根据ctfwiki,使用了pwntools中flat函数,它可以让你免于写类似b'a'
和p32
这种煞风景的结构,而自动帮你构建符合要求的payload。
payload代码
4.get_shell
突然发现攻防世界的题目顺序每次都在变,那有点狗了。这道明明应该放在第一道的。
nc过去就是shell。以下是它的main函数。
5.hello_pwn
最简单的栈溢出。main函数如下。
利用read函数读了16个字符,而unk_601068这个变量实际上只占4个空间,我们可以影响到栈下面的dword_60106C。把下面那个变量设置为1853186401即可获得flag。
payload代码
6.guess_num
仍然是栈溢出。但是这道题我不太明白为什么不能直接移除到ret2text的方式,直接去调用cat flag的函数,可能是和该题开启了canary的方式(运行过程中没有报错就挺奇怪的
看了网上的wp,利用溢出去改变随机数的种子,让其产生的随机数固定,然后我们就能成功猜数,通过正常的程序流cat flag。总结一下就是利用栈溢出了,但是没有完全利用。
在看wp的过程中,还了解到在python中利用ctypes
能够导入一个libc库从而直接运行c函数,非常牛皮。
payload代码
7.int_overflow
本题中有strcpy函数提供栈溢出条件,同时题目设置了一道关卡,必须想到整数溢出通过关卡后才能去利用栈溢出。
在这道题中,由于payload较长,我们正常写payload可能会写成这样。
如果利用上flat来去掉一些难看的结构,我们可能会写成这样。
但是这还是非常麻烦,特别是我们要手动算出最后要添加多少个a,来到达260的长度。
所以我现在利用flat函数的高阶用法,利用一个字典来指定第几位是什么值,其他的值就会自动补为a。
最终payload代码
8.cgpwn2
本题应该属于基本ROP中的ret2libc。没有现成的后门函数,比如system('/bin/sh')
或者system('cat flag')
之类的。
但是这个后门函数中有system,我们再找到一个/bin/sh字符串就能够去手动调用了。可惜shift+F12,没有找到这个字符串。
我们观察可执行文件的运行流程,它会让我们输入姓名和一条信息,在信息那块有gets造成的栈溢出,而姓名那块我们则可以输入一个/bin/sh来手动把name变成我们需要的字符串。
payload代码
9.string
这道题的流程相比之前所有的题目都要复杂。但是考点实际上只有两个,一个是格式化字符串漏洞,一个是shellcode的构建。
以下是这道题的主要流程
graph TD main["主函数main<br>包含sub_400996<br>和sub_400D72<br>开局输出了两个secret地址<br>为之后的fmtstr利用"] sub_400996["sub_400996<br>输出welcom信息"] sub_400D72["sub_400D72(a1)<br>输入角色名<br>包含sub_400A7D<br>sub_400BB9<br>sub_400CA6(a1)"] sub_400A7D["sub_400A7D<br>选择east or up<br>必须选择east"] sub_400BB9["sub_400BB9<br>选择1还是0<br>必须选择1<br>然后提示输入一个地址<br>我们应该输入主函数中提示的secret地址<br>利用格式化字符串漏洞<br>将secret[0]变为85"] sub_400CA6["sub_400CA6(a1)<br>在成功利用格式化字符串漏洞后<br>输入shellcode执行"] main-->sub_400996-->sub_400D72 sub_400A7D-->sub_400BB9-->sub_400CA6
以下为程序中的关键代码
我在花了很久终于整理出流程并且有了解体思路后,由于我对格式化字符串漏洞不太熟练,之前做 cgfsb的时候只是用了pwntools中的fmtstr_payload,没有了解具体payload的实现原理,这里便一直无法突破第一关。
这是格式化字符串漏洞那个子函数里栈的情况,format是格式化字符串,var_78则是我们输入的地址。
根据 原理介绍 - CTF Wiki (ctf-wiki.org) 对格式化字符串原理的介绍,当格式化字符串中使用了 %d, %s之类的标记,但是没有指定参数,那么就会从format变量栈上面的变量中取值。所以相当于var_78
已经指明了地址,现在我们的目标是将这个地址里的值变为85,我们可以使用以下payload。
首先这里我们主要利用的%标记是%n,它的功能是将之前输出的字符个数的值存放到对应的地址中,在这里,就会存放到var_78
中,因为没有指定参数。
而这个payload中没有使用n
而是使用了hhd
,它们的区别是写的内存地址的长度,若是%n
,则是向4个字节的内存地址写数据,%hn
则是2个字节,%hhn
则会是1个字节。因为这道题里我们需要改变的两个变量占的空间是8位,即1个字节,故我们这里使用%hhn
。
那为什么%hhn
中间有7$
,这个有点难以解释,我们可以暂且记为偏移量减去1。
然后%85c
用来快速生成85个字符,从而得到85这个数字存往var_78
中,通过第一关。
然后我们可以利用以下代码生成shellcode
payload代码
10.level3
攻防世界的最后一题啦!题目的流程很简单,就是一个输入,然后就没了,相比第九题string简单许多。
它的考点是ret2libc,利用libc来得到system函数的真实地址和/bin/sh的真实地址,然后调用获得shell。
当我们在用C语言编程时,我们都会大量应用库函数,比如printf和scanf等,这些函数都是存在在动态链接库中的。
理论上我们可以使用动态链接库中的任意函数,但是这些函数在内存中的地址在程序运行的一开始是不知道的,这是为了提升效率,只有当真正去调用它的时候,才会进行绑定,这也叫做叫延迟绑定lazy bind
。然后这个绑定后的真实地址会被存在GOT表中。
在这道题中,题目的附件里给了一个libc文件 libc_32.so.6
。它实际上不神秘,它本质上也是一个ELF文件,也能用checksec查看保护情况。
它也能用IDA打开,只不过它的函数特别特别多,我们可以在函数列表用ctrl + F
来搜索我们想要查看的函数。
可以用shift + F12搜索我们想要的字符串。
两个都有,但是它们在IDA里看到的地址并不是程序运行中实际上的地址。
我也不知道在IDA里可以看到的地址应该被称为什么,暂且叫为形式地址。
这里有一个重要的关系,两个东西的形式地址的差和两个东西的真实地址的差是相同的。
因为所有的形式地址我们都是已知的,也就是只要知道了一个东西的真实地址,我们就可以求出其他任何东西的真实地址。
在这道题中的ELF文件中,有write
函数,我们可以利用write函数打印的功能,把自己got表中的内容打印出来从而获得write函数在本次运行中在内存中的真实地址。
我们首先用plt直接调用write函数,然后之后的参数分别是 返回地址【这里设置为了main,让程序回到开始】,然后是write的三个参数,第一个参数1表示文件句柄,当1是应该会输出到终端,第二个参数就是我们想要输出的东西,第三个参数是输出的最大长度。
然后我们利用截取前4个字节,用u32,反打包为一个值。【u可以理解为unpack, p则是pack】
这样我们就获得了write函数的真实地址,从而我们可以获得system和/bin/sh的真实地址。
最后调用一波即可。
最终payload代码
BUUCTF
1.test_your_nc
题如其名,nc后直接获得shell。
2.rip
这道题玄学的很,初学建议跳过这题。
考点就是ret2text,gets栈溢出+现成的后门漏洞直接get shell。
payload代码
3.warmup_csaw_2016
发现BUUCTF的题里用flat函数构造payload的时候,具体的函数地址都需要封装,比如 flat({10: p64(sys_addr)})
,而在攻防世界里不封装也没问题,挺奇怪的。以后为了保险都写上封装函数吧!
这道题也是最简单的ret2text。不多说。
payload代码
4.ciscn_2019_n_1
还是ret2text。这道题的逻辑是通过gets造成的栈溢出修改一个变量的值,从而顺着程序流程获得flag。
下面是栈情况
我们需要将var_4里的值变成11.28125。然而我们不知道浮点数在计算机内部是如何表示的。
这时候我们可以在IDA View-A里按空格查看汇编代码。找到汇编里代码里的浮点数表示。
payload代码
5.pwn1_sctf_2016
还是ret2text。这道题与众不同的是,它是用c++写的,还用了string这个类,反汇编出来的代码十分反人类。
这道题里用的读入函数是fgets,按理来说是很安全的。但是题目中的逻辑会把字符串中的I变成you,从而将字符串长度变长,再加上strcpy函数的作妖,使得32个字节的s栈溢出。
payload代码
6.jarvisoj_level0
和 攻防世界#2level0重复。最简单的ret2text,不多说。
payload代码
7.ciscn_2019_c_1
此题和攻防世界 #10level3 一样,属于ret2libc。IDA中没有发现system,也没有/bin/sh字符串。
比level3还更难,因为level3直接提供了libc库文件,这道题里没有,我们需要利用LibcSearcher这个库来查找libc版本号。
这里我使用了 rycbar77/LibcSearcher: 根据函数地址查询libc,可本地或在线查询 (github.com) 维护的LibcSearcher,支持本地和在线查询,作者的安装教程也写的很详细。
程序中大量使用了puts函数来进行输出,一旦puts函数被使用,got表中就会存储其真实地址,于是我们再调用puts函数本身,把自己输出出来,作为查询libc版本的依据。
值得注意的是,由于本地是64位的linux,构造payload传递参数的时候,和32位不同。差别如下。
其中pop_rdi_addr 可以用 ROPgadget --binary ciscn_2019_c_1 | grep "pop rdi"
获得。
在获得puts函数的真实地址后,我们利用LibcSearcher查询libc版本,确定版本后,便可以根据两个函数真实地址的差和两个函数形式地址的差是相等的这个规律,获得system和/bin/sh的地址。
最后按照64位调用函数的格式调用即可。
这道题最后调用的时候还需要栈对齐,这玩意儿我还不太会,但是其格式就是在pop_rdi_addr前面加上ret的地址,先记住吧。
payload代码
- 上一篇:[红包活动] 淘宝找春节同款抽随机红包
- 下一篇:[美图] 一树红花迎春来
猜你还喜欢
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[web] 免费公共DNS大全(IPv6+IPv4)
[硬件检测] 内存测试工具 MemTestPro 汉化版(7.0)
[硬件检测] 专业硬件检测工具 | HWiNFO(8.0.5400.0)
[系统加速] 利用内存给硬盘加速 | RamCache III 去限制版(1.01.12)
[游戏技巧] 龙之信条2存档备份教程(建议收藏)
[游戏资讯] 龙之信条2存档位置在哪 存档备份教程
[游戏资讯] 最近热门手游有哪些,装备全靠打的手游有哪些游戏,好玩的角色扮演游戏手游
[游戏资讯] 《无人深空》轨道新篇开启!快来定制自己的飞船探索宇宙吧
[游戏攻略] 2024咸鱼之王最强阵容 附雷电云手机搬砖教程
[云图志] 【皇马】Adidas Y-3 山本耀司联名广告 图集
[下载工具] Internet Download Manager 6.42.7 (IDM)
[即时通讯] 腾讯QQ PC版9.7.22.29315去广告绿色纯净版
[影视] 灌篮高手 WEB-DL版下载/Slam Dunk/スラムダンク/灌篮高手:THE FIRST/灌篮高手电影版 2022 The First Slam Dunk 61.35G
[开发环境] PhpStorm2023中文激活版v2023.3.3 正式版
[图像制作] Adobe Illustrator 2024 v28.1.0.141 破解版
[资料] 3000 套电影电视剧 LOGO 宣传片常用音效合集包
[截图软件] HyperSnap(截图软件)_v9.4.0.00_汉化破解版
[安卓软件] 酷我音乐APP_v10.7.6.4 去广告破解豪华VIP版
[输入法] 搜狗拼音输入法PC版13.13.0.8820精简优化版
[即时通讯] 微信PC版WeChat 3.9.9.43 多开防撤回绿色版
[影视] 灌篮高手 WEB-DL版下载/Slam Dunk/スラムダンク/灌篮高手:THE FIRST/灌篮高手电影版 2022 The First Slam Dunk 61.35G
[安卓软件] Android GIF助手 v3.9.7 GIF图片编辑器破解版
[影视] 如何做爱 WEB-DL版下载/第一次 2023 How to Have Sex 5.33G
[电视剧] 三体 (2024) 全8集 网飞版本 中文字幕 合集
[剧集] 繁花 (2023)[全30集][打包]
[影视] 三大队 WEB-DL版下载/Endless Journey/请转告局长,三大队任务完成了 2023 三大队 6.7G
[纪录片] 河西走廊【10集 国语 中文字幕 1080P 10.8G MP4】
[安卓软件] OfficeSuite中文版APP v14.2.50872.0破解版
[影视] 饥饿游戏:鸣鸟与蛇之歌 WEB-DL版下载/饥饿游戏:鸣鸟与蛇的歌谣 / 饥饿游戏前传:鸣鸟与灵蛇之歌(港) / 饥饿游戏:鸣鸟与游蛇之歌(台) / 鸣鸟与蛇之歌 / 鸣鸟与蛇的歌谣 / 鸣禽与蛇的歌谣 / 饥饿游戏前传 / The Hunger Games: The Ballad of Songbirds and Snakes 2023 The Ballad of Songbirds and Snakes 27.17G
[影视] 涉过愤怒的海 WEB-DL版下载/怒海 / Across the Furious Sea 2023 涉过愤怒的海 26.3G
- 最新评论
-
谢谢支持!!CC下载站 评论于:03-26 很棒的资源,感谢分享云体风身 评论于:03-26 感谢分享,好东西云体风身 评论于:03-26 谢谢支持!CC下载站 评论于:03-14 央视精品,感谢付出提供。qwer9009 评论于:03-14 谢谢支持!!!CC下载站 评论于:03-13 谢谢分享!Ypc9182 评论于:03-12 谢谢支持!!CC下载站 评论于:03-11 感谢本网站收集和提供这么多的资料,谢谢!Ypc9182 评论于:03-10 很棒的资源,支持一下lingzhi007 评论于:03-10
- 热门tag