Sophos XG 漏洞调试环境搭建

发布于 2024-12-04 11:54:06 字数 14340 浏览 7 评论 0

0x00 前言

Sophos UTM 和 Sophos XG 是两款不同的产品,前者偏向于通用威胁管理,后者偏向于硬件防火墙。本文将要介绍 Sophos XG 漏洞调试环境的搭建方法。

0x01 简介

本文将要介绍以下内容:

  • 环境搭建
  • jetty 调试环境搭建
  • csc 配置文件解密
  • Postgresql 数据库查询

0x02 基础知识

架构如下图

Alt text

注:图片引用自 https://codewhitesec.blogspot.com/2020/07/sophos-xg-tale-of-unfortunate-re.html

总的来说,分为以下三部分:

  • Jetty:处理 Web 数据,将数据转发至 csc 作进一步处理
  • csc:主程序:加载 Perl Packages,实现主要功能
  • Postgresql:用来存储数据

我在实际研究过程中,这三部分遇到了以下问题:

  • Jetty:添加调试信息后无法启动 java
  • csc:csc 加载 Perl Packages 后会自动删除,无法获得 Perl Packages 的实现细节
  • Postgresql:用户权限低,无法查询数据库表

下面将要逐个介绍三个问题的解决方法

0x03 环境搭建

参考资料:https://docs.sophos.com/nsg/sophos-firewall/18.5/Help/en-us/webhelp/onlinehelp/VirtualAndSoftwareAppliancesHelp/VMware/VMwareInstall/index.html

1.下载安装包

官方网站默认只提供最新版本的下载,但是可以通过猜测正确的版本号下载旧版本

2.导入 VMware Workstation

下载得到 zip 文件,解压后运行 sf_virtual.ovf

3.VMware Workstation 网卡配置

需要添加两个网卡 VMnet7VMnet8 ,VMnet7 设置为 Host-only172.16.16.0 ,VMnet8 设置为 NAT ,具体方法如下:

(1)VMnet7

打开 VMware Workstation,依次选择 Edit -> Virtual Network Editor...

Add Network... -> VMnet7

VMnet7 设置为:

  • Type: Host-only
  • Subnet Address: 172.16.16.0

(2)VMnet8

VMnet8 设置为:

  • Type: NAT

4.Sophos XG 网卡配置

  • Network Adapter 设置为 VMnet7
  • Network Adapter 2 设置为 VMnet8
  • Network Adapter 3 设置为 VMnet8

配置如下图

Alt text

5.启动 Sophos XG

默认登录口令: admin

6.查看 IP 地址

依次输入 1.Newwork Configuration -> 1.Interface Configuration

得到 LAN 的 ip 为 172.16.16.16

7.进入 Web 配置页面进行激活

浏览器访问 https://172.16.16.16:4444

注册页面选择: I don't have a serial number(start a trial)

按照提示进行注册

注册成功后,重新访问 https://172.16.16.16:4444 进行配置

0x04 jetty 调试环境搭建

1.查看 Java 进程相关信息

执行命令: ps ww|grep java

输出:

java             3238   923 root     1393m  264m S    /lib/jvm/java-11-openjdk/bin/java -Xmx384m -Xms12m -Xss256k -XX:MaxMetaspaceSize=100m -Dhybrid.enabled=false -Djna.tmpdir=/tmp/java -Djava.io.tmpdir=/tmp/java -Dsun.jnu.encoding=UTF-8 -Dfile.encoding=UTF-8 -Djava.awt.headless=true -Djetty.home=/usr/share/jetty -Djetty.base=/usr/share/jetty -jar /usr/share/jetty/start.jar --lib=/usr/share/webconsole/properties/

从输出中得到 Java 版本为 java-11-openjdk

2.定位配置文件

配置文件路径为 /usr/bin/jetty ,内容如下:

#!/bin/sh

if   [ "${RAM}" == "2GB" ]; then
        heap_size=256
elif [ "${RAM}" == "4GB" ]; then
        heap_size=384
else
        heap_size=512
fi

HYBRID_ENABLED=false

if [ $HYBRID_ENABLED = true ]; then
    HYBRID_ENABLED=`opcode gethainfo -s nosync | grep -q "hamode=1" && echo "true" || echo "false"`
fi
if [ ! -d /tmp/java ]; then
    mkdir /tmp/java
fi
/scripts/umnt_mount_dir.sh "JVM" "/tmp/java" "mount"

##
# sun.jnu.encoding=UTF-8 - System property is required with file.encoding otherwise some java APIs unable to read file having double byte characters in file name.
##
exec /lib/jvm/java-11-openjdk/bin/java -Xmx${heap_size}m -Xms12m -Xss256k "-XX:MaxMetaspaceSize=100m" "-Dhybrid.enabled=${HYBRID_ENABLED}" "-Djna.tmpdir=/tmp/java" "-Djava.io.tmpdir=/tmp/java" "-Dsun.jnu.encoding=UTF-8" "-Dfile.encoding=UTF-8" "-Djava.awt.headless=true" "-Djetty.home=/usr/share/jetty" "-Djetty.base=/usr/share/jetty" -jar /usr/share/jetty/start.jar "--lib=/usr/share/webconsole/properties/"
/scripts/umnt_mount_dir.sh "JVM" "/tmp/java"
exit $?

3.添加调试参数

修改文件属性: mount -o rw,remount /

在 exec 所在行添加调试参数: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000"

4.重启服务

执行命令: service tomcat:restart -ds nosync

查看服务状态: service -S | grep tomcat

发现 tomcat 状态为 STOPPED

为了获得详细的报错信息,直接运行 /usr/bin/jetty

输出:

Error occurred during initialization of VM
Could not find agent library jdwp on the library path, with error: libjdwp.so: cannot open shared object file: No such file or directory

发现是 JDK 的问题,这里选择替换一个完整的 JDK

5.替换 JDK

下载 jdk-11.0.15_linux-x64_bin.tar.gz 并上传至 Sophos XG

备份原文件夹: cp -r /lib/jvm/java-11-openjdk /lib/jvm/java-11-openjdk_backup

将 jdk-11.0.15_linux-x64_bin.tar.gz 解压: tar zxvf /tmp/jdk-11.0.15_linux-x64_bin.tar.gz

替换 /lib/jvm/java-11-openjdk :

rm -rf /lib/jvm/java-11-openjdk
cp -r /tmp/jdk-11.0.15 /lib/jvm/java-11-openjdk

6.再次重启服务

执行命令: service tomcat:restart -ds nosync

查看服务状态: service -S | grep tomcat

发现 tomcat 状态为 RUNNING

确认参数被修改,执行命令: ps ww|grep java

输出:

java             1827   923 root     1454m  158m S    /lib/jvm/java-11-openjdk/bin/java -Xmx384m -Xms12m -Xss256k -XX:MaxMetaspaceSize=100m -Dhybrid.enabled=false -Djna.tmpdir=/tmp/java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000 -Djava.io.tmpdir=/tmp/java -Dsun.jnu.encoding=UTF-8 -Dfile.encoding=UTF-8 -Djava.awt.headless=true -Djetty.home=/usr/share/jetty -Djetty.base=/usr/share/jetty -jar /usr/share/jetty/start.jar --lib=/usr/share/webconsole/properties/

7.修改防火墙规则

执行命令: iptables -I INPUT -p tcp --dport 8000 -j ACCEPT

8.使用 IDEA 远程调试

如下图

Alt text

在调试过程中,如果遇到无法下断点的情况,重启 java 服务即可: service tomcat:restart -ds nosync

0x05 csc 配置文件解密

查看 csc 进程相关信息

执行命令: ps ww|grep csc

部分输出:

csc               859     1 root     25916 23600 S    csc -L 3 -w -c /_conf/cscconf.bin
csc               869   859 root      8628   452 S    csc -L 3 -w -c /_conf/cscconf.bin
cfs               870   859 root     34736 29380 S    {cfs} csc -L 3 -w -c /_conf/cscconf.bin
listener          871   859 root     21752 15088 S    {listener} csc -L 3 -w -c /_conf/cscconf.bin
lcdd              889   871 root     21108 13556 S    {lcdd} csc -L 3 -w -c /_conf/cscconf.bin
postgres          890   871 root     29712 25040 S    {postgres} csc -L 3 -w -c /_conf/cscconf.bin
sigdb             891   871 root     26756 23208 S    {sigdb} csc -L 3 -w -c /_conf/cscconf.bin
reportdb          892   871 root     26756 23104 S    {reportdb} csc -L 3 -w -c /_conf/cscconf.bin
awarrensmtp       893   871 root     25916 22296 S    {awarrensmtp} csc -L 3 -w -c /_conf/cscconf.bin

csc 进程读取 /_conf/cscconf.bin 作为配置文件,而 /_conf/cscconf.bin 是一个加密的文件,所以这里需要对 /_conf/cscconf.bin 进行解密

这里我采用的方法是通过 IDA 修改程序代码,改变实现逻辑,导出解密后的配置文件

使用 IDA 加载 csc,查看 main() 函数的实现逻辑,部分代码:

signed int __cdecl csc_main(int a1, char *const *a2)
{
  //****ignore code*****//
  if ( strlen(v14) > 4 )
  {
    v4 = strlen(v14);
    if ( !strcmp(&v14[v4 - 4], ".bin") )
    {
      extract_conf((int)v14);
      v17 = 1;
      v14 = "/_conf/csc/csc.conf";
    }
  }
  //****ignore code*****//
    if ( v17 )
      system(
        "rm -rf /_conf/csc/csc /_conf/csc/csc.conf /_conf/csc/cscconf/ /_conf/csc/constants.conf /_conf/csc/cscconf.tar.g"
        "z /_conf/csc/global.conf /_conf/csc/cfsconf /_conf/csc/service /_conf/csc/bind_file_list");
  //****ignore code*****//
}

分析以上代码,csc 先调用 extract_conf() 函数导出配置,最后执行系统命令 rm -rf /_conf/csc/csc /_conf/csc/csc.conf /_conf/csc/cscconf/ /_conf/csc/constants.conf /_conf/csc/cscconf.tar.gz /_conf/csc/global.conf /_conf/csc/cfsconf /_conf/csc/service /_conf/csc/bind_file_list 删除配置文件,导致我们无法直接获得相关配置文件

查看 extract_conf() 函数的实现代码:

unsigned int __cdecl extract_conf(int a1)
{
  int v2; // [esp+18h] [ebp-10h]
  unsigned int v3; // [esp+1Ch] [ebp-Ch]

  v3 = __readgsdword(0x14u);
  system("mount --make-private /_conf/csc");
  if ( mount("none", "/_conf/csc", "tmpfs", 0, 0) )
  {
    puts("mount tmpfs failed");
    exit(70);
  }
  v2 = sub_8052494(a1, "/_conf/csc/cscconf.tar.gz");
  if ( v2 == -1 )
  {
    printf("Cannot read file %s\n", a1);
    exit(70);
  }
  if ( v2 == -2 )
  {
    printf("Cannot read file2  %s\n", a1);
    exit(70);
  }
  system("tar -zxf /_conf/csc/cscconf.tar.gz -C /_conf/csc");
  return __readgsdword(0x14u) ^ v3;
}

分析以上代码,csc 先调用 sub_8052494() 函数对 /_conf/csc/cscconf.tar.gz 进行解密,接着执行系统命令 tar -zxf /_conf/csc/cscconf.tar.gz -C /_conf/csc 将配置文件释放到文件夹 /_conf/csc

综合以上分析,我们可以采取以下方式导出配置文件:修改 csc 程序,将释放路径 /_conf/csc 修改为另一路径,例如 /var/aaaaa ,那么,csc 在删除配置文件时,由于指定了固定的绝对路径,导致无法删除新的文件夹,这样我们就能从中获得完整的配置文件

具体的实现方法如下:

(1) 修改 csc

使用 IDA 加载 csc,查看 Exports ,找到 extract_conf ,双击进入 IDA View ,定位到字符串 tar -zxf /_conf/csc/cscconf.tar.gz -C /_conf/csc ,如下图

Alt text

切换到 Hex View,如下图

Alt text

/_conf/csc 修改为 /var/aaaaa ,如下图

Alt text

右键选择 Apply changes

依次选择 Edit -> Patch program -> Apply patches to input file... -> OK ,生成新的文件 csc

(2) 替换 csc

通过 ssh 登录,上传新的文件 csc,保存至 /tmp/csc

备份 csc 并进行替换,执行以下命令:

mount -o rw,remount /
cp /usr/bin/csc /usr/bin/csc_original
mkdir /var/aaaaa
cp /tmp/csc /usr/bin/csc
chmod 755 /usr/bin/csc
ll /usr/bin/csc
reboot

(3) 确认配置文件是否导出成功

等待系统重启,进入底层 shell,依次输入 5.Device Management -> 3.Advanced Shell

查看文件夹 /var/aaaaa ,如下图

Alt text

配置文件导出成功

(4) 恢复 csc

mount -o rw,remount /
cp /usr/bin/csc_original /usr/bin/csc
reboot

(5) 下载配置文件

通过 ssh 登录,下载文件夹 /var/aaaaa 中的内容

0x06 Postgresql 数据库查询

查看端口信息,执行命令: netstat -tulpen |grep postgres

输出:

tcp        0      0 127.0.0.1:5432          0.0.0.0:*               LISTEN      65534      3800       1087/postgres 
tcp        0      0 127.0.0.1:5433          0.0.0.0:*               LISTEN      65534      5846       1182/postgres 
tcp        0      0 127.0.0.1:5434          0.0.0.0:*               LISTEN      65534      5813       1161/postgres

通过搜索,发现以上三个数据库的连接信息依次对应以下三个文件:

  • /usr/share/webconsole/properties/ConnectionPool.cfg
  • /usr/share/webconsole/properties/ConnectionPoolForReports.cfg
  • /usr/share/webconsole/properties/ConnectionPoolForSignature.cfg

文件中的配置信息如下:

  • JDBCConnectionURL=jdbc:postgresql://127.0.0.1:5432/corporate?user=pgrouser&autoReconnect=true
  • JDBCConnectionURL=jdbc:postgresql://127.0.0.1:5433/iviewdb?user=pgrouser&autoReconnect=true
  • JDBCConnectionURL=jdbc:postgresql://127.0.0.1:5434/signature?user=pgrouser&autoReconnect=true

测试命令 1:

psql -p 5432 corporate -U pgrouser
corporate=> \d

输出:

ERROR:  permission denied for relation pg_class

提示没有权限

测试命令 2:

psql -p 5432 corporate -U pgrouser
select * from tbluser;

能够获得用户信息

注:

将用户 pgrouser 换成 nobody 具体相同的权限

从以上信息得知,用户 pgrouser 和 nobody 都不是 root 用户,功能受限,下面尝试寻找 root 用户

对解密的 csc 配置文件进行检测,定位到 \service\postgres.csc ,关键文件内容:

EXEC /bin/synccmd "/sbin/pg_dump -U pgroot corporate -a --disable-triggers -t tblhavmac -f /tmp/corphavmac"
EXEC /bin/synccmd "/sbin/pg_dump -U pgroot corporate -a --disable-triggers -t tblinterface -t tblipaddress -f /tmp/corpifdb"
EXEC /bin/synccmd "/sbin/pg_dump -U pgroot corporate -a --disable-triggers -n config -T tbllivesslvpnusers -T tblhbcloudcredential -f /tmp/corpdb"

找到关键用户 pgroot

测试命令 3:

psql -U pgroot -d corporate
\d

执行成功

0x07 小结

本文介绍了在搭建 Sophos XG 调试环境过程中一些问题的解决方法。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

豆芽

暂无简介

文章
评论
26 人气
更多

推荐作者

alipaysp_qCPZes5aGh

文章 0 评论 0

BeginEnd

文章 0 评论 0

温柔一刀

文章 0 评论 0

qq_eW9dqv

文章 0 评论 0

cz003

文章 0 评论 0

mb_y5iXe1gw

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文