CVE-2024-3400: PAN-OS Command Injection Vulnerability in GlobalProtect Gateway. Learn More

CVE-2024-3400: PAN-OS Command Injection Vulnerability in GlobalProtect Gateway. Learn More

Services
Capture
Managed Detection & Response

Eliminate active threats with 24/7 threat detection, investigation, and response.

twi-managed-portal-color
Co-Managed SOC (SIEM)

Maximize your SIEM investment, stop alert fatigue, and enhance your team with hybrid security operations support.

twi-briefcase-color-svg
Advisory & Diagnostics

Advance your cybersecurity program and get expert guidance where you need it most.

tw-laptop-data
Penetration Testing

Test your physical locations and IT infrastructure to shore up weaknesses before exploitation.

twi-database-color-svg
Database Security

Prevent unauthorized access and exceed compliance requirements.

twi-email-color-svg
Email Security

Stop email threats others miss and secure your organization against the #1 ransomware attack vector.

tw-officer
Digital Forensics & Incident Response

Prepare for the inevitable with 24/7 global breach response in-region and available on-site.

tw-network
Firewall & Technology Management

Mitigate risk of a cyberattack with 24/7 incident and health monitoring and the latest threat intelligence.

Solutions
BY TOPIC
Offensive Security
Solutions to maximize your security ROI
Microsoft Exchange Server Attacks
Stay protected against emerging threats
Rapidly Secure New Environments
Security for rapid response situations
Securing the Cloud
Safely navigate and stay protected
Securing the IoT Landscape
Test, monitor and secure network objects
Why Trustwave
About Us
Awards and Accolades
Trustwave SpiderLabs Team
Trustwave Fusion Security Operations Platform
Trustwave Security Colony
Partners
Technology Alliance Partners
Key alliances who align and support our ecosystem of security offerings
Trustwave PartnerOne Program
Join forces with Trustwave to protect against the most advance cybersecurity threats
SpiderLabs Blog

Patch the Vuln - Feathers - SQLi(1)

Spot the Vuln -> Patch the Vuln

SpotTheVuln

This blog post series is designed to be a companion to the Spotthevuln.com website (thanks to Billy Rios - @XSSniper).

Spotthevuln.com was designed to give developers more insight into designing code with security in mind.

When developers write source code they rarely think about security.

After insecure code is deployed,one of two things can happen.

  1. The bug can be found,in which case the developers have to waste development time in order to rewrite their solutions.
  2. The vulnerability is exploited,and the organization loses money,consumer trust,and can gain a negative reputation to their brand.

These problems can be avoided if the developers wrote the code correctly (securely) the first time.

Spotthevuln.com can aid developers,development managers,and QA staff by helping them sharpen their skills in spotting vulnerabilities in source code.

Spotthevuln.com use actual code snippets from open source applications to demonstrate how often vulnerable pieces of code get deployed into the real world.

The purpose is simple:

  • Every Monday a vulnerable piece of code is posted.
  • Every Friday the solution is posted.

On Monday, look at the piece of the code to see if you can identify what the security vulnerability is. Like everything else being able to spot vulnerable code takes practice.

Doing this exercise should take between 5 and 10 minutes out of your day. Do it while you drink your morning coffee and you will already be on your way to being able to write more secure applications.

The more secure code is,the better off we will all be.

PatchTheVuln

Where SpotTheVuln focuses on developers and source code flaws, PatchTheVuln gives operational security staff more insight and experience creating active, external defenses for vulnerabilities identified within their live web applications.

Every Monday, we will provide examples of IDS/IPS/WAF rules solutions that can be used to identify and prevent expliot attempts targeting the web vulnerability discussed the prevoius week on SpotTheVuln.

This Week's Vulnerabilty - Feathers

Details from SpotTheVuln website:

Vulnerability Details

Affected Software: Corpse C&C

Fixed in Version: Not Patched

Issue Type: SQL Injection

Original Code: Found Here

Details

This week's bugs are in the CORPSE C&C (in the bsrv.php file). There are a couple of bugs here, most of them are very straight forward. Funny stuff first if $ver is blank, we will fail the "security check". So, in order to reach any of these vulns, we have to provide an arbitrary value for $ver. $ver is set from $_GET[ver'], so we have to provide a bsrv.php?ver=pwnd for each request in order to reach the vulnerable code. It's rigorous security checks like this that make exploitation difficult.

$id and $param are validated through a manual process (code on line 27 — 36). I don't know why the developer didn't take advantage of built-in escaping routines but the validation provided here seem to defend against common vulns. What's also puzzling, is why the other variables weren't validated/escaped. Veteran Spot the Vuln readers have seen this pattern before (escape one variable, miss the next variable) in other software, but for some reason I still find it surprising every time I see it. Now, let's get onto the actual bugs. The most obvious are $uid and $httpport which are set directly from user controlled input ($_GET). These two variables are then used to build a dynamic SQL statement. This results in SQL injection.

Additionally, $uptimem and $uptimeh are used to set $sql_uptime. $sql_uptime is then used in a dynamic SQL statement resulting in yet another SQL injection.
$browser is taken from getenv("HTTP_USER_AGENT"), which is attacker controlled (the user agent header in the HTTP request). Although $browser isn't used on this page, it's just asking for trouble :)

Upon first glance, it seems like $real_ip and $socksport could be used to reach a SQL injection. After some more investigation, it is likely that the fsockopen call would probably fail before $real_ip and $socksport could be passed to a dynamic SQL statement. With that said, $real_ip and $socksport can be still be used to generate a fsockopen request to an arbitrary system (line 59).

Vulnerable Code Location(s)

 <?php // Gettin all information$id = $_GET['id'];$httpport = $_GET['httpport'];$socksport = $_GET['socksport'];$uptimem = $_GET['uptimem'];$uptimeh = $_GET['uptimeh'];$param = $_GET['param'];$ver = $_GET['ver'];$uid = $_GET['uid'];$wm = $_GET['wm'];$lang = $_GET['lang'];//$ssip = $_GET['ssip'] ;$ip = getenv("REMOTE_ADDR");$real_ip = getenv("HTTP_X_FORWARDED_FOR");$browser = getenv("HTTP_USER_AGENT"); //Security checkif($ver == ''){ exit;} include_once('./mysqllog.php'); //Replace symbols$id = ereg_replace("<","‹",$id);$id = ereg_replace(">","›",$id);$id = ereg_replace("\\"",""",$id);$id = ereg_replace(";","",$id);$id = ereg_replace("%","",$id);$param = ereg_replace("<","‹",$param);$param = ereg_replace(">","›",$param);$param = ereg_replace("\\"",""",$param);$param = ereg_replace(";","",$param);$param = ereg_replace("%","",$param); /*=========================$flip = file("logs/cip.dat");$size  = strlen($flip);if ($size > 10) {  $arr = explode(":", $flip[0]);  $aport=311;} if($arr[1] == $uid || $arr[1] == "0") { $fp = fsockopen($arr[0],$aport, $errno, $errstr, 30);  fputs($fp,"IP:$ip PORT:$param $tim SOCKS:$socksport HTTP:$httpport Uptime:$uptimeh:$uptimem lang-$lang uid:$uid id:$id v:$ver\\"); fclose($fp);}//=========================*/ $date = date("Y-m-d");$time=date("H:i:s");list($year, $month, $day) = explode('-', $date);$sql_uptime = "$uptimeh:$uptimem"; if($real_ip != "") { $fp = fsockopen($real_ip,$socksport, $errno, $errstr, 30);  if(!$fp) {  $okk = false;   } else {  $okk = true;    $link = mysql_connect($mysql_host, $mysql_login, $mysql_pass) or die("Could not connect: " . mysql_error());  mysql_select_db($mysql_db, $link) or die("Could not select : " . mysql_error());  $query = 'SELECT COUNT(*) FROM socks where uid = "'. $uid .'"';  $result = mysql_query($query, $link) or die("Could not execute: " . mysql_error());  $count = mysql_result($result, 0);  if ($count == 0) {   $query = 'INSERT INTO socks VALUES ("'.$uid.'", "'. $real_ip . '", "'. $httpport .'", "'. $socksport . '", "'. $sql_uptime .'", "'. mktime() .'", "0")';   $result = mysql_query($query, $link) or die("Could not execute: " . mysql_error());  } else {    $query = 'UPDATE socks SET  `ip` = "'. $real_ip .'", `hport` = "'. $httpport .'", `sport` = "'. $socksport .'", `uptime` = "'. $sql_uptime .'", `update` = "'. mktime() .'" WHERE `uid` = "'.$uid.'"';   $result = mysql_query($query, $link) or die("Could not execute: " . mysql_error());   $query = 'COMMIT';   $result = mysql_query($query, $link) or die("Could not execute: " . mysql_error());  }  mysql_close($link);   //$fh=fopen("logs/P.$day.$month.txt","a+");  //ip:hport:sport:bport:uptime:uid  //fputs($fh,"$real_ip@$httpport@$socksport@$param@$uptimeh:$uptimem@$uid\\");  //fclose($fh);  send_command();  exit; }} if( ($ip != "") && ($ip != $real_ip) ) { $fp = fsockopen($ip,$socksport, $errno, $errstr, 30); if(!$fp) {  send_command();  exit; } else {  $link = mysql_connect($mysql_host, $mysql_login, $mysql_pass) or die("Could not connect: " . mysql_error());  mysql_select_db($mysql_db, $link) or die("Could not select : " . mysql_error());  $query = 'SELECT COUNT(*) FROM socks where uid = "'. $uid .'"';  $result = mysql_query($query, $link) or die("Could not execute: " . mysql_error());  $count = mysql_result($result, 0);  if ($count == 0) {   $query = 'INSERT INTO socks VALUES ("'.$uid.'", "'. $ip . '", "'. $httpport .'", "'. $socksport . '", "'. $sql_uptime .'", "'. mktime() .'", "0")';   $result = mysql_query($query, $link) or die("Could not execute: " . mysql_error());  } else {    $query = 'UPDATE socks SET  `ip` = "'. $ip .'", `hport` = "'. $httpport .'", `sport` = "'. $socksport .'", `uptime` = "'. $sql_uptime .'", `update` = "'. mktime() .'" WHERE `uid` = "'.$uid.'"';   $result = mysql_query($query, $link) or die("Could not execute: " . mysql_error());   $query = 'COMMIT';   $result = mysql_query($query, $link) or die("Could not execute: " . mysql_error());  }  mysql_close($link);   //$fh=fopen("logs/P.$day.$month.txt","a+");  //ip:hport:sport:bport:uptime:uid  //fputs($fh,"$ip@$httpport@$socksport@$param@$uptimeh:$uptimem@$uid\\");  //fclose($fh);  send_command();  exit; }} send_command();exit; function send_command() {$cmdname="logs/cfg.dat";$cmduid="logs/uid.ini"; if(filesize("$cmduid") == 0) { $fh=fopen($cmdname,"r"); $cfgdata=fread($fh,filesize($cmdname)); fclose($fh); echo "CMND$cfgdata"; exit;} $array=file($cmduid);$kolvo=count($array);for($ei=0;$ei<$kolvo;$ei++) { $llen=strlen($array[$ei]); $llen=$llen-2; $array[$ei]=substr($array[$ei],0,$llen); if($array[$ei] == $uid) {  $fh=fopen($cmdname,"r");  $cfgdata=fread($fh,filesize($cmdname));  fclose($fh);  echo "CMND$cfgdata";  exit; }}echo "CMND\\";} ?>

ModSecurity Solution

From the vulnerabilty data highlighted above, a virtual patching solution with ModSecurity would need to enforce input validation for a number of request variables. A quick google search for "bsrv.php" shows that this is example format for requests to this page:

http://www.example.com/bsrv.php?pal=0&bay=0&gold=0&id=0000&param=1010&socksport=37350&httpport=28770&uptimem=2&uptimeh=4&uid=

Input Validation #1 - Enforce Digits Only

After reviewing the GET parameters that are used in the vulnerable queries above, it appears that we could enforce input validation for these parameters by only allowing digit characters for:

  • uid
  • httpport
  • uptimem
  • uptimeh
  • socksport

Example ModSecurity Rule

SecRule ARGS:uid|ARGS:httpport|ARGS:uptimem|ARGS:uptimeh|ARGS:socksport "!^\d+$" \"phase:2,t:none,t:urlDecodeUni,log,block,msg:'Input Validation Error for Parameter.',logdata:'%{matched_var_name}: %{matched_var}'"

Input Validation #2 - Enforce IP Address Format

The $real_ip paramter is taken from the X-Forwarded-For request header data of the request, which can be controlled by the client. We must therefore add some input validate to that data as well to ensure that it has the proper IP address format.

Example ModSecurity Rule

SecRule REQUEST_HEADERS:x-forwarded-for "!^\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(, )?)*\b$" \"phase:1,t:none,log,block,msg:'Input Validation Error for Parameter.',logdata:'%{matched_var_name}: %{matched_var}'"

 

Latest SpiderLabs Blogs

Fake Dialog Boxes to Make Malware More Convincing

Let’s explore how SpiderLabs created and incorporated user prompts, specifically Windows dialog boxes into its malware loader to make it more convincing to phishing targets during a Red Team...

Read More

The Secret Cipher: Modern Data Loss Prevention Solutions

This is Part 7 in my ongoing project to cover 30 cybersecurity topics in 30 weekly blog posts. The full series can be found here. Far too many organizations place Data Loss Prevention (DLP) and Data...

Read More

CVE-2024-3400: PAN-OS Command Injection Vulnerability in GlobalProtect Gateway

Overview A command injection vulnerability has been discovered in the GlobalProtect feature within Palo Alto Networks PAN-OS software for specific versions that have distinct feature configurations...

Read More