Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
BlackLotus-Z2A-Challenge — BlackLotus-Z2A-Challenge, Nothing to see here 4 now , please move along | Kitploit
Tools/GitHubGitHub/spiralbl0ck/blacklotus-z2a-challenge
Static AnalysisReverse EngineeringMalware AnalysisCTFLearning & Education
GitHubspiralbl0ck/blacklotus-z2a-challenge

BlackLotus-Z2A-Challenge

BlackLotus-Z2A-Challenge, Nothing to see here 4 now , please move along

View Repository

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
32463 years agoNot yet reviewed
Share

BlackLotus-Z2A-Challenge

BlackLotus-Z2A-Challenge, Nothing to see here 4 now , please move along

First things first Capture23

For aesthetic purposes soley, I will shamesly borrow(steal) :)) from @darthmaulware(Ryan “DM” Smith) solution the yara detection rules just to make it look proffesional. Go check his twitter he's a fking cool person! Ps. Ryan please don't get mad bc i stole that :))) and thx for support in discord :)

Please check his work also :)

https://gitlab.com/malre-rcs/zero2automated/-/blob/main/solutions/bi_weekly_challenge/BlackLotus_20230321/BlackLotus_HTTP_Downloader.ipynb

root@kitploit:~
rule Blacklotus_HTTP_Downloader
{
        meta:
            description = "Rule to detect Blacklotus HTTP Downloader"
            author = "Darth Maulware"
            sha256 = "d68f668b4240f9518e4f80499d93d8c5a1eddece0771658c33ae916cc54f5a66"

        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)
}

Also for aesthetical reasone i will also steal this because it looks cool :) again sorry ryan please don't get mad on me :)

root@kitploit:~
        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 if i were you i wouldn't trust 100% capa(at least in this specific case) because here it say the sample uses rc4 when actually sample uses aes but whatever , as mentioned this is strictly for aesthetics :)

Before we start you will encounter through this report a lot of

1

Please ignore this as ida fails to properly dissasamble this in assembly this is

1

And this crashes the debugger ? why ?

because it tries to write at address 0, which in hacker folklor is know as writing at null pointer address which was something exploited widely in order to obtain CE(code execution), and this has been obviously mitigated.

And such with the current mitigation if you try to write at 0 it will crash that process in our case the malware & consequently the debugger.

Now if we open this is ida

1

I renamed every function to indicate some logic it does, let's start with first function, do_syscall() Capture23

We imediatly notice the use of syscalls, which it's a known method to make the life of an analyst harder when it comes to dynamic analysis.

For those who are not familiar with syscall's in windows here is a cool video made by oalabs(https://www.youtube.com/watch?v=Uba3SQH2jNE). Please watch it cause i did too and it helped me a lot to understand what happens in this function

If we inspect the "pseudo-code" resolved by ida we see it looks like this

Capture4

If we inspect statically solve_hash it looks like this

1

2

From a pseudo-perspective it looks like this

4

Please reffer to solve_hash.py to see my "emulation" of this in case you wanna see a piece of automation and you wanna find out what the syscall are resolve by hasing lookup algorithm. But non of the less this is part of a project called SysWhispers2 or at least that's what i pressume the malware's authors used as inspiration. None of the less please reffer to the upper videoclip of oalabs for better understanding.

Anyways the anti_debug function is easily bypass-able and well knows(https://anti-debug.checkpoint.com/techniques/debug-flags.html#manual-checks-ntglobalflag). The way to bypass it is to have scyllahide installed and NtGlobalFlag checked(which you should have by default on if you use x86dbg).None of the less this is what you are supposed to check

4

And this is how the anti-debug "pseudo-function" looks like

4

Pretty simple if you aks me

Next we have check_inmemory_ldr function which looks like this

1

2

Now for the purpose of the function analysis if we ask kind enough x86dbg we can see that if we run till syscall instruction x86dbg will be kind enough to return us the syscall it is about the execute . In our case

2

Now based on the current context we can presume that Ntsetinformationthread we be used as some sort of anti analysis trick. Surely enough if we do a quick google search we come to find this https://ntquery.wordpress.com/tag/ntqueryinformationthread/

Fortunatelly easily bypass-able just nop+ret patch-it :)

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

Following the execution order after this next function is

4

Again if we inspect to see what it does

Capture4

If simply checks a flag in teb to see if the current process(the exe in our case) is being debugged. This is yet again easily bypassable as it's a known method(https://anti-debug.checkpoint.com/techniques/debug-flags.html#manual-checks-peb-beingdebugged-flag) same way we used scyllahide this time you must have checked
Capturez

which should be on by default

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

Now custom_hash2_and_aplib_possible which looks like this

2

And from a graph perspective

3

Please reffer to decompress_aplib.py to see the "emulation" of this function.

Exploring get_ntdll_and_unhook2 it looks like this

1

2

From a graph view it looks like this

1

Not too shabby :))

Bakctracking a little we have aplib_decompress, now it looks like this

1

From a static code analysis looks like this

1

2

3

4

Mhmm a little big nothing to worry here folks it's doable :)

If you use the aplib_decompress.py emulation script you should end up with something like this

1

Cool thing i didn't notice on other blogs/analysis was this if we take a look again at ida's pseudo code for ntdll_and_unhook2

1

you'll see a interesting memcpy

at one point when i was doing the dynamica analysis i noticed another dll being loaded, which was another version of ntdll

1

if we look in debugger it looks like this

1

i was not able to detect what was hooked/patched but if someone knows please do a pull request and edit this document. Also in my attempts to find what gets hooked i tried to do bindiff between the two ntdlls and unfortunatelly i found nothing but it might be because i was already doing diff on system dll which was infected so not a clean run so maybe that's why ¯_(ツ)_/¯

1

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

Going further with the analysis process, on the unexplained functions we have some_hasing and ntquertyinformationprocess_anti_debug, thoese have not been explained. check_if_being_debug_through_teb and anti_debug has already been explained fortunatelly because they were used in the upper function/functions, so please read upper sections if wanna revise the knowledge about them. I would like to start first with ntquertyinformationprocess_anti_debug and afterwards finish with some_hasing.

Inspecting it we see the same function called 3 times.

1234

And from an assembly stance

1

2

For convinience i have already named it, which is ntquertyinformationprocess_ProcessDebugPort. From where did i knwon the function which were called were ntquertyinformationprocess_ProcessDebugPort? Inspecting them reveals an already saw function call/known algorithms to us

1

What about the comments made in ida ? Well if you search ntqueryinformationprocess on google we come along a good resource about anti debugging(https://anti-debug.checkpoint.com/techniques/debug-flags.html) . If we follow allong we can see it explain us that based on certain values passed as parameters to this functions it can be used as an anti-debuggin method.

For example for the first call we can see the following stack arguments in the debugger

1

If we now go and check msdn page for ntqueryinformationprocess

1

Same process repeats for the next two syscalls

2

which 0x1e is specific for ProcessDebugObjectHandle anti-debug method(https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software)

and finally ProcessDebugFlags

2

So how do we bypass them ?! Take a chill pill fam, cause ScyllaHide has about back braw

obama-pew

As you can see

1

So we safe! Not quite, while ScyllaHide has our back for the first 2 syscall, for the last syscall we have to do it manually ! and wtf do i do ??? Well simple solution! we return from this function so like from the whole ntquertyinformationprocess_anti_debug and set eax to 0 . So under normal circumasnces it looks like this

1

And with our "help" it looks like this and we safely let the execution go :)

1

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

Now some_hasing , you' lready know the drill

1

And now pseudo-code

2

We notice a strange thing here. Ida's pseudo-code fails here... because if we follow the graph after call_syscall there are more instruction to disassamble. So what we do here now ? Well we will relly on the debugger here to dynamically analyse this code...

So we see that the syscall it does is

1

Now if we look ntquerydefaultlocale google shows that this is an undocumented api which takes 2 arguments(http://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FLocale%2FNtQueryDefaultLocale.html). Cool so what it does ? It returns current Locale Identifier. Cool so wtf is a Locale Identifier? From msdn (https://learn.microsoft.com/en-us/windows/win32/intl/locale-identifiers) a 32-bit value that consists of a language identifier and a sort order identifier. On a tl;dr note what language you speak on that pc :)

Afterwards it check to see if api didn't fail to execute and if it didn't fail to execute it takes the value returned by ntquerydefaultlocale, substract 0x419 compares it with 0x26(probably a constant) as you can see in the picture below.

1

If it is not smaller or equal to 0x26 it compares it with 0x818 otherwise does same comparisson with 0x819 as you can clearly see

2

So wtf is happening here ? any why these specific constants. Well I'll be straight to point. While searching for different constants i came around this article(https://www.cnblogs.com/DirWang/p/17281690.html#autoid-8-0-0), a researcher which has already analysed blacklotus better than I could. And as someone said once: "You can't cheat in malware analysis , you can just make your work easier". So what the researcher said is that basically this function checks for specific constants which identify what language is spoken on the computer . In his article he provides a link to this(https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-LCID/[MS-LCID].pdf) which is like a standard document from microsoft with every language identifier.

Now using our hax00r l33t logic we can deduct that probably 0x26 it like an offset used , so like any 0x26 next language identifiers after 0x419,which are

2

If we also inspect that document we can also see that 0x818 corresponds to

2

and 0x819 to

2

And we know from previous "investigations"/online reports that this malware dind't run on certain PC from certain regions of the world, so we can conclude that this function checks to see on which region is the infected machine.

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

Crazy ham00brg33r up to now , fam what next ? We server some_more_syscall function. Aight! So what you got there ack! Here it is

1

We want more! Sure thing dawg!

2

3jgukd

1

Hmmmm

1

So check to see if kerneldebugger is present(https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntexapi/system_information_class.htm)(0x23) , checky checky!

So what ack! We we g0t pcr(piles and combinations party)

2

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

Now if we inspect iterate_over_modules() function it looks like this

1

From a "pseudo-code" perspective it looks like

2

From a standalone pov it looks like the assembly and ida's pseudo-code match, so what is the logic of this function do ? well pretty simple, it iterates over the in memory modules(dll's) and checks against a list of 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;

And if no in memory dll's were found to have same hash we return 0 , else 1 and we crash the debugger. And so such a conclusion we can say this is another anti-analysis method. Correct but what about each of the hash values ? Well i'll cheat again(as someone said once you can't cheat at malware analysis, only make your life more easier :) ). The upper afro-mentioned asian researcher was kind enough to provide us a list of values from which the values were derived

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

Now to dynamically see if the any values correspond to any dll mentioned

2

And sure enough it does :)

But how did i end-up coming wit the conclusion that the algorithms checks agains these values ? well when i emulated a piece of this malware i had to re-implement iterate_over_module_name_and_hash(in solve_hash_syscalls.py file ) and in this function we have

1

where x(passed argument) in this case is v2 which is an array(a pointer) of values which gets increments(where it point in array) as long as it doesn't match any values from the upper already mentioned values. Man that's a mouthfull :P

Cool beans! Next

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

iterate_over_modules2 roughly same story here

1

And pseudo-code

2

Roughly same story only different 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;

which correspond to

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

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

iterate_over_modules3 same story here

1

And pseudo-code

2

same story different 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;

which correspond to

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 i ended up renaimg it to anti_debug_measure2_RtlAddVectoredExceptionHandler_int3. Why , you' see in a minute. So it looks like this

1

And from a pseudo-code perspective it looks like this

1

So what in the f is this ? well it's basically creating an exception handler for __debugbreak(int 3) which will execute code whenever int3 is raised. I ended up searching for more and came around this

(https://blog.lexfo.fr/dridex-malware.html) which is a cool resource which let's us know this is simply an anti-debug mechanism, and for our case we just run this function we ignore sub_13F2820D0 which

gets triggered whenever we execute int3 and patch eax to 0 :) so in memory execution looks like this :)

Before patch

1

After patch

1

After that you exit the function and also edit rax/eax to 0 so you skip the jne to crash debugger

1

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

Anti_debug_measure_2 which i later changed to anti_debug_measure2_RtlAddVectoredExceptionHandler_int2

1

2

Again nothing new under the sun same thing just hookin other int/syscall this time int2, same trick to bypass use dynamically patching return value to bypass it :)

If you search for anti analysis 2dh on google a bunch of stuff will appear so yeah you can use that as a reference to learn more about that i didn't spend a lot of time with this :)

For this one even if you say try to step over it will end up at ret as here

1

and to bypass this simply execute till return and you are good :)

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

So now comes anti_debug measure heap which i later renamed iterate_over_current_process_and_check_again_hases

1

And a cool feature of this function is that this uses ntquerysysteminformation inside iterate_over_current_process_and_hash_check to list all the running processes. This is how iterate_over_current_process_and_hash_check looks like

1

2

Cool beans but how tf did i came to the conclusion that iterate_over_current_process_and_hash_check does what the name suggest, well first it's the ntquerysysteminformation call , which if you search on google you will see it used to get a list of running processes, and than i simply took and educated guess based on the following code snippet 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 ) that it would copy the list of processes iterate over each on and compare each hash from the previous array with whatever process was running. Now again kudos to the asian's research blog because idk how tf he came to get the actual name of v4 array values. Please reffer to iterate_over_modules.py in case you wanna see how i emulated this.

Ps. if you debug dynamically this function you will end up hitting int 2d again, and solution is same as mentioned above only that you basically run till return 0xf times, which basically walks the hev and after that if you wanna be sure you hit return from iterate_over_current_process_and_check_again_hases just put a br at the end of this function and you are safe :)

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

1

2

1

So yeah we fortunate this is not that big , and what's more we have already implemented demangle_strings. Now i have re-implemented this for bigger arrays please go see anti_debug_measure.py .

this basically checks against

root@kitploit:~
   \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

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

Now get_oem_key

1

2

3

4

5

1

2

First it demmangles string to

root@kitploit:~
   \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

And than queries
\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

and checks their values against qemu,vbox,VMWARE as it can be seen in ida snippet and x86 window :)

1

2

As it can be seen in first snippet it checks vmware against whatever values was stored in my vm at the time at the analysis :)

not big deal just run this function until ret and change eax when retuning to 0 :) to bypass this anti anaylsis method :)

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

now get_oem_from_firmware

1

2

3

4

5

Now something interesting we see that this function starts with sub_13F267288() which has 0x52534D42 passed as parameter. If you search this value on google you will come along a lot of cool questions on different forums eg(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==/) or this(https://github.com/digitalocean/go-smbios/blob/master/smbios/stream_windows.go) but most interesting after reading this and searching for RSMB you may come along this https://evasions.checkpoint.com/techniques/firmware-tables.html which explains us that this is an anti analysis method :) Cool so wtf does this do ?

First dumps SMBIOS Firmware Table, than demangles a string for first string being qemu than calls sub_13F2655E0 with params as demangled string and firmware table. From static analysis

1

2

precisely if ( v4 != v5) i came to the conlsuion that this is a strcmp implementation ish, it will check whatever is in firmware table with demangled string. As it can be seen in the debugger 1 r8 is a ptr to firmware table and more interesting we can see that blah blah something ... virtualbox is the name found in the firmware table and than rcx is qemu so we can safely say this a strcmp ish implementation. And surely as it can be seen we safe :) for this check

1

Now this process repeats for VirtualBox,vbox,VBOX,VMware strings :) Generally solution to bypass this function checking is run it till ret patch eax and continue analysis :)

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

Cool now check_oem_key ()

1

2

3

1

2

3

So wtf this do ? well same trick as previously explainied but this time with acpi table . wtf do i mean here ? well better read this 14 slides(https://dc4420.org/slides/2015-11-24/acpi_vm_detect.pdf) they explain it better, but same cheap trick :)) this time against BOCHS,BXPC,VMWARE

1

2

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

I wanna start with anti_debug_processor_Timing() function and than finish with check_for_flags(). So

1

This how looks. So wtf does it do ? it reads the current value of the processor’s time-stamp, than takes the name of processor(in our case GenuineIntel) than substract the retrived timestamp from name of processor and than simply check if the result is bigger than 19999.

After rdtsc

1

after cpuid

1

As it can be seen the string is split in 3 registers

1

And in our case we see we "fail" this check and set eax to 1

1

Solution to this anti-check simply return from function and patch eax to 0 :)

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

Now entry_to_peb()

1

2

3

4

5

6

7

From a pseudo-code perspective

1

2

3

So until the if check there's nothing new we already saw this type of algorithm so what about it ? well if you go to the already referenced write-up of the asian research you'll see that it says that it checks to see if version of windows is bigger than win7/server 2008 r2. but how did he came up with this ideea ? well if we read http://waleedassar.blogspot.com/2012/08/major-minorsubsystemversion.html he says

1

also if you also read this :)

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

and apply what it says here that if gets automatically casted to KUSER_SHARED_DATA structure but here my ida was bugged durin the analysis so it is what it is :)

in order not to bore you with same repetion of roughly ish same algorithm here are the final function retrived and demangled strings :) this was a grullin process as this was done with a debugger :) i was to lazy to emulate this

root@kitploit:~
  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  
} 

And with that this marks the end of the first half of the blacklotus analysis challenge.

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

For the second half

Assembly perspective

1

Pseudo-code perspective

1

We will start the dissection with some_hash() function

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

Graph perspective

1

Assembly perspective

1

2

3

Pseudo-code perspective

1

Download Tool