Reputation: 253
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
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