前言
继续ctf的旅程
开始攻防世界web高手进阶区的10分题
本文是weiphp的writeup
解题过程
进入界面
点击
进入一个登陆界面
没有注册
那肯定得找源码了
惯例源码+御剑
发现git泄露
那就githack
然后代码审计了
代码审计是累
在Base.php
中看到
public function post_data($url, $param, $type = 'json', $return_array = true, $useCert = [])
{
$res = post_data($url, $param, $type, $return_array, $useCert);
// 各种常见错误判断
if (isset($res['curl_erron'])) {
$this->error($res['curl_erron'] . ': ' . $res['curl_error']);
}
if ($return_array) {
if (isset($res['errcode']) && $res['errcode'] != 0) {
$this->error(error_msg($res));
} elseif (isset($res['return_code']) && $res['return_code'] == 'FAIL' && isset($res['return_msg'])) {
$this->error($res['return_msg']);
} elseif (isset($res['result_code']) && $res['result_code'] == 'FAIL' && isset($res['err_code']) && isset($res['err_code_des'])) {
$this->error($res['err_code'] . ': ' . $res['err_code_des']);
}
}
return $res;
}
跟踪post_data
在common.php
中
function post_data($url, $param = [], $type = 'json', $return_array = true, $useCert = [])
{
$has_json = false;
if ($type == 'json' && is_array($param)) {
$has_json = true;
$param = json_encode($param, JSON_UNESCAPED_UNICODE);
} elseif ($type == 'xml' && is_array($param)) {
$param = ToXml($param);
}
add_debug_log($url, 'post_data');
// 初始化curl
$ch = curl_init();
if ($type != 'file') {
add_debug_log($param, 'post_data');
// 设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
} else {
// 设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, 180);
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
// 设置header
if ($type == 'file') {
$header[] = "content-type: multipart/form-data; charset=UTF-8";
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
} elseif ($type == 'xml') {
curl_setopt($ch, CURLOPT_HEADER, false);
} elseif ($has_json) {
$header[] = "content-type: application/json; charset=UTF-8";
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
}
// curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
// dump($param);
curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
// 要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 使用证书:cert 与 key 分别属于两个.pem文件
if (isset($useCert['certPath']) && isset($useCert['keyPath'])) {
curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLCERT, $useCert['certPath']);
curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLKEY, $useCert['keyPath']);
}
$res = curl_exec($ch);
if ($type != 'file') {
add_debug_log($res, 'post_data');
}
// echo $res;die;
$flat = curl_errno($ch);
$msg = '';
if ($flat) {
$msg = curl_error($ch);
}
// add_request_log($url, $param, $res, $flat, $msg);
if ($flat) {
return [
'curl_erron' => $flat,
'curl_error' => $msg
];
} else {
if ($return_array && !empty($res)) {
$res = $type == 'json' ? json_decode($res, true) : FromXml($res);
}
return $res;
}
}
发现可以用来SSRF
传入诸如url=file:///etc/passwd
的参数,会导致simple_xml_load_string
出错
一番尝试后
得到flag
结语
看了看wp
发现这个cms有各种漏洞
被日穿了
- sqli
- 免登录文件上传
- 登录后文件上传
- 包含日志执行
可参考以下两篇wp