Recon 00 :
just go to the website and add the robots.txt , it goes something like this :
https://hackycorp.com/robots.txt
and we found the key :
af9c328a-02b4-439d-91c6-f46ab4a0835b
Recon 01 :
Really?
it just too simple add some thing after the url that you know is BS. something like this :
https://hackycorp.com/opihrgweopuirgne
and then you got the key :
aeaee57f-2a82-41da-bc4c-d081c8cddfc8
Recon 02 :
Finally, some thing cool. for this level you should first see the refrences to learn what is the security.txt so when we see in the refrences it say that in most websites if its standard it most be in the address .well-known/security.txt, so we go for it:
https://hackycorp.com/.well-known/security.txt
and then we got the key for next level :
99685e30-7061-4ac0-83bf-4ccc0409faac
Recon 03 :
kind of tricky. first try was to try and go to the assets but there was not support any directory listing , for example if we visit this :
https://assets.hackycorp.com/img
we get access denied, so we should try to get other directory. after reading the code we see that there use this for there logo :
images/logo.png
so we tried this :
https://hackycorp.com/images/
we get a directory and there we have a file names key.txt so when we visit that we get the key for next level :
93790afa-6985-47fd-b564-aa7ba59ed6a9
Recon 04 :
for this level we use there hints to visit the /admin , so when we visit this url :
https://hackycorp.com/admin/
we get the key for next level :
ad1d44d6-ab73-4640-8291-c5bf2343e2a5
Recon 05 :
for this level we use some fuzzing tool. my favorite ffuf. and for the wordlist we visit this Seclist.
one of the wordlists under the fuzzing is common.txt and we use that, using this ffuf command :
ffuf -u https://hackycorp.com/FUZZ -w common.txt -mc 200,301,302output of the code :
.well-known/security.txt [Status: 200, Size: 156, Words: 24, Lines: 4, Duration: 98ms]
admin [Status: 301, Size: 178, Words: 6, Lines: 8, Duration: 158ms]
images [Status: 301, Size: 178, Words: 6, Lines: 8, Duration: 109ms]
index.html [Status: 200, Size: 16011, Words: 5888, Lines: 278, Duration: 119ms]
robots.txt [Status: 200, Size: 121, Words: 14, Lines: 7, Duration: 117ms]
startpage [Status: 301, Size: 178, Words: 6, Lines: 8, Duration: 109ms]
:: Progress: [4750/4750] :: Job [1/1] :: 135 req/sec :: Duration: [0:00:23] :: Errors: 0 ::only directory we did not visit until not is startpage so we go to this url :
https://hackycorp.com/startpage/
and we get this key :
498621b0-17fe-4ebb-8324-3de7743fea51
Recon 06 :
in web servers can have multiple websites in them. a web server has only one IP then in that we server we can set multiple websites and how the web server open the right website for us? using header. if we send a request directly to the ip of the web server without any header web server show us the default page that we can call vhost too. for this first we need to find the IP address. we use this command :
dig hackycorp.comthen we get the IP :
51.158.147.132
and when we send a request to it :
curl http://51.158.147.132we get this output :
<h1>Well done! You solved recon_06 </h1>
The key for this exercise is 5cf83b5d-eb6c-4eee-af6c-945f9aed8dfdso the key is :
5cf83b5d-eb6c-4eee-af6c-945f9aed8dfd
we could just visit the http://51.158.147.132 in our browser, its the same thing.
Recon 07 :
like the past level but this time We bypass TLS certificate validation to reach the default TLS virtual host.-k lets you bypass TLS certificate checks, and a fake Host header forces the web server to fall back to its default virtual host after TLS is established.Because the certificate presented by the default vhost does not match the IP address, curl would normally abort the connection unless -k is used.
so for this we use this command :
curl -k https://51.158.147.132 -H "Host: random"and output :
<h1>Well done! You solved recon_07</h1>
The key for this exercise is 23eafa56-6d55-4b78-8307-24e7dc2ce5e6so the key is :
23eafa56-6d55-4b78-8307-24e7dc2ce5e6
Recon 08 :
for this level first we need to find the certificate then encode and find all the alt names and then try to connect to one of those alt names. lets go.
first we can find SSL using openssl but we need to decode it too so we use this command :
openssl s_client -connect hackycorp.com:443 -servername hackycorp.com \
| openssl x509 -noout -ext subjectAltName-
openssl s_clientfetches the certificate -
openssl x509 -textdecodes it -
-noouthides raw PEM output
then we have this output :
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R13
verify return:1
depth=0 CN = hackycorp.com
verify return:1
X509v3 Subject Alternative Name:
DNS:66177e3f25e3ea0713807b1dc5f0b9df.hackycorp.com, DNS:hackycorp.com, DNS:www.hackycorp.comthis URL looks interesting 66177e3f25e3ea0713807b1dc5f0b9df.hackycorp.com so we send a request to it :
curl https://66177e3f25e3ea0713807b1dc5f0b9df.hackycorp.comwe get this output :
<h1>Well done! You solved recon_08</h1>
The key for this exercise is: 1763ec4f-8467-47f7-9a80-6de93a1a2253and the key is :
1763ec4f-8467-47f7-9a80-6de93a1a2253
Recon 09 :
This level is easy. objective is very clear we should check the header.
so we use this curl command :
curl -I https://hackycorp.com- -I is mean we send a HEAD request, with this we only get the header, what we want.
the output is this :
HTTP/1.1 200 Connection established
HTTP/1.1 200 OK
Server: nginx
Date: Sat, 03 Jan 2026 10:19:52 GMT
Content-Type: text/html
Content-Length: 16011
Last-Modified: Tue, 31 Mar 2020 03:12:16 GMT
Connection: keep-alive
ETag: "5e82b510-3e8b"
pentesterlab_recon_09: 99d0738b-1e52-4a00-8885-b15894b2c79e
Accept-Ranges: bytesso the key is :
99d0738b-1e52-4a00-8885-b15894b2c79e
Recon 10 :
this one is kind of tricky, it says that in subdomain that gives us has the key in color red.
it suggest a tool that they dont work really. beucase of that i had this idea to write a python code that go to every subdomain and donwload the logo.png , they put the key on that and after check the downloaded logoes we could find our key. this is our code :
import requests
from pathlib import Path
# Generate hosts
hosts = [f"0x{i:02x}.a.hackycorp.com" for i in range(256)]
output_dir = Path("logos")
output_dir.mkdir(exist_ok=True)
for host in hosts:
url = f"http://{host}/logo.png"
try:
r = requests.get(
url,
timeout=5,
verify=False,
proxies={"http": "", "https": ""}
)
print(f"{host} -> {r.status_code} {r.headers.get('Content-Type')}")
if r.status_code == 200 and "image" in (r.headers.get("Content-Type") or ""):
file_path = output_dir / f"{host}.png"
file_path.write_bytes(r.content)
print(f"[+] Saved {file_path}")
except requests.RequestException as e:
print(f"[!] {host} failed: {e}")so when we find the red images we can extract the key :
483f8b15-e4a8-4387-b052-4b2204c7eb69
Recon 11 :
for this level we need to find out a vhost that has no DNS resolve. for this first we can use ffuf to find the right vhost in host header then we can access it. the lesson of this lab is You can bypass DNS resolution entirely by manipulating the Host header.
but first look at this :
❯ curl https://hackycorp.com -H "Host: random.hackycorp.com"<h1>Well done! You solved recon_07</h1>
The key for this exercise is 23eafa56-6d55-4b78-8307-24e7dc2ce5e6as you can see many header would return this for recon lab seven so we should filter this out. for this goal we use -fr in ffuf this would accept a regex and filter that out.
so our command is this :
ffuf -w SecLists/Discovery/Web-Content/common.txt -u https://hackycorp.com -H "Host: FUZZ.hackycorp.com" -fr recon_07and the output :
:: Method : GET
:: URL : https://hackycorp.com
:: Wordlist : FUZZ: /home/parhamf/owasp/wordlist/SecLists/Discovery/Web-Content/common.txt
:: Header : Host: FUZZ.hackycorp.com
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Regexp: recon_07
________________________________________________
ADMIN [Status: 200, Size: 108, Words: 12, Lines: 4, Duration: 98ms]
Admin [Status: 200, Size: 108, Words: 12, Lines: 4, Duration: 102ms]
admin [Status: 200, Size: 108, Words: 12, Lines: 4, Duration: 106ms]
www [Status: 200, Size: 16011, Words: 5888, Lines: 278, Duration: 102ms]
:: Progress: [4750/4750] :: Job [1/1] :: 116 req/sec :: Duration: [0:00:42] :: Errors: 0 ::
so when we send request to each of the admins we get same response :
curl https://hackycorp.com -H "Host: admin.hackycorp.com"<h1>Well done! You solved recon_11 </h1>
The key for this exercise is e4599fa9-1cc4-4916-a394-ce455a954d86so the key is :
e4599fa9-1cc4-4916-a394-ce455a954d86
Recon 12 :
its a simple level the lesson is In load-balanced systems, inconsistencies are vulnerabilities — and repetition reveals them.
so its good to some times send multiple requests.
after sending some
curl http://balancer.hackycorp.com/we get this :
<h1>Well done! You solved recon_12 </h1>
The key for this exercise is 29e5c97c-7230-46ae-937c-6c56ff33b84fand the key is :
29e5c97c-7230-46ae-937c-6c56ff33b84f
if you don’t want to send the curl manually you can use this :
for i in $(seq 0 10); do curl http://balancer.hackycorp.com/ ;doneRecon 13 :
for this level we need to find TXT record, its a kind of DNS record. for this we can use dig command :
dig TXT key.z.hackycorp.comin the output we can see this :
;; ANSWER SECTION:
key.z.hackycorp.com. 7194 IN TXT "9f883f22-6ea5-4631-bbe8-95841ad63f56"
we can use +short in the dig command to directly get the key :
9f883f22-6ea5-4631-bbe8-95841ad63f56
Recon 14 :
this level is DNS zone transfer (AXFR).
if an authoritative DNS server allows AXFR to anyone, you can dump the entire zone (A, NS, MX, TXT, etc.) in one request — instant recon and often flags in TXT records.
A DNS zone is a portion of the DNS namespace that is managed by a specific authoritative DNS server.
AXFR (Authoritative Zone Transfer) is a DNS operation used to transfer the entire DNS zone from one DNS server to another.
This domain is vulnerable because its authoritative DNS server allows unrestricted AXFR, leaking the entire DNS zone to anyone on the internet.
we can use this command :
dig axfr z.hackycorp.com @z.hackycorp.comdig— DNS query tool.axfr— request a full zone transfer (AXFR).z.hackycorp.com— the DNS zone you want to dump.@z.hackycorp.com— query this authoritative DNS server (use its name/IP as the server).
output :
; <<>> DiG 9.18.39 <<>> axfr z.hackycorp.com @z.hackycorp.com
;; global options: +cmd
z.hackycorp.com. 604800 IN SOA ns1.hackycorp.com. ns1.hackycorp.com. 2 604800 86400 2419200 604800
z.hackycorp.com. 604800 IN NS z.hackycorp.com.
z.hackycorp.com. 604800 IN A 51.158.147.132
key.z.hackycorp.com. 604800 IN TXT "9f883f22-6ea5-4631-bbe8-95841ad63f56"
recon_14.z.hackycorp.com. 604800 IN TXT "e5fce970-6d94-43c1-bdd5-a06c2b235f9c"
z.hackycorp.com. 604800 IN SOA ns1.hackycorp.com. ns1.hackycorp.com. 2 604800 86400 2419200 604800
;; XFR size: 6 recordswe can use +short in the dig command to directly get the key :
e5fce970-6d94-43c1-bdd5-a06c2b235f9c
Recon 15 :
This level is the next step of the previous one. It’s still about DNS zone transfers, but with an important twist: internal zones.
A public DNS server can sometimes be tricked into leaking internal DNS zones if it is authoritative for them or misconfigured.
Even though a zone is called internal (int), it does not automatically mean private.
If:
- a publicly reachable nameserver
- is authoritative for an internal zone
- and allows AXFR
then anyone can dump that internal zone.
This domain is vulnerable because a public authoritative DNS server allows unrestricted AXFR on an internal zone, leaking internal infrastructure data.
for this level we can use this command :
dig axfr int @z.hackycorp.comint — the internal DNS zone name
others are the same as the previous level.
the output is :
; <<>> DiG 9.18.39-0ubuntu0.24.04.2-Ubuntu <<>> axfr int @z.hackycorp.com
;; global options: +cmd
int. 604800 IN SOA int. internals. 2 604800 86400 2419200 604800
int. 604800 IN NS int.
int. 604800 IN A 127.0.0.1
recon_15.int. 604800 IN TXT "b55b45a8-63b1-42f7-bd12-a36219ff883d"
int. 604800 IN SOA int. internals. 2 604800 86400 2419200 604800
;; Query time: 102 msec
;; SERVER: 51.158.147.132#53(z.hackycorp.com) (TCP)
;; WHEN: Tue Jan 06 13:39:43 +0330 2026
;; XFR size: 5 records (messages 1, bytes 229)so they key is :
b55b45a8-63b1-42f7-bd12-a36219ff883d
Recon 16 :
for this level we need to find the bind version that used by the DNS server. for this level we use this command :
dig @<server_ip> version.bind CH TXTfor finding the host IP address we use dig , we did it before so we directly use the IP in the command.
dig @51.158.147.132 version.bind CH TXTthe output :
; <<>> DiG 9.18.39-0ubuntu0.24.04.2-Ubuntu <<>> @51.158.147.132 version.bind CH TXT
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2017
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 001143b4d569e181f8296ef2695ce12cad9ea60786392ae8 (good)
;; QUESTION SECTION:
;version.bind. CH TXT
;; ANSWER SECTION:
version.bind. 0 CH TXT "4e5e76e1-728a-49be-aea8-4591ba11e588"
;; AUTHORITY SECTION:
version.bind. 0 CH NS version.bind.
;; Query time: 87 msec
;; SERVER: 51.158.147.132#53(51.158.147.132) (UDP)
;; WHEN: Tue Jan 06 13:47:16 +0330 2026
;; MSG SIZE rcvd: 132we can use the +short too, the key is :
4e5e76e1-728a-49be-aea8-4591ba11e588
Recon 17 :
easy. search hackycorp github on google then you have the organization profile and then go to the test1 repository and you can find the last developer name and you got the key :
d0fad5ef-ebb2-467c-8868-34e3cf4878b4
the github link : https://github.com/hackycorp/test1
Recon 18 :
when you go organization profile in people tab there is one developer in there public repository you can see a test repository then when you open in it, in the TEST file you can see they key :
80cb2045-c8bf-4357-8931-a28dd0f3fbb9
Recon 19 :
for this level we need to check .patch url for the git commit hash.
go to the repo7 in the commits open all of them and add .patch at the end then you see a page.
in the second commit .patch page :
you can see a different email :
From 98b4472d5e46af145968345b262bc930c4b8c6e3 Mon Sep 17 00:00:00 2001
From: Hacky Dev <9590c69b-f9d0-469d-9475-827bf0e1126e@hackycorp.com>
Date: Wed, 18 Nov 2020 10:49:08 +1100
Subject: [PATCH] Another test
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index 0527e6b..33d0227 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,2 @@
This is a test
+This is a another testand there is you key :
9590c69b-f9d0-469d-9475-827bf0e1126e
Recon 20 :
easy. just go to repo3 check the branches and there is your key :
08be82ba-e5fd-4fae-b2c2-272a18d31f80
Recon 21 :
this time as the previous level you go to repo4 and then in the other branch you can see a file names KEY in that you have the key :
a60b4aee-642a-483b-9262-ccfc2ed46f0d
Recon 22 :
for this level the manual way is too hard , too many commits and files. we can make it lot easier.
first clone the repo :
git clone https://github.com/hackycorp/repo9.gitthe go to the repo9 using cd repo9.
now lets play, we can use this git command to check which files has been deleted.
git log --diff-filter=D --summaryresult of this command :
commit e8fec2d079cf9bfdf782a9ce4aab8ae8ce947548
Author: Hacky Dev <dev@hackycorp.com>
Date: Wed Nov 18 11:11:56 2020 +1100
Another test
delete mode 100644 KEY.txtso we found the file name and the commit that file has been deleted now easily we can access the file using this command :
git show "e8fec2d079cf9bfdf782a9ce4aab8ae8ce947548^":"KEY.txt"there is one catch here the ^ mean find the file from parent commit we use that because the gives the command by log command is the commit that file is deleted so if we want the key in that commit its not there its in the parent comment.
and we have this key :
3ee505c2-8aa9-4d5e-810e-921778dce1e6
Recon 23 :
check the commits and in one of them there is the message and in that we have the key :
5c75cfe9-52dd-475b-8cfa-7ffc492abeca
Recon 24 :
check the page code you can see the assets would load from this url :
assets.hackycorp.com
so open this link now :
assets.hackycorp.com/key.txt
and there it is you have the key :
e94ab8a5-b0c1-4559-8bc7-cae2e53b10e0
Recon 25 :
for this level you need a aws account if you like me cant have an aws account directly use this key :
ff360948-c048-4f0c-a302-e806c50192d9
Recon 26 :
check out the source of the page and in the script.js you can find the key, the url :
view-source:https://assets.hackycorp.com/js/script.js
and the key :
d6b75269-97a3-44de-be32-fff0dd55e7ef