【红日Day14-CTF】变量覆盖造成SQL注入

练习记录

复现代码:

https://pan.baidu.com/s/1pHjOVK0Ib-tjztkgBxe3nQ 密码: 59t2

漏洞分析:

进入网站:

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

在这里插入图片描述
这次的CTF题目考察的是一个SQL注入问题,且解法有两种(PHP版本为5.2.x)。我们先来看一下整个网站的框架。

day 应用部署目录
├─css 存放css静态文件
├─image 存放图片文件
├─config.php 连接mysql的配置文件
├─content.php 留言查看文件
├─do.php 留言文件
├─function.php 全局功能函数
├─global.php 全局过滤文件
├─index.php 主页文件
├─login.php 登录文件
├─logout.php 登出文件
├─register.php 注册文件
├─waf.php WAF文件

在观察程序的过程中,我们明显发现 content.php文件中存在 变量覆盖SQL注入漏洞。

include './global.php';
extract($_REQUEST);

$sql = "select * from test.content where id=$message_id";
$arr = select($sql);

但是在程序开头,引入了全局过滤文件global.php,我们这里还要看看它是如何进行过滤的。
global.php引用了3个文件
在这里插入图片描述
waf.php中,我们可以明显看到程序对 GET 、 POST 、 COOKIES 三种数据处理方式不一样。

<?php
    
foreach ($_GET as $key => $value) {
    if ($key != "username"&&strstr($key, "password") == false) {
        $_GET[$key] = filtering($value);
    }
}
foreach ($_POST as $key => $value) {
    if ($key != "username"&&strstr($key, "password") == false) {
        $_POST[$key] = filtering($value);
    }
}
foreach ($_REQUEST as $key => $value) {
    if ($key != "username"&&strstr($key, "password") == false) {
        $_REQUEST[$key] =   ($value);
    }
}

$request_uri = explode("?", $_SERVER['REQUEST_URI']);
if (isset($request_uri[1])) {
    $rewrite_url = explode("&", $request_uri[1]);
    foreach ($rewrite_url as $key => $value) {
        $_value = explode("=", $value);
        if (isset($_value[1])) {
            $_REQUEST[$_value[0]] = dhtmlspecialchars(addslashes($_value[1]));
        }
    }
}

foreach ($_POST as $key => $value) {
    $_POST[$key] = safe_str($value);
    $_GET[$key] = dhtmlspecialchars($value);
}
foreach ($_COOKIE as $key => $value) {
    $_COOKIE[$key] = safe_str($value);
    $_GET[$key] = dhtmlspecialchars($value);
}
    
?>

下面,我们分别来看这两种解法。

解法一:

可以通过GETPOSTcontent.php 文件传递如下payload 获取flag:

message_id=-1/*%00*/union/**/select/**/1,flag,3,4/**/from/**/flag

如果是 GET方式传递数据的话,数据会经过filtering函数过滤,而在filtering 函数中,开头的 eregi检测,我们又可以使用%00 截断绕过,但是下方还有循环替换恶意字符的代码,这里无法绕过。filtering函数代码如下:
在这里插入图片描述

也就是说我们的 payload 经过 filtering函数处理后变成了下面这样( select 被过滤掉了):

message_id=-1/*%00*/union/**//**/1,flag,3,4/**/from/**/flag

当我们继续看代码时,会发现下面的代码又把 message_id 变量的值还原了。因为 content.php文件中有代码: extract($_REQUEST),所以这里也就造成了注入。
在这里插入图片描述
那如果是 POST 方式传送数据,会先经过filtering函数处理,然后经过 safe_str函数。 safe_str函数主要用了 addslashes函数过滤数据,可以发现对我们的 payload 并没有影响。 safe_str 函数代码如下:
在这里插入图片描述
这里能进行注入的原因,主要是因为超全局数组 $_REQUEST中的数据,是 $_GET 、 $_POST 、 $_COOKIE的合集,而且数据是复制过去的,并不是引用。所以对$_GET 、 $_POST处理并不会影响$_REQUEST中的数据。

在这里插入图片描述

解法二:

第二种解法是通过COOKIE 的方式进行解题。我们会发现程序对COOKIE数据的处理方式,明显和处理$_GET 、 $_POST的方式不一样。对 COOKIE数据的处理方式具体如下:
在这里插入图片描述
payload 为:message_id=0 union select 1,2,flag,4 from flag现在连eregi函数都不用绕了。
在这里插入图片描述

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

猜你喜欢

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