Hackthebox challenge writeup - Find the easypass

Thu 24 December 2020

A writeup of how I approached the HTB challenge Find the easypass. Hackthebox is a fun platform that lets you work on your enumeration, pentesting and hacking skills.

Introduction

This is my first reversing challenge. I have no idea what I am up for.

The challenge start with the download of a .zip file, so I guess we are going to crack it open in a way.

findtheeasypass@kali:/mnt/hgfs/kali_share/challenge-findtheeasypass$ zip2john findtheeasypass.zip > output.txt 
ver 2.0 findtheeasypass.zip/EasyPass.exe PKZIP Encr: cmplen=210117, decmplen=402432, crc=BC1E0C86

Let as also use the unzip and zipdetails tools to see whats inside this archive:

findtheeasypass@kali:/mnt/hgfs/kali_share/challenge-findtheeasypass$ unzip -lv findtheeasypass.zip 
Archive:  findtheeasypass.zip
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
  402432  Defl:N   210105  48% 2017-07-03 10:12 bc1e0c86  EasyPass.exe
--------          -------  ---                            -------
  402432           210105  48%                            1 file


findtheeasypass@kali:/mnt/hgfs/kali_share/challenge-findtheeasypass$ zipdetails findtheeasypass.zip 
00000 LOCAL HEADER #1       04034B50
00004 Extract Zip Spec      14 '2.0'
00005 Extract OS            00 'MS-DOS'
00006 General Purpose Flag  0009
      [Bit  0]              1 'Encryption'
      [Bits 1-2]            1 'Maximum Compression'
      [Bit  3]              1 'Streamed'
00008 Compression Method    0008 'Deflated'
0000A Last Mod Time         4AE35191 'Mon Jul  3 10:12:34 2017'
0000E CRC                   BC1E0C86
00012 Compressed Length     000334C5
00016 Uncompressed Length   00062400
0001A Filename Length       000C
0001C Extra Length          0000
0001E Filename              'EasyPass.exe'
0002A PAYLOAD

334EF STREAMING DATA HEADER 08074B50
334F3 CRC                   BC1E0C86
334F7 Compressed Length     000334C5
334FB Uncompressed Length   00062400

334FF CENTRAL HEADER #1     02014B50
33503 Created Zip Spec      1F '3.1'
33504 Created OS            00 'MS-DOS'
33505 Extract Zip Spec      14 '2.0'
33506 Extract OS            00 'MS-DOS'
33507 General Purpose Flag  0009
      [Bit  0]              1 'Encryption'
      [Bits 1-2]            1 'Maximum Compression'
      [Bit  3]              1 'Streamed'
33509 Compression Method    0008 'Deflated'
3350B Last Mod Time         4AE35191 'Mon Jul  3 10:12:34 2017'
3350F CRC                   BC1E0C86
33513 Compressed Length     000334C5
33517 Uncompressed Length   00062400
3351B Filename Length       000C
3351D Extra Length          0024
3351F Comment Length        0000
33521 Disk Start            0000
33523 Int File Attributes   0000
      [Bit 0]               0 'Binary Data'
33525 Ext File Attributes   00000020
      [Bit 5]               Archive
33529 Local Header Offset   00000000
3352D Filename              'EasyPass.exe'
33539 Extra ID #0001        000A 'NTFS FileTimes'
3353B   Length              0020
3353D   Reserved            00000000
33541   Tag1                0001
33543   Size1               0018
33545   Mtime               01D2F3CBBE63685D 'Mon Jul  3 09:12:34
                            2017 526217300ns'
3354D   Ctime               01D2F3CBC75A08C1 'Mon Jul  3 09:12:49
                            2017 564281700ns'
33555   Atime               01D2F3CBBE34604E 'Mon Jul  3 09:12:34
                            2017 217991800ns'

3355D END CENTRAL HEADER    06054B50
33561 Number of this disk   0000
33563 Central Dir Disk no   0000
33565 Entries in this disk  0001
33567 Total Entries         0001
33569 Size of Central Dir   0000005E
3356D Offset to Central Dir 000334FF
33571 Comment Length        0000
Done

My first thought is that we want to feed this into a password cracker.

Crack the password of a .zip file

We want to use johntheripper or hashcat to crack the password of our zip-file.

Prepare the hash:

findtheeasypass@kali:/mnt/hgfs/kali_share/challenge-findtheeasypass$ zip2john findtheeasypass.zip > output3.txt 
ver 2.0 findtheeasypass.zip/EasyPass.exe PKZIP Encr: cmplen=210117, decmplen=402432, crc=BC1E0C86

Feed it to johntheripper:

findtheeasypass@kali:/mnt/hgfs/kali_share/challenge-findtheeasypass$ john output3.txt 
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
Will run 2 OpenMP threads
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
Warning: Only 3 candidates buffered for the current salt, minimum 8 needed for performance.
Warning: Only 7 candidates buffered for the current salt, minimum 8 needed for performance.
Almost done: Processing the remaining buffered candidate passwords, if any.
Warning: Only 4 candidates buffered for the current salt, minimum 8 needed for performance.
Proceeding with wordlist:/usr/share/john/password.lst, rules:Wordlist
Proceeding with incremental:ASCII
0g 0:00:00:03  3/3 0g/s 1754Kp/s 1754Kc/s 1754KC/s sheenthim..mahlon1

For this to work with hashcat we have to edit our output3.txt and remove the following part:

findtheeasypass.zip/EasyPass.exe:

Feed it to hashcat:

findtheeasypass@kali:/mnt/hgfs/kali_share/challenge-findtheeasypass$ hashcat -m 17200 -a 3 output2.txt
hashcat (v6.1.1) starting...

OpenCL API (OpenCL 1.2 pocl 1.5, None+Asserts, LLVM 9.0.1, RELOC, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
=============================================================================================================================
* Device #1: pthread-Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz, 2868/2932 MB (1024 MB allocatable), 2MCU

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates

Applicable optimizers applied:
* Not-Iterated
* Single-Hash
* Single-Salt
* Brute-Force

Watchdog: Hardware monitoring interface not found on your system.
Watchdog: Temperature abort trigger disabled.

Host memory required for this attack: 64 MB

The wordlist or mask that you are using is too small.
This means that hashcat cannot use the full parallel power of your device(s).
Unless you supply more work, your cracking speed will drop.
For tips on supplying more work, see: https://hashcat.net/faq/morework

Approaching final keyspace - workload adjusted.

Session..........: hashcat                       
Status...........: Exhausted
Hash.Name........: PKZIP (Compressed)
Hash.Target......: $pkzip2$1*1*2*0*334c5*62400*bc1e0c86*0*2a*8*334c5*b...kzip2$
Time.Started.....: Tue Dec  1 09:50:17 2020 (0 secs)
Time.Estimated...: Tue Dec  1 09:50:17 2020 (0 secs)
Guess.Mask.......: ?1 [1]
Guess.Charset....: -1 ?l?d?u, -2 ?l?d, -3 ?l?d*!$@_, -4 Undefined 
Guess.Queue......: 1/15 (6.67%)
Speed.#1.........:      335 H/s (0.01ms) @ Accel:1024 Loops:62 Thr:1 Vec:8
Recovered........: 0/1 (0.00%) Digests
Progress.........: 62/62 (100.00%)
Rejected.........: 0/62 (0.00%)
Restore.Point....: 1/1 (100.00%)
Restore.Sub.#1...: Salt:0 Amplifier:0-62 Iteration:0-62
Candidates.#1....: s -> X

Ok, we now have two different ways to bruteforce the password of a .zip file. But maybe there is a faster route to the target? When accepting the challenge on hack-the-box you see that the user who got firstblood (the person who first solved the challenge) used 08H 37M 40S which might suggest that he bruteforced this, but lets try some other stuff while our bruteforcing work its magic.

PS: After working on this .zipfile for a while I saw that the password was in cleartext on the same page as I downlaoded the file, so the challenge was obviously not to crack open the password file itself.

findtheeasypass@kali:/mnt/hgfs/kali_share/challenge-findtheeasypass$ unzip -P hackthebox findtheeasypass.zip 
Archive:  findtheeasypass.zip
  inflating: EasyPass.exe

Inspecting unknown files

Ok, we have got the .zip file extracted and its time to see on the content inside it. The archive contain only a single file: EasyPass.exe.

First we want to check that the file might be what the extension say it is:

findtheeasypass@kali:/mnt/hgfs/kali_share/challenge-findtheeasypass$ file EasyPass.exe 
EasyPass.exe: PE32 executable (GUI) Intel 80386, for MS Windows

Lets also see what strings are present:

findtheeasypass@kali:/mnt/hgfs/kali_share/challenge-findtheeasypass$ strings -a EasyPass.exe | less
This program must be run under Win32
CODE
`DATA
...
Click
Button1Click

Ok, we now have a Win32 Executable which I want do run. Since Im on a Linux system I have to do some work just to be able to execute the file.

findtheeasypass@kali:/mnt/hgfs/kali_share/challenge-findtheeasypass$ sudo apt-get install wine32
findtheeasypass@kali:/mnt/hgfs/kali_share/challenge-findtheeasypass$ wine EasyPass.exe

You will now see that the program ask for a password, and if you enter the wrong password it says so.

So I guess the new task is to find the passsword it ask for.

Reverse engineering

First I need to download and install a debugger, a program that I can use to see into the bits & bytes of a program while it is running. Since EasyPass is a windows program I have to find a debugger that can execute and debug windows executable.

I tried several free (as-in-beer) debuggers, and ended up with IDA-Free: https://www.hex-rays.com/products/ida/support/download_freeware/

Again, being on Linux I have to run it through wine:

findtheeasypass@kali:/mnt/hgfs/kali_share/challenge-findtheeasypass$ wine idafree70_windows.exe 
findtheeasypass@kali:/mnt/hgfs/kali_share/challenge-findtheeasypass$ wine "/home/findtheeasypass/.wine/drive_c/Program Files/IDA Freeware 7.0/ida64.exe"

Load up the *EasyPass.exe" file in IDA Free (I just went with the suggested defaults option):

Start the program, and when the program is running inside IDA Free, do a textsearch (ALT+T) for the "Wrong password" string that we encountered earlier:

As we can see from the search result, this flow is leading to the "Wrong password" message:

CODE:00454131 call    sub_404628
CODE:00454136 jnz     short loc_454144
CODE:00454138 mov     eax, offset aGoodJobCongrat     ; "Good Job. Congratulations"
CODE:0045413D call    sub_427A30
CODE:00454142 jmp     short loc_45414E
CODE:00454144 ; ---------------------------------------------------------------------------
CODE:00454144
CODE:00454144 loc_454144:                             ; CODE XREF: sub_454070+C6↑j
CODE:00454144 mov     eax, offset aWrongPassword      ; "Wrong Password!"
CODE:00454149 call    sub_427A30
CODE:0045414E

We are now looking at assembly code, and a brief knowledge of assembler will help us out:

With this in mind, lets translate the assembly code:

Call the subroutine at sub_404628, if the zeroflag is not zero, jump to loc_454144 and present the "Wrong password" text. If the zeroflag is zero, dont jump but proceed and show the "Good Job. Congratulations" text.

If we have translated the code correctly, the interesting part is inside sub_404628 or immediately follow it. So we start setting a breakpoint on CODE:00454136. When we set a breakpoint, the execution will pause at that point so we will be able to inspect the state of various registers.

In the screenshot we see that registers IF and AF is 1 which will trigger the JNZ to show us the "Wrong password" text. The registers are probably set inside the sub_404628 so we have to move our breakpoint to catch the interesting bits.

Lets try move from CODE:00454136 to CODE:00454131 and run our program again. Use the "Execute each instruction" to step the code line-by-line:

After a few steps we will see a new assembler keyword:

So if we assume that it compares our input with whatever the password is, let us examine the content of the registers EAX and EDX:

In the EAX register we can read ttt which is the value I gave in the inputbox, and in the EDX register we can read fortran! which might be a candidate for a password.

Let us re-run the program and try the fortran! password:

Congratulations, the challenge is solved. Submit your flag and move on learning new stuff :)

Here are some of the other debugger alternatives I look into, but choosed to not use:

Since we are running wine you could also take a look at: https://wiki.winehq.org/Wine_Developer%27s_Guide/Debugging_Wine#Disassembling_programs

Cracking a passwordprotected zip file, take 2

We did not finish our passwordcracking attempt since the password was provided as part of the challenge, and thus no cracking was needed.

Anyway, for the sake of completeness:

findtheeasypass@kali:/mnt/hgfs/kali_share/challenge-findtheeasypass$ cat words.dict 
hackthebox

findtheeasypass@kali:/mnt/hgfs/kali_share/challenge-findtheeasypass$ zip2john findtheeasypass.zip > output.txt 
ver 2.0 findtheeasypass.zip/EasyPass.exe PKZIP Encr: cmplen=210117, decmplen=402432, crc=BC1E0C86

findtheeasypass@kali:/mnt/hgfs/kali_share/challenge-findtheeasypass$ john output.txt --wordlist=words.dict 
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
No password hashes left to crack (see FAQ)

findtheeasypass@kali:/mnt/hgfs/kali_share/challenge-findtheeasypass$ john output.txt --show
findtheeasypass.zip/EasyPass.exe:hackthebox:EasyPass.exe:findtheeasypass.zip::findtheeasypass.zip

1 password hash cracked, 0 left
findtheeasypass@kali:/mnt/hgfs/kali_share/challenge-findtheeasypass$

Cheers...

Comments