WriteUp
web1
是一道正则匹配绕过的…web2
是一个sql
注入题,web3
大概也是sql
注入吧。
Web1
源码贴出来:
<?php
error_reporting(0);
if(!isset($_GET['act']) || !isset($_GET['p'])){
highlight_file(__FILE__);
exit();
}
if(trim($_GET['act']) === "" || trim($_GET['p']) === ""){
die('no null!');
}
$act = $_GET['act'];
$act = addslashes($act);
$p = $_GET['p'];
$p = addslashes($p);
if(preg_match('/[A-Za-z0-9(){};<>`]/i',$p) == 1){
die('waf');
}
if(preg_match('/[{};<>`]/i',$act) == 1){
die('waf');
}
if(preg_match('/[A-Za-z0-9(){};]+\(/i',$act) == 1){
die('hacker, your act has some problems!');
}
echo $p.$act;
echo $_;
eval($p.$act.';');
理解了大半天,最后还是把正则表达式给理解错了…心塞。
[] 是定义匹配的字符范围。比如[a-zA-Z0-9]表示相应位置的字符要匹配英文字符和数字。
对p
参数的限制是不能输入任何出现在[]
之间的字符,单独输入字母、数字、括号等都是会被匹配到的。
对act
参数的限制首先是不允许输入{};<>
中的任何一个字符。再其次,要求[]
中的任意字符不能直接接(
,刚开始理解为压根不能出现(
…
最终的payload
为:
?p=$_&act=GET[1]()&1=phpinfo
当时做题的时候对正则表达式会一直匹配,直到结束理解不太深刻吧。
Web2
这是一道原题。suctf2018 mutilsql
做的时候可以通过盲注拿到数据库user()
的值为suctf@host
…当然也是运气好,恰好测试了这个字段,然后就去找原题,很顺利地找到,直接用了poc
…就getshell
,拿到flag
了。
题目的问题是:
后台在显示用户的信息的时候,会在数据库中进行一个查询操作,这里存在一个二次注入。后台的sql
语句应该是:
select * from xxx where username='username'
在注册时候单引号等等应该都被过滤了,但是在再次查询时候过滤不够,导致sql
注入。
Web3
没有思路,只知道过滤了一些报错注入会用到的函数。