Al Smith
Al Smith

Reputation: 253

Why do these syscalls do nothing?

I have to write some shellcode, and there's one part that doesn't work:

   0:   b0 c9                   mov    $0xc9,%al
   2:   cd 80                   int    $0x80
   4:   89 c3                   mov    %eax,%ebx
   6:   89 c1                   mov    %eax,%ecx
   8:   b0 cb                   mov    $0xcb,%al
   a:   cd 80                   int    $0x80

It's the equivalent of setreuid(geteuid(),geteuid()) (at least I hope it is). It doesn't crash the program or mess anything up, the problem is it doesn't do anything. For example, I put shellcode that executes /bin/sh after this and /bin/sh executes fine. Any setuid related syscalls seem to have absolutely no effect.

When I run strace, it outputs:

syscall_4294957257(0, 0x8048552, 0xffffd875, 0xf7fc7000, 0xf7fc7000, 0xffffd618) = -1 (errno 38)
syscall_4294967243(0xffffffda, 0xffffffda, 0xffffd875, 0xf7fc7000, 0xf7fc7000, 0xffffd618) = -1 (errno 38)
execve("/bin//sh", NULL, NULL)          = 0

I get the same output for setuid(id) and getuid(). So what I am wondering is why strace recognises execve as execve, but not the others. Shouldn't strace just recognise setreuid?

Upvotes: 2

Views: 739

Answers (1)

Sneftel
Sneftel

Reputation: 41474

A linux syscall reads the syscall number from the EAX register under x86. By moving C9 into AL, you're only setting the bottom 8 bits of EAX, leaving garbage in the rest. That's why strace calls what you did "syscall_4294957257": It's FFFFD8C9 in hex. (note that it ends with C9.) It's also why you see that errno 38, which translates to ENOSYS "function not implemented", or in other words, "I don't know what you're asking me to do".

The solution is to to clear eax before setting al, like so:

31 c0                   xor    eax,eax
b0 c9                   mov    al,0xc9 

Upvotes: 4

Related Questions