题目地址:
https://github.com/eboda/insomnihack/tree/master/l33t_hoster
源码如下:
phpif (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",);
//限制了php文件上传,黑名单形式,那么肯定可以绕过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); //array_pop删除数组最后一个元素并返回该元素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 "";foreach(glob($userdir . "*") as $file) {echo ";
}echo "";?>
Upload your pics!
这道题首先可以上传.htaccess,那么此时就可以让服务器去解析任意后缀当作php执行,一步一步看
首先
if (count($parts) === 0) {die("lol filename is empty");
}
这一段代码判断$parts的值,但是如果上传.htacess,经过array_pop和array_shift将变成空数组,此时将无法向下执行,又因为程序是以.点分割,所以直接..htacess就可以绕过,即最后将拼接成.htaccess,我修改了一下代码,var_dump了一下$FILES数组,此时可以看看$FILES数组的内容:
接下来要绕过exif_imagetype()函数和getimagesize()函数,查一下这两个函数的用法
也就是将检查我们上传的文件,并返回一个常量,否则返回false,那我们要让.htaccess文件绕过它,就要针对它的检测特性去构造数据,因为它最终要返回常量,那我们就要让这个函数认为.htaccess为一个合法的图像类型
其中常量包括:
预期解法:
采用xbm格式,X Bit Map
在计算机图形学中,X Window系统使用X BitMap(XBM),一种纯文本二进制图像格式,用于存储X GUI中使用的光标和图标位图
XBM数据由一系列包含单色像素数据的静态无符号字符数组组成。当格式被普遍使用时,XBM通常出现在标题(.h文件)中,每个图像在标题中存储一个数组。以下C代码示例了一个XBM文件:
也就是用c代码来标识一个xbm文件,前两个#defines指定位图的高度和宽度(以像素为单位),比如以下xbm文件:
#define test_width 16
#define test_height 7
static char test_bits[] ={0x13, 0x00, 0x15, 0x00, 0x93, 0xcd, 0x55, 0xa5, 0x93, 0xc5, 0x00, 0x80,0x00, 0x60 };
在这个c文件中高和宽都是有#在前面的,那么我们即使把它放在.htaccess文件中也不会影响.htaccess的实际运行效果,所以新的.htaccess文件内容如下
#define width 1337 # Define the width wanted by the code (and say we are a legit xbitmap file lol)
#define height 1337 # Define the heightAddType application/x-httpd-php .php16 # Say all file with extension .php16 will execute php
php_value zend.multibyte1# Active specific encoding (you will see why after :D)
php_value zend.detect_unicode1 # Detect ifthe file have unicode content
php_value display_errors1 # Display php errors
接下来可以上传php16了,那么对于上传的php要绕过其