AlgoSec破解license

来源:互联网 发布:守望先锋游戏数据查询 编辑:程序博客网 时间:2024/05/29 04:39

AlgoSec是防火墙规则审计的好工具。但是其license奇贵无比,一个防火墙的license动辄几万人民币。所以如果想试用的话,需要进行破解。

1. 查找关键文件

一开始我也不知道破解的入口在哪里。大胆猜测,在服务器上以关键字license和lic进行查找,发现了以下文件:/usr/share/fa/bin/install_lic_cli。运行一下,结果为:

[root@localhost afa]# /usr/share/fa/bin/install_lic_cli
Error: Please provide license file.
Usage: install_lic_cli -file

看来这个就是安装license的程序,查看一下,发现已经被加密了:

[root@localhost afa]# cat /usr/share/fa/bin/install_lic_cli
#!/usr/bin/perl
use algoenc;
b畞疙}Rb纄J屒忲v甗U慥皳eEu{侮卍慸线yG销I踹r龠睭榝3圲u熓曕龢碥[臙鷔蜹窾兞”敨翡迧bx砍[x潚’f雪in纍 [W瓘〉fb蹃!$襣羒z綅澋.瘱鏦闻B唼遫w齙iik鶤1……

是否加密了我们就无计可施了呢?并不是的,这是一个perl脚本,而perl具有调试功能,从而让我们看到解密后的程序。调试时,n为单步运行,s为步入函数内部,q为退出。
随便写一个文件作为license,单步运行到第52、53行时发现:

[root@localhost afa]# perl -d /usr/share/fa/bin/install_lic_cli -file test.lic
……
main::(/usr/share/fa/bin/install_lic_cli:52):
52: my $fa_server = FwaUtil::which_script(“fa_server”);
DB<1> n
main::(/usr/share/fa/bin/install_lic_cli:53):
53: my $sCMD = “$fa_server -f LICENSE install $lic_path”;

查找了一下,服务器上确实有fa_server这个文件。这还是一个加密了的perl脚本,单步运行一下就发现:

[root@localhost afa]# perl -d /usr/share/fa/bin/fa_server -f LICENSE install test.lic
……
FwaLic::CODE(0xa0dbab8)(/usr/share/fa/perl_lib/FwaLic.pm:78):

查看一下FwaLic.pm,这次没有加密。代码比较多就不贴了,关键有两点:

  • 这一行,校对fa_usage这个文件的MD5:

    %md5sig = ( fa_usage => ‘1ef898e850586874af2d37405b5561b9’,

  • 这几行,说明fa_usage就是用来验证和安装license的:

    # check if defined a license file name (= it was sent)
    # then we will send it to fa_usage with -v to check
    # that given license file name is valid
    if (defined $license_file_name)
    {
    $lic_param = “-v $license_file_name”;
    }

再查看一下,发现fa_usage是一个二进制文件,因此关键在于如何破解该文件。

2. 反编译寻找绕过方式

反编译Linux文件可以用objdump,我们把概要信息和完整的反编译结果都生成出来:

objdump -x /usr/share/fa/bin/fa_usage > fa_usage_info.txtobjdump -D /usr/share/fa/bin/fa_usage > fa_usage.txt

注意fa_usage_info.txt中的SYMBOL TABLE

08052200 w .data 00000000 data_start
00000000 F UND 00000149 fputs@@GLIBC_2.0
00000000 F UND 0000001d __errno_location@@GLIBC_2.0
080502e9 g F .text 00000177 lic_sign_file_internal
00000000 F UND 00000034 sprintf@@GLIBC_2.0
00000000 F UND 0000008d popen@@GLIBC_2.1
00000000 F UND 0000007a open@@GLIBC_2.0
00000000 F UND 00000076 creat@@GLIBC_2.0
0804fe86 g F .text 000000ce lic_load_file_to_ctx
08050590 g F .text 00000005 __libc_csu_fini
08048e00 g F .text 00000000 _start
0804b82d g F .text 000000ff allow_init_license
0804fd0e g F .text 00000178 lic_parse_file_stream
0804dcef g F .text 00000091 lic_print_error
0804cfa0 g F .text 0000005e add_to_list
0804cffe g F .text 0000000a get_head_list
00000000 w UND 00000000 __gmon_start__
00000000 w UND 00000000 _Jv_RegisterClasses
08050654 g O .rodata 00000004 _fp_hw
0804da51 g F .text 0000006d parse_mac_address
0804e8bf g F .text 00000359 SHA1ProcessMessageBlock
0804e7e4 g F .text 000000db SHA1Input
00000000 F UND 00000167 strchr@@GLIBC_2.0
08050638 g F .fini 00000000 _fini
0804fc4e g F .text 000000c0 validate_all_fields_exist
00000000 F UND 0000033c calloc@@GLIBC_2.0
00000000 F UND 000000a7 strncpy@@GLIBC_2.0
00000000 F UND 0000007a write@@GLIBC_2.0
0804aa22 g F .text 00000545 log_init
00000000 F UND 00000037 toupper@@GLIBC_2.0
00000000 F UND 00000171 fgets@@GLIBC_2.0
00000000 F UND 0000003d rename@@GLIBC_2.0
08050460 g F .text 00000029 lic_sign_file
0804ff54 g F .text 00000294 copy_and_sign_file
00000000 F UND 0000019f __libc_start_main@@GLIBC_2.0
08052280 g O .data 0000006c ERROR_STRINGS
00000000 F UND 000001b9 strrchr@@GLIBC_2.0
00000000 F UND 0000003d chmod@@GLIBC_2.0
00000000 F UND 0000012e __assert_fail@@GLIBC_2.0
0804db83 g F .text 00000095 lic_free_ctx
0804d078 g F .text 0000004d lfalic
00000000 F UND 0000007a read@@GLIBC_2.0
00000000 F UND 00000197 perror@@GLIBC_2.0
0804cec0 g F .text 00000094 initnode
0804de40 g F .text 000001ae lic_check
0804c48d g F .text 00000564 write_lic_ids
0804d38b g F .text 00000111 str_to_long
08050658 g O .rodata 00000004 _IO_stdin_used
00000000 F UND 0000003d gettimeofday@@GLIBC_2.0
00000000 F UND 00000046 strtol@@GLIBC_2.0
00000000 F UND 000001b1 free@@GLIBC_2.0
0804f6ca g F .text 0000022a lic_parse_key_value
0804f0d5 g F .text 000000d3 parse_version
08049ef0 g F .text 00000b32 write_log
00000000 F UND 0000003d access@@GLIBC_2.0
08052200 g .data 00000000 __data_start
00000000 F UND 0000002b mkstemp@@GLIBC_2.0
00000000 F UND 0000003f ioctl@@GLIBC_2.0
0804dde4 g F .text 0000005a lic_perror
00000000 F UND 0000003c socket@@GLIBC_2.0
00000000 F UND 0000003c __ctype_b_loc@@GLIBC_2.3
0804d49c g F .text 000005b5 parse_vendor_string
00000000 F UND 000001e8 fclose@@GLIBC_2.1
00000000 F UND 0000003c mktime@@GLIBC_2.0
0804cf54 g F .text 0000004c searchname
0804e28f g F .text 000000b7 begin_mac_address_iterator
08052340 g O .bss 00000004 stderr@@GLIBC_2.0
0804e49e g F .text 0000008c end_mac_address_iterator
00000000 F UND 00000032 fopen@@GLIBC_2.1
00000000 F UND 00000039 unlink@@GLIBC_2.0
0804f4be g F .text 0000009f parse_issuer
0804dac0 g F .text 000000c3 lic_alloc_ctx
0805065c g O .rodata 00000000 .hidden __dso_handle
0804b17c g F .text 0000038f calc_checksum_read
00000000 F UND 0000009a feof@@GLIBC_2.0
00000000 F UND 00000022 strcpy@@GLIBC_2.0
0805200c g O .dtors 00000000 .hidden __DTOR_END__
0804edb1 g F .text 00000165 parse_date
080505a0 g F .text 00000069 __libc_csu_init
00000000 F UND 00000039 printf@@GLIBC_2.0
0804bdf9 g F .text 00000385 check_ids_validity
00000000 F UND 0000001b ctime@@GLIBC_2.0
0804e346 g F .text 00000158 next_mac_address
00000000 F UND 0000002b atoi@@GLIBC_2.0
0804e52a g F .text 0000020d lic_print_ctx
0804dd80 g F .text 00000064 lic_println_error
080501e8 g F .text 00000101 create_tmp_output_file_path
0804e738 g F .text 00000068 SHA1Reset
0804ed60 g F .text 00000051 parse_hex_digit
08052300 g O .data 00000030 MONTH_LIST
0804bc42 g F .text 00000119 install_license
0804dfee g F .text 0000011b lic_check_basic
00000000 F UND 0000006f close@@GLIBC_2.0
0804bd5b g F .text 0000009e check_if_license_exists
0804f353 g F .text 0000016b parse_host_id
00000000 F UND 0000015f fwrite@@GLIBC_2.0
00000000 F UND 00000024 fprintf@@GLIBC_2.0
00000000 F UND 00000192 strstr@@GLIBC_2.0
00000000 F UND 00000020 time@@GLIBC_2.0
0804d008 g F .text 0000000a get_list_len
0804f1a8 g F .text 000000e6 parse_exp_date
08052338 g ABS 00000000 __bss_start
00000000 F UND 000001c3 malloc@@GLIBC_2.0
0804af67 g F .text 00000130 cp_files
0804f55d g F .text 0000016d parse_license_info
0804b097 g F .text 000000e5 split_buffer
00000000 F UND 000000f6 fputc@@GLIBC_2.0
0804d012 g F .text 00000065 print_list
0804dc18 g F .text 000000d7 lic_strerror_r
0804ef16 g F .text 000001bf parse_sign
0805258c g O .bss 00000004 full_license_name
08050489 g F .text 00000029 lic_sign_file_forced
0804bb9f g F .text 000000a3 get_lic_path
08049cd9 g F .text 00000215 validate_dates
0804d0c5 g F .text 000002c6 lfalic_lic
00000000 F UND 000001aa strcat@@GLIBC_2.0
0804e1b4 g F .text 000000db get_mac_address_for_interface
00000000 F UND 000000b0 __xpg_strerror_r@@GLIBC_2.3.4
08052590 g ABS 00000000 _end
08052344 g O .bss 00000004 stdout@@GLIBC_2.0
0804e7a0 g F .text 00000044 SHA1Result
0804c17e g F .text 0000030f read_lic_ids
00000000 F UND 000000ae strspn@@GLIBC_2.0
00000000 F UND 00000034 sscanf@@GLIBC_2.0
00000000 F UND 00000024 fscanf@@GLIBC_2.0
0804ec18 g F .text 00000147 SHA1PadMessage
00000000 F UND 0000003f lseek@@GLIBC_2.0
0804f8f4 g F .text 0000035a lic_parse_line
0804b92c g F .text 00000273 check_license_date
08052338 g ABS 00000000 _edata
0804993f g F .text 0000039a print_license
0804f28e g F .text 000000c5 parse_issued
00000000 F UND 000000ae strcspn@@GLIBC_2.0
00000000 F UND 00000057 strdup@@GLIBC_2.0
08048ed4 g F .text 00000a6b read_log
00000000 F UND 00000037 tolower@@GLIBC_2.0
00000000 F UND 00000025 strcmp@@GLIBC_2.0
0804e109 g F .text 000000ab lic_check_mac_address
00000000 F UND 000000f4 exit@@GLIBC_2.0
080504b2 g F .text 000000cf lic_validate_signature
00000000 F UND 00000023 pclose@@GLIBC_2.1
0804b50b g F .text 00000322 write_checksum
08050609 g F .text 00000000 .hidden __i686.get_pc_thunk.bx
0804cbe8 g F .text 000002d8 main
0804c9f1 g F .text 000001f5 write_majic
08048a58 g F .init 00000000 _init

这里就是fa_usage中的各个子函数及其入口地址,带lic字样的就是和license相关的。我们在fa_usage.txt中查看这些函数的反编译结果,就能找到破解方法。
假如你看过我之前的一篇文章X-Pack破解试用就知道,一般license文件都会带签名,我们只要能绕过验签环节,就能以最小的改动进行破解。于是,lic_validate_signature这个函数吸引了我的注意力。我猜测这个函数就是比对license签名和根据license计算出的签名的函数。根据反编译结果,一个返回值是$0x0,另一个是$0x16。我们不妨假设$0x0表示一致,使其始终返回$0x0。如果猜错了,使其始终返回$0x16即可。

3. 破解

这部分涉及的汇编语句为:

8050562: c7 45 ec 16 00 00 00 movl $0x16,0xffffffec
8050569: eb 11 jmp 805057c
805056b: 83 45 fc 01 addl $0x1,0xfffffffc
805056f: 83 7d fc 01 cmpl $0x1,0xfffffffc
8050573: 7e d5 jle 805054a
8050575: c7 45 ec 00 00 00 00 movl $0x0,0xffffffec
805057c: 8b 45 ec mov 0xffffffec,%eax
805057f: c9 leave
8050580: c3 ret

注意8050562和8050575两行,对应的十六进制值为c7 45 ec 16 00 00 00c7 45 ec 00 00 00 00。我们将fa_usage用十六进制编辑器打开,例如Notepad++的插件HexEditor。然后查找c7 45 ec 16 00 00 00,通过上下文确认无误,将其改为c7 45 ec 00 00 00 00,保存即可。
用破解后的fa_usage替换原文件,用破解后fa_usage的新MD5值替换FwaLic.pm中的旧MD5值。然后再准备一个狂拽酷炫吊炸天的license文件:

LICENSE_VER=7.0
EXP_DATE=15-sep-2017
HOSTID=E505250101F7
ISSUER=root
ISSUED=01-May-2017
LICENSE_INFO1=PerFW;3;mvpboss1004;88888888
LICENSE_INFO2=Core;Optimization;Risk
SIGN=1234567890abcdef

这就是一个licenseID为88888888、可用于3个防火墙、于2017年9月1日到期、授予mvpboss1004的license。注意这里HOSTID要改为服务器的MAC地址,ISSUED不要离当前日期超过5天。

5. 升级注意事项

显然,升级后需要重新破解。除此之外还需要以下操作:

  • 破解完后要重启服务,或直接重启系统;
  • 要重新导入license,其中licenseID和SIGN要改的和原来不一样,ISSUED要改成当天时间
0 0