解析烧录固件失败_Sophos UTM固件反编译Perl源码

ce43914527a6fd4f9eacfca74f96fa7d.png

从网络设备或其他IoT设备提取到固件之后进行安全分析和漏洞挖掘工作,对 Sophos UTM进行安全分析时,发现其具体提供Web功能的是一个Linux文件,并没有发现web功能实现的html代码,通过Burp Suite抓包Web请求发现所有web页面的请求展示都是通过该Linux文件实现,自然必须对其进行解析才行继续分析,但难度非常大,一度束手无策,经过几天的详细排查分析,最终得以解决。

由于国内外资料网站均没有对Sophos UTM固件文件的反编译资料,故梳理成文,分享给大家。

分析

UTM是Unified Threat Management的缩写,简称为统一威胁管理,各个安全厂商都有自己的UTM产品,比较出名的是Fortinet、WatchGuard、Sophos等等。

此次需要进行安全分析的产品就是Sophos UTM,官方网站为:

https://www.sophos.com/en-us/products/unified-threat-management.aspx

获取到的固件文件为一个完整打包好的ISO光盘文件,使用VmWare Workstation安装之后, 就可以进入到UTM页面中。

本地访问的地址是:

https://192.168.21.100:4444/

5ee2339d6d2ed021c2672af68c22d65c.png

一般来说获取一个ssh shell将会非常有助于安全分析,比完全从Web入手难度就要下降几个等级,下面就先来获取命令行shell。

1. 获取ssh shell & root shell

Sophos UTM默认情况下不允许使用ssh shell,必须在web页面中开启,Management-System Settings-Shell Acess开启shell功能。

c5e3b75743cf5ef663b67594ba181f04.png

注意要选择 "Allow password authentication",否则要使用证书验证,比较麻烦,不方便分析。

接着输入root和loginuser 两个用户的密码,并使用loginuserssh 登录。

 1a@DESKTOP-22L12IV:$ ssh loginuser@192.168.21.100 2loginuser@192.168.21.100's password: 3Last login: Mon Nov  9 05:34:23 2020 from 192.168.21.1 4 5 6Sophos UTM 7(C) Copyright 2000-2014 Sophos Limited and others. All rights reserved. 8Sophos is a registered trademark of Sophos Limited and Sophos Group. 9All other product and company names mentioned are trademarks or registered10trademarks of their respective owners.1112For more copyright information look at /doc/astaro-license.txt13or http://www.astaro.com/doc/astaro-license.txt1415NOTE: If not explicitly approved by Sophos support, any modifications16      done by root will void your support.1718loginuser@test:/home/login > su19Password:20test:/home/login # id21uid=0(root) gid=0(root) groups=0(root),890(xorp)22test:/home/login # uname -a23Linux test 3.8.13.27-0.176377654.gd7350fc-smp64 #1 SMP Wed Sep 17 10:45:23 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux24test:/home/login # cat /proc/version25Linux version 3.8.13.27-0.176377654.gd7350fc-smp64 (abuild@axgbuild) (gcc version 4.3.4 [gcc-4_3-branch revision 152973] (SUSE Linux) ) #1 SMP Wed Sep 17 10:45:23 UTC 201426test:/home/login # cat /etc/version27 9.20800828test:/home/login #

2. 登录抓包

接下来就是登录抓包进行登录验证分析,使用的工具是Burp Suite Pro,正确配置之后,就可以有完整的登录验证包。

 1POST /webadmin.plx HTTP/1.1 2Host: 192.168.21.100:4444 3User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0 4Accept: text/javascript, text/html, application/xml, text/xml, */* 5Accept-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 6Accept-Encoding: gzip, deflate 7X-Requested-With: XMLHttpRequest 8X-Prototype-Version: 1.5.1.1 9Content-type: application/x-www-form-urlencoded; charset=UTF-810Content-Length: 28711Origin: https://192.168.21.100:444412Connection: close13Referer: https://192.168.21.100:4444/1415{"objs": [{"elements": {"login_username": "admin", "login_password": "test0011"}, "FID": "login_process"}], "SID": "0", "browser": "gecko", "backend_version": -1, "loc": "english", "_cookie": null, "wdebug": 0, "RID": "1604979704552_0.8572369473251601", "current_uuid": "", "ipv6": true}

发现登陆是使用json格式进行网络请求,方法是POST,请求的的接口文件是webadmin.plx,同时登陆之后的页面请求和展示都是通过webadmin.plx进行数据交互,接下来就是对webadmin.plx进行解析分析。

疑难问题

截止到此处,还没有遇到无法解决的问题,但深入文件分析时却给了沉重的一击,先来看webadmin.plx的文件属性:

1test:/var/sec/chroot-httpd/var/webadmin # file webadmin.plx2webadmin.plx: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), stripped

32位可执行文件,没有异常,但是当使用GDB调试的时候提示:

e1adc6ff6ed08d84017476f793f6e1a5.png

GDB提示文件格式不正确,事实是该文件可以执行:

1test:/var/sec/chroot-httpd/var/webadmin # ./webadmin.plx2[19370] WARN: Use of uninitialized value $ENV{"REQUEST_METHOD"} in string eq at /wfe/asg/modules/asg_fcgi.pm line 59.3test:/var/sec/chroot-httpd/var/webadmin #

有正常的错误返回,说明webadmin.plx文件正常,执行正常。

又发现该文件没有任何的Section:

1a@DESKTOP-22L12IV:$ readelf -S webadmin.plx2There are no sections in this file.

IDA Pro又能够正常解析elf文件,只有 LOAD节。

983c8062e133d5493844310227494703.png

两眼一抓瞎,这时该怎么办?

GDB调试进程,失败。

尝试使用GDB附加调试进程,失败+1,not in executable format: File format not recognized。

尝试GDB附加父进程,然后调试子进程,失败+1,not in executable format: File format not recognized。

尝试GDB dumps内存,失败+1,not in executable format: File format not recognized。

GDB Server远程调试,失败+1,not in executable format: File format not recognized。

获取两个不同版本的webadmin.plx文件,进行补丁对比,无差别,失败+1。

查找分析ELF反调试手段,失败+1。

最后得出结论,GDB调试无效,继续接着找其他办法。

梳理一下目前得到的信息:

  1. webadmin.plx负责处理UTM系统登录,页面交互处理等等工作,是一个主体处理文件。
  2. ELF可执行程序,32位。
  3. 可正常执行。
  4. GDB调试无效。
  5. 无反调试。
  6. 补丁对比无效。

若进行安全分析和漏洞挖掘,就必须剁掉webadmin.plx,接着分析吧。

确认Perl 编译器

分析webadmin.plx,查找ELF中的字符串,其中几个字段尤为可疑:

 1a@DESKTOP-22L12IV:Sophos_UTM$ strings webadmin.plx |grep Perl      2psym_Perl_newSVpv                                                                        3psym_Perl_stack_grow                                                                     4psym_Perl_Itmps_floor_ptr                                                                5psym_Perl_sv_setiv                                                                       6psym_Perl_markstack_grow                                                                 7psym_Perl_Iexit_flags_ptr                                                                8psym_Perl_save_int                                                                       9psym_Perl_push_scope                                                                    10psym_Perl_Isv_no_ptr                                                                    11psym_Perl_call_sv                                                                       12psym_Perl_Imarkstack_max_ptr                                                            13psym_Perl_Istack_base_ptr                                                               14psym_Perl_Gop_mutex_ptr                                                                 15psym_Perl_eval_pv                                                                       16psym_Perl_Gthr_key_ptr                                                                  17psym_Perl_call_list                                                                     18psym_Perl_Icurstackinfo_ptr                                                             19psym_Perl_get_context                                                                   20psym_Perl_Guse_safe_putenv_ptr                                                          21psym_Perl_IXpv_ptr                                                                      22psym_Perl_pop_scope    

很明显,跟Perl有很大的关系。

eee26cc6b6edcdd5b1f7945f823d1d78.png

IDA中也显示同样的结果,怀疑该webadmin.plx是由Perl编译出来的,接下来就是验证自己的想法。

搜索引擎中查找资料,发现主流有三款程序可以从Perl代码编译成ELF软件:PerlAPP,PerlCC,Perl2EXE,而针对Perl ELF反编译就只有52破解网站上有一份PerlAPP在Windows下的资料,Linux下的资料一无所有,也是奇葩,Perl越混越差了。

从IDA对webadmin.plx的反编译代码中分析查找,找到一处关键字:

 1 v1 = *(_DWORD *)psym_Perl_Istack_sp_ptr(a1); 2  v2 = (int **)psym_Perl_Imarkstack_ptr_ptr(a1); 3  v3 = **v2; 4  --*v2; 5  v4 = (v1 - (*(_DWORD *)psym_Perl_Istack_base_ptr(a1) + 4 * v3)) >> 2; 6  v18 = sub_804E6EC(); 7  v33 = a1; 8  v34 = psym_Perl_get_hv(a1, "PerlApp::lic", 1); //PerlApp::lic,此处为关键字 9  if ( v4 )10    v19 = *(_DWORD *)(*(_DWORD *)psym_Perl_Istack_base_ptr(a1) + 4 * (v3 + 1));11  else12    v19 = psym_Perl_Isv_undef_ptr(a1);13  v20 = *(int **)(v18 + 48);14  licFree(*(_DWORD *)(v18 + 56));15  *(_DWORD *)(v18 + 56) = 0;

从PerlApp::lic关键字来分析,基本可以确认webadmin.plx是使用PerlAPP编译而成的ELF文件。

问题复现

webadmin.plx确认是由PerlAPP工具编译而来,接下来就来验证一下,在Linux环境下搭建一套PerlAPP环境。

PerlAPP的全称是Perl Dev Kit(PDK),由ActiveState公司开发,但是其已经在2016年不再进行更新维护,在2020年10月份正式终止软件生命周期。

00b7eafbb41b732f3fc1832598d522f6.png

https://www.activestate.com/blog/perl-dev-kit-pdk-now-end-of-life/

软件终止更新还好,影响不大,但网络上Linux版本的PerlAPP非常难找,最终是在一个不起眼的小网站上下载到了低版本的安装包(这又是一个辛酸的故事),进行安装测试。

PerlApp安装需要32位Active Perl(必须),而非操作系统自带的perl,又下载了一个低版本的Active Perl,才算完成PDK的安装(一把辛酸泪)。

d59908da920ac570a07be8e395f08749.png

最后拿一个最简单的perl示例代码来进行测试:

1[test@192 Desktop]$ cat test.pl 2#!/usr/bin/perl 34print "Hello, World!";5[test@192 Desktop]$ perl test.pl 6Hello, World!7[test@192 Desktop]$ 

使用PerlApp进行编译测试:

9d53a08d1727384835816afd00c88994.png

shell中也能够正常执行:

1[test@192 Desktop]$ ./test 2Hello, World! # 正常执行3[test@192 Desktop]$ 

使用GDB调试编译好的程序:

 1[test@192 Desktop]$ gdb test 2GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-119.el7 3Copyright (C) 2013 Free Software Foundation, Inc. 4License GPLv3+: GNU GPL version 3 or later  5This is free software: you are free to change and redistribute it. 6There is NO WARRANTY, to the extent permitted by law.  Type "show copying" 7and "show warranty" for details. 8This GDB was configured as "x86_64-redhat-linux-gnu". 9For bug reporting instructions, please see:10...11"/home/test/Desktop/test": not in executable format: File format not recognized # 同样的报错提示12(gdb) 

好吧,同样的not in executable format: File format not recognized报错提示,完美复刻webadmin.plx遇到的问题。

反编译Perl源码

现在来梳理一下目前的信息:

1. webadmin.plx是使用 PerlApp编译而成的ELF文件

2. 不能使用GDB调试,GDB Server也不行

3. 网络上没有Linux反编译Perl的资料

团队小伙伴ztop(此处应该有掌声)的帮助下,发现使用IDA的linux_server,结合IDA远程调试,就可以完美绕过GDB无法调试的问题。在Centos 7中无法使用IDA远程调试,不知道具体原因是什么,遂放弃,选择使用Kali 2018 R4,IDA的主机为Windows。

 1root@kali:~# chmod +x linux_server 2root@kali:~# ./linux_server 3IDA Linux 32-bit remote debug server(ST) v1.22. Hex-Rays (c) 2004-2017 4Listening on 0.0.0.0:23946... 5========================================================= 6[1] Accepting connection from 192.168.21.1... 7Warning: Section header string table index 26 is out of bounds 8Hello, World! 9Looking for GNU DWARF file at "/usr/lib32/2651bcf6f5569acd1dba629eaaaa5f002af684.debug"... no.10Looking for GNU DWARF file at "/usr/lib32/.debug/2651bcf6f5569acd1dba629eaaaa5f002af684.debug"... no.11[1] Closing connection from 192.168.21.1...12==========================================================

linux_server的监听23946端口,需要在宿主机进行配置。

bbe1440400ee822b931b090ad63ddfde.png

webadmin.plx的main函数中:

 1signed int __cdecl paperl_main(int a1, int a2, int a3, _DWORD *a4, int (__cdecl *a5)(int)) 2{ 3  signed int v5; // ebx 4  int v7; // [esp+10h] [ebp-8h] 5 6  v7 = dword_805B4F8; 7  v5 = paperl_create((int ***)&v7, a1, a2, a3, a4, a5, 1); //此函数内部进行perl 代码执行。 8  paperl_destruct(v7); 9  return v5;10}

进入到paperl_create()函数内部:

1      ptr = sub_804C370(**v43, "*SCRIPTNAME", (int)"scriptname");2        if ( ptr )3        {4          v27 = (int *)sub_804C370(**v43, ptr, (int)"script"); //此函数对perl代码进行初始化5          v43[9] = v27;6          if ( !v27 || (v28 = (char *)sub_804C2D0(strlen(ptr) + 14, (int)"hashline"), (v43[8] = (int *)v28) == 0) )

找到关键代码位置:

 1LOAD:0804E224 jz      loc_804E32E 2LOAD:0804E22A mov     eax, [edi] 3LOAD:0804E22C mov     ecx, offset aScript             ; "script" 4LOAD:0804E231 mov     edx, [ebp+ptr] 5LOAD:0804E237 mov     eax, [eax] 6LOAD:0804E239 call    sub_804C370                    ; 函数执行后,解密出perl代码 7LOAD:0804E23E mov     [edi+24h], eax 8LOAD:0804E241 test    eax, eax 9LOAD:0804E243 jz      loc_804E51710LOAD:0804E249 mov     edx, [ebp+ptr]11LOAD:0804E24F cld12LOAD:0804E250 mov     ecx, 0FFFFFFFFh13LOAD:0804E255 xor     eax, eax

经过一系列的仔细调试和分析,最终发现0804E239 call sub_804C370函数执行后,eax 指向堆的内存中出现了#!/usr/bin/perl字符,

e2731a4dc8f6bffb9fe46bb18246ad49.png

验证它:

16e87c2d1dc1ab5b1508415b27b4f683.png

很明显都是明文字符,dump出来进行校验,获取到完整的webadmin.plx功能的perl源码:

 1# setting line discipline to utf8 -------------------------- 2binmode( STDOUT, ':utf8' ); 3binmode( STDIN, ':utf8' ); 4 5# getting our paths 6my ( $apppath, $appname ) = &get_path_and_appname(); 7 8# load core config ------------------------------------------ 9die '[' . $$ . '] DIED: core configuration could not be found' unless -e $RealBin . '/core/res/config.ph';10my $config_basic = read_ph( $RealBin . '/core/res/config.ph' );11die "Could not read core config in [$RealBin/core/res/config.ph]!" unless $config_basic;1213# fetching application config ------------------------------14die '[' . $$ . '] DIED: application configuration could not be found' unless -l $RealBin . '/config';15my $config_app = read_ph( $RealBin . '/config' );16die "Could not read config for [" . $appname . "] in [" . $RealBin . "/config]!" unless $config_app;1718# initialize Astaro::Logdispatcher -------------------------19Astaro::Logdispatcher->init({20  syslogname      => 'webadmin',21  myname          => 'webadmin',22  redirect_stdout => 0,23  redirect_stderr => 0,24  configfile      => 'core/res/core-log.conf',25  configset       => {26    logvars         => {27      logbitmask       => 7,28      syslogmtypeinfo  => 1,29      syslogcallerinfo => 1,30      tofilehandle     => 031    }32  },33  logfiler        => [34    '+ .',35  ],36  printfile       => '/dev/null'37});

至此完整的获取Sophos UTM webadmin功能的perl源代码,剩余的工作就是基础的代码审计和漏洞挖掘。

梳理总结

Perl编译的ELF文件在执行时,会在/tmp/目录下生成libperl.so文件,perl 代码通过调用so文件接口j来执行,本次调试释放路径是/tmp/pdk-root/757fcfe556133c27007d41e4e52f4425/libperl.so ,也可以通过hook so的函数来达到获取perl源码的目的。

Perl语言编译的ELF文件,如何进行反编译,网络上没有任何有价值的信息,之前对python和go编译的ELF文件都有过反编译经验,按道理来说同样是能够通过反编译来获取源代码,但是GDB无法调试ELF困扰了很长时间,动态获取源码相对于静态去逆向解密算法要简单很多,虽然最后也并不简单。

其中的工作并没有去逆向解密算法,理清楚算法的情况下,可以编写脚本静态还原perl源代码,但以安全分析或漏洞挖掘为目标,算是告一段落了,后续工作也可以编写IDA的python脚本,动态提取源代码。

资料索引

1. demo

https://utm.trysophos.com/

2. 从PDK打包的可执行程序里面解出完整的Perl源码

https://www.52pojie.cn/thread-317216-1-1.html

注意事项

1. VmWare Workstation安装固件ISO需要选择低版本的兼容性,否则无法安装。

2. Active Perl要选择X32位安装包,X64的安装包无法安装PDK。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值