upload-labs靶场通关教程
Pass-01
我们先上传带有一句话木马的1.php
查看页面源代码发现是前端js弹窗,我们直接禁用前端即可。
再进行上传1.php,我们就可以上传了。
Pass-02
做完每一题之后,我们最好清理一下上传的文件,以免对后续操作产生影响。
依旧上传1.php,但是发现不行
我们抓包,将content-Type改成image/png,再次上传发现成功上传
从源码上的角度去看
只判断了file的type的值,就可以绕过了
Pass-03
依旧先上传1.php
提示:不允许上传.asp,.aspx,.php,.jsp后缀文件
我们只需要上传.phtml就可以绕过,上传
从源码上看
这里只对后缀进行了限制,并没有对content-type,所以我们可以原封不动
Pass-04
之后过滤的会越来越多,因为是靶场,我们可以直接从源码入手
关键过滤代码为- $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");
复制代码 过滤了非常多,但仔细发现并没有过滤.htaccess文件
我们可以先上传.htaccess文件- AddType application/x-httpd-php .jpg .txt .png
复制代码 再去上传1.png,内容为一句话木马
Pass-05
关键过滤代码为- $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");
复制代码 这里过滤了上一题的.htaccess但没有过滤.user.ini然后再去上传1.jpg
Pass-06
直接看源码
可以发现少了一行转小写的代码,那我们直接大小写绕过
放包即可上传
Pass-07
这关源码删去了trim()函数,也就是用来去除字符串两端的空格,所以我们如果在上传文件的后缀名里面加上空格,不属于黑名单内容,我们就可以成功进行上传
放包上传即可
Pass-08
可以看到没有使用deldot()过滤文件名末尾的点,可以使用文件名后加 .进行绕过,即1.php.
Pass-09
缺少了- $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
复制代码 php在window的时候如果文件名+": DATA"会把: DATA之后的数据当成文件流处理,不会检测后缀名,且保持": DATA"之前的文件名 他的目的就是不检查后缀名。
注意这里url中要删掉最后的: DATA
Pass-10
使用 deldot() 删除文件名末尾的点
deldot() 函数从末尾向前检测,检测到第一个点后,会继续向前检测,但遇到空格会停下来
可以构造文件名:1.php. .绕过检测
url中依旧是去掉后面的字符,保留到1.php
Pass-11
查看源码我们可以发现他仅仅对文件名称进行了替换,替换之后的后缀没有进行黑名单验证,这里我们就可以使用双写文件后缀进行文件上传
Pass-12
这一关白名单,通过%00截断可绕过白名单限制,但需确保PHP版本低于5.3.4且magic_quotes_gpc已关闭。
原理简述:PHP函数如move_uploaded_file在底层C语言实现时,会因遇到0x00(URL编码为%00)截断字符串。利用此特性,可绕过某些文件上传限制。
即可上传成功- 代码分析:
- $is_upload = false;
- $msg = null;
- 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;
- if(move_uploaded_file($temp_file,$img_path)){
- $is_upload = true;
- } else {
- $msg = '上传出错!';
- }
- } else{
- $msg = "只允许上传.jpg|.png|.gif类型文件!";
- }
- }
- 知识补充:
- php的一些函数的底层是C语言,而move_uploaded_file就是其中之一,遇到0x00会截断,0x表示16进制,URL中%00解码成16进制就是0x00。
- strrpos(string,find[,start]) 函数查找字符串在另一字符串中最后一次出现的位置(区分大小写)。
- substr(string,start[,length])函数返回字符串的一部分(从start开始 [,长度为length])
- magic_quotes_gpc 着重偏向数据库方面,是为了防止sql注入,但magic_quotes_gpc开启还会对$_REQUEST, $_GET,$_POST,$_COOKIE 输入的内容进行过滤
复制代码 Pass-13
第13题与12题思路一样使用白名单限制上传文件类型,但上传文件的存放路径可控,- $img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
复制代码 但因为是POST型,需要对%00进行解码或在16进制中修改,POST不会像GET那样对%00进行自动解码。
Pass-14
本关会读取判断上传文件的前两个字节,判断上传文件类型,并且后端会根据判断得到的文件类型重命名上传文件
使用 图片马 + 文件包含 绕过- 补充:
- 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里执行 **copy logo.jpg/b+test.php/a test.jpg**
- #logo.jpg为任意图片;test.php 插入的木马文件;test.jpg 生成的图片木马
复制代码
然后将test.png上传
再点击黄色的文件包含漏洞字眼
然后打一个很简单的文件包含漏洞
Pass-15
使用getimagesize()检查是否为图片文件
- getimagesize() 函数用于获取图像大小及相关信息,成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息。
- 主要是针对*.php直接更改文件后缀为图片后缀,上一题创建的图片马仍然可以使用。
复制代码
Pass-16
- exif_imagetype()读取一个图像的第一个字节并检查其后缀名。
- 返回值与getimage()函数返回的索引2相同,但是速度比getimage快
复制代码 方法同Pass-14
Pass-17
- $is_upload = false;
- $msg = null;
- if (isset($_POST['submit'])){
- // 获得上传文件的基本信息,文件名,类型,大小,临时文件路径
- $filename = $_FILES['upload_file']['name'];
- $filetype = $_FILES['upload_file']['type'];
- $tmpname = $_FILES['upload_file']['tmp_name'];
- $target_path=UPLOAD_PATH.'/'.basename($filename);
- // 获得上传文件的扩展名
- $fileext= substr(strrchr($filename,"."),1);
- //判断文件后缀与类型,合法才进行上传操作
- if(($fileext == "jpg") && ($filetype=="image/jpeg")){
- if(move_uploaded_file($tmpname,$target_path)){
- //使用上传的图片生成新的图片
- $im = imagecreatefromjpeg($target_path);
- if($im == false){
- $msg = "该文件不是jpg格式的图片!";
- @unlink($target_path);
- }else{
- //给新图片指定文件名
- srand(time());
- $newfilename = strval(rand()).".jpg";
- //显示二次渲染后的图片(使用用户上传图片生成的新图片)
- $img_path = UPLOAD_PATH.'/'.$newfilename;
- imagejpeg($im,$img_path);
- @unlink($target_path);
- $is_upload = true;
- }
- } else {
- $msg = "上传出错!";
- }
- }else if(($fileext == "png") && ($filetype=="image/png")){
- if(move_uploaded_file($tmpname,$target_path)){
- //使用上传的图片生成新的图片
- $im = imagecreatefrompng($target_path);
- if($im == false){
- $msg = "该文件不是png格式的图片!";
- @unlink($target_path);
- }else{
- //给新图片指定文件名
- srand(time());
- $newfilename = strval(rand()).".png";
- //显示二次渲染后的图片(使用用户上传图片生成的新图片)
- $img_path = UPLOAD_PATH.'/'.$newfilename;
- imagepng($im,$img_path);
- @unlink($target_path);
- $is_upload = true;
- }
- } else {
- $msg = "上传出错!";
- }
- }else if(($fileext == "gif") && ($filetype=="image/gif")){
- if(move_uploaded_file($tmpname,$target_path)){
- //使用上传的图片生成新的图片
- $im = imagecreatefromgif($target_path);
- if($im == false){
- $msg = "该文件不是gif格式的图片!";
- @unlink($target_path);
- }else{
- //给新图片指定文件名
- srand(time());
- $newfilename = strval(rand()).".gif";
- //显示二次渲染后的图片(使用用户上传图片生成的新图片)
- $img_path = UPLOAD_PATH.'/'.$newfilename;
- imagegif($im,$img_path);
- @unlink($target_path);
- $is_upload = true;
- }
- } else {
- $msg = "上传出错!";
- }
- }else{
- $msg = "只允许上传后缀为.jpg|.png|.gif的图片文件!";
- }
- }
复制代码 根据源码和题目提示可以得知这是一个二次渲染
上传的图片经过了后缀名、内容类型和imagecreatefromgif函数的严格验证,确保其为GIF格式。随后,图片经过了二次渲染处理。然而,在后端的二次渲染过程中,需要识别并标记出渲染后未发生改变的十六进制(Hex)区域。通过利用文件包含漏洞,可以在这些未变区域嵌入恶意代码,进而使用蚁剑工具进行远程连接和操作。
这里的二次渲染图片使用大菜鸡师傅的。
先上传一张原始jpg,然后直接下载二次渲染后的jpg
脚本如下:
[code] |