
गोलंग बाइनरीज़ के लिए एक कमांड लाइन विंडोज API ट्रेसिंग टूल।
Golang बायनरी फ़ाइलों के लिए एक कमांड लाइन Windows API ट्रेसिंग टूल।
नोट: यह टूल एक PoC और कार्य-प्रगति वाला प्रोटोटाइप है, कृपया इसे वैसे ही समझें। प्रतिक्रिया का हमेशा स्वागत है!
हालाँकि Golang प्रोग्राम में निर्माण और रनटाइम व्यवहार के संबंध में बहुत सी बारीकियाँ होती हैं, फिर भी उन्हें OS लेयर के साथ इंटरैक्ट करना होता है, और इसका मतलब है कि किसी बिंदु पर उन्हें Windows API से फ़ंक्शन कॉल करने की आवश्यकता होती है।
Go रनटाइम पैकेज में asmstdcall नामक एक फ़ंक्शन होता है और यह फ़ंक्शन Windows API के साथ इंटरैक्ट करने के लिए एक प्रकार का "गेटवे" है। चूँकि इस फ़ंक्शन से Windows API फ़ंक्शन को कॉल करने की उम्मीद की जाती है, हम मान सकते हैं कि इसे फ़ंक्शन के पते और उसके पैरामीटर जैसी जानकारी तक पहुँचने की आवश्यकता है, और यहीं पर चीज़ें और अधिक दिलचस्प हो जाती हैं।
Asmstdcall एक एकल पैरामीटर प्राप्त करता है जो निम्नलिखित संरचना के समान कुछ का पॉइंटर है:
struct LIBCALL {
DWORD_PTR Addr;
DWORD Argc;
DWORD_PTR Argv;
DWORD_PTR ReturnValue;
[...]
}
इनमें से कुछ फ़ील्ड API फ़ंक्शन कॉल होने के बाद भरे जाते हैं, जैसे रिटर्न वैल्यू, अन्य asmstdcall द्वारा प्राप्त किए जाते हैं, जैसे फ़ंक्शन पता, तर्कों की संख्या और तर्कों की सूची। भले ही ये कब सेट हों, यह स्पष्ट है कि asmstdcall फ़ंक्शन Golang में संकलित प्रोग्रामों के निष्पादन के बारे में बहुत सी दिलचस्प जानकारी में हेरफेर करता है।
gftrace asmstdcall और इसके काम करने के तरीके का लाभ उठाकर उल्लिखित संरचना के विशिष्ट फ़ील्ड की निगरानी करता है और इसे उपयोगकर्ता को लॉग करता है। यह टूल किसी एकल API फ़ंक्शन को हुक किए बिना या उसके लिए हस्ताक्षर किए बिना, Golang एप्लिकेशन द्वारा कॉल किए गए प्रत्येक Windows फ़ंक्शन का फ़ंक्शन नाम, उसके पैरामीटर और रिटर्न वैल्यू भी लॉग करने में सक्षम है।
टूल Go रनटाइम इनिशियलाइज़ेशन के सभी शोर को अनदेखा करने का प्रयास करता है और केवल इसके बाद कॉल किए गए फ़ंक्शन (अर्थात main पैकेज से फ़ंक्शन) को लॉग करता है।
यदि आप इस परियोजना और शोध के बारे में अधिक जानना चाहते हैं, तो ब्लॉगपोस्ट देखें।
नवीनतम रिलीज़ डाउनलोड करें।
gftrace.exe <filepath> <params>
आपको बस इतना करना है कि gftrace.cfg फ़ाइल में उन फ़ंक्शन को निर्दिष्ट करें जिन्हें आप ट्रेस करना चाहते हैं, उन्हें बिना रिक्त स्थान के अल्पविराम से अलग करें:
CreateFileW,ReadFile,CreateProcessW
एक पैकेज Y की एक Golang विधि X किसी विशिष्ट परिदृश्य में जिन Windows API फ़ंक्शन को कॉल करेगी, उन्हें या तो विधि के विश्लेषण द्वारा या अनुमान लगाकर निर्धारित किया जा सकता है। इसे निर्धारित करने के लिए कुछ दिलचस्प विशेषताओं का उपयोग किया जा सकता है, उदाहरण के लिए, Golang एप्लिकेशन "Wide" और "Ex" सेट (जैसे CreateFileW, CreateProcessW, GetComputerNameExW, आदि) के फ़ंक्शन को कॉल करना पसंद करते हैं, इसलिए आप अपने विश्लेषण के दौरान इस पर विचार कर सकते हैं।
डिफ़ॉल्ट कॉन्फ़िग फ़ाइल में कई फ़ंक्शन हैं जिनका मैंने पहले ही परीक्षण किया है (कम से कम उनमें से अधिकांश) और निश्चित रूप से कह सकता हूँ कि किसी बिंदु पर Golang एप्लिकेशन द्वारा उन्हें कॉल किया जा सकता है। मैं इसे समय-समय पर अपडेट करने का प्रयास करूँगा।
एक सरल Golang फ़ाइल में CreateFileW() और ReadFile() को ट्रेस करना जो "os.ReadFile" को दो बार कॉल करती है:
- CreateFileW("C:\Users\user\Desktop\doc.txt", 0x80000000, 0x3, 0x0, 0x3, 0x1, 0x0) = 0x168 (360)
- ReadFile(0x168, 0xc000108000, 0x200, 0xc000075d64, 0x0) = 0x1 (1)
- CreateFileW("C:\Users\user\Desktop\doc2.txt", 0x80000000, 0x3, 0x0, 0x3, 0x1, 0x0) = 0x168 (360)
- ReadFile(0x168, 0xc000108200, 0x200, 0xc000075d64, 0x0) = 0x1 (1)
TunnelFish मैलवेयर में CreateProcessW() को ट्रेस करना:
- CreateProcessW("C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe", "powershell /c "Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn; Get-Recipient | Select Name -ExpandProperty EmailAddresses -first 1 | Select SmtpAddress | ft -hidetableheaders"", 0x0, 0x0, 0x1, 0x80400, "=C:=C:\Users\user\Desktop", 0x0, 0xc0000ace98, 0xc0000acd68) = 0x1 (1)
- CreateProcessW("C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe", "powershell /c "Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn; Get-Recipient | Select Name -ExpandProperty EmailAddresses -first 1 | Select SmtpAddress | ft -hidetableheaders"", 0x0, 0x0, 0x1, 0x80400, "=C:=C:\Users\user\Desktop", 0x0, 0xc0000c4ec8, 0xc0000c4d98) = 0x1 (1)
- CreateProcessW("C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe", "powershell /c "Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn; Get-Recipient | Select Name -ExpandProperty EmailAddresses -first 1 | Select SmtpAddress | ft -hidetableheaders"", 0x0, 0x0, 0x1, 0x80400, "=C:=C:\Users\user\Desktop", 0x0, 0xc00005eec8, 0xc00005ed98) = 0x1 (1)
- CreateProcessW("C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe", "powershell /c "Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn; Get-Recipient | Select Name -ExpandProperty EmailAddresses -first 1 | Select SmtpAddress | ft -hidetableheaders"", 0x0, 0x0, 0x1, 0x80400, "=C:=C:\Users\user\Desktop", 0x0, 0xc0000bce98, 0xc0000bcd68) = 0x1 (1)
- CreateProcessW("C:\WINDOWS\system32\cmd.exe", "cmd /c "wmic computersystem get domain"", 0x0, 0x0, 0x1, 0x80400, "=C:=C:\Users\user\Desktop", 0x0, 0xc0000c4ef0, 0xc0000c4dc0) = 0x1 (1)
- CreateProcessW("C:\WINDOWS\system32\cmd.exe", "cmd /c "wmic computersystem get domain"", 0x0, 0x0, 0x1, 0x80400, "=C:=C:\Users\user\Desktop", 0x0, 0xc0000acec0, 0xc0000acd90) = 0x1 (1)
- CreateProcessW("C:\WINDOWS\system32\cmd.exe", "cmd /c "wmic computersystem get domain"", 0x0, 0x0, 0x1, 0x80400, "=C:=C:\Users\user\Desktop", 0x0, 0xc0000bcec0, 0xc0000bcd90) = 0x1 (1)
[...]
Sunshuttle मैलवेयर में एकाधिक फ़ंक्शन को ट्रेस करना:
- CreateFileW("config.dat.tmp", 0x80000000, 0x3, 0x0, 0x3, 0x1, 0x0) = 0xffffffffffffffff (-1)
- CreateFileW("config.dat.tmp", 0xc0000000, 0x3, 0x0, 0x2, 0x80, 0x0) = 0x198 (408)
- CreateFileW("config.dat.tmp", 0xc0000000, 0x3, 0x0, 0x3, 0x80, 0x0) = 0x1a4 (420)
- WriteFile(0x1a4, 0xc000112780, 0xeb, 0xc0000c79d4, 0x0) = 0x1 (1)
- GetAddrInfoW("reyweb.com", 0x0, 0xc000031f18, 0xc000031e88) = 0x0 (0)
- WSASocketW(0x2, 0x1, 0x0, 0x0, 0x0, 0x81) = 0x1f0 (496)
- WSASend(0x1f0, 0xc00004f038, 0x1, 0xc00004f020, 0x0, 0xc00004eff0, 0x0) = 0x0 (0)
- WSARecv(0x1f0, 0xc00004ef60, 0x1, 0xc00004ef48, 0xc00004efd0, 0xc00004ef18, 0x0) = 0xffffffff (-1)
- GetAddrInfoW("reyweb.com", 0x0, 0xc000031f18, 0xc000031e88) = 0x0 (0)
- WSASocketW(0x2, 0x1, 0x0, 0x0, 0x0, 0x81) = 0x200 (512)
- WSASend(0x200, 0xc00004f2b8, 0x1, 0xc00004f2a0, 0x0, 0xc00004f270, 0x0) = 0x0 (0)
- WSARecv(0x200, 0xc00004f1e0, 0x1, 0xc00004f1c8, 0xc00004f250, 0xc00004f198, 0x0) = 0xffffffff (-1)
[...]
DeimosC2 फ्रेमवर्क एजेंट में एकाधिक फ़ंक्शन को ट्रेस करना:
- WSASocketW(0x2, 0x1, 0x0, 0x0, 0x0, 0x81) = 0x130 (304)
- setsockopt(0x130, 0xffff, 0x20, 0xc0000b7838, 0x4) = 0xffffffff (-1)
- socket(0x2, 0x1, 0x6) = 0x138 (312)
- WSAIoctl(0x138, 0xc8000006, 0xaf0870, 0x10, 0xb38730, 0x8, 0xc0000b746c, 0x0, 0x0) = 0x0 (0)
- GetModuleFileNameW(0x0, "C:\Users\user\Desktop\samples\deimos.exe", 0x400) = 0x2f (47)
- GetUserProfileDirectoryW(0x140, "C:\Users\user", 0xc0000b7a08) = 0x1 (1)
- LookupAccountSidw(0x0, 0xc00000e250, "user", 0xc0000b796c, "DESKTOP-TEST", 0xc0000b7970, 0xc0000b79f0) = 0x1 (1)
- NetUserGetInfo("DESKTOP-TEST", "user", 0xa, 0xc0000b7930) = 0x0 (0)
- GetComputerNameExW(0x5, "DESKTOP-TEST", 0xc0000b7b78) = 0x1 (1)
- GetAdaptersAddresses(0x0, 0x10, 0x0, 0xc000120000, 0xc0000b79d0) = 0x0 (0)
- CreateToolhelp32Snapshot(0x2, 0x0) = 0x1b8 (440)
- GetCurrentProcessId() = 0x2584 (9604)
- GetCurrentDirectoryW(0x12c, "C:\Users\user\AppData\Local\Programs\retoolkit\bin") = 0x39 (57)
[...]
gftrace GPL v3 लाइसेंस के तहत प्रकाशित किया गया है। अधिक जानकारी के लिए LICENSE नामक फ़ाइल देखें।