Introduction:
Hello all back with another interesting blog for you guys this time I am going to be covering a technique that advanced attacker use for evasion, it is known as Argument Spoofing Mitre has also documented this technique.
Although this technique can be implemented in high level language but in this case I have used assembly because it seemed easier with assembly, I also generated the shellcode because why not. Let's just jump in.
Argument Spoofing:
Let's first discuss what is argument spoofing. Basically attackers hide process arguments by overwriting the process memory at execution time, the arguments process memory or command-line arguments are stored in the process environment block (PEB), it is a data structure used by Windows to store information used by a process. Defense tools monitor process creations and may retrieve the process arguments from the PEB.
Let's head over to the fun part.
Demo:
First of all let's open up the debugger and see the process environment block structure and let's see how we can view the command line from the debugger.
I am using windbg for this demo and I'll be changing the notepad commandline argument.
To view the default command line I have used process hacker.
<process hacker notepad>
Let's view the PEB of the notepad process, by using the dt command.
dt _peb
Notice in the above screenshot there is a RTL_USER_PROCESS_PARAMETERS structure keep in mind that it is at an offset of 0x020.
Now let's view the command line argument of the notepad process, using windbg. By using the !peb command we can view the commandline of the process from the memory.
I need to get the address of the RTL_USER_PROCESS_PARAMETERS so that we can view the arguments and get the offset that we can use to further develop the program.
dt _peb @$peb
Going deeper in the structure of the processparameters. In the below screenshot we can see the offset of the commandLine which is 0x070.
Great! Now let's change the arguments of the process through windbg.
Let's verify through process hacker whether the arguments have been changed or not.
Awesome, we successfully changed the starting bytes of the string in the command line for demo purpose I am not going to overwrite the whole argument.
Shellcode and Assembly:
Since we know that the peb is in segment register and an offset of 60h, we can start our program by getting the address of the PEB,
mov r9, gs:[r15+0x60]
We save the address of the PEB in the r9 register, now we we need to go to the RTL_USER_PROCESS_PARAMETER structure and it is at an offset of 0x20 for that we do the following instruction.
mov r9, [r9+0x20]
Further down the line we have to go to the _UNICODE_STRING structure, we will add 0x70 in the r9 register.
add r9, 0x70
We have the _UNICODE_STRING structure address in the r9 register.
Now that we have the address of the UNICODE_STRING structure we can then copy our bytes to the memory of the UNICODE STRING address.
Assembly Code:
| [bits 64] global _start section .text _start:
| |||||||||||||||||||||||||||||||
I have compiled the above code with nasm and Golink as the linker.
I had to run the program through the debugger otherwise it will be terminated very quickly because it doesn't have much instruction.From the debugger:
And we have successfully changed the command line argument :).
We can generate the shellcode of the above code and inject it into our own process, so let's generate the shellcode with the following command,
nasm -f win64 cmdline.asm -o cmdline.o
for i in $(objdump -D $1.o | grep "^ " | cut -f2); do echo -n "\x$i" ; done
I have added some code in the assembly program to call the sleep function (so that the program does not close immediately) but that is a whole different story and this blog is not for that (but if someone wants the code then I'll be more then happy to share it you can contact me on my Linkedin, so let's skip the detail for now I'll do a full series of blogs for the shellcode development.
Using a shellcode injection c language program I have injected my shellcode and let's see whether the program arguments are changed or not.
Great we can see from the above screenshot that the argument are changed by injecting the shellcode in our own process.
I hope you guys learned something new till next time.
References:
https://www.ired.team/miscellaneous-reversing-forensics/windows-kernel-internals/exploring-process-environment-block
https://attack.mitre.org/techniques/T1564/010/
https://www.bordergate.co.uk/argument-spoofing/


