So, for a course in school we are trying to find an assembly code which would find the system hostname (i.e. what's printed out when running "hostname" or "uname -n" in the terminal).
But after a lot of googling, we are stuck. The thing is, the code is then to be converted to shellcode, but with all the versions we've tried it results in segmentation fault. Usually we've written a small C program, assembled it and then using gdb written it into shellcode.
And we always end up with segmentation errors.
So, any suggetions as to how, as simply as possible, find the system hostname through assembly? (Running Ubuntu x86 through VirtualBox)
And secondly, any ideas how to errorcheck current shellcode which results in segmentation fault? (Running executable code from the stack is enabled)
Thanks a lot in advance, with either problem!
The "new uname" syscall returns following structure:
#define __NEW_UTS_LEN 64
struct new_utsname {
char sysname[__NEW_UTS_LEN + 1];
char nodename[__NEW_UTS_LEN + 1];
char release[__NEW_UTS_LEN + 1];
char version[__NEW_UTS_LEN + 1];
char machine[__NEW_UTS_LEN + 1];
char domainname[__NEW_UTS_LEN + 1];
};
That means we need to allocate at least 390 bytes for the struct and the nodename
begins at offset 65. On 32 bit linux the uname syscall is #122
. As such the standalone code could look like:
xor %eax, %eax # eax=0
sub $122, %eax # eax=-sys_uname
lea (%esp, %eax, 4), %esp # allocate buffer
neg %eax # fix sign of sys_uname
mov %esp, %ebx # address of the buffer
int $0x80 # syscall
mov $4, %al # sys_write (assume eax==0)
lea -3(%eax), %ebx # stdout (1)
lea 65(%esp), %ecx # address of nodename
lea 60(%eax), %edx # length (do strlen if you want)
int $0x80 # syscall
mov $1, %al # sys_exit
int $0x80 # syscall
This will print the whole nodename
, so includes a bunch of trailing zeroes (which are normally not visible). Determining the exact string length is left as an exercise ;)
This is position independent (and zero byte free) code, just getting the machine code bytes and copying it into the stack should make it work as shellcode (assuming executable stack as you said):
void main()
{
char code[] = {
0x31, 0xc0, 0x83, 0xe8, 0x7a, 0x8d, 0x24, 0x84,
0xf7, 0xd8, 0x89, 0xe3, 0xcd, 0x80, 0xb0, 0x04,
0x8d, 0x58, 0xfd, 0x8d, 0x4c, 0x24, 0x41, 0x8d,
0x50, 0x3c, 0xcd, 0x80, 0xb0, 0x01, 0xcd, 0x80 };
((void(*)())code)();
}
Compile using gcc -m32 -z execstack
.