靶场下载链接
https://github.com/c0ny1/upload-labs
话不多说,直接喂饭
lab-1
上传php木马,发现弹出提示框,查看源码可知是前端过滤
bp抓包,先上传一张正常的jpg图片
修改文件内容和后缀,大概就是想怎么改就怎么改的样子
比如这样
拿下
然后蚁剑连接图片(在图片处右击,即可获得图片位置)
lab-2
第二关修改 Content-Type为 image/jpeg
tips:MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准。MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。image/jpeg
lab-3
修改.php后缀
php跟phtml的关系
PHP(Hypertext Preprocessor)是一种通用的开源脚本语言,用于服务器端的Web开发。它可以嵌入到HTML中,通过服务器端的解析运行来生成动态的Web页面。
PHTML(PHP HTML)是一种特定于PHP的文件扩展名,它表示包含PHP代码的HTML文件。实际上,PHTML文件本质上是HTML文件,但可以在其中嵌入PHP代码,使页面具有动态功能。
因此,PHTML文件本质上是PHP文件的一种变体,用于在HTML文件中嵌入PHP代码和逻辑。这样,开发人员可以使用PHP的强大功能来处理表单数据、数据库连接和其他服务器端操作,同时保持页面的结构和样式。
lab-4
把所有不符合的后缀都过滤了
.htaccess作用
.htaccess(Hypertext Access)是一个在 Apache Web 服务器上使用的配置文件,用于控制和定制Web服务器的行为。它是一个纯文本文件,通常位于网站的根目录中。
.htaccess 文件的作用很多,下面列举几个常见的应用场景:
1. 重定向和URL重写:可以使用.htaccess 文件来设置 URL 重写规则,将不同的 URL 请求重定向到指定的页面或修改 URL 结构。比如,可以将动态的 URL 修改为更友好更易读的静态 URL。
2. 访问控制:通过.htaccess 文件,可以限制特定目录或文件的访问权限。可以设置密码保护目录,仅允许授权用户访问。
3. MIME 类型设置:.htaccess 文件还可以设置文件的 MIME 类型,指示服务器如何解释和处理不同类型的文件。
4. 缓存控制:通过.htaccess 文件,可以配置网页的缓存策略,以优化网站的加载速度和减少服务器负载。
5. 错误处理:可通过.htaccess 文件自定义错误页面,当服务器发生错误时,将会显示自定义的错误页面,提供更友好的用户体验。
简单来说,就是让服务器在解析文件的时候,.htaccess文件所在目录下,全部以php文件解析
lab-5
和第四关一样,并且加上了.htaccess,但是没有将后缀进行大小写统一,于是可以通过大小写绕过
lab-6
黑名单过滤,对比第五关发现没有对后缀名进行去空处理,可在后缀名中加空格绕过
lab-7
查看源码发现没有对后缀名进行去”.”处理。通常情况下,当访问一个网址时,Web服务器会尝试解析URL中的路径,并根据设置的规则去寻找对应的文件。而在解析文件路径时,Web服务器会自动去掉文件后缀名中最后的点"."。可在后缀名中加”.”绕过
lab-8
对比前几关发现还是黑名单,但是没有对后缀名进行去“::$DATA”处理,利用windows特性,可在后缀名中加” ::$DATA”绕过
lab-9
对比前面的几关,路径拼接的是处理后的文件名,于是构造info.php. . (点+空格+点),经过处理后,文件名变info.php.,即可绕过
lab-10
审计源码,发现第十关是将后缀名替换为空,于是可以利用双写进行绕过
连接一句话木马
lab-11
审计一下源码,发现为白名单过滤
$img_path直接拼接,因此可以利用%00截断绕过
%00截断
00截断是操作系统层的漏洞,由于操作系统是C语言或汇编语言编写的,这两种语言在定义字符串时,都是以\0(即0x00)作为字符串的结尾。操作系统在识别字符串时,当读取到\0字符时,就认为读取到了一个字符串的结束符号。因此,我们可以通过修改数据包,插入\0字符的方式,达到字符串截断的目的。
字符串截断攻击是利用输入验证或处理中的漏洞,通过插入特定的字符来截断字符串,改变原本的逻辑或绕过限制。当 %00 字符被插入到字符串中时,它会被用作字符串的终止字符,导致后续的内容被忽略。
tips:
php环境中截断条件:
1.php版本小于5.3.4 详情关注CVE-2006-7243
2.php的magic_quotes_gpc为OFF状态,便会有00截断,利用00截断上传。
lab-12
和十一关不同的是这次的save_path是通过post传进来的,还是利用00截断,但这次需要主动解码,因为post不会像get对%00进行自动解码。
然后就会消失了
lab-13
图片马
图片马制作比较简单,需要一张图片, 一个php文件。
通过copy将图片和php文件组合在一起。
使用cmd执行如下命令
copy 123.jpg /b + shell.php /a shell.jpg
tips:图片在前,php代码在后,先/b后/a ,顺序颠倒就不成功了
lab-14
这关和lab-13一样,只需要上传图片马即可。
函数的作用:会对目标文件的16进制去进行一个读取,去读取头几个字符串是不是符合图片的要求的。
lab-15
以利用图片马就可进行绕过
exif_imagetype() 读取一个图像的第一个字节并检查其签名.本函数可用来避免调用其它 exif 函数用到了不支持的文件类型上和$_SERVER[‘HTTP_ACCEPT’] 结合使用来检查浏览器是否可以显示某个指定的图像。
lab-16
本关综合判断了后缀名、content-type,以及利用imagecreatefromgif判断是否为gif图片,最后再做了一次二次渲染,绕过方法
上传上去发现里面的一句话木马被渲染了
试试其他的写入方法
二次渲染
二次渲染就是根据用户上传的照片,新生成一个照片,删除原始照片,将新照片添加到数据库中。比如一些网站将用户上传的头像生成大中小的图像,在二次渲染中,我们在图片中写的木马也会渲染掉。
lab-17
条件竞争
文件先保存在upload文件夹下,然后再判断是否合法,若合法则进行重命名,否则调用unlink函数删除非法文件。
审计代码发现存在条件竞争问题,非法文件上传后会先保存在upload目录下,然后调用unlink函数删除,在这中间时间差里,我们通过不断上传和访问非法文件,只要速度快就可以触发成功。
- 先设置上传shell.php请求,burp拦截到上传文件后发送到爆破模块,因为这里没有参数需要爆破,只需反复发起请求即可,所以payload设置为null payloads,请求次数为6000次,线程为50.
- 接下来设置访问请求,浏览器构造请求url://http://192.168.10.136/upload-labs/upload/info.php,进行访问,发送到burp的爆破模块、6000次请求次数、50个线程。
- 同时开始攻击,观察第二个请求返回的长度,长度不一样的则成功。
这里的第二个攻击也可以利用脚本实现:
import requests
url = "http://192.168.1.106/upload-labs/upload/info.php"
while True:html = requests.get(url)if html.status_code == 200:print("OK")break
最后直接变为病毒库
lab-18
$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 1if( $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 fileif( $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" );}
......
......
......
};
这关的myupload.php中保存上传文件路径的代码其实是有点问题的,setDir函数里$this->cls_upload_dir = $dir;应该加上’/’,改为$this->cls_upload_dir = $dir.'/';,不然保存的图片只会保存在根目录下,不会保存在upload目录下。
本关和lab-17一样存在条件竞争漏洞,关键函数move、renameFile,先将上传文件保存到upload目录下,再进行重命名,只不过在move之前进行了checkExtension白名单过滤,不能上传php文件进行文件包含来getshell了。幸运的是白名单里有zip、7z、rar等Apache不能解析的后缀名,所以我们可以利用条件竞争+解析漏洞来绕过。 绕过方法: 和上一关一样,上传并访问info.php.7z
lab-19
这关比较简单,pathinfo()返回一个关联数组包含有$file_name的信息,第二个参数PATHINFO_EXTENSION决定了返回后缀名。从我们自定义的文件名save_name中取出后缀名,与黑名单比较,最后与上传目录拼接起来变为上传路径。
绕过方法:
靶机为Windows:
- 空格绕过
- ::$DATA绕过
- 点绕过
- 0x00截断
- 大小写绕过
- Apache解析漏洞绕过
- /.绕过
tips:move_uploaded_file()会忽略掉文件末尾的/.,所以可以构造save_path=1.php/.,这样file_ext值就为空,就能绕过黑名单,而move_uploaded_file()函数忽略文件末尾的/.可以实现保存文件为.php。
靶机为linux:
- 0x00截断绕过
- /.绕过
lab-20
explode() 函数使用一个字符串分割另一个字符串,并返回由字符串组成的数组,这里是用 . 将文件名打散,并返回数组。 reset() 函数把数组的内部指针指向第一个元素,并返回这个元素的值。 end() 函数将数组内部指针指向最后一个元素,并返回该元素的值(如果成功)。
函数执行流程:文件名通过POST方法提交->MIME白名单校验->后缀名白名单校验->获取文件名并拼接后缀名,构成上传路径 关键:is_array函数判断文件名save_name是否是数组,若不是则用explode函数以.来打散成数组,end函数获取文件后缀、reset获取文件名,最后f i l e [ c o u n t ( file[count(file[count(file) - 1]拼接上最后一个文件后缀=>构成上传路径。
绕过方法: 这里可以构造save_name[0] = info.php/,save_name[2] = jpg,这样数组的长度为2,save_name[1] = null,所以最终file_name=info.php/.,到这里就构成了19题中的/.绕过。
0x00截断绕过,不过php版本要低于5.3.4
参考链接:upload-labs_拓海AE的博客-CSDN博客