红日安全——代码审计项目复现~
Day 1 Wish List
in_array()
(PHP 4, PHP 5, PHP 7)
in_array — 检查数组中是否存在某个值
bool in_array ( mixed
$needle(待搜索值)
, array$haystack(待搜索的数组)
[, bool$strict
= FALSE ] )
因为php是弱类型语言,in_array()第三个参数如果没有设置TRUE的话,就不会检查needle和haystack类型是否相同,若不同就会进行强制转换,进而导致绕过,造成任意文件上传。
课后练习--SQL Injection
//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 "<center><table border='1'>";
foreach ($row as $key => $value) {
echo "<tr><td><center>$key</center></td><br>";
echo "<td><center>$value</center></td></tr><br>";
}
echo "</table></center>";
}
else{
die($conn->error);
}
?>
//config.php
<?php
$servername = "localhost";
$username = "fire";
$password = "fire";
$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;
}
?>
# 搭建CTF环境使用的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','Lucia@hongri.com',3000);
INSERT INTO users VALUES(2,'Danny','Danny@hongri.com',4500);
INSERT INTO users VALUES(3,'Alina','Alina@hongri.com',2700);
INSERT INTO users VALUES(4,'Jameson','Jameson@hongri.com',10000);
INSERT INTO users VALUES(5,'Allie','Allie@hongri.com',6000);
create table flag(flag varchar(30) not null);
INSERT INTO flag VALUES('HRCTF{1n0rrY_i3_Vu1n3rab13}');
此题包含一个in_array和一个sql报错注入,但是这里的in_array绕过与否,对拿flag没什么影响。
in_array()
这里的白名单是用户的id,1~5,如果id不在白名单内的话,会返回id $id is not in whitelist.
绕过,只需以数字开头,后面随意,即会返回Unknown cloumn '' in 'where clause'
即绕过成功。
updatexml()
由于stop_hack()函数里面过滤了很多关键字,所以很多注入都无法实现,这里我用updatexml(),但是字符串拼接函数也被禁用了,然后又get到了一些新姿势
MAKE_SET(bits,str1,str2,...)
可以按照上图来理解
也可以理解为:
bits的参数会转为二进制,如,1为,0001,倒过来排序,则为1000,将bits后面的字符串str1,str2等,放置在这个倒过来的二进制排序中,取出值为1对应的字符串,则得到welcome;如, 1 | 4 -> 0001 | 0100 = 0101 倒序排列的到 1010 得到 welcome,w3r,还有要注意的就是NULL,不取出 ,只有二进制为1时才会取出对应字符串 。
还可以找到类似的函数:lpad()、reverse()、repeat()、export_set()(lpad()、reverse()、repeat()这三个函数使用的前提是所查询的值中,必须至少含有一个特殊字符,否则会漏掉一些数据)。
Resources:
updatexml injection without concat
Day 2 Twig
Twig模版引擎
这是一个模版语言,相当于把一些冗长的语句简化成模版,本题{{link|escape}},只是相当于用php内置函数htmlspecialchars去转义字符。
htmlspecialchars
(PHP 4, PHP 5, PHP 7)
htmlspecialchars — 将特殊字符转换为 HTML 实体
string htmlspecialchars ( string
$string
[, int$flags
= ENT_COMPAT | ENT_HTML401 [, string$encoding
= ini_get("default_charset") [, bool$double_encode
= TRUE ]]] )
filter_var()
filter_var
(PHP 5 >= 5.2.0, PHP 7)
filter_var — 使用特定的过滤器过滤一个变量
mixed filter_var ( mixed
$variable(待过滤变量)
[, int$filter(过滤类型)
= FILTER_DEFAULT [, mixed$options
]] )
这题用js伪协议好像绕过不了~
课后练习--SSRF
// index.php
<?php
$url = $_GET['url'];
if(isset($url) && filter_var($url, FILTER_VALIDATE_URL)){
$site_info = parse_url($url);
if(preg_match('/sec-redclub.com$/',$site_info['host'])){
exec('curl "'.$site_info['host'].'"', $result);
echo "<center><h1>You have curl {$site_info['host']} successfully!</h1></center>
<center><textarea rows='20' cols='90'>";
echo implode(' ', $result);
}
else{
die("<center><h1>Error: Host not allowed</h1></center>");
}
}
else{
echo "<center><h1>Just curl sec-redclub.com!</h1></center><br>
<center><h3>For example:?url=http://sec-redclub.com</h3></center>";
}
?>
// f1agi3hEre.php
<?php
$flag = "HRCTF{f1lt3r_var_1s_s0_c00l}"
?>
本题要构造以sec-redclub.com结尾,而且还要绕过filter_var,但是绕过之后,执行命令发现没有反应~~不晓得什么情况~