Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
Tools/GitHubGitHub/spiralbl0ck/blacklotus-z2a-challenge
Statische AnalyseReverse EngineeringMalware-AnalyseCTFLernen & Bildung
GitHubspiralbl0ck/blacklotus-z2a-challenge

BlackLotus-Z2A-Challenge

BlackLotus-Z2A-Challenge, Hier gibt es noch nichts zu sehen, bitte gehen Sie weiter

Repository anzeigen

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
3247vor 3 JahrenNoch nicht geprüft
Teilen

BlackLotus-Z2A-Challenge

BlackLotus-Z2A-Challenge, hier gibt es im Moment nichts zu sehen, bitte weitergehen

Das Wichtigste zuerst Capture23

Nur aus ästhetischen Gründen werde ich schamlos die Yara-Erkennungsregeln aus der Lösung von @darthmaulware(Ryan “DM” Smith) ausleihen (stehlen) :)), nur um es professionell aussehen zu lassen. Schau dir seinen Twitter an, er ist eine verdammt coole Person! Ps. Ryan, bitte sei nicht sauer, weil ich das geklaut habe :))) und danke für die Unterstützung auf Discord :)

Bitte schau dir auch seine Arbeit an :)

https://gitlab.com/malre-rcs/zero2automated/-/blob/main/solutions/bi_weekly_challenge/BlackLotus_20230321/BlackLotus_HTTP_Downloader.ipynb``` rule Blacklotus_HTTP_Downloader { meta: description = "Rule to detect Blacklotus HTTP Downloader" author = "Darth Maulware" sha256 = "d68f668b4240f9518e4f80499d93d8c5a1eddece0771658c33ae916cc54f5a66"

root@kitploit:~
    strings:
        $opcode1 = {48 89 4C 24 08 48 89 54 24 10 4C}
        $opcode2 = {89 44 24 18 4C 89 4C 24 20 48 83}
        $opcode3 = {EC 28 B9 31 62 D7 2E 90 90 E8 ??}
        $opcode4 = {?? ?? ?? 48 83 C4 28 48 8B 4C 24}
        $opcode5 = {08 48 8B 54 24 10 4C 8B 44 24 18}
        $opcode6 = {4C 8B 4C 24 20 4C 8B D1 90 90}

    condition:
        (uint16(0) == 0x5a4d and filesize < 500KB and all of them)

}

root@kitploit:~
Auch aus ästhetischen Gründen werde ich das auch klauen, weil es cool aussieht :) nochmal sorry Ryan, bitte sei mir nicht böse :)```
        C:\\Users\\REM\\Desktop>capa.exe -f pe -r capa-rules-5.0.0 d68f668b4240f9518e4f80499d93d8c5a1eddece0771658c33ae916cc54f5a66.exe
        matching: 100%|████████| 124/124 [00:02<00:00, 46.96 functions/s, skipped 1 library functions (0%)]

        +------------------------+------------------------------------------------------------------------------------+
        | ATT&CK Tactic          | ATT&CK Technique                                                                   |
        |------------------------+------------------------------------------------------------------------------------|
        | DEFENSE EVASION        | Obfuscated Files or Information T1027                                              |
        | DISCOVERY              | Process Discovery T1057                                                            |
        | EXECUTION              | Shared Modules T1129                                                               |
        +------------------------+------------------------------------------------------------------------------------+

        +-----------------------------+-------------------------------------------------------------------------------+
        | MBC Objective               | MBC Behavior                                                                  |
        |-----------------------------+-------------------------------------------------------------------------------|
        | ANTI-BEHAVIORAL ANALYSIS    | Debugger Detection::Process Environment Block BeingDebugged [B0001.035]       |
        |                             | Debugger Detection::Process Environment Block NtGlobalFlag [B0001.036]        |
        | CRYPTOGRAPHY                | Encrypt Data::RC4 [C0027.009]                                                 |
        |                             | Generate Pseudo-random Sequence::RC4 PRGA [C0021.004]                         |
        | DATA                        | Encode Data::XOR [C0026.002]                                                  |
        | DEFENSE EVASION             | Obfuscated Files or Information::Encoding-Standard Algorithm [E1027.m02]      |
        +-----------------------------+-------------------------------------------------------------------------------+

        +------------------------------------------------------+------------------------------------------------------+
        | CAPABILITY                                           | NAMESPACE                                            |
        |------------------------------------------------------+------------------------------------------------------|
        | execute syscall instruction (35 matches)             | anti-analysis                                        |
        | check for PEB BeingDebugged flag (2 matches)         | anti-analysis/anti-debugging/debugger-detection      |
        | check for PEB NtGlobalFlag flag                      | anti-analysis/anti-debugging/debugger-detection      |
        | encode data using XOR (2 matches)                    | data-manipulation/encoding/xor                       |
        | encrypt data using RC4 PRGA (2 matches)              | data-manipulation/encryption/rc4                     |
        | get process heap flags                               | host-interaction/process                             |
        | get ntdll base address (3 matches)                   | linking/runtime-linking                              |
        | parse PE header (2 matches)                          | load-code/pe                                         |
        | resolve function by parsing PE exports (2 matches)   | load-code/pe                                         |
        +------------------------------------------------------+------------------------------------------------------+

tbh wenn ich du wäre, würde ich capa nicht zu 100 % vertrauen (zumindest nicht in diesem speziellen Fall), weil es hier sagt, dass die Sample RC4 verwendet, obwohl sie tatsächlich AES verwendet, aber egal, wie bereits erwähnt, ist das rein ästhetisch :)

Bevor wir loslegen, wirst du in diesem Report eine Menge

1

sehen.

Bitte ignoriere das, da IDA das in Assembly nicht richtig disassemblieren kann, das ist

1

Und das lässt den Debugger abstürzen? Warum?

Weil versucht wird, an Adresse 0 zu schreiben, was im Hacker-Folklor als Schreiben auf eine Nullzeiger-Adresse bekannt ist, was früher weit verbreitet ausgenutzt wurde, um CE (Code Execution) zu erlangen, und das wurde offensichtlich entschärft.

Und so wird bei der aktuellen Absicherung, wenn du versuchst, an 0 zu schreiben, der Prozess abstürzen – in unserem Fall die Malware und folglich der Debugger.

Wenn wir das jetzt in IDA öffnen

1

Ich habe jede Funktion umbenannt, um eine gewisse Logik anzudeuten. Fangen wir mit der ersten Funktion an, do_syscall() Capture23

Wir bemerken sofort die Verwendung von Syscalls, was eine bekannte Methode ist, um das Leben eines Analysten bei der dynamischen Analyse schwerer zu machen.

Für diejenigen, die mit Syscalls in Windows nicht vertraut sind, hier ein cooles Video von oalabs (https://www.youtube.com/watch?v=Uba3SQH2jNE). Bitte schau es dir an, denn ich habe es auch getan, und es hat mir sehr geholfen zu verstehen, was in dieser Funktion passiert.

Wenn wir den von IDA aufgelösten „Pseudo-Code“ untersuchen, sehen wir, dass es so aussieht

Capture4

Wenn wir statisch solve_hash untersuchen, sieht es so aus

1

2

Aus einer Pseudo-Perspektive sieht es so aus

4

Bitte beziehe dich auf solve_hash.py, um meine „Emulation“ davon zu sehen, falls du ein Stück Automatisierung sehen und herausfinden möchtest, welche Syscalls durch den Hashing-Lookup-Algorithmus aufgelöst werden. Aber nichtsdestotrotz ist das Teil eines Projekts namens SysWhispers2 oder zumindest nehme ich an, dass die Autoren der Malware sich davon inspirieren ließen. Nichtsdestotrotz beziehe dich bitte auf das obige Video von oalabs zum besseren Verständnis.

Wie auch immer, die anti_debug-Funktion ist leicht zu umgehen und gut bekannt (https://anti-debug.checkpoint.com/techniques/debug-flags.html#manual-checks-ntglobalflag). Der Weg, sie zu umgehen, ist, ScyllaHide installiert zu haben und NtGlobalFlag aktiviert zu haben (was du standardmäßig aktiviert haben solltest, wenn du x86dbg verwendest). Nichtsdestotrotz ist das, was du überprüfen sollst

4

Und so sieht die Anti-Debug-„Pseudo-Funktion“ aus

4

Ziemlich einfach, wenn du mich fragst

Als Nächstes haben wir die Funktion check_inmemory_ldr, die so aussieht

1

2

Nun, für den Zweck der Funktionsanalyse: Wenn wir x86dbg freundlich genug fragen, können wir sehen, dass, wenn wir bis zur Syscall-Instruktion laufen, x86dbg so freundlich ist, uns den Syscall zurückzugeben, der ausgeführt werden soll. In unserem Fall

2

Basierend auf dem aktuellen Kontext können wir nun vermuten, dass NtSetInformationThread als eine Art Anti-Analyse-Trick verwendet wird. Sicher genug, wenn wir eine schnelle Google-Suche machen, finden wir das: https://ntquery.wordpress.com/tag/ntqueryinformationthread/

Glücklicherweise leicht zu umgehen, einfach nop+ret patchen :)

=============================================================================

Der Ausführungsreihenfolge folgend ist die nächste Funktion nach dieser

4

Wenn wir wieder untersuchen, was sie tut

Capture4

Sie prüft einfach ein Flag im TEB, um festzustellen, ob der aktuelle Prozess (in unserem Fall die EXE) debuggt wird. Das ist erneut leicht umgehbar, da es eine bekannte Methode ist (https://anti-debug.checkpoint.com/techniques/debug-flags.html#manual-checks-peb-beingdebugged-flag). Auf dieselbe Weise, wie wir ScyllaHide verwendet haben, musst du diesmal Capturez

aktiviert haben, was standardmäßig aktiviert sein sollte.

=============================================================================

Jetzt custom_hash2_and_aplib_possible, das so aussieht

2

Und aus einer Graphen-Perspektive

3

Bitte beziehe dich auf decompress_aplib.py, um die „Emulation“ dieser Funktion zu sehen.

Wenn wir get_ntdll_and_unhook2 untersuchen, sieht es so aus

1

2

Aus einer Graph-Ansicht sieht es so aus

1

Nicht übel :))

Wenn wir ein wenig zurückverfolgen, haben wir aplib_decompress, das jetzt so aussieht

1

Aus einer statischen Code-Analyse sieht es so aus

1

2

3

4

Mhmm, ein bisschen groß, aber keine Sorge, Leute, das ist machbar :)

Wenn du das Emulations-Skript aplib_decompress.py verwendest, solltest du so etwas wie das hier erhalten

1

Eine coole Sache, die ich in anderen Blogs/Analysen nicht bemerkt habe, ist Folgendes: Wenn wir uns noch einmal den IDA-Pseudocode für ntdll_and_unhook2 ansehen

1

wirst du ein interessantes memcpy sehen.

An einem Punkt, als ich die dynamische Analyse durchführte, bemerkte ich, dass eine andere DLL geladen wurde, die eine andere Version von ntdll war

1

Wenn wir in den Debugger schauen, sieht es so aus

1

Ich konnte nicht erkennen, was gehookt/gepatcht wurde, aber wenn jemand es weiß, mache bitte einen Pull Request und bearbeite dieses Dokument. Außerdem habe ich bei meinen Versuchen herauszufinden, was gehookt wird, versucht, einen Bindiff zwischen den beiden ntdlls zu machen, und leider nichts gefunden, aber es könnte daran liegen, dass ich bereits einen Diff an einer System-DLL gemacht habe, die infiziert war, also kein sauberer Lauf, vielleicht ist es das ¯_(ツ)_/¯

1

=============================================================================

Wenn wir mit dem Analyseprozess weitermachen, haben wir bei den ungeklärten Funktionen some_hasing und ntquertyinformationprocess_anti_debug, diese wurden nicht erklärt. check_if_being_debug_through_teb und anti_debug wurden glücklicherweise bereits erklärt, weil sie in der/den obigen Funktion(en) verwendet wurden. Bitte lies also die obigen Abschnitte, wenn du dein Wissen darüber auffrischen möchtest. Ich möchte zuerst mit ntquertyinformationprocess_anti_debug beginnen und danach mit some_hasing abschließen.

Wenn wir es untersuchen, sehen wir dieselbe Funktion dreimal aufgerufen.

1234

Und aus einer Assembly-Position

1

2

Der Einfachheit halber habe ich sie bereits benannt, nämlich ntquertyinformationprocess_ProcessDebugPort. Woher wusste ich, dass die aufgerufenen Funktionen ntquertyinformationprocess_ProcessDebugPort waren? Wenn wir sie untersuchen, offenbart sich ein bereits gesehener Funktionsaufruf bzw. bekannte Algorithmen für uns

1

Was ist mit den Kommentaren in IDA? Nun, wenn du ntqueryinformationprocess bei Google suchst, stoßen wir auf eine gute Ressource über Anti-Debugging (https://anti-debug.checkpoint.com/techniques/debug-flags.html). Wenn wir ihr folgen, sehen wir, dass sie erklärt, dass basierend auf bestimmten Werten, die als Parameter an diese Funktion übergeben werden, dies als Anti-Debugging-Methode verwendet werden kann.

Zum Beispiel können wir für den ersten Aufruf die folgenden Stack-Argumente im Debugger sehen

1

Wenn wir jetzt die MSDN-Seite für ntqueryinformationprocess prüfen

1

Derselbe Prozess wiederholt sich für die nächsten beiden Syscalls

2

wobei 0x1e spezifisch für die Anti-Debug-Methode ProcessDebugObjectHandle ist (https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software)

und schließlich ProcessDebugFlags

2

Also, wie umgehen wir sie?! Entspann dich, Kumpel, denn ScyllaHide hat unseren Rücken

obama-pew

Wie du sehen kannst

1

Also sind wir sicher! Nicht ganz. Während ScyllaHide uns bei den ersten beiden Syscalls den Rücken freihält, müssen wir den letzten Syscall manuell erledigen! Und was zum Teufel soll ich tun??? Nun, einfache Lösung! Wir kehren aus dieser Funktion zurück, also quasi aus der gesamten ntquertyinformationprocess_anti_debug, und setzen eax auf 0. Unter normalen Umständen sieht es also so aus

1

Und mit unserer „Hilfe“ sieht es so aus, und wir lassen die Ausführung sicher weiterlaufen :)

1

=============================================================================

Jetzt some_hasing, du kennst das Spiel bereits

1

Und jetzt der Pseudo-Code

2

Wir bemerken hier etwas Seltsames. IDAs Pseudo-Code versagt hier ... denn wenn wir dem Graphen nach call_syscall folgen, gibt es weitere zu disassemblierende Instruktionen. Was machen wir also jetzt hier? Nun, wir verlassen uns hier auf den Debugger, um diesen Code dynamisch zu analysieren ...

Wir sehen also, dass der Syscall, den er ausführt, folgender ist

1

Wenn wir jetzt ntquerydefaultlocale nachschlagen, zeigt Google, dass dies eine undokumentierte API ist, die 2 Argumente nimmt (http://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FLocale%2FNtQueryDefaultLocale.html). Cool, also was macht sie? Sie gibt die aktuelle Gebietsschema-Kennung (Locale Identifier) zurück. Cool, also was zum Teufel ist eine Gebietsschema-Kennung? Von MSDN (https://learn.microsoft.com/en-us/windows/win32/intl/locale-identifiers) ein 32-Bit-Wert, der aus einer Sprachkennung und einer Sortierreihenfolgen-Kennung besteht. Kurz gesagt: Welche Sprache du auf diesem PC sprichst :)

Danach prüft sie, ob die API nicht fehlgeschlagen ist, und wenn sie nicht fehlgeschlagen ist, nimmt sie den von ntquerydefaultlocale zurückgegebenen Wert, subtrahiert 0x419 und vergleicht ihn mit 0x26 (wahrscheinlich eine Konstante), wie du im Bild unten sehen kannst.

1

Wenn er nicht kleiner oder gleich 0x26 ist, vergleicht sie ihn mit 0x818, andernfalls macht sie denselben Vergleich mit 0x819, wie du deutlich sehen kannst

2

Also, was zum Teufel passiert hier? Und warum diese spezifischen Konstanten? Nun, ich komme direkt zum Punkt. Während ich nach verschiedenen Konstanten suchte, stieß ich auf diesen Artikel (https://www.cnblogs.com/DirWang/p/17281690.html#autoid-8-0-0), einen Forscher, der BlackLotus bereits besser analysiert hat, als ich es könnte. Und wie jemand einmal sagte: „Du kannst in der Malware-Analyse nicht schummeln, du kannst dir deine Arbeit nur einfacher machen.“ Was der Forscher also sagte, ist, dass diese Funktion im Grunde nach bestimmten Konstanten sucht, die identifizieren, welche Sprache auf dem Computer gesprochen wird. In seinem Artikel stellt er einen Link zu diesem Dokument bereit (https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-LCID/[MS-LCID].pdf), das wie ein Standarddokument von Microsoft mit jeder Sprachkennung ist.

Wenn wir nun unsere hax00r-l33t-Logik anwenden, können wir ableiten, dass 0x26 wahrscheinlich wie ein Offset verwendet wird, also quasi alle 0x26 nächsten Sprachkennungen nach 0x419, welche sind

2

Wenn wir auch dieses Dokument prüfen, können wir sehen, dass 0x818 entspricht

2

und 0x819

2

Und wir wissen aus früheren „Untersuchungen“/Online-Berichten, dass diese Malware auf bestimmten PCs aus bestimmten Regionen der Welt nicht lief. Wir können also schlussfolgern, dass diese Funktion prüft, in welcher Region sich der infizierte Rechner befindet.

=============================================================================

Verrückter Ham00brg33r bis jetzt, Kumpel, was kommt als Nächstes? Wir servieren die Funktion some_more_syscall. Alles klar! Also, was hast du da, ack! Hier ist sie

1

Wir wollen mehr! Klar doch, Kumpel!

2

3jgukd

1

Hmmmm

1

Also prüft sie, ob ein Kerneldebugger vorhanden ist (https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntexapi/system_information_class.htm)(0x23), checky checky!

Also was, ack! Wir haben pcr (Piles and Combinations Party)

2

=============================================================================

Wenn wir jetzt die Funktion iterate_over_modules() untersuchen, sieht sie so aus

1

Aus einer „Pseudo-Code“-Perspektive sieht es so aus

2

Aus einer eigenständigen Perspektive sieht es so aus, als ob Assembly und IDA-Pseudo-Code übereinstimmen. Was ist also die Logik dieser Funktion? Nun, ziemlich einfach: Sie iteriert über die im Speicher befindlichen Module (DLLs) und prüft gegen eine Liste von Hashes :) v4[0] = 0x1E7EACEF; v4[1] = 0x4468A620; v4[2] = 0x68536B95; v4[3] = 0x73EBBB53; v4[4] = 0xDA165168; v4[5] = 0xB24D33A7; v4[6] = 0xB1E2CEC6; v4[7] = 0x5136992; v4[8] = 0x98C500D9; v4[9] = 0x3E0169B6;

Und wenn keine im Speicher befindlichen DLLs mit demselben Hash gefunden werden, geben wir 0 zurück, sonst 1 und wir lassen den Debugger abstürzen. Mit einer solchen Schlussfolgerung können wir sagen, dass dies eine weitere Anti-Analyse-Methode ist. Richtig, aber was ist mit jedem der Hash-Werte? Nun, ich schummle wieder (wie jemand einmal sagte, du kannst bei der Malware-Analyse nicht schummeln, nur dein Leben einfacher machen :)). Der oben erwähnte asiatische Forscher war so freundlich, uns eine Liste von Werten bereitzustellen, von denen die Werte abgeleitet wurden

sbiedll.dll dbghelp.dll api_log.dll dir_watch.dll pstorec.dll vmcheck.dll wpespy.dll cmdvrt64.dll avghookx.dll snxhk.dll

Um nun dynamisch zu sehen, ob irgendwelche Werte einer der genannten DLLs entsprechen

2

Und sicher genug, tut es :)

Aber wie bin ich zu dem Schluss gekommen, dass der Algorithmus gegen diese Werte prüft? Nun, als ich ein Stück dieser Malware emulierte, musste ich iterate_over_module_name_and_hash (in der Datei solve_hash_syscalls.py) neu implementieren, und in dieser Funktion haben wir

1

wobei x (übergebenes Argument) in diesem Fall v2 ist, ein Array (ein Zeiger) von Werten, das inkrementiert wird (wohin es im Array zeigt), solange es mit keinem der oben bereits erwähnten Werte übereinstimmt. Mann, das ist ein echter Zungenbrecher :P

Cool beans! Weiter

=============================================================================

iterate_over_modules2, ungefähr dieselbe Geschichte hier

1

Und Pseudo-Code

2

Ungefähr dieselbe Geschichte, nur andere Hashes :)

v5[0] = 0x7D73878E; v5[1] = 0xEF36424B; v5[2] = 0xAF64BC2B; v5[3] = 0x1DBBC879; v5[4] = 0xAE6D1D56; v5[5] = 0x7B3242F2; v5[6] = 0x14D922B9; v5[7] = 0x4C92DF53;

welche entsprechen

sample.exe bot.exe sandbox.exe malware.exe test.exe klavme.exe myapp.exe testapp.exe

=============================================================================

iterate_over_modules3, dieselbe Geschichte hier

1

Und Pseudo-Code

2

dieselbe Geschichte, andere Hashes :)v4[0] = 0x42D12D59; v4[1] = 0xEC5D7AA; v4[2] = 0x861E460F; v4[3] = 0x84BCC8DB; v4[4] = 0x6474D72B; v4[5] = 0xB8B9C504; v4[6] = 0x69A0620E; v4[7] = 0x6017EE43; v4[8] = 0xE93BE2E0; v4[9] = 0x149EFC55; v4[10] = 0xE3FA84A4; v4[11] = 0x7CFDD7AF; v4[12] = 0x5B098C67; v4[13] = 0x2F1FB18E; v4[14] = 0xFE8F2B18;

die den folgenden entsprechen

prl_cc.exe prl_tools.exe qemu-ga.exe vmtoolsd.exe vmwaretray.exe vmwareuser.exe VGAuthService.exe vmacthlp.exe vboxservice.exe vboxtray.exe VMSrvc.exe VMUSrvc.exe xenservice.exe

=============================================================================

Anti_debug_measure_1 habe ich schließlich in anti_debug_measure2_RtlAddVectoredExceptionHandler_int3 umbenannt. Warum, wirst du gleich sehen. Es sieht also so aus

1

Und aus einer Pseudocode-Perspektive sieht es so aus

1

Also, was zur Hölle ist das? Nun, es erstellt im Grunde einen Exception-Handler für __debugbreak(int 3), der Code ausführt, wann immer int3 ausgelöst wird. Ich habe dann weitergesucht und bin auf das hier gestoßen

(https://blog.lexfo.fr/dridex-malware.html), was eine coole Ressource ist und uns wissen lässt, dass dies schlicht ein Anti-Debug-Mechanismus ist. In unserem Fall führen wir diese Funktion einfach aus, ignorieren sub_13F2820D0, das immer dann ausgelöst wird, wenn wir int3 ausführen, und patchen eax auf 0 :) Die Ausführung im Speicher sieht dann so aus :)

Vor dem Patch

1

Nach dem Patch

1

Danach verlässt du die Funktion und setzt zusätzlich rax/eax auf 0, sodass du das jne zum Absturz des Debuggers überspringst.

1

=============================================================================

Anti_debug_measure_2, das ich später in anti_debug_measure2_RtlAddVectoredExceptionHandler_int2 geändert habe

1

2

Wieder nichts Neues unter der Sonne, dasselbe Spiel, nur dass diesmal ein anderer int/Syscall gehookt wird, nämlich int2. Gleicher Trick zum Umgehen: Rückgabewert dynamisch patchen :)

Wenn du bei Google nach „anti analysis 2dh“ suchst, erscheint eine Menge Zeug. Du kannst das also als Referenz nutzen, um mehr darüber zu erfahren. Ich habe nicht viel Zeit damit verbracht :)

Selbst wenn du hier versuchst, mit Step Over darüberzugehen, landest du bei ret, wie hier

1

Um das zu umgehen, führe einfach bis zum Return aus, und du bist gut dabei :)

=============================================================================

Jetzt kommt also anti_debug measure heap, das ich später in iterate_over_current_process_and_check_again_hases umbenannt habe

1

Ein cooles Merkmal dieser Funktion ist, dass sie ntquerysysteminformation innerhalb von iterate_over_current_process_and_hash_check verwendet, um alle laufenden Prozesse aufzulisten. So sieht iterate_over_current_process_and_hash_check aus

1

2

Cool beans, aber wie zum Teufel bin ich zu dem Schluss gekommen, dass iterate_over_current_process_and_hash_check das tut, was der Name vermuten lässt? Nun, zuerst ist da der ntquerysysteminformation-Aufruf. Wenn du bei Google suchst, wirst du sehen, dass er verwendet wird, um eine Liste laufender Prozesse zu erhalten. Danach habe ich einfach eine fundierte Vermutung auf der Grundlage des folgenden Code-Snippets angestellt LODWORD(v4) = RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, 8u, v10); v3 = v4; v5 = ntquerysysteminformation(); v6 = v3; .... memcpy(v9, v6[8], *(v6 + 28)); v9[*(v6 + 28) >> 1] = 0; if ( some_hash_0x1003F(v9) == a1 ), dass es die Prozessliste kopiert, jeden einzelnen durchläuft und jeden Hash aus dem vorherigen Array mit dem gerade laufenden Prozess vergleicht. Nochmals Kudos an das asiatische Forschungsblog, denn ich weiß nicht, wie zum Teufel er auf die tatsächlichen Namen der v4-Array-Werte gekommen ist. Bitte schau in iterate_over_modules.py nach, falls du sehen willst, wie ich das emuliert habe.

Ps. Wenn du diese Funktion dynamisch debuggst, wirst du erneut auf int 2d stoßen. Die Lösung ist dieselbe wie oben beschrieben, nur dass du im Grunde 0xf Mal bis zum Return ausführst, was den Heap sozusagen durchläuft. Wenn du danach sicher sein willst, dass du den Return von iterate_over_current_process_and_check_again_hases erreichst, setze einfach einen Breakpoint am Ende dieser Funktion, und du bist auf der sicheren Seite :)

============================================================================= anti_debug_measure_heap

1

2

1

Also ja, wir haben Glück, dass das nicht so groß ist, und außerdem haben wir demangle_strings bereits implementiert. Ich habe das nun für größere Arrays neu implementiert, bitte schau dir anti_debug_measure.py an.

Dies prüft im Grunde gegen``` \Registry\Machine\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters \Registry\Machine\SYSTEM\ControlSet001\Services\vioscsi \Registry\Machine\SYSTEM\ControlSet001\Services\VirtIO-FS Service \Registry\Machine\SYSTEM\ControlSet001\Services\VirtioSerial \Registry\Machine\SYSTEM\ControlSet001\Services\BALLOON \Registry\Machine\SYSTEM\ControlSet001\Services\BalloonService \Registry\Machine\SYSTEM\ControlSet001\Services\netkvm \Registry\Machine\SOFTWARE\VMware, Inc.\VMware Tools \Registry\Machine\HARDWARE\ACPI\DSDT\VBOX__ \Registry\Machine\HARDWARE\ACPI\FADT\VBOX__ \Registry\Machine\HARDWARE\ACPI\RSDT\VBOX__ \Registry\Machine\SOFTWARE\Oracle\VirtualBox Guest Additions \Registry\Machine\SYSTEM\ControlSet001\Services\VBoxGuest \Registry\Machine\SYSTEM\ControlSet001\Services\VBoxMouse \Registry\Machine\SYSTEM\ControlSet001\Services\VBoxService \Registry\Machine\SYSTEM\ControlSet001\Services\VBoxSF \Registry\Machine\SYSTEM\ControlSet001\Services\VBoxVideo

root@kitploit:~
Jetzt get_oem_key

![1](https://assets.kitploit.com/production/public/readmes/44337/2a188d30cf6be94954d1432a2928bc11c0546da19b9092e5dfc7d2c195e47d54.png)

![2](https://assets.kitploit.com/production/public/readmes/44337/aa44c5cb77b983c38dfa6be61b9ed0482df4082a81ebe73c7f295dd43844669f.png)

![3](https://assets.kitploit.com/production/public/readmes/44337/6227b500e17378e4f4682e86ce1928898be52b0781b496156ce8a975f4ae1226.png)

![4](https://assets.kitploit.com/production/public/readmes/44337/67227ce4e2999496337e5894b1990937f519ebf72574d20532e6ea9a2170f864.png)

![5](https://assets.kitploit.com/production/public/readmes/44337/82fa372a01bbc8dba4d2dec1b0a0ca46836c9c9cd514aecb8637ebcfd6059435.png)

![1](https://assets.kitploit.com/production/public/readmes/44337/24973f6832bf4752014bfe5f77dbc75b2a5254e5ed809b980f98803d35464824.png)

![2](https://assets.kitploit.com/production/public/readmes/44337/b976c0dad1e2b872649a6df1b61d19b220863b0cb770feb5caa92c93ffa9bad7.png)

Zuerst demangelt es den String zu```
 \Registry\Machine\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0
 \Registry\Machine\SYSTEM\ControlSet001\Control\SystemInformation
 \Registry\Machine\HARDWARE\Description\System
 Identifier
 SystemManufacturer
 SystemBiosVersion
 VMWARE
 QEMU
 VBOX

Und dann fragt er ab
\Registry\Machine\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0 \Registry\Machine\SYSTEM\ControlSet001\Control\SystemInformation \Registry\Machine\HARDWARE\Description\System

und vergleicht ihre Werte mit qemu, vbox, VMWARE, wie man im IDA-Snippet und im x86-Fenster sehen kann :)

1

2

Wie man im ersten Snippet sehen kann, prüft es VMWare gegen die Werte, die zu Analysezeit in meiner VM gespeichert waren :)

Keine große Sache, einfach diese Funktion bis zum ret ausführen und eax beim Zurückkehren auf 0 ändern :) um diese Anti-Analyse-Methode zu umgehen :)

=============================================================================

Jetzt get_oem_from_firmware

1

2

3

4

5

Jetzt sehen wir etwas Interessantes: Diese Funktion beginnt mit sub_13F267288(), dem 0x52534D42 als Parameter übergeben wird. Wenn man diesen Wert bei Google sucht, stößt man auf viele coole Fragen in verschiedenen Foren, z.B.(https://ru.stackoverflow.com/questions/778618/c-%D0%9A%D0%B0%D0%BA-%D0%B4%D0%BE%D1%81%D1%82%D0%B0%D1%82%D1%8C-%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%86%D0%B8%D1%8E-%D0%BE%D0%B1-%D1%83%D1%81%D1%82%D1%80%D0%BE%D0%B9%D1%81%D1%82%D0%B2%D0%B0%D1%85-%D0%BA%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%B0-%D0%BD%D0%B5-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D1%8F-wmi) (https://msdn-whiteknight.github.io/answers/html/tools/html/ru.stackoverflow.com/posts/780170.html) (https://www.maldun.com/analysis/YXNkZmRzZmFkc2Y2NDEwNjlkc2Zhc2RmYXNkZg==/) oder dieser(https://github.com/digitalocean/go-smbios/blob/master/smbios/stream_windows.go). Am interessantesten ist jedoch, dass man nach dem Lesen davon und der Suche nach RSMB auf diesen Link stößt: https://evasions.checkpoint.com/techniques/firmware-tables.html, der uns erklärt, dass dies eine Anti-Analyse-Methode ist :) Cool, also was zur Hölle macht das?

Zuerst dumpt es die SMBIOS-Firmware-Tabelle, dann demangelt es einen String – wobei der erste String qemu ist – und ruft dann sub_13F2655E0 mit den Parametern demangelter String und Firmware-Tabelle auf. Aus der statischen Analyse

1

2

Genauer gesagt bin ich bei if ( v4 != v5) zu dem Schluss gekommen, dass dies eine Art strcmp-Implementierung ist; sie prüft, was auch immer in der Firmware-Tabelle steht, gegen den demangelten String. Wie man im Debugger sehen kann 1 r8 ist ein Zeiger auf die Firmware-Tabelle und interessanterweise können wir sehen, dass bla bla etwas ... virtualbox der Name in der Firmware-Tabelle ist und rcx qemu ist, also können wir mit Sicherheit sagen, dass dies eine strcmp-artige Implementierung ist. Und wie man sehen kann, sind wir bei diesem Check sicher :)

1

Dieser Vorgang wiederholt sich nun für die Strings VirtualBox, vbox, VBOX, VMware :) Die allgemeine Lösung, um diese Funktionsprüfung zu umgehen, ist, sie bis zum ret auszuführen, eax zu patchen und die Analyse fortzusetzen :)

============================================================================

Cool, jetzt check_oem_key ()

1

2

3

1

2

3

Also, was zur Hölle macht das? Nun, derselbe Trick wie zuvor erklärt, aber diesmal mit der ACPI-Tabelle. Was meine ich damit? Nun, besser man liest diese 14 Folien(https://dc4420.org/slides/2015-11-24/acpi_vm_detect.pdf), die erklären es besser, aber derselbe billige Trick :)) diesmal gegen BOCHS, BXPC, VMWARE

1

2

============================================================================

Ich möchte mit der Funktion anti_debug_processor_Timing() beginnen und dann mit check_for_flags() abschließen. Also

1

So sieht das aus. Also, was zur Hölle macht es? Es liest den aktuellen Wert des Zeitstempels des Prozessors, nimmt dann den Namen des Prozessors (in unserem Fall GenuineIntel), subtrahiert dann den abgerufenen Zeitstempel vom Namen des Prozessors und prüft dann einfach, ob das Ergebnis größer als 19999 ist.

Nach rdtsc

1

nach cpuid

1

Wie man sehen kann, ist der String auf 3 Register aufgeteilt

1

Und in unserem Fall sehen wir, dass wir diesen Check "failen" und eax auf 1 gesetzt wird

1

Die Lösung für diesen Anti-Check ist einfach: von der Funktion zurückkehren und eax auf 0 patchen :)

============================================================================

Jetzt entry_to_peb()

1

2

3

4

5

6

7

Aus der Pseudocode-Perspektive

1

2

3

Bis zum if-Check gibt es also nichts Neues, wir haben diese Art von Algorithmus bereits gesehen, also was ist damit? Nun, wenn du zu dem bereits referenzierten Write-up der asiatischen Forschung gehst, wirst du sehen, dass dort steht, dass geprüft wird, ob die Windows-Version größer als Win7/Server 2008 R2 ist. Aber wie ist er auf diese Idee gekommen? Nun, wenn wir http://waleedassar.blogspot.com/2012/08/major-minorsubsystemversion.html lesen, sagt er

1

auch wenn du das hier liest :)

https://reverseengineering.stackexchange.com/questions/26157/how-to-show-kuser-shared-data-members-in-decompiled-c-code

und anwendest, was dort steht, dass es automatisch in die KUSER_SHARED_DATA-Struktur gecastet wird, aber hier war meine IDA während der Analyse fehlerhaft, also ist es, wie es ist :)

Um dich nicht mit derselben Wiederholung des mehr oder weniger gleichen Algorithmus zu langweilen, hier sind die endgültigen, abgerufenen und demangelten Funktions-Strings :) Das war ein mühsamer Prozess, da dies mit einem Debugger gemacht wurde :) Ich war zu faul, das zu emulieren.``` user32.dll advapi32.dll Rpcrt4.dll bcrypt.dll ole32.dll Cabinet.dll

CreateWindowExW
ShutdownBlockReasonCreate
ShutdownBlockReasonDestroy
DestroyWindow CloseHandle
CreateProcessW InitializeProcThreadAttributeList
UpdateProcThreadAttribute LoadAppInitDlls Sleep
GetExitCodeProcess
MoveFileExW
OpenSCManagerW OpenServiceW
QueryServiceStatus
StartServiceW
CloseServiceHandle
GetUserNameW
ConvertSidToStringSidW
LookupAccountNameW
CreateWellKnownSid
LookupPrivilegeValueW
ConvertStringSecurityDescriptorToSecurityDescriptorW
RpcStringBindingComposeW
RpcBindingFromStringBindingW
RpcStringFreeW RpcBindingSetOption
RpcBindingSetAuthInfoExW
RpcBindingFree
NdrClientCall2
NdrClientCall3
BCryptOpenAlgorithmProvider
BCryptSetProperty
BCryptGenerateSymmetricKey
BCryptDecrypt
BCryptDestroyKey
BCryptCloseAlgorithmProvider
BCryptGetProperty BCryptGenRandom
CoCreateInstance
CoInitializeEx
CoUninitialize CoInitializeSecurity
CoSetProxyBlanket
if >win7/server 2008 r2 { CreateDecompressor
CloseDecompressor Decompress
}

root@kitploit:~
Und damit endet die erste Hälfte der blacklotus-Analyse-Challenge.

============================================================================

Für die zweite Hälfte

Assembly-Perspektive

![1](https://assets.kitploit.com/production/public/readmes/44337/f509798bf72f72025531efc98bbd0a850e571d003e3a39b7ac2e6438d1da93c8.png)

Pseudocode-Perspektive

![1](https://assets.kitploit.com/production/public/readmes/44337/23fafc5104114ff3d2086230e1be3d9b2dbe1660120b55ad100af0c8a12baec5.png)

Wir beginnen die Zerlegung mit der Funktion some_hash()

============================================================================

Graph-Perspektive

![1](https://assets.kitploit.com/production/public/readmes/44337/2c8d738be9b2f025155521050ba0ea68aaeebd7cf3bd9a5c4fcd122c24722712.png)

Assembly-Perspektive

![1](https://assets.kitploit.com/production/public/readmes/44337/04fb6139172c8f4fab8898395d505ad40b8ba52051ca387a2ec93ffe56ff8674.png)

![2](https://assets.kitploit.com/production/public/readmes/44337/7133eb6348241a56009a6a0d1ce87c26a840bbbc2da99bd459b40c8f5654d366.png)

![3](https://assets.kitploit.com/production/public/readmes/44337/1f60aef395eccf029138d3ca7bcbccafd5328b5056bcae635deabadb8005e2c0.png)

Pseudocode-Perspektive

![1](https://assets.kitploit.com/production/public/readmes/44337/3ae95f232939daab4e4b2b68fa31d94150b4e9b69abd0cd324e5ecc4f8ffe14b.png)
Tool herunterladen