Dear Diary (archived)
My security oriented Diary
I found a bug in sudo while studying CVE-2021-3156. accepted and patched. https://github.com/sudo-project/sudo/issues/95
I'm studying/explaining Malware from PMA Labs using IDA and Hopper
I tried the sstic challenge (finished 12th on the 1st flag, couldn't find the others)
on iatus to code stuff and learn more languages
back with more malware
2021/03/30
Dear Diary, today I'm starting a diary
Dear Diary, I started you.
I'm watching YouTube video about Fuzzing & Buffer Overflow : https://www.youtube.com/watch?v=FCIfWTAtPr0
the video is too beginner oriented, I'll give a try to part 4 (finding the offset) anyway. Part 5 is about EIP.
Not really useful to me (a priori), but the videos are very short so it's cool.
I'm planning to give a try to sstic challenge 2021, it starts this weekend : https://www.sstic.org/2021/news/
I did some ARM64 disassembly stuff this morning while drinking my first coffee of the day, using hopper disasm. Turn out it's much easier when the source code isn't written in swift(c)(r)(tm)
CVE-2021-3156 is scary. Congratz Qualys for finding it.
https://www.kb.cert.org/vuls/id/794544
Apple’s Big Sur is also vulnerable, as well as cisco, netapp, juniper, ...
Also, https://www.youtube.com/watch?v=2_ZaNBl6qNo
I like this channel, I subbed some times ago, and the discord dudes are cools too
mysql suck :[
why is it so bad ?
should I buy Hopper disasm ?
I want to go home. I'm going home.
I'm home
Exploring CVE-2021-3156 @ home
This is what I understood :
You can use multiple line in argument by escaping with \
Sudo ignore the character following \
what if \ is the last character ? it ignores \0 (NULL) and read stuff it shouldn't read because the null terminator is ignored.
Let's find out.
The commit fixing the bug is here https://github.com/sudo-project/sudo/commit/1f8638577d0c80a4ff864a2aad80a0d95488e9a8
and here https://github.com/sudo-project/sudo/commit/b301b46b79c6e2a76d530fa36d05992e74952ee8
and ... here ? https://github.com/sudo-project/sudo/commit/c4d384082fdbc8406cf19e08d05db4cded920a55
This was also submitted by Qualys the same day, let's assume it's part of it https://github.com/sudo-project/sudo/commit/c0eecf85c8b0920a9398920d5f5dae0ee2804b46
Well... it's not as simple as " we forgot that having a backlash as last character could happens ". No no no. It's an error with flags and stuff, because sudo DO check for this. (i'll have to check for sure but I assume it does)
Also, sudo and sudoedit are the same binary. sudoedit is just a symlink to sudo, and sudo is checking its own name to set some flags here and there in order to behave as "sudo" or as "sudoedit". Well, that's what I understood anyway. I'll check, of course.
My immediate thought was : what if it's called neither "sudo" nor "sudoedit" ? huh ? huh ? aren't I smart? Well... I'm not the smartest one.
This is the patch published 3 days after the CVE fix : https://github.com/sudo-project/sudo/commit/19d5845f8b6ae429a597d53c7f8201514537b590 The program name may now only be "sudo" or "sudoedit".
Anyway... code stuff !
The old code :
This is honestly a weird way to check if it's invoked as "sudoedit". It could technically be "anythinglongerthan4edit". Why ? dunno ! Probably very legacy.
The new check is as easy as :
While we're here we can clearly see one bigass fix : valid_flags = EDIT_VALID_FLAGS;
Well... I know it is because youtube told me it was about flags. :]
The new code is still weird, imho. It says : The plugin API includes the program name (either sudo or sudoedit). But this is not what the code is doing. it checks if it's " sudoedit " or " anything else ".
Anyway... I'm on my windows, I have WSL and ubuntu installed.
huh ? okay then ...
C'mooon... really ?
how about this ?
I tried on my mac M1. " sudo -V " works. and sudoedit is " command not found ".
I'm starting up a linux cloud instance.
nice ! I found a boring bug ! :o)
it should not happen. the usage() clearly say that -v and -V are valid.
There are some other potential issues still happening with sudoedit. could it lead to a security issue ? dunno.
So let's check parse_args.c, again.
No, I'm not. I'm checking all calls to usage() from parse_args.
mmm ? Let's try something.
ho so there are two different usage() for sudo and sudoedit.
Okay ... actually so the warning I get isn't from usage() but from usage_excl()
Let's check the 1.8.21p2 source code just in case
The source I got from apt source shows :
It's pretty much the same I guess ?
The source also show that the main bug that issued the CVE is fixed :
The flag is here. mode is set and different than MODE_VERSION so it indeed show usage_excl(). But why ?
After some time thinking about it, it's obvious :
But why does it call usage_excl() here ?
why is mode set but it's clearly not MODE_VERSION ?
Because sudoedit set mode = MODE_EDIT;
I'll submit a bug report and see how it goes.
First day, first bug. yay \o/
Bug report : https://github.com/sudo-project/sudo/issues/95
That was one big messy daily report. I wanted to explore a CVE and found a (minor) but instead.
That's even better, isn't it ?
Zzzz
Or not, my bug was (partially :( )) fixed and closed already.
and I found another problem (pretty much the same bug actually) when calling sudoedit -h
I think I understand why there is no sudoedit on mac. it shouldn't exist in the first place, imho.
When you read this diary you clearly see that I wrote stuff that were clearly incorrect. I'm not removing it. it accurately describe my thought process and I'm not always right on first try.
Zzz ?
2021/03/31
Dear diary, it's morning already. I'm not working today. More CVE ?
It turn out that Macos also have (had) the sudoedit problem.
sudoedit does not exist by default on mac but the code is still here anyway
just create a sudoedit symlink
ln -s /usr/bin/sudo sudoedit
it does not require any privilege to be created
the sudoedit code is still in the sudo binary
My bugreport has been closed with a patch that check if progname is "sudoedit"
They also added a separate getopt config for sudoedit
It's not my code, so I can't say that my code has been added to billions of devices. But it's because of my report, and this Diary, that the code has been patched. it still feels good :]
Perhaps I should take it easy since I want to do a difficult challenge starting in a few days. Non non Biyori, then some simple asm later.
I'm going to play with "Practical Malware Analysis" binaries. It's easy stuff but it's exactly what I want for today. I'm going back to work tomorrow and it will be a PITA day.
Playing with PMA Labs
Let's start with Lab01-01.exe.
I'm even using IDE Free 70 instead of my licensed version.
According to " detect it easy " it's a 32bits PE executable, unpacked, compiled with MSVC 6.0
Opening it in IDA with default option
Only the EntryPoint is exported, it import kernel32 and msvcrt
Some useful strings
it's easy to guess what's going to happens if you execute it. it will destroy/replace your kernel32.dll
Opening the Entry Point in IDA. Nothing unusual, it appears to be some standard init.
Before exiting, it call a sub, which should be our WinMain and the var pushed before the call should be our usual args.
Let's rename it to WinMain and let IDA do its magic (the stuff we're willing to pay for)
Jumping into WinMain, it feels wrong. Let's call it main instead.
Isn't it much better ? initenv (whatever that is) create envp. now it feels right.
The first few lines of our main(int argc, const char **argv, const char **envp), commented
Let's explain, because I have time. remove the book-keeping stuff and focus on the user code.
eax = argc. nothing to see here. argc is the number of argument. 1 mean "no argument" (the 1st arg is the program name), 2 mean, of course, 1 argument
compare eax with 2. So we can guess it's expecting to be called with an argument in command line.
cmp set the ZF and CF flag according to the result of the comparison.
cmp dst, src | ZF | CF |
---|---|---|
dst = src | 1 | 0 |
dst < src | 0 | 1 |
dst > src | 0 | 0 |
So if argc == 2 then ZF should be 1
Next is JNZ (Jump Non Zero), also known as JNE (Jump Not Equal)
I'll be honest here. I always get confused by JNZ. it jump if ZF = 0. But if you think of it as being "JNE" it's much easier.
Anyway : if(argc != 2) { goto loc_401813; }
it jump directly to the end of our main. Therefore, because eax = 0, we get something like :
if(argc != 2) { return 0; }
our "malware" wont work without argument. It's probably a security measure because this is a fake malware for educational purpose.
What's happening if argc = 2 ?
First, it get a pointer to argv (which contain our arguments from command line)
next, esi will point to a string, esi is often used for loop
finally, eax = eax+4. we're in 32bit, a pointer is 4 byte long. Basically, eax will now point to argv[1] instead of argv[0]
we have a string, a loop and argv[1]. easy guess : it will check if the exe will be called like this :
I'm skipping a bunch of mov, cmp, test, loop, with a final jnz going straight to exit if the comparison fail.
For the curious :
Next, all the following jnz goes to exit so I'll skip it :
Thank you IDA for knowing the win32 api <3
Hey... did you know that writing this take forever ?
I'm supposed to be on a break.
Enough for now. All the calls above speak for themselves. go read MSDN to know more :)
2021/03/32
Dear diary, this day doesn't exist (citation needed)
2021/04/01
Dear Diary, new COVID lockdown, again ... meh... :[
Anyway, back to the previous exercise.
MapViewOfFile: https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-mapviewoffile
CreateFileMappingA: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createfilemappinga
CreateFileA: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
About CreateFileA dwDesiredAccess :
dwDesiredAccess | Mask |
---|---|
GENERIC_READ | 0x80000000 |
GENERIC_WRITE | 0x40000000 |
GENERIC_EXECUTE | 0x20000000 |
GENERIC_ALL | 0x10000000 |
CreateFileA return a file handle (in eax, return value are always in eax),
then CreateFileMappingA is passing this eax as hFile argument and return a file handle (HANDLE) in eax
which is used as the hFileMappingObject argument.
finally, CreateFileMappingA return a LPVOID
If the function succeeds, the return value is the starting address of the mapped view.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
TL;DR : "C:\Windows\System32\Kernel32.dll" is mapped in memory
Lab01-01.dll is created with CreateFileA, follow by CreateFileMappingA & MapViewOfFile. same as above.
I'm not at home with my IDA, VM, Windows, etc... so that's it for now. I'll have to go home to read the rest of the code.
Dear Diary, I'm home again.
I'm reading the next piece of code and it's going to get a little bit messy. The reason is that it call a bunch of sub_xxxxxx and I'll also need to rename some local var. It's not difficult to guess what's going to happens, but since I'm writing this diary I'll push myself to reverse every part of it.
The list of local vars :
With a quick look at the code, I have no way to really what the vars means so I'll have to reverse every sub one by one first. Luckily, we have only 7 sub_, which is very very low.
After some browsing each of them, this is a small one. I already renamed it :
But it's only called by the entry point, which isn't user code so we can safely ignore it. _controlfp : Gets and sets the floating-point control word.
Another one, renamed it, also called by the entry point :
We're down to 5 sub. 3 of them do not do any external call to dll's function. 2 of them call kernel32.dll (& msvcrt ?).
sub_4010A0 (renamed to : read_file)
called by : sub_4011E0 (which I renamed to search_file)
system calls : CreateFileA, CreateFileMappingA, MapViewOfFile, IsBadReadPtr, UnmapViewOfFile, CloseHandle, _stricmp
sub_4011E0 (renamed to : search_file)
called by : main, sub_4011E0 (yes, it's calling itself)
system calls : FindFirstFileA, malloc, _stricmp, FindClose, FindNextFileA,
For now I'll just rename "sub_4011E0" to "search_file" and "sub_4010A0" to "read_file". Considering how it also call "Create_File" it's probably not just "reading" files, but for now I'll keep it as is. It's just a random guess according to the calls it's doing.
So, "main" call "search file" which is calling "read_file". I wish I could do graphs, but github doesn't support it.
"read_file" also call "sub_401040"
"sub_401040" only call "401000"
I guess it's time for a graph, I'll use the IDA's proximity browser.
Not bad, huh ? So, what is sub_401000 ? there is a loop in it, but here is the first part before the loop.
Let's remove some stuff for now :
Haaa what a pain ! "cx" is the the lower 16bit of the 32bit ecx register.
Basically it seems to test if whatever is at edx+6 == 0
"whatever is at edx+6" is defined by esp+arg_4.
So, again, what is arg_4 ?
Dear Diary, I'm going to eat before I forget to, and read some manga. (Beware of the villainess)
See you tomorrow. I'm forcing myself to take a break.
2021/04/02
Dear Diary, I just tested IDA Free 70 on my mac M1 : it works.
The part of the code where I stopped yesterday still upset me.
why +6 ? why 16 bits ? it's important to give up and keep going, perhaps I'll know why later. Perhaps it does not matter and it's just the compiler doing compiler stuff. But the purpose of the Diary is to go in depth. Or not... it's just my notepad, I do wtf I want to.
For some reason I can't extract the PMA Labs on my M1, it says the password is incorrect.
it seems to be a known problem. I installed "keka" and the extraction works.
TL;DR : I can keep on reversing this exe on my mac now
To be honest, this is the kind of code where a decompiler would be helpful.
And I have one, hopper disassembler. does it help ?
Meh ...
By the way, if we go back near the end of the the main :
Just saying.
Anyway... I have a little bit of dilemma here. is it my diary or does it become some kind of tutorial ? If it was just me, I would have happily just ignored this annoying sub. it doesn't seems to matter that much. I can always come back to it later, or not. does it even matter ?
i really want to go check that dll instead. And drink coffee too.
Lab01.dll
It import kernel32 (createProcess, sleep, createmutex, ...), msvcrt, and ws2_32. nice :]
Isn't it much more fun ? ws2 is winsock <3 internet stuff \o/ https://docs.microsoft.com/en-us/windows/win32/winsock/windows-sockets-start-page-2
it export the EntryPoint only, what least that's what IDA says, and hopper agrees.
strings are : "hello", "sleep", "SADFHUHF", "172.26.152.13"
A quick look at the main function tell me that :
It create a mutex named SADFHUHF
it open a socket, send "hello"
wait to receive something
"sleep" : call Sleep
"exec" : call CreateProcessA
"q" : call CloseHandle and exit
loop back to hello
I don't think I need to do any intensive reverse engineering here. it's a 5mn job.
Lab01_02.exe
Opening in IDA :
Nice <3
Only function found, the entry point.
Import : LoadLibraryA, GetProcAddress, VirtualProtect, VirtualAlloc, VirtualFree, ExitProcess, CreateServiceA, exit, InternetOpenA
The imports are super suspicious of course. the broken PE too.
Conclusion : it's probably UPX packed.
Strings : Kernel32.dll, Advapi32.dll, msvcrt.dll, wininet.dll
I guess I have to explain a little bit what's happening here ?
It's very easy, it's trying to load dll dynamically :
LoadLibraryA :
https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibrarya
Loads the specified module into the address space of the calling process. The specified module may cause other modules to be loaded.
HMODULE LoadLibraryA( LPCSTR lpLibFileName );
lpLibFileName : The name of the module. This can be either a library module (a .dll file) or an executable module (an .exe file). The name specified is the file name of the module and is not related to the name stored in the library module itself, as specified by the LIBRARY keyword in the module-definition (.def) file.
GetProcAddress :
https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress
Retrieves the address of an exported function or variable from the specified dynamic-link library (DLL).
FARPROC GetProcAddress( HMODULE hModule, LPCSTR lpProcName );
hModule : A handle to the DLL module that contains the function or variable.
lpProcName : The function or variable name, or the function's ordinal value.
If the function succeeds, the return value is the address of the exported function or variable.
If the function fails, the return value is NULL.
Easy ? Right ? Instead of importing a function from a dll, you load it at runtime.
About the broken PE now :
IDA -> View -> Open Subviews -> Segments
UPX0
UPX1
UPX2
.idata
UPX2
Toldyaso, it's UPX packed. There is an IDA plugin. Named "Universal Unpacker" or something but i need my licensed IDA version.
And it's on my computer at home. My mac run IDA Free 70. Pooh.
i don't want to bother trying to unpack it on my mac when in can do it at home. I'll do something else instead.
SSTIC 2021
The challenge will be published in less than 2h.
I just hope it won't be something i know nothing about, I'll be happy if i get one flag. Please don't be an iPhone app or something that start with crypto. The rules probably won't allow me to publish what I'm doing so I'll have to start a private diary and publish it after the deadline.
My bet is that it will be an IOT device.
I was checking the github repo you're reading : 33 Clones, 18 Unique cloners <- wtf ?
The challenge is up.
TL;DR : i need to learn the USB protocol.
...
i found the first flag <3
2021/04/03
Dear Diary, while asleep i got some idea about how to solve the 2nd flag.
and here i am struggling with too many potential attack vector...
i reversed most of the flag2 code, i can't find a flaw yet.
4PM and i still can't find the 2nd flag. Also, i did some shopping to take a break.
nobody found the 2 flag yet.
Brain meltdown
2021/04/04 : Dear diary, i still can't find the flaw i need in the sstic challenge. i RE'd everything, twice. My brain is melting
2021/04/05 : Dear diary, my brain need a break.
2021/04/06 : Dear diary, I'm making a Neural network based game using GMS2 during my break (if you can call that a break)
2021/04/07
Dear diary, I'll go back to my usual easier stuff. The sstic challenge can wait a little bit.
I found 2 interesting links :
https://github.com/thalium/icebox : Icebox is a Virtual Machine Introspection solution that enable you to stealthily trace and debug any process (kernel or user).
https://github.com/umanovskis/baremetal-arm : This repository contains a tutorial ebook concerning programming a bare-metal ARM system. More specifically it deals with a ARMv7A version of the ARM Versatile Express platform, emulated on a regular PC through QEMU.
2021/04/11
Dear Diary, i started learning TypeScript, it easy.
2021/04/21
Dear Diary, I'm also learning Rust, it's not as easy as typescript (obviously).
I gave up on the SSTIC challenge, i still have a long way to go i guess. The difficulty gap between the 1st and 2nd flag is hardcore. I hope the solution to the 2nd flag isn't some obvious trap i failed to notice. (probably is. i think I'll be upset when I'll read the solution)
I should go back trying to find bug in stuff.
I haven't read the PostgreSQL source code for a long time. Guess I'll just do that. Easy, peaceful, no stress. I'm an idiot.
2021/05/12
Dear Diary, I'm learning rust. it's very time-consuming, sorry.
2021/11/09
Dear Diary, long time no see. I learned Rust and Swift, and a bit of kotlin.
Also, i'm really trying hard to switch to Ghidra, but everytime i use it remind me of how good IDA is. Still, IDA is so damn expensive... of course it's time to renew my IDA licence and i can't really spare the expense.
About the SSTIC challenged. I finished 12th on the first flag but couldn't find the others. imho, the 2nd flag was too far away. I was on the right path. I fully reverse engineered the binary, found the exploit (a poorly designed struct related to username, if i remember correctly), the exploit would have helped to poke the windows kernel and get a shell.
Anyway, i'm busy analyzing a malware in my small spare time. An old-school one corrupting the MBR. Good old time.
uselessdisk.exe
I'm not done with it but here a summary of the important part :
2021/11/10 : Exploring emotet
SHA256 : 878d5137e0c9a072c83c596b4e80f2aa52a8580ef214e5ba0d59daa5036a92f8
Probably the scariest trojan of the current days. Let's explore it. I using ghidra again.
According to ghidra, the only import is
KERNEL32.DLL::WTSGetActiveConsoleSessionId
I wonder what it can possibly be with so little and i'll have to find out.
The obvious step for now is to find out how it load other functions to be able to do anything.
There isn't that much function and a quick overview found this stuff, i renamed the functions with my own naming convention.
I have no idea what it's doing. I'll have to (possibly) patch the function signature too.
There is also a lot of repetitive call to the same function pointer
Then i'll have to trace back the references to the function pointers
Here is how it looks for now
Tons of "CALL dword ptr [k_DLL_FP1/2/3]" and there isn't a single write directly referring to the FP's addresses
It must be part of a struct or an array
AND their addresses are : 0040c1e8, 0040c17c, 0040c1a8, they're quite close to each-others
AND there is a lot of 4 bytes data in there. possibly a huge list of (function?) pointer
if i scroll up a little bit i find the address "0040c040", an XREF find me a PUSH to this address.
and it lead directly to "k_DLL_loadfunction3?(0x21,0x54b7e774,&DAT_0040c040);"
Heh :)
If we look at all the &DAT_ in k_DLL_loadfunction3, the address are not that far to each other
And not far from the FP too.
I'll bet on an array of struct for now and take a closer look at k_DLL_loadfunction3?
(Btw, the 2nd argument may be a hash)
k_DLL_loadfunction3
Duuuuh ! Of course there is a loop, of course the "suspected hash" is XOR'd
Time for celebration
Back to k_DLL_loadfunction?
The call to function2 is always the same : k_DLL_loadfunction2?(0x4a604ebc,&local_8);```
It's not loading something as my naming imply. it's probably doing a system call.
it is now named "k_DLL_systemCall?"
We have a repetition of this pattern
One of them have to a LoadLibrary() or something close to it.
it would be way to inconvenient if it wasn't the case (but we never know with malware, i may be deep into a rabbit hole instead)
i'll take a small break, rename stuff, explore some more.
And it's getting late anyway.
The function calling k_DLL_loadfunction is this one, looks familiar ? i hope it does or you haven't been paying attention
2021/11/13
got my hand surgery yesterday, it went well
both my brain and hand are out of service
it hurt just a little bit, from time to time, and the opioïd medication is effective
The press is talking about BotenaGO malware, targeting NAS, Router & IoT.
look like it use a lot of different exploit
eg : (from https://www.bleepingcomputer.com/news/security/botenago-botnet-targets-millions-of-iot-devices-with-33-exploits/)
BotenaGo incorporates 33 exploits for a variety of routers, modems, and NAS devices, with some notable examples given below:
CVE-2015-2051, CVE-2020-9377, CVE-2016-11021: D-Link routers
CVE-2016-1555, CVE-2017-6077, CVE-2016-6277, CVE-2017-6334: Netgear devices
CVE-2019-19824: Realtek SDK based routers
CVE-2017-18368, CVE-2020-9054: Zyxel routers and NAS devices
CVE-2020-10987: Tenda products
CVE-2014-2321: ZTE modems
CVE-2020-8958: Guangzhou 1GE ONU
i'm still exploring emotet. i resolved some FP by guessing their parameters. Eg:
2021/11/14
Dear diary, my left hand is still pretty much unusable for daily activity (cooking, putting on socks, ...) BUT i can type on keyboard much more easily now. Anyway ...
I successfully compiled ghidra from source using IntelliJ IDEA Ultimate. Thank god i won't have to use the recommended Eclipse IDE.
On a M1 Powered Mac.
I'm renting a Mac Mini M1 at scaleway so i don't have to use my macbook Air M1 for SRE.
I just finished running the UnitTest, it took 35mn.
All tests related to debugger failed. I'm not surprised. M1 isn't supported, yet.
this failed is a bit more surprising but pretty much harmless :
there is no M1 native for 7zip. Meh... i don't care.
Now i can use the latest and greatest Ghidra and perhaps patch some bugs too ?
2021/11/15
Lots of post-surgery paperwork today.
I hope i'll have some post-paperwork time to play with emotet.
to fastcall or not fastcall ?
The decompiled code was :
But with that, 0xd22e2014 vanished into nothingness.
Clearly, it's there for a reason and ECX have to be an argument, right ? Luckily, there is a call convention for that kind of call.
And it become :
Yet, it doesn't return anything, which is unlikely. And the 2nd call is :
EAX could be the returned value of k_get_something_from_TIB and passed to k_DLL_importWithHash
Another fast call ? Mmmmm
I don't know... it look like it but i don't like the output.
It's probably wrong.
At some point you gotta stop the guesswork, or even stop reading the decompiled output, and focus on the real code : ASM.
That's why i really like IDA : Assembly first.
Oops, paperwork. BBL.
Note for later : https://docs.microsoft.com/en-us/cpp/cpp/thiscall?view=msvc-170
2021/11/16
More post-surgery stuff, i'll finally get to see what's hiding behind all the bandage.
I did some googling about the TIB and stuff, it's not easy. And more specifically about the PEB.
The thing, i still don't really get how it get to load DLL without using a single string ("kernel32.dll")
I understand that the code is using hash to find the function it's looking for, but still...
When wikipedia'ing about the PEB i found this :
Ldr
A pointer to a PEB_LDR_DATA structure providing information about loaded modules
Contains the base address of kernel32 and ntdll.
Aaaand there it is.
It's safe to assume that emotet will browse all loaded dll, which is guaranteed to have at least kernel32.dll
safe to assume, because there are a lot of loops in the code
I can guess it will check every method in every dll
compare it with a hash
save the address of the function that match the hash
This is the stuff i named with "FP"
i'll have "to go deeper" and analyse "k_get_something_from_TIB" to confirm my intuition
PS : i'm still digging my rabbit hole, everything you see above is based on a lot of assumption and intuition coming from experience
It would be embarrassing if i were completely off-track but that wouldn't be the first time and that's part of the process
Not for later, this look super important as i've seen this somewhere into the code : From wikipedia's PEB :
Back from the clinic, my hand is officially "OK" <3
So...
Some good info :
https://rstforums.com/forum/topic/107778-anatomy-of-the-process-environment-block-peb/
https://0xevilc0de.com/locating-dll-name-from-the-process-environment-block-peb/
https://www.aldeid.com/wiki/PEB-Process-Environment-Block
(in_FS_OFFSET + 0x30) is the PEB
PEB + 0xC = PEB_LDR_DATA
PEB_LDR_DATA + 0xC = InLoadOrderModuleList : _LIST_ENTRY
See : https://docs.microsoft.com/fr-fr/windows/win32/api/winternl/ns-winternl-peb_ldr_data?redirectedfrom=MSDN
Some more infodump :
Luckily, Ghidra knows wth is a LIST_ENTRY, but it doesn't know about PEB and LDR :(
My typing and naming doesn't seem to be correct yet, but we're getting somewhere :
i found a good video : https://www.youtube.com/watch?v=Tk3RWuqzvII
The video appears to describe what our function is doing. Nice.
We can go back for now and safely assume it loaded kernel32.dll
2021/11/17
TL;DR : i sorted out the mess i made the past 2 days.
Now it make sense, right ?
Also, i created the LDR_DATA_TABLE_ENTRY in ghidra, sorted out some more mess too.
i still have some weird stuff but :
it loop over each entry of the table.
if the (lowercase) hashed name == hash then return a pointer to baseDll
return 0 if it couldn't find it
a mini-victory self-five for me ! yay !
2021/11/18
Dear Diary,
i checked some video about github autopilot. it looks seriously awesome.
I'm on the waiting list...
2021/11/19
i really, really, want my access to copilot :(
2021/12/02
I still don't have access to copilot, i'm upset about it.
I want to give a try to EUFI Reverse engineering.
brb.
2023/12/23
hi there, i'm back. And, yes, i got my access to copilot since then. I love it.
Today i decided that i want to play with USB. I also ordered a Flipper Zero but i'm waiting to receive it. I might buy a HackRF one too (and renew my ham radio license).
I just installed Writerside EAP and using it to write this.
Nothing much on the cybersec front. Busy with work and stuff. (like getting my motorcycle licence <3 )