mercoledì 22 agosto 2018

Beginners Quest (Google CTF) - 3° Security by obscurity

Good EVENING!

I'm here for our third meeting.

Used tools:
  • unzip, unxz, bunzip2, gunzip (decompress archive files)
  • rockforyou.txt wordlist (contains different words for dictionary attack)
  • fcrackzip (for cracking password of a zip file)
The state of the art is


Let's continue to our top side path.
Here the CHALLENGE


As always, download the attachment, check the file type, rename it and extract the content:
  • file 2cdc6654fb2f8158cd976d8ffac28218b15d052b5c2853232e4c1bafcb632383
It is a zip file.
  • mv 2cdc6654fb2f8158cd976d8ffac28218b15d052b5c2853232e4c1bafcb632383 obscurity.zip
  • unzip obscurity.zip
The content is composed of another compressed archive .zip. If you try to uncompress recursively the content, you will note that each nested archive file contains another archive file with no extension in the name but you can find out it by using the file command as:
  • file -b --mime-type filename
If you want to try to extract manually the content of each nested archive file, good luck <3 (and I'm proud of you... I joke, NO, I'm NOT!). It's better to develop a "small" (my brain: "si fa per dire") script that allows you to extract automatically nested archives.
I prepared for you a python script, that I call (FOR YOU) recursive.py, for our purpose:
#!/usr/bin/env python
# coding=utf-8

import magic
import os
import sys
import gzip
import subprocess
import shutil
import tarfile
import zipfile
import contextlib
import lzma #Run sudo apt-get install python-lzma or sudo pip install pyliblzma if it does not find the module lzma
import tarfile
import bz2

path = os.path.abspath(sys.argv[1]) #E' importante che io qui converta il path in assoluto perché os.walk deve avere il path ASSOLUTO. Se faccio cosi, evito che l'utente debba ogni volta dare in input il path assoluto, quindi può usare anche il path relativo

def recursive_obscurity(path):
    files = []
    # r=root, d=directories, f = files in a path
    for r, d, f in os.walk(path):
     #r = r + '/' #altrimenti la directory me la vede come . oppure folder senza la / e se devo concatenarlo al nome di un file non mi funge
 #for directory in d:
     print 'Root List'
     print r
     os.chdir(r) #Qui cambio la current working directory per lo script Python (quindi per la subshell) ogni volta che si addentra nelle sottocartelle
     print os.getcwd()
     print 'Directory List'
     print d
            for filename in f:
                print 'Current files: '
                print f
         print filename
         mime = magic.Magic(mime=True)
         extension = mime.from_file(r + '/' + filename).split('/')[1]
         print extension
  print r
                if extension == 'zip':
                
      if not filename.endswith('.zip'): 
          os.rename(filename, filename + '.zip') #evito che mi esce archive.zip.zip.
          filename = filename + '.zip' #cosi non mi cambia solo il nome del file nella directory ma mi cambia anche il nome nella variabile
      zip_ref = zipfile.ZipFile(os.path.abspath(filename), 'r')
      zip_ref.extractall(os.path.abspath(r))
     
      for info in zip_ref.infolist():
          print(info.filename)
   if '/' in info.filename: #Se il file è all'interno di una directory dentro l'archivio... Faccio la distinzione tra directory dentro lo zip o file dentro lo zip perché altrimenti in 'f' mi mette il percorso del file compresa la directory per evitare che si perda la coerenza con la current working directory che setto nello script. Ad esempio io ho solo il file dev/shm/file.txt. Considero solo il primo livello, cioè il folder 'dev'
      d.append(info.filename.split('/')[0])
   else:
             f.append(info.filename) #Aggiungo alla lista dei file della directory corrente i file appena estratti dallo zip
      zip_ref.close()
            
                elif extension == 'x-xz':
      if not filename.endswith('.xz'): 
          os.rename(filename, filename + '.xz') #evito che mi esce archive.xz.xz
          filename = filename + '.xz'
                    
      file_to_write = filename.replace('.xz','')
      with contextlib.closing(lzma.LZMAFile(filename)) as xz:
                        with tarfile.open(fileobj=xz) as f:
                            f.extractall(file_to_write)
       d.append(file_to_write) #Aggiungo alla lista delle directory della cartella corrente corrente perché anche se ho tar.xz, lui mi estrae non solo l'xz ma anche il tar

                elif extension == 'x-bzip2':
      if not filename.endswith('.bz2'):  
          os.rename(filename, filename + '.bz2') #evito che mi esce archive.gz.gz
          filename = filename + '.bz2' #cosi non mi cambia solo il nome del file nella directory ma mi cambia anche il nome nella variabile filename
                    file_to_write = filename.replace('.bz2','')
          with open(file_to_write, 'wb') as new_file, bz2.BZ2File(filename, 'rb') as file:
                   for data in iter(lambda : file.read(100 * 1024), b''):
                  new_file.write(data)
       f.append(file_to_write) #Aggiungo alla lista dei file della directory corrente i file appena estratti dall'archivio

                elif extension == 'gzip':
      if not filename.endswith('.gz'): 
          os.rename(filename, filename + '.gz') #evito che mi esce archive.gz.gz. Mi cambia il nome del file nella directory
          filename = filename + '.gz' #cosi non mi cambia solo il nome del file nella directory ma mi cambia anche il nome nella variabile filename
                    with gzip.open(filename, 'rb') as f_in:
          file_to_write = filename.replace('.gz','') #uso replace cosi dal file destinazione mi toglie, come usuale, il .gz
              with open(file_to_write, 'wb') as f_out: 
                     shutil.copyfileobj(f_in, f_out)
                            f.append(file_to_write)
            
         elif extension == 'x-tar':
      if not filename.endswith('.tar'): 
          os.rename(filename, filename + '.tar') #evito che mi esce archive.tar.tar
          filename = filename + '.tar'
                    tar = tarfile.open(filename)
      tar.extractall()

      for info in tar.getnames():
          print(info)
   if not '/' in info: #getnames() purtroppo mi ritorna le directory in formati ricorsivi, cioè [livello1, livello1/livello2, ...] che a me non va bene perché rischio di leggere la stessa cartella più volte, quindi a me serve solo il primo livello, per cui tutto quello che ha '/' in getnames() non lo considero  
      if os.path.isdir(info): #Se è una directory
          d.append(info)
      else: #Se non è una directory sarà una file
                 f.append(info) #Aggiungo alla lista dei file della directory corrente i file appena estratti dallo zip
      tar.close()

                elif extension == 'x-7z-compressed':
      if not filename.endswith('.7z'): 
          os.rename(filename, filename + '.7z') #evito che mi esce archive.7z.7z
          filename = filename + '.7z' #cosi non mi cambia solo il nome del file nella directory ma mi cambia anche il nome nella variabile
      directory_to_write = 'dest'  
      subprocess.check_output(['7za', 'x', '-y', filename, '-o'+directory_to_write])
      d.append(directory_to_write) #Faccio l'append in 'd' e non in 'f' perché è una directory

recursive_obscurity(path)
Save the .py file and run the script passing as argument the path where you want to extract recursively all compressed files (zip, xz, bz2, gz, tar, 7z) :
  • python recursive.py
At the end of this process, when it asks you for the password, press CTRL+C to stop the process. In the current folder you will see several .zip file and the last extracted archive is the one containing a password.txt file that will contain the solution key.
The problem is that this compressed file is protected by a password, so we cannot extract the password.txt file.
One tool could save us: fcrackzip. It is used to crack the password of zip files. We try to use a dictionary attack. For this we need to have some wordlist file. You can find it on /usr/share/wordlists or on Internet. I will use rockyou.txt wordlist contained in the archive /usr/share/wordlists/rockyou.txt.gz, so extract this rockyou.txt.gz and copy its content in our workspace.
Rename also the protected zip file as output.zip. 
Type and execute:
  • fcrackzip -v -D -u -p rockyou.txt output.zip
At this point, you will get a message with Password Found!!! and you are able to extract the content from the protected zip file. The extracted file, called password.txt, contains the solution key:
  • less password.txt
WE DID!


If you want to be SPOILED for the solution key, just click below

Nessun commento:

Posta un commento