Posts
ctfshow入门框架复现
web466 #Laravel5.4反序列化 Laravel5.4版本 ,提交数据需要base64编码 这种多半都是框架反序列化的漏洞,本地搭一个Laravel5.4来分析一下 部署环境 composer create-project laravel/laravel=5.4 Laravel5.4 --prefer-dist --ignore-platform-reqs --no-security-blocking cd Laravel5.4 php artisan key:generate php artisan serve 由于laravel5.4是比较老的版本且存在安全漏洞,所以composer会默认阻止安装,需要带上--ignore-platform-reqs --no-security-blocking 前面会有一个报错导致无法正常运行,这是因为加入上面两个参数后会导致composer自己下一些php8.x新版本的依赖包,需要修改 platform_check.php 文件 后面访问8000端口就可以了 在项目中添加一个反序列化路由和控制器 在routes/web.php中添加 Route::get('/seri',"SeriController@index"); 新建app/Http/Controllers/SeriController.php <?php namespace App\Http\Controllers; class SeriController extends Controller{ public function index(){ if(isset($_GET['ser'])){ $ser = $_GET['ser']; unserialize($ser); } else{ highlight_file(__FILE__); } return "Debug Laravel5.4 by yourself!"; } } ?> 配置一下xdebug,方便后面调试链子 漏洞分析 __destruct()方法寻找 先找找可用的__destruct()方法 看到\Illuminate\Broadcasting\PendingBroadcast::__destruct() public function __destruct() { $this->events->dispatch($this->event); } $this->events和$this->event两个参数都是可控的,找一个不存在dispatch方法的类可以触发__call() 链1 Generator::__call方法 全局搜索一下__call()方法,找到一个之前yii框架类似的\Faker\Generator::__call public function __call($method, $attributes) { return $this->format($method, $attributes); } 跟进format public function format($formatter, $arguments = array()) { return call_user_func_array($this->getFormatter($formatter), $arguments); } 看看getFormatter函数是干啥的 ...
K8s基础
什么是Kubernetes Kubernetes又名k8s,是一个由Google开源,现由 CNCF(云原生计算基金会)维护的容器编排平台 Kubernetes(K8s) 集群是k8s的基本运行单元,由一个控制平面和一组用于运行容器化应用的工作机器组成, 这些工作机器称作节点(Node)。每个集群至少需要一个工作节点来运行 Pod。 K8S集群主要负责容器编排,本质上来说,K8S不仅能将单个容器运行起来,将其对外暴露出去提供服务。还提供了:路由网关、集群监控、灾难恢复,以及应用的水平扩展等能力。 Kubernetes架构 从结构图不难看出,k8s主要是由Master节点(控制平面)以及工作器节点组成,Master节点参与对Node节点的管理控制 Master节点 MasterNode主要包括四个部分: ApiServer:顾名思义就是提供API接口进行资源操作,并提供认证、授权、访问控制、API 注册和发现等机制 Controller Manager:控制管理,负责维护集群的状态,监控各种资源状态的变化 Scheduler:调度程序,负责资源的调度,其实就是根据策略将Pod调度到相应的机器上 etcd:里面保存了整个集群的状态,用作 Kubernetes 所有集群数据的后台数据库。 Worker节点 WorkerNode主要有以下部分: pod:k8s的最小的调度和运行单元,一个pod可以包含一个或多个容器,pod内所有容器都共用一个IP地址和网络命名空间,其实就类似于一台机器以及机器上的进程服务 kubelet:每台节点上的代理,负责维护容器的生命周期 Kube-proxy:通过为Service资源的ClusterIP生成iptable或ipvs规则,实现将K8S内部的服务暴露到集群外面去;处理节点上的网络规则,让 Pod 之间能互相通信 k8s和docker,docker-compose的区别 最大的区别就是在于运行管理方面,doker和docker-compose更偏向于单机运行的管理,docker一次只能管理一个容器,虽然docker-compose能同时管理多个容器,但本质上还是只限制在一台机器中,而k8s是集群多机器编排,可以同时管理多台机器 除此之外,k8s还有以下特点: 弹性伸缩:容器数量的控制,流量高峰自动加副本,低谷自动缩减,节省成本 自我修复/高可用:对容器进行监测,如果某台机器宕机,Pod 自动迁移到其他机器,而出现问题的机器会自动抛弃或重启 自动部署和回滚:自动对容器的回滚更新且更新版本时无缝替换,用户无感知 k8s工作流程 k8s工作的时候通常会使用kubectl,kubectl 是 k8s 的客户端工具,可以使用命令行管理集群 具体流程如下: kubectl向apiserver发送部署创建请求(例如使用 kubectl create -f deployment.yml) apiserver将请求写入etcd,随后收到etcd的回调事件 apiserver将回调事件发送给ControllerManager,ControllerManager中的ReplicationController根据deployment的描述创建一个ReplicaSet并将ReplicaSet对象返回给apiserver并持久化回etcd Scheduler调度程序看到未调度的pod对象,根据调度规则选择一个可调度的节点,将节点名写入pod描述的nodeName字段中,并将pod对象返回给apiserver并写入etcd apiserver接收到etcd的回调后会将更新pod的事件发送给pod对应的node上的kubelet进程 kubelet在看到有pod对象中nodeName字段属于本节点,将其从队列中拉出,通过容器运行时创建pod中描述的容器 k8s安全基础 一方面是组件接口的安全风险: API server未授权访问 API server的默认服务接口是8080和6443,但是8080只提供http服务,并没有认证与授权机制,而6443两者兼并 默认情况下8080端口是不会启动的,但是如果使用者开启了该服务,就可能会造成API的未授权访问,从而控制整个k8s集群 使用kubectl获取集群信息 kubectl -s [ip]:[port] get nodes Kubelet未授权访问 Kubelet也是运行API服务的,默认服务端口是10250和10248,同样也容易存在未授权访问 etcd信息泄露 etcd默认监听2379(用于客户端连接)和2380(用于多个etcd之间的通信)端口 默认情况下,etcd两个端口的访问都需要证书去进行认证,所以如果我们拿到了证书或者使用者给etcd设置了允许匿名访问,那么就可以读取etcd中的数据,导致信息泄露风险 etcd v2:Kubernetes ≤ 1.5的版本默认使用etcd v2 /v2/keys/?recursive=true etcd v3:k8s v1.6开始默认使用 etcd v3,一般使用etcdctl实现对etcd的访问 文档:https://github.com/etcd-io/etcd/tree/main/etcdctl ...
Docker逃逸学习
前言 趁着这几天刚出完公司的题,抽出时间看了一下docker逃逸方面的东西,这里的话主要就是放攻击手法了,一些基础的概念就懒得赘述了 如何判断虚拟环境类型 参考:https://yuy0ung.github.io/blog/%E4%BA%91%E5%AE%89%E5%85%A8/%E8%AF%86%E5%88%AB%E8%99%9A%E6%8B%9F%E6%9C%BAdocker%E5%92%8Ck8s%E9%9B%86%E7%BE%A4%E7%8E%AF%E5%A2%83/ 通常在getshell之后,我们都需要考虑一个问题:我们是真的拿到目标机器的shell了还是只是处于机器中虚拟环境里?前者的话肯定直接做一些比如提权,内网穿透,横向移动,权限维持等内网渗透的手法,但是如果我们此时是处在机器中的虚拟环境中的话,我们需要先判断该虚拟环境的类型 通常情况下,shell的虚拟环境可能有三个类型:虚拟机,Docker,k8s。这三种类型对应着三种不同的攻击面: 虚拟机:通常考虑横向移动来扩大攻击效果 Docker:通常考虑容器逃逸到宿主机 K8s:通常先尝试接管集群,以获取对容器和集群资源的完全控制(注意:K8s其实本质上也是跑容器,只不过不一定用 Docker,现代 K8s 常见运行时是 containerd / cri-o) 当然,仍有一些特殊的情况比如:Docker运行在虚拟机里,这种情况在这里就不讲述了 查看主机名和进程 hostname #查看主机名 ps aux #显示系统上所有用户的详细进程信息 Docker 默认 hostname 通常是容器 ID 的前 12 位(不绝对),PID1非系统进程,可初步判断当前为容器环境 如果是在普通虚拟机或物理机里,PID 1 通常是:systemd 或者 init 如果是在容器里,PID 1 可能是: bash,sh,python,node,java,nginx,tini,supervisord 但是注意: 有些容器也会跑 systemd 有些轻量 VM 也可能不是 systemd 所以 PID 1 只是作为初步的判断 检查根目录下.dockerenv文件 ls -la /.dockerenv 通过判断根目录下的.dockerenv文件是否存在,确认当前环境是否为容器环境。 需要注意:有些 Docker 容器可能没有这个文件,甚至有些镜像为了伪装会删除掉这个文件 看 cgroup 信息 cat /proc/1/cgroup 或者: cat /proc/self/cgroup 这个文件是一个 内核提供的虚拟文件,里面包含了PID 1 这个进程属于哪些 cgroup,而cgroup 是 Linux 用来做资源隔离和限制的机制,通常用于限制一个进程/容器的cpu,内存等资源使用 ...
0CTF2022 Hessian_onlyjdk
品到细糠了
AliCTF2025-Jtools
又学到一种二次反序列化的新东西
Facebook CTF2019wp
远古老题
WebLogic T3反序列化
好难啊压根看不懂
ctfshow入门代码审计
ctfshow入门sqli-labs二刷
复健一下