6.D.2. Optimizing original

Again we’ll be commenting the ASM code to make it more clear and obvious what’s being used for several function, parameters and calls.
Basically, it uses the execve function with /bin/sh as the file to execute and several parameters as arguments.

Used functions:
– Execve –> syscall 0xb

Used arguments:
From the strace output, the call is displayed along with it’s arguments.

execve(“/bin//sh”, [“/bin//sh”, “-c”, “echo HODORHODORHODOR! | wall”], [/* 0 vars */])

Registers:
As for the registers, it would contain the following values for the execve call:
– EAX: syscall 0xb
– EBX: “/bin//sh”
– ECX: “/bin//sh”, “-c”, “echo HODORHODORHODOR! | wall”
– EDX: NULL

Compiling:

$ ../compile_asm.sh asm_linx86_send-string-all-terminals_shellstorm_sample3_mod-alt
[+] Assembling with Nasm ... 
[+] Linking ...
[+] Done!

Running with strace:

For the sake of brevity, I’ve snipped the text a little.

$ strace ./asm_linx86_send-string-all-terminals_shellstorm_sample3_mod-alt
execve("./asm_linx86_send-string-all-terminals_shellstorm_sample3_mod-alt", ["./asm_linx86_send-string-all-ter"...], [/* 29 vars */]) = 0
execve("/bin//sh", ["/bin//sh", "-c", "echo HODORHODORHODOR! | wall"], [/* 0 vars */]) = 0
brk(0)                                  = 0x8063000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fdb000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3

...<SNIP>...

clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7e1d968) = 11076
close(4)                                = 0
stat64("/usr/local/sbin/wall", 0xbffffc70) = -1 ENOENT (No such file or directory)
stat64("/usr/local/bin/wall", 0xbffffc70) = -1 ENOENT (No such file or directory)
stat64("/usr/sbin/wall", 0xbffffc70)    = -1 ENOENT (No such file or directory)
stat64("/usr/bin/wall", {st_mode=S_IFREG|S_ISGID|0755, st_size=18056, ...}) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7e1d968) = 11077
close(3)                                = 0
close(-1)                               = -1 EBADF (Bad file descriptor)
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 11076
--- SIGCHLD (Child exited) @ 0 (0) ---
sigreturn()                             = ? (mask now [])
                                                                               
Broadcast Message from ???@stud                                                
        (/dev/pts/2) at 20:11 ...                                              
                                                                               
HODORHODORHODOR!                                                               
                                                                               
[{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 11077
--- SIGCHLD (Child exited) @ 0 (0) ---
sigreturn()                             = ? (mask now [])
exit_group(0)                           = ?

Compiling it as C file and running:

When running our modified and optimized version, we get results as expected and the size of the shellcode is 70 bytes which is smaller than the original version of 82 bytes.

$ ../compile_c.sh asm_linx86_send-string-all-terminals_shellstorm_sample3_mod-alt-c
[+] Compiling ... 
[+] Done!

$ ./asm_linx86_send-string-all-terminals_shellstorm_sample3_mod-alt-c
Shellcode Length:  70
                                                                               
Broadcast Message from ???@stud                                                
        (/dev/pts/0) at 21:43 ...                                              
                                                                               
HODORHODORHODOR!