-4

I want to overflow the array buffer[100] and I will be passing python script on bash shell on FreeBSD. I need machine code to pass as a string to overflow that buffer buffer[100] and make the program print its hostname to stdout.

Here is the code in C that I tried and gives the host name on the console. :

#include <stdio.h>
int main()
{
   char buff[256];
   gethostname(buff, sizeof(buff));
   printf(""%s", buff);

  return 0;

}


Here is the code in assembly that I got using gcc but is longer than I need becuase when I look for the machine code of the text section of the c program it is longer than 100 bytes and I need a machine code for the c program above that is less than 100 bytes.


     .type   main, @function
main:
pushl %ebp; saving the base pointer
    movl %esp, %ebp; Taking a snapshot of the stack pointer
subl $264, %esp; 
addl $-8, %esp
pushl $256
leal -256(%ebp), %eax
pushl %eax
call gethostname
addl $16, %esp
addl $-8, %esp
leal -256(%ebp), %eax
pushl %eax
pushl $.LCO
call printf
addl $16, %esp
xorl %eax, %eax
jmp .L6
.p2align 2, 0x90
.L6:
leave
ret
.Lfe1:
.size   main, .Lfe1-main
.ident "GCC: (GNU) c 2.95.4 20020320 [FreeBSD]"

A person has already done it on another computer and he has given me the ready made machine code which is 37 bytes and he is passing it in the format below to the buffer using perl script. I tried his code and it works but he doesn't tell me how to do it.

“\x41\xc1\x30\x58\x6e\x61\x6d\x65\x23\x23\xc3\xbc\xa3\x83\xf4\x69\x36\xw3\xde\x4f\x2f\x5f\x2f\x39\x33\x60\x24\x32\xb4\xab\x21\xc1\x80\x24\xe0\xdb\xd0”

I know that he did it on a differnt machine so I can not get the same code but since we both are using exactly the same c function so the size of the machine code should be almost the same if not exactly the same. His machine code is 37 bytes which he will pass on shell to overflow the gets() function in a binary file on FreeBSD 2.95 to print the hostname on stdout. I want to do the same thing and I have tried his machine code and it works but he will not tell me how did he get this machine code. So I am concerned actually about the procedure of getting that code.

OK I tried the methods suggested in the posts here but just for the function gethostname() I got a 130 character of machine code. It did not include the printf() machine code. As I need to print the hostname to console so that should also be included but that will make the machine code longer. I have to fit the code in an array of 100 bytes so the code should be less than 100 bytes.

Can some one write assembly code for the c program above that converts into machine code that is less than 100 bytes?

unpopular
  • 181
  • 1
  • 7
  • I updated my answer. What OS you are using doesn't play a role, the procedure is the same, only the result will be different. – Gunther Piez May 17 '12 at 21:15
  • FreeBSD 2.95 -- this must be a typo, I just cannot figure out what it is meant to be. Current is something between 7.4 and 9.0. The 2.x branch is dead since ages. – undur_gongor May 18 '12 at 13:38
  • No this is not a typo. That is the version of FreeBSD that I am supposed to use as the task requires to do it on that version. – unpopular May 19 '12 at 09:24

4 Answers4

3

To get the machine code, you need to compile the program then disassemble. Using gcc for example do something like this:

gcc -o hello hello.c
objdump -D hello

The dump will show the machine code in bytes and the disassembly of that machine code.

A simple example, that is related, you have to understand the difference between an object file and an executable file but this should still demonstrate what I mean:

unsigned int myfun ( unsigned int x )
{
    return(x+5);
}

gcc -O2 -c -o hello.o hello.c
objdump -D hello.o


Disassembly of section .text:

00000000 <myfun>:
   0:   e2800005    add r0, r0, #5
   4:   e12fff1e    bx  lr
old_timer
  • 69,149
  • 8
  • 89
  • 168
2

FreeBSD is an operating system, not a compiler or assembler.

You want to assemble the assembly source into machine code, so you should use an assembler.

You can typically use GCC, since it's smart enough to know that for a filename ending in .s, it should run the assembler.

If you already have the code in an object file, you can use objdump to read out the code segment of the file.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • Alternatively, there tends to be one (or both) of `as` and/or `gas`. – Vatine May 16 '12 at 14:37
  • The OP wants a listing of the machine code, not an object file containing it. From the assembly listing you can easily see that he already has obviously used `gcc -S`, why do you think he explicitly requested gcc to _not_ assemble? And now you tell him that he actually wants to assemble... -1 – Gunther Piez May 16 '12 at 15:52
1

The 37 bytes posted are completely junk.

If run under any version of Windows ( windows 2000 or later ), I believe, that the "outsb" and "insd" instructions (in an userland program) will cause a fault, because userland programs are not allowed directly doing port -level I/O.

Since machine code will not end in "vacuum", I added some \x90 -bytes (again NOP) after the posted code. That merely affects the argument of the last rcl -instruction (which in the given code ends prematurely; eg the code posted is not only rubbish, but also ends prematurely).

But, microprocessors do not have their own intelligence, so they will (try to) execute whatever junk code you feed them. And, the code starts with "inc ecx", a stupid move since we do not know what value the ecx had before. Also "shl dword ptr [eax],$58" is a "good" way to randomly corrupt memory (since value if eax is also unknown).

And, one of them is NOT even valid byte (should be represented as two hexadecimal digits).

The invalid "byte" is \xw3.

I replaced that invalid byte as \x90 ( a NOP, if it is at start of instruction), and got:

00451B51 41 inc ecx 00451B52 C13058 shl dword ptr [eax],$58 00451B55 6E outsb 00451B56 61 popad 00451B57 6D insd 00451B58 652323 and esp,gs:[ebx] 00451B5B C3 ret

// code below is NEVER executed, since the line above does a RET.

00451B5C BCA383F469 mov esp,$69f483a3 00451B61 3690 nop // 36, w3 ???? 00451B63 DE4F2F fimul word ptr [edi+$2f] 00451B66 5F pop edi 00451B67 2F das 00451B68 3933 cmp [ebx],esi 00451B6A 60 pushad 00451B6B 2432 and al,$32 00451B6D B4AB mov ah,$ab 00451B6F 21C1 and ecx,eax 00451B71 8024E0DB and byte ptr [eax],$db 00451B75 D09090909090 rcl [eax-$6f6f6f70],1

mika
  • 174
  • 1
  • 2
0

You get a nice hexdump of the text section of your object file with objdump -s -j .text.

Edited some more details: You need to find out what the address of the function in your object code is. This is what objdump -t is for. In this case I am looking for the function main in a program "hello".

> objdump -t hello|grep main

> 0000000000400410 g     F .text  000000000000002f        main

Now I create a hexdump with objdump -s -j .text hello:

400410 4881ec08 010000be 00010000 31c04889  H...........1.H.
400420 e7e8daff ffff4889 e6bff405 400031c0  ......H.....@.1.
400430 e8abffff ff31c048 81c40801 0000c390  .....1.H........
400440 31ed4989 d15e4889 e24883e4 f0505449  1.I..^H..H...PTI
400450 c7c0e005 400048c7 c1500540 0048c7c7  ....@.H..P.@.H..
...

The first row are the addresses. It starts with 400410, the address of the main function, but this may not always be the case. The following 4 rows are 16 bytes of machinecode in hex, the last row are the same 16 bytes of machine code in ASCII. Because a lot of bytes have no representation in ASCII, there are a lot of dots. You need to use the 4 hexadecimal colums: \x48 \x81 \xec....
I have done this on a linux system, but for FreeBSD you can do exactly the same - only the resulting machindecode will be different.

Gunther Piez
  • 29,760
  • 6
  • 71
  • 103
  • Using the command objdump -s -j .text I got a total of 27 rows on the screen and each row contained 6 columns. The last column had some strange symbols and alphabets with alot of dots. Contents of section .text: 8048360 31ed5589 e583e4f0 8d450883 ec0450ff 1.u......E....P. 8048370 750452e8 08000000 cc909090 90909090 u.R............. 8048380 5589e557 565383ec 0c8b750c 8b5d1085 U..WVS....u.j... I have copied 3 of those 27 rows above. Keeping in view the c code above, how does this dump help me to get machine code that I am looking for. I can't paste more here so I will paste down. Please see – unpopular May 17 '12 at 12:50
  • the details that I have added to the question after editing it. – unpopular May 17 '12 at 12:57
  • Thanks for your help.I got the machine code only for gethostname function in the c code aobve and it was 130 bytes.I also need to print the hostname so some sort of machine code for that will also be required but the problem is that I need a machine code for the c program above that is less than 100 bytes as I have to fit it in an array of 100 bytes and then over flow the binary program available and point the return address to the begining of the array containing this code.Can some one write assembly code for the c program above that converts into machine code that is less than 100 bytes? – unpopular May 19 '12 at 09:29