SYNOPSIS

Outlining the attack path demonstrated in this writeup is much easier through a picture rather than a description, since a picture is worth a thousand words.

Attack Path - Find The Easy Pass

The aim of this walkthrough is to provide help with the Find The Easy Pass challenge on the Hack The Box website. Please note that no flags are directly provided here. Moreover, be aware that this is only one of the many ways to solve the challenges.

It belongs to a series of tutorials that aim to help out with finishing the Beginner-Track challenges.

PREPARATION

After reading the challenge description

Find the password (say PASS) and enter the flag in the form HTB{PASS}

we set out and download the provided challenge files. There is only one this time: - Find The Easy Pass.zip -.

source-files

Once downloaded, we make sure to copy the provided sha256 checksum and use it for integrity check.

source-files-hash

Once nice way to do this is to use the -c option with the sha256sum command.

┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$ ll
total 208K
-rw-r--r-- 1 htb-bluewalle htb-bluewalle 206K May 26 22:02 'Find The Easy Pass.zip'
┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$ echo "0c48ca8a4a3ab2f73f76b0e6535c2feb510c1caf16b8bcc41c74b392c945e4db  Find The Easy Pass.zip" | sha256sum -c
Find The Easy Pass.zip: OK
┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$

Looks like the file was not tampered with so we decompress it.

┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$ unzip -P hackthebox Find\ The\ Easy\ Pass.zip
Archive:  Find The Easy Pass.zip
  inflating: EasyPass.exe            
┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$ ll
total 604K
-rw-r--r-- 1 htb-bluewalle htb-bluewalle 393K Jul  3  2017  EasyPass.exe
-rw-r--r-- 1 htb-bluewalle htb-bluewalle 206K May 26 22:02 'Find The Easy Pass.zip'
┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$

SEARCH-FOR-STRINGS

After determining the file type as a 32-bit windows portable executable,

┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$ file EasyPass.exe 
EasyPass.exe: PE32 executable (GUI) Intel 80386, for MS Windows
┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$ 

we try and store all the printable strings in a separate file. This way, we can easily sort through them. For example, searching for all words starting with pass (case insensitive) does provide us with some ideas about where to look.

┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$ strings EasyPass.exe > easypass_strings.txt
┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$ cat easypass_strings.txt | grep -i -n pass*
1960:PasswordChar
3795:Wrong Password!
5158:Enter Password
5171:Check Password
┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$

Looks like some login text. Let’s use vim and take a better look at the environment where those words are mentioned. Maybe we get lucky and the password is located near one of them.

strings-vim

No luck this time. Moreover, since the generated strings file alone contains more than 5000 entries,

┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$ wc -l easypass_strings.txt 
5174 easypass_strings.txt
┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$

RUNNING-THE-EXECUTABLE

it is time to take an other approach. How about simply running it (which could be very dangerous if it were a malware) and see what happens? But there is an other issue with this. Namely, running native windows 32-bit apps on linux (pwnbox - parrot os, debian based) does not work right out of the box.

After doing some quick online research we end up with the wine tool. It comes already installed on the pwnbox, so all that’s left for us is to run it.

┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$ wine EasyPass.exe 
it looks like wine32 is missing, you should install it.
multiarch needs to be enabled first.  as root, please
execute "dpkg --add-architecture i386 && apt-get update &&
apt-get install wine32:i386"
wine: created the configuration directory '/home/htb-bluewalle/.wine'
0050:err:ole:StdMarshalImpl_MarshalInterface Failed to create ifstub, hr 0x80004002
0050:err:ole:CoMarshalInterface Failed to marshal the interface {6d5140c1-7436-11ce-8034-00aa006009fa}, hr 0x80004002
0050:err:ole:apartment_get_local_server_stream Failed: 0x80004002
0048:err:ole:StdMarshalImpl_MarshalInterface Failed to create ifstub, hr 0x80004002
0048:err:ole:CoMarshalInterface Failed to marshal the interface {6d5140c1-7436-11ce-8034-00aa006009fa}, hr 0x80004002
0048:err:ole:apartment_get_local_server_stream Failed: 0x80004002
0050:err:ole:start_rpcss Failed to open RpcSs service
it looks like wine32 is missing, you should install it.
multiarch needs to be enabled first.  as root, please
execute "dpkg --add-architecture i386 && apt-get update &&
apt-get install wine32:i386"
wine: failed to open L"C:\\windows\\syswow64\\rundll32.exe": c0000135
wine: configuration in L"/home/htb-bluewalle/.wine" has been updated.
it looks like wine32 is missing, you should install it.
multiarch needs to be enabled first.  as root, please
execute "dpkg --add-architecture i386 && apt-get update &&
apt-get install wine32:i386"
00f8:err:module:load_wow64_ntdll failed to load L"\\??\\C:\\windows\\syswow64\\ntdll.dll" error c0000135
00f8:err:virtual:virtual_setup_exception stack overflow 1488 bytes in thread 00f8 addr 0x7f3288b160b0 stack 0x470a30 (0x470000-0x471000-0x56fd20)
┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$

It does not work, but we get some nice hints about the follow up instructions.

┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$ sudo dpkg --add-architecture i386 && sudo apt-get update && sudo apt-get install wine32:i386
Ign:1 https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/6.0 InRelease
...
...
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 wine32:i386 : Depends: libwine:i386 (= 5.0.3-3) but it is not going to be installed
               Recommends: wine:i386 (= 5.0.3-3)
E: Unable to correct problems, you have held broken packages.
┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$

But sadly, nor does this one. Running them separately seems to be working.

┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$ sudo dpkg --add-architecture i386
┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$ sudo apt-get update 
Hit:1 https://debian.neo4j.com stable InRelease
Hit:2 https://repos.insights.digitalocean.com/apt/do-agent main InRelease                    
Hit:3 https://download.docker.com/linux/debian bullseye InRelease                            
Hit:4 https://packages.microsoft.com/debian/10/prod buster InRelease                         
Ign:5 https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/6.0 InRelease                    
Hit:6 https://deb.parrot.sh/parrot parrot InRelease   
Hit:7 https://deb.parrot.sh/direct/parrot parrot-security InRelease
Hit:8 https://deb.parrot.sh/parrot parrot-backports InRelease
Hit:9 https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/6.0 Release
Reading package lists... Done
┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$

All that’s left now is to find a way to install the wine32 module. One quick (and dirty) fix we find online is the following:

┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$ sudo apt install -t parrot-backports wine32
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  gcc-11-base:i386 glib-networking:i386 gstreamer1.0-plugins-base:i386
...
...
Scanning application launchers
Removing duplicate launchers or broken launchers
Launchers are updated
┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$

Now, with everything (finally) prepared, it’s time to finally run it.

┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$ wine EasyPass.exe 
wine: could not load kernel32.dll, status c0000135
┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$

Dang, not again… Well, just like before, looking up some fixes online provides us with the answer.

┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$ mv ../.wine/ ../.wine-old/
┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$

Let’s try it again…

┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$ wine EasyPass.exe 
wine: created the configuration directory '/home/htb-bluewalle/.wine'
0048:err:ole:StdMarshalImpl_MarshalInterface Failed to create ifstub, hr 0x80004002
0048:err:ole:CoMarshalInterface Failed to marshal the interface {6d5140c1-7436-11ce-8034-00aa006009fa}, hr 0x80004002
0048:err:ole:apartment_get_local_server_stream Failed: 0x80004002
0050:err:ole:StdMarshalImpl_MarshalInterface Failed to create ifstub, hr 0x80004002
0050:err:ole:CoMarshalInterface Failed to marshal the interface {6d5140c1-7436-11ce-8034-00aa006009fa}, hr 0x80004002
0050:err:ole:apartment_get_local_server_stream Failed: 0x80004002
0050:err:ole:start_rpcss Failed to open RpcSs service
wine: configuration in L"/home/htb-bluewalle/.wine" has been updated.

Great, it appears to be working and we are provided with a password field. Trying out some default credentials all lead to the same error message: Wrong Password!.

wine-run

STATIC-ANALYSIS

Sadly, running the program did not really help us out. Maybe if we could understand how the program actually works… We set out with this new goal in mind to get some reverse engineering done.

Firing up Ghidra (Applications -> Reverse Engineering -> Ghidra), agreeing to the conditions, creating a new project and importing our executable should get us a similar screen:

ghidra

Clicking (left) two times on our executable should open it in the CodeBrowser. Once opened, we run the automatic analysis that pops-up.

Using Search -> For Strings… and filtering for - Wrong Password! - results in only one match. Selecting it (double click on match) should move us to it’s place in the source code. Once there, we can follow the function reference to the decompiled version.

ghidra-reference

ghidra-decompiled

One way to solve this challenge would be to use static analysis on this source code and reverse engineer the final password from it. Clearly, the - uVar10 - variable holds the password and we would have to work from there step-by-step.

void UndefinedFunction_00454050(uint *param_1,byte *param_2,byte *param_3)

{
  ushort *puVar1;
  char *pcVar2;
  undefined4 uVar3;
  uint uVar4;
  byte bVar5;
  uint uVar6;
  int iVar7;
  undefined2 uVar8;
  uint unaff_EBX;
  int unaff_EBP;
  int iVar9;
  int unaff_ESI;
  undefined4 *in_FS_OFFSET;
  bool in_CF;
  byte in_AF;
  undefined uVar10;
  undefined4 uStack32;
  undefined *puStack28;
  int iStack24;
  
  uVar10 = (undefined4 *)(unaff_ESI + 1) == (undefined4 *)0x0;
  uVar8 = SUB42(param_2,0);
  out(*(undefined4 *)(unaff_ESI + 1),uVar8);
  iVar9 = unaff_EBP;
  if (!in_CF) {
    *param_1 = *param_1 ^ (uint)param_1;
    bVar5 = 9 < ((byte)param_1 & 0xf) | in_AF;
    uVar4 = (uint)(CONCAT11((char)((uint)param_1 >> 8) - bVar5,(byte)param_1 + bVar5 * -6) & 0xff0f)
    ;
    uVar6 = (uint)param_1 & 0xffff0000 | uVar4;
    iVar9 = unaff_EBP + 1;
    pcVar2 = (char *)(uVar6 + 0x5e004486);
    *pcVar2 = *pcVar2 + (char)(unaff_EBX >> 8);
    bVar5 = *param_3;
    *param_3 = *param_3 + (byte)param_3;
    puVar1 = (ushort *)(uVar6 + 0x30);
    *puVar1 = *puVar1 + (ushort)CARRY1(bVar5,(byte)param_3) * (((ushort)iVar9 & 3) - (*puVar1 & 3));
    *param_2 = *param_2 ^ (byte)((uint)param_2 >> 8);
    out(*(undefined *)(unaff_ESI + 5),uVar8);
    bVar5 = in(uVar8);
    unaff_EBX = (uint)param_1 & 0xffff0000 | uVar4 & 0xffffff00 | (uint)bVar5;
    iVar7 = 5;
    do {
      iVar7 = iVar7 + -1;
    } while (iVar7 != 0);
    uVar10 = 1;
    puStack28 = &DAT_00454171;
    uStack32 = *in_FS_OFFSET;
    *in_FS_OFFSET = &uStack32;
    iStack24 = iVar9;
    FUN_004042b4((int *)(unaff_EBP + -7),(int)&DAT_00454188);
    FUN_004042b4((int *)(unaff_EBP + -0xb),(int)&DAT_00454194);
    FUN_004042b4((int *)(unaff_EBP + -0xf),(int)&DAT_004541a0);
    FUN_004042b4((int *)(unaff_EBP + -0x13),(int)&DAT_004541ac);
  }
  FUN_004042b4((int *)(iVar9 + -0x18),(int)&DAT_004541a0);
  FUN_004042b4((int *)(iVar9 + -0x1c),(int)&DAT_004541b8);
  FUN_004042b4((int *)(iVar9 + -0x20),(int)&DAT_004541c4);
  FUN_004042b4((int *)(iVar9 + -0x24),(int)&DAT_004541d0);
  uVar3 = *(undefined4 *)(iVar9 + -0x24);
  FUN_0040459c((int **)(iVar9 + -4),8);
  FUN_00433110(*(int *)(unaff_EBX + 0x2f8),(int *)(iVar9 + -0x28));
  FUN_00404628(*(uint **)(iVar9 + -0x28),*(uint **)(iVar9 + -4));
  if ((bool)uVar10) {
    FUN_00427a30((uint *)"Good Job. Congratulations");
  }
  else {
    FUN_00427a30((uint *)"Wrong Password!");
  }
  *in_FS_OFFSET = uVar3;
  FUN_0040421c((int *)(iVar9 + -0x28));
  FUN_00404240((int *)(iVar9 + -0x24),9);
  return;
}

DYNAMIC-ANALYSIS

Such an analysis would be quite a hurdle and require more time, therefore, we go with dynamic analysis instead.

Installing ollydbg happens to be both easy and quick.

┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$ sudo apt install ollydbg
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following NEW packages will be installed:
  ollydbg
0 upgraded, 1 newly installed, 0 to remove and 25 not upgraded.
Need to get 1,115 kB of archives.
After this operation, 2,622 kB of additional disk space will be used.
Get:1 https://deb.parrot.sh/parrot parrot/main amd64 ollydbg all 1.10-1parrot2 [1,115 kB]
Fetched 1,115 kB in 0s (2,832 kB/s)
Selecting previously unselected package ollydbg.
(Reading database ... 508345 files and directories currently installed.)
Preparing to unpack .../ollydbg_1.10-1parrot2_all.deb ...
Unpacking ollydbg (1.10-1parrot2) ...
Setting up ollydbg (1.10-1parrot2) ...
Scanning application launchers
Removing duplicate launchers or broken launchers
Launchers are updated
┌─[eu-dedivip-2][10.10.14.25][htb-bluewalle@htb-xh9th8t7hj][~/find-the-easy-pass]
└──╼ []$

Running - ollydbg EasyPass.exe and

ollydbg

choosing View -> Executable modules -> EasyPass should change our left-top window.

ollydbg-module

Let’s search for the - Wrong Password! - string. (Right click in top-left window) -> Search for -> All referenced text strings -> (Right click in new window) -> Search for text -> “Wrong Password!” -> (Right click on match) -> Follow in Disassembler.

Now that we found our place in the source code, let’s set a breakpoint here and run the executable.

Choosing — (Right click on - Wrong Password! - match in top-left window) -> Breakpoint -> Toggle — should set the breakpoint. Starting our program is then done by clicking the play button.

But considering the breakpoint we just set, the execution will only continue till before the point where - Wrong Password! - get’s displayed. Then it would stop.

ollydbg-breakpoint

We start it and wait until the execution halts. Then we head over to the bottom-right window since this is where the data which surrounds our test input/password is displayed. Maybe the real password is stored nearby?

The only other ASCII field other than our test input in our close environment contains the - <password> - string.

ollydbg-paused

VERIFICATION

Could this be the password? Running - EasyPass.exe - with wine and inputting the found password - confirms it. We have our winner!

wine-success

Given that this was a challenge box without any instantiated targets, there is simply not much to clean up here. Once we submit the password as - HTB{<password>} - we move on to the next machine.