pass-1(前端验证)
这题前端验证,直接把js禁了就行
上传zoe.php 成功
pass-2(MIME绕过)
支持jpeg,png,gif类型,那就bp抓包该类型
pass-3(特殊后缀名绕过)
没有禁特殊后缀名,那就用php3,php4这样的上传
pass-4(.htaccess)
这题禁了很多。但是没禁.htaccess,就可以利用这个上传,先构建.htaccess
<FilesMatch "121.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
再把一句话写进121.txt 文件中,在把后缀名改成jpg即可。
最后用蚁剑连接121.jpg就可以了
pass-5(apache多个后缀名绕过)
deldot()函数从后向前检测,当检测到末尾的第一个点时会继续它的检测,但是遇到空格会停下来strrchr() 函数查找字符串在另一个字符串中最后一次出现的位置,并返回从该位置到字符串结尾的所有字符。这个字符串原来是判断后缀名,但是再被deldot去了一个.值后还有一个.,所以成功上传,构建zoe.php.空格.即可
apache1.x,2.x的解析漏洞,上传如a.php.rar a.php.gif 类型的文件名,可以避免对于php文件的过滤机制,但是由于apache在解析文件名的时候是从右向左读,如果遇到不能识别的扩展名则跳过,rar等扩展名是apache不能识别的,因此就会直接将类型识别为php,从而达到了注入php代码的目的zoe.php.rar
也可以user.ini : 自 PHP 5.3.0 起,PHP 支持基于每个目录的 .htaccess 风格的 INI 文件。此类文件仅 CGI/FastCGI SAPI 处理。此功能使得 PECL 的 htscanner 扩展作废。如果使用 Apache,则用.htaccess 文件有同样效果。php.ini 是 php的配置文件,.user.ini 中的字段也会被 php 视为配置文件来处理,从而导致 php 的文件解析漏洞。所以构建.user.ini文件为auto_prepend_file=3.png
意思是所有的php文件都自动包含666.jpg文件。.user.ini相当于一个用户自定义的php.ini。
3.png内容为一句话木马
再把user_ini.cache_ttl改的小一点,来让等待时间减少,单位是秒。再复制3.png地址,把3.png改为readme.php即可连接蚁剑。
pass-6(大小写绕过)
没有禁大小写,那就改大小写上传
pass-7(空格绕过)
没有用trim() 函数移除字符串两侧的空白字符或其他预定义字符。可以再php之后加上空格上传
旧版Windows Server中存在空格和dot漏洞类似于 a.php. 和 a.php[空格] 这样的文件名存储后会被windows去掉点和空格,从而使得加上这两个东西可以突破过滤,成功上传,并且被当作php代码来执行
pass-8(.绕过)
这题没有deldot()函数删除文件末尾点,所以可以再文件末尾加上 . 来上传
psaa-9(::$DATA)
php在window的时候如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持"::$DATA"之前的文件名 他的目的就是不检查后缀名。随意在文件值后加上::$DATA上传
pass-10(.空格.)
deldot()函数从后向前检测,当检测到末尾的第一个点时会继续它的检测,但是遇到空格会停下来strrchr() 函数查找字符串在另一个字符串中最后一次出现的位置,并返回从该位置到字符串结尾的所有字符。这个字符串原来是判断后缀名,但是再被deldot去了一个.值后还有一个.,所以成功上传
那就zoe.php.空格.这样的上传
pass-11(双写)
这题str_ireplace()找到php,php5之类的后缀名并把它替换为空,所以用双写上传
less-12(get00截断)
substr(字符串,从什么位置开始,返回长度) 函数返回字符串的一部分。
strrrpos(被查字符串,查找的字符串) 函数查找字符串在另一字符串中最后一次出现的位置(不区分大小写)。
也就是取出最后一个 . 之后的值,in_array(搜索的值,搜索到数组) 函数搜索数组中是否存在指定的值。
看与白名单是否相符,最后用随机数把文件名混淆。
既然有随机数,为了防止随机,就用00截断把随机数隔开,先上传白名单后缀名,再用bp改
这里遇到了点麻烦,用00截断时一直说上传出错,搜了说是php.ini的magic_quotes_gpc要关闭
我就把他关了,还有在使用00截断时php版本要小于5.3.34
less-13(post00截断)
这题和12题就是一个用get方式一个用post方式,差别就是post不会像get一样对%00自动解码
所以需要手动进行url编码
less-14(文件头)
这个题就是检测文件头来判断是否是jpg,png,gif类型可以直接在一句话的开头加上各个文件的文件头来绕过,要在bp把上传的php文件改后缀为白名单的
也可以搞一个图片马(copy 1.png/b+1.php/a 2.png)来绕过,不过因为有随机数会导致文件名改变,所以用bp抓包来看上传之后的文件名,之后再用
题目的文件包含漏洞来执行一句话。
less-15(文件头)getimagesize
getimagesize — 取得图像信息 ,获取的顺序为,宽,高,类型,属性(宽和高)。
image_type_to_extension — 根据指定的图像类型返回对应的后缀名。
利用这两个函数来判断上传的文件与白名单的文件类型是否相符。
还是和14题一样,图片马或者在开头加上文件头
less-16(文件头)exif_imagetype
这题提示说要把php_exif开了
exif_imagetype — 判断一个图像的类型。读取图像的第一个字节并检查其签名。这个函数速度比getimagesize快,但是需要开启php-exif
14,15,16基本一样,就是使用的函数不一样。
所以都可以用图片马或加文件头来绕过。
less-17(二次渲染)
basename() 函数返回路径中的文件名部分。
strrchr() 函数查找字符串在另一个字符串中最后一次出现的位置,并返回从该位置到字符串结尾的所有字符。
substr(字符串,从什么位置开始,返回长度) 函数返回字符串的一部分。
strrchr获取.后缀名,substr把. 去掉。然后判断后缀名和类型。
用move_uploaded_file把文件移动到新位置
imagecreatefromjpeg — 由文件或 URL 创建一个新图象。对上传的图片进行二次渲染。
srand(time());没什么用
strval() 函数用于获取变量的字符串值。
rand()函数生成随机整数。这两个就是给渲染后的图片取个随机名字
imagejpeg(图像,保存路径) — 输出图象到浏览器或文件。把图片输出到浏览器,然后保存的指定位置。然后删除原图片。
这题有jpg,png,gif三种,jpg和png在渲染之后很难找到他们与原图片之间没有改变的地方,而gif是无损的,找到没变的地方比较容易,所以用gif做
先上传一张正常的gif再让上传的图片与原图片比较,找到不变的地方,写入一句话即可
蓝色是不变的地方,在蓝色写入一句话,然后再次上传有一句话的图片,利用文件包含漏洞,不过因为上传之后对文件进行了重新命名,所以要用bp看一下上传之后的名字
加上一句话,然后上传
less-18(条件竞争)
这题前面都是正常的,不过他先上传文件,再判断文件后缀名,虽然会再判断之后删除不满足条件的文件,但是只要在他删除之前访问到上传的文件,把文件里的内容执行了,那么执行文件之后产生的内容服务器是不会管的。
<?php fwrite(fopen('a.php','w'),'<?php @eval($_POST["a"])?>');?>
先写一个名字为10.php生成小马的php文件,然后bp抓包不停的上传这个文件,上传过程中不停的访问这个文件,会有那么一些时候服务器反应不过来被我们访问到,那就会生成小马,并且在不断上传过程中是不会改变文件名的。
在写一个python
import requests
a="http://localhost/upload-labs-master/upload/10.php"
while True:
b=requests.get(url=a)
if b.status_code==200:
print('111')
break
把上传的文件传到intruder
然后clear,之后随便找一个不相干的数字add,比如我找长度的最后一个数字
选择numbers类型把数字设置大一点,把线程设置大一点
在不停上传的同时不停访问文件,直到出现111
less-19
less-20
file_exists(文件路径) 函数检查文件或目录是否存在。
pathinfo(文件,要返回的数组元素) 函数以数组的形式返回关于文件路径的信息。[dirname]: 目录路径;[basename]: 文件名;[extension]: 文件后缀名;[filename]: 不包含后缀的文件名。
这题主要是要绕过黑名单,可以用Windows命名规则来绕过,比如在php后面加点,空格,::$DATA,还有利用move_uploaded_file的特性,会把文件末尾的/.忽略
这题还有一个save_name会把名字改成upload-19.jpg,把jpg改成php再加上面的东西就行
less-21
这题先检查文件类型(in_array(搜索的值,搜索到数组) 函数搜索数组中是否存在指定的值。),再看save_name是否为空(empty),利用三目运算符来选择,save_name不空则选择save_name,空则选择上传的文件名字,再看选中的是不是数组(is_array),不是就将文件以点分割为数组,然后取出数组最后一个元素(end),检查后缀名是否符合(in_array),然后把数组第一个元素与count($file)-1个元素以点连接,之后就是正常的上传。
这题想不出来,看了wp,就说把save_name[0]=1.php,save_name[2]=jpg|png|gif
当我们手动为数组分配下标的时候,可以不管大小先后,是否连续去定义,且我们定义了几个,count就是多少。所以手动为save_name分配下标0和2,count为2,2-1=1,下标1为空,所以最终的file_name应该为1.php.,但是上传的为1.php,应该是Windows命名规则把后面的那个点忽略了,最保险的是下标0处改为1.php/,最后就会变成1.php/.,move_upload_file就会把/.忽略。
这题也可以用图片马绕过,配合文件包含漏洞。