红日安全——代码审计项目复现~

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

[红日安全]代码审计Day1 - in_array函数缺陷

Day 2 Twig

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,但是绕过之后,执行命令发现没有反应~~不晓得什么情况~

Resources:

SSRF技巧之如何绕过filter_var( )

浅谈CTF中命令执行与绕过的小技巧