得到题目输入1,返回一个数组
![又是堆叠注入([SUCTF 2019]EasySQL) - 图1](/uploads/projects/u390550@fftlfh/ed069051b5004a66f40c9474b4fcfb82.png)
不由得让我想起春秋战役里面的堆叠注入
经过尝试(‘),(“)都被过滤了
简单试一试输入,发现有三种回显,分别位’nonono’,空以及返回array
在这里,很多都被返回了nonono,我想应该是被过滤了,但是太多我们都不可能一一尝试,所以跑一下字典
![又是堆叠注入([SUCTF 2019]EasySQL) - 图2](/uploads/projects/u390550@fftlfh/53a2e3f9f88c6bfa39b462b0f561f0e9.png)
很明显,507的应该是被过滤的字符。由于和春秋战役太相似,春秋战役直接给我来了个正则很长。这咋办。
所以我们试试堆叠注入
![又是堆叠注入([SUCTF 2019]EasySQL) - 图3](/uploads/projects/u390550@fftlfh/d2281f8a35de2446448f76f0fbea95b6.png)
果然返回来了,那无疑是堆叠注入了
但是。接下来有个头疼的地方了,flag这个被过滤了
怎么爆字段。发现有源码:
<?phpsession_start();include_once "config.php";$post = array();$get = array();global $MysqlLink;//GetPara();$MysqlLink = mysqli_connect("localhost",$datauser,$datapass);if(!$MysqlLink){die("Mysql Connect Error!");}$selectDB = mysqli_select_db($MysqlLink,$dataName);if(!$selectDB){die("Choose Database Error!");}foreach ($_POST as $k=>$v){if(!empty($v)&&is_string($v)){$post[$k] = trim(addslashes($v));}}foreach ($_GET as $k=>$v){}}//die();?><html><head></head><body><a> Give me your flag, I will tell you if the flag is right. </ a><form action="" method="post"><input type="text" name="query"><input type="submit"></form></body></html><?phpif(isset($post['query'])){$BlackList = "prepare|flag|unhex|xml|drop|create|insert|like|regexp|outfile|readfile|where|from|union|update|delete|if|sleep|extractvalue|updatexml|or|and|&|\"";//var_dump(preg_match("/{$BlackList}/is",$post['query']));if(preg_match("/{$BlackList}/is",$post['query'])){//echo $post['query'];die("Nonono.");}if(strlen($post['query'])>40){die("Too long.");}$sql = "select ".$post['query']."||flag from Flag";mysqli_multi_query($MysqlLink,$sql);do{if($res = mysqli_store_result($MysqlLink)){while($row = mysqli_fetch_row($res)){print_r($row);}}}while(@mysqli_next_result($MysqlLink));}?>
看到mysql_multi_query(),可以堆叠注入
![又是堆叠注入([SUCTF 2019]EasySQL) - 图4](/uploads/projects/u390550@fftlfh/34e178d2df14e7a70cf969536cd7afd1.png)
那确实,但是他妈的被过滤了咋整
我们发现,查询语句为
![又是堆叠注入([SUCTF 2019]EasySQL) - 图5](/uploads/projects/u390550@fftlfh/b58279fbd19798bb04c84bb85825c4eb.png)
通过堆叠注入sql_mode的值为PIPES_AS_CONCAT
![又是堆叠注入([SUCTF 2019]EasySQL) - 图6](/uploads/projects/u390550@fftlfh/d96c1ac5e013d3c190605a5e124b878c.png)
![又是堆叠注入([SUCTF 2019]EasySQL) - 图7](/uploads/projects/u390550@fftlfh/c04f7281cdd941ab46c081d7d1cf7078.png)
这里解释一下PIPES_AS_CONCAT
![又是堆叠注入([SUCTF 2019]EasySQL) - 图8](/uploads/projects/u390550@fftlfh/7809d8b6a66978012ff5117029dba523.png)
这句话sql语句的意思是开启mysql中支持管道符来进行字符串的拼接操作
简单准备的原始数据表:
![又是堆叠注入([SUCTF 2019]EasySQL) - 图9](/uploads/projects/u390550@fftlfh/3b479ff450bb416c887c772b3f7164d3.png)
没有开启这个模式的时候
![又是堆叠注入([SUCTF 2019]EasySQL) - 图10](/uploads/projects/u390550@fftlfh/39bc240e64a1c2d95fb396a86a9947d0.png)
开启了这个模式后
![又是堆叠注入([SUCTF 2019]EasySQL) - 图11](/uploads/projects/u390550@fftlfh/93e5ffc33f56b90c8eec13be5e3ab708.png)
可以从上图看到,数据表中的数据被带出来了,下面这张图更清晰
![又是堆叠注入([SUCTF 2019]EasySQL) - 图12](/uploads/projects/u390550@fftlfh/ca8fbd1401c7f913f272fa3d4565c8ec.png)
从而将 || 视为字符串的连接操作符而非或运算符,所以构造出来
只输入数字进行查询是因为,执行数字时有回显,判断是执行成功的,查询字符串则会报错,一般来说php会设置默认不显示报错信息,因此使用数字查询开启这个模式来手动构造注入漏洞
这样在进行查询的时候将||运算符当成连接符成这样的语句
select 1,flag from Flag
