0x01 前言
pwn题目有时候也有类似于计算的题目,通过输入值然后和程序内部的值进行比较,通常这种题目是非常简单的,本文的题目来源于山东省大学生科技节网络大赛决赛的一道pwn。
文件名为hexcalc,将在文章末尾给出,因为没有搭建环境,请自行在“/etc/problem/hexcalc/flag.txt”目录下创建flag.txt文件,内容随意,用于测试。
0x02 程序分析
程序是64位的,所以我们要在64位系统下做题,IDA也使用64位的。先跑一下看看吧。
只是简单的输入输出,但是长度似乎有限制,我们拿到IDA下面分析看看main函数。
主要的程序流程并不复杂,先是输入20个字符,然后通过check_password计算输入的字符串是否和password相等。这里的password是一个全局变量,双击能看到其值为0x14214242,如果输入的字符串结算结果正确那就执行print_flag()函数来打印flag{XXXX}。那我们就主要分析一下check_password函数。
check_password函数也不复杂,就是通过一个for循环,循环四次,每次计算DWORD(四字节)的长度,将和累加,然后返回,正好是我们输入的20个字符。其实这里可以将每次计算看作是一个int型数据累加和。因为int刚好是4字节。分析到这里我们大概就有思路了,只要输入的字符串的计算结果是0x14214242就可以了。可以让前四个字节的值为0x14214242后面的全部为0即可。
0x03 构造pyload
因为我们要计算的是内存里面的十六进制数,但我们们输入的是字符串,要转换为16进制数,所以肯定会有一些不可输入的字符,所以我们借助pwntools来解题。
我们来构造如下pyload:
1 2 3 |
password = 0x14214242 pyload = p32(password) pyload += p32(0)+p32(0)+p32(0)+p32(0) |
首先定义好4字节的password,然后通过p32转化为4字节字符串,然后后面全部补16字节的0
这个pyload打印出来其实长下面这样,仔细计算刚好20字节。
1 |
BB!\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 |
完整脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#coding:utf-8 from pwn import * conn = process("./hexcalc") print conn.recv() #构造pyload password +0 +0 +0 +0 =password password = 0x14214242 pyload = p32(password) pyload += p32(0)+p32(0)+p32(0)+p32(0) conn.sendline(pyload) print conn.recvline() |
运行结果如下:
0x04 结束语
其实这道题目相当于签到题了,稍微懂点pwn的就能解答出来,本文就简单的写一下,主要是练习IDA和pwntools的使用,以及程序的分析。