
أداة سطر أوامر لتتبع واجهة برمجة تطبيقات ويندوز (Windows API) للبرامج الثنائية بلغة Go.
أداة تتبع لواجهة برمجة تطبيقات Windows عبر سطر الأوامر لثنائيات Golang.
ملاحظة: هذه الأداة هي إثبات مفهوم ونموذج أولي قيد التطوير، لذا يُرجى التعامل معها على هذا الأساس. الملاحظات مرحب بها دائمًا!
على الرغم من أن برامج Golang تحتوي على العديد من التفاصيل الدقيقة فيما يتعلق بطريقة بنائها وسلوكها في وقت التشغيل، إلا أنها لا تزال بحاجة إلى التفاعل مع طبقة نظام التشغيل، مما يعني أنها في مرحلة ما تحتاج إلى استدعاء دوال من واجهة برمجة تطبيقات Windows.
تحتوي حزمة وقت تشغيل Go على دالة تُسمى asmstdcall وهذه الدالة هي نوع من "البوابة" المستخدمة للتفاعل مع واجهة برمجة تطبيقات Windows. نظرًا لأنه من المتوقع أن تستدعي هذه الدالة دوال واجهة برمجة تطبيقات Windows، يمكننا افتراض أنها تحتاج إلى الوصول إلى معلومات مثل عنوان الدالة ومعاملاتها، وهنا تصبح الأمور أكثر إثارة للاهتمام.
تستقبل asmstdcall معاملًا واحدًا هو مؤشر إلى شيء مشابه للهيكل التالي:
struct LIBCALL {
DWORD_PTR Addr;
DWORD Argc;
DWORD_PTR Argv;
DWORD_PTR ReturnValue;
[...]
}
بعض هذه الحقول يتم ملؤها بعد استدعاء دالة API، مثل قيمة الإرجاع، والبعض الآخر تستقبله asmstdcall، مثل عنوان الدالة وعدد الوسائط وقائمة الوسائط. بغض النظر عن وقت تعيينها، من الواضح أن دالة asmstdcall تتعامل مع الكثير من المعلومات المثيرة للاهتمام فيما يتعلق بتنفيذ البرامج المترجمة بلغة Golang.
تستفيد أداة gftrace من asmstdcall وطريقة عملها لمراقبة حقول محددة من الهيكل المذكور وتسجيلها للمستخدم. الأداة قادرة على تسجيل اسم الدالة ومعاملاتها وكذلك قيمة الإرجاع لكل دالة Windows يتم استدعاؤها بواسطة تطبيق Golang. كل ذلك دون الحاجة إلى تعليق (hook) أي دالة API أو امتلاك توقيع لها.
تحاول الأداة أيضًا تجاهل كل الضوضاء الناتجة عن تهيئة وقت تشغيل Go وتسجيل الدوال التي تُستدعى بعد ذلك فقط (أي الدوال من الحزمة الرئيسية).
إذا كنت تريد معرفة المزيد عن هذا المشروع والبحث، راجع منشور المدونة.
قم بتنزيل أحدث إصدار.
gftrace.exe <filepath> <params>
كل ما عليك فعله هو تحديد الدوال التي تريد تتبعها في ملف gftrace.cfg، وفصلها بفاصلة بدون مسافات:
CreateFileW,ReadFile,CreateProcessW
لا يمكن تحديد دوال Windows API الدقيقة التي قد تستدعيها طريقة Golang X من حزمة Y في سيناريو معين إلا من خلال تحليل الطريقة نفسها أو محاولة تخمينها. هناك بعض الخصائص المثيرة للاهتمام التي يمكن استخدامها لتحديد ذلك، على سبيل المثال، يبدو أن تطبيقات Golang تفضل دائمًا استدعاء الدوال من مجموعة "Wide" و "Ex" (مثل CreateFileW، CreateProcessW، GetComputerNameExW، إلخ) لذا يمكنك أخذها في الاعتبار أثناء تحليلك.
يحتوي ملف التكوين الافتراضي على دوال متعددة قمت باختبارها بالفعل (على الأقل معظمها) ويمكنني القول بالتأكيد أنه يمكن استدعاؤها بواسطة تطبيق Golang في مرحلة ما. سأحاول تحديثه لاحقًا.
تتبع CreateFileW() و ReadFile() في ملف Golang بسيط يستدعي "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)
تتبع CreateProcessW() في برنامج TunnelFish الضار:
- 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 لمزيد من المعلومات.