吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 15262|回复: 83
收起左侧

[原创] 某国产“自主”操作系统专属 Electron 应用“移植”

  [复制链接]
chen_null 发表于 2021-1-10 13:15
本帖最后由 chen_null 于 2021-1-10 13:18 编辑

某国产“自主”操作系统专属 Electron 应用“移植”

2020-12-30_16-53.png

最近在 Linux 相关群组内看到某个国产软件给某个国产系统提供了专版应用,这个专版应用在别的系统上都不可以正常运行,但是有老哥发现这个 xxxx 程序读取了 lsb-release, libyyosdevicea.so 和 os-release,在替换这三个文件成 yy 系统的文件之后,就可以直接登陆了...所以我就进行了分析和学习。

自主规避模式,将某操作系统的名字换成了 yy,而某国产软件的名字换成了 xxxx。请不要无端联想。

分析

首先先解压 deb 包,看到的是一个 Electron 程序的正常架构。

~/d/r/u/v2 > tree
.
├── control
├── control.tar.gz
├── data.tar.xz
├── debian-binary
├── md5sums
├── opt
│   └── apps
│       └── com.xxxx
│           ├── entries
│           │   ├── applications
│           │   │   └── com.xxxx.desktop
│           │   ├── doc
│           │   │   └── xxxx
│           │   │       └── copyright
│           │   ├── icons
│           │   │   └── hicolor
│           │   │       ├── 128x128
│           │   │       │   └── apps
│           │   │       │       └── xxxx.png
│           │   │       ├── 16x16
│           │   │       │   └── apps
│           │   │       │       └── xxxx.png
│           │   │       ├── 256x256
│           │   │       │   └── apps
│           │   │       │       └── xxxx.png
│           │   │       ├── 48x48
│           │   │       │   └── apps
│           │   │       │       └── xxxx.png
│           │   │       └── 64x64
│           │   │           └── apps
│           │   │               └── xxxx.png
│           │   ├── lintian
│           │   │   └── overrides
│           │   │       └── xxxx
│           │   └── pixmaps
│           │       └── xxxx.png
│           ├── files
│           │   ├── blink_image_resources_200_percent.pak
│           │   ├── content_resources_200_percent.pak
│           │   ├── content_shell.pak
│           │   ├── icudtl.dat
│           │   ├── libffmpeg.so
│           │   ├── libnode.so
│           │   ├── LICENSES.chromium.html
│           │   ├── locales
│           │   │   ├── zh-CN.pak
│           │   │   └── zh-TW.pak
│           │   ├── natives_blob.bin
│           │   ├── pdf_viewer_resources.pak
│           │   ├── resources
│           │   │   ├── app.asar
│           │   │   ├── electron.asar
│           │   │   ├── sae.dat
│           │   │   └── wcs.node
│           │   ├── snapshot_blob.bin
│           │   ├── ui_resources_200_percent.pak
│           │   ├── version
│           │   ├── views_resources_200_percent.pak
│           │   └── xxxx
│           └── info
├── postinst
├── postrm
├── sign
└── usr
    ├── lib
    │   └── license
    │       └── libyyosdevicea.so
    └── share
        └── doc
            └── com.xxxx
                ├── changelog.Debian.gz
                └── copyright

32 directories, 106 files

这里我们直入正题,看下 opt/apps/com.xxxx/files/ 的 xxxx 文件,发现这个文件有点大,IDA 分析不动...所以就先照着别的老哥说的,看下 opt/apps/com.xxxx/files/resources 下的 app.asar。这个文件直接用 asar e app.asar $解压到的目录 就解压开了。比较关键的是下面的函数,应该是通过 node.js 的 module 进行生成 token,然后将这个 token 塞入 http 请求的头部,然后服务器进行特殊校验就可以判断是否允许通过了。

function getToken() {
    let pathname = path.dirname(__dirname);
        let wcs = require(path.join(pathname, './wcs.node'));
        let kp = path.join(pathname, 'sae.dat');
        let buf = wcs.get_cc_data(1, kp);
        return buf.toString('ascii');
}

function bindToken(session) {
        session.webRequest.onBeforeSendHeaders(
                { urls: urlFilters },
                (details, callback) => {
                        if (details.url.indexOf('/cgi-bin/mmwebxxxx-bin/webxxxxnewloginpage') > -1) {
                                details.requestHeaders['extspam'] = getToken();
                                details.requestHeaders['client-version'] = app.getVersion();
                        }
                }
        );
}

那么现在就去分析下 wcs.node 了。看了下 wcs.node 的 strings 结果,发现没有什么关键的字符串,并且在 lld 的结果中没有发现 libyyosdevicea.so,猜测用了 dlopen 进行动态加载,所以查了下 dlopen 的交叉引用

Direction        Type        Address        Text
Down        p        sub_7B180+31        call    _dlopen
Down        p        sub_800D0+C5        call    _dlopen

然后再看了下 sub_800D0 的引用,发现字符串似乎被加密了

.text:0000000000080189                 lea     rdi, weird_str
.text:0000000000080190                 mov     esi, 2          ; mode
.text:0000000000080195                 call    _dlopen

查了下 weird_str 的交叉引用,看来就是 xor 了下字符串

.text:00000000000845EC                 mov     [rsp+var_8], 0
.text:00000000000845F5                 lea     rax, weird_str
.text:00000000000845FC                 nop     dword ptr [rax+00h]
.text:0000000000084600
.text:0000000000084600 loc_84600:                              ; CODE XREF: sub_844D0+146↓j
.text:0000000000084600                 mov     rcx, [rsp+var_8]
.text:0000000000084605                 xor     byte ptr [rcx+rax], 17h
.text:0000000000084609                 add     rcx, 1
.text:000000000008460D                 mov     [rsp+var_8], rcx
.text:0000000000084612                 cmp     rcx, 21h
.text:0000000000084616                 jb      loc_84600

写个 IDAPython 脚本解密下

import idautils
import idc

def get_str(addr, str_len):
    s = ''
    for i in range(str_len):
        temp = idaapi.get_byte(addr + i)
        if temp == 0:
            break
        s += chr(temp)
    return s

def xor_again(func):
    op, xor_num, str_len = None, None, None
    for curr_addr in idautils.FuncItems(func):
        mnem = idc.print_insn_mnem(curr_addr)
        if mnem == 'lea':
            op = idc.get_operand_value(curr_addr, 1)
        if mnem == 'xor':
            xor_num = idc.get_operand_value(curr_addr, 1)
        if mnem == 'cmp':
            str_len = idc.get_operand_value(curr_addr, 1)
            enc_s = get_str(op, str_len)
            dec_s = ''
            for i in enc_s:
                dec_s += chr(ord(i) ^ xor_num)
            print("%x %x %x %s" % (op, xor_num, str_len, dec_s))

xor_again(0x844D0)

输出如下

49bf60 1 2c Failed to load symbol "get_hddsninfo" : %s.

49bf20 11 13 Failed to load %s.

49bfb0 19 2c Failed to load symbol "yy_get_mb_sn" : %s.

49c100 14 d yy_is_active
49c020 1f 10 yy_get_hwserial
49c140 4 13 basic_string::erase
49bef0 17 21 /usr/lib/license/libyydevicea.so
49c160 17 36 %s: __pos (which is %zu) > this->size() (which is %zu)
49bf8d 1e 7 unknown
49bff0 17 26 Failed to load symbol "get_mac" : %s.

49c0b0 5 14 yy_get_licensetoken
49bf40 1b 11 yy_get_hddsninfo
49bf95 14 d yy_get_mb_sn
49bfdd 1f b yy_get_mac
49c040 6 2f Failed to load symbol "yy_get_hwserial" : %s.

49c070 11 d yy_get_osver
49c0d0 17 2f Failed to load symbol "get_licensetoken" : %s.

49bec0 1d 10 /etc/lsb-release
49c110 7 28 Failed to load symbol "is_active" : %s.

49c080 15 28 Failed to load symbol "get_osver" : %s.

49bedd 14 e DISTRIB_ID=yy
49bed1 2 b DISTRIB_ID=

移植

那目的很明确了,将汇编中指向 0x49bef0(/usr/lib/license/libyydevicea.so) 和 0x49bec0(/etc/lsb-release) 的地方,指向我们自定义的字符串。

借助 Keypatch 就好。

我们先在 .eh_frame 上加上自定义字符串。

.eh_frame:000000000022BC78 yy_new_so      db '/opt/apps/com.xxxx/misc/libyydevicea.so',0
.eh_frame:000000000022BC78                                         ; DATA XREF: sub_800D0:loc_80189↑o
.eh_frame:000000000022BCA6                 db    0
.eh_frame:000000000022BCA7                 db    0
.eh_frame:000000000022BCA8 lsb_new         db '/opt/apps/com.xxxx/misc/lsb-release',0

然后让汇编中指向 0x49bef0 的地方指向新的字符串。

.text:0000000000080189                 lea     rdi, yy_new_so ; "/opt/apps/com.xxxx/misc/libyydevi"...
.text:0000000000080190                 mov     esi, 2          ; mode
.text:0000000000080195                 call    _dlopen

同理

.text:000000000007FD94                 lea     rsi, lsb_new    ; Keypatch modified this from:
.text:000000000007FD94                                         ;   lea rsi, lsb_release
.text:000000000007FD9B                 lea     rdi, [rbp+var_250]
.text:000000000007FDA2                 mov     edx, 8

然后 patch 下 libyydevicea.so

.rodata:000000000000651E ; char filename[]
.rodata:000000000000651E filename        db '/opt/apps/com.xxxx/misc/os-release',0

然后就能登上了...

Patch 结果

~/d/r/u/v/o/a/c/f/resources > radiff2 -u wcs.node wcs.node.bak                       
-0x0007fd97:0d bf 1a  "\r\xbf\x1a"
+0x0007fd97:25 c1 41  "%\xc1A"
-0x0008018c:e8 ba 1a  "\xe8\xba\x1a"
+0x0008018c:60 bd 41  "`\xbdA"
-0x0022bc78:2f 6f 70 74 2f 61 70 70 73 2f 63 6f 6d 2e 71 71 2e 77 65 69 78 69 6e 2f 6d 69 73 63 2f 6c 69 62 75 6f 73 64 65 76 69 63 65 61 2e 73 6f 00 00 00 2f 6f 70 74 2f 61 70 70 73 2f 63 6f 6d 2e 71 71 2e 77 65 69 78 69 6e 2f 6d 69 73 63 2f 6c 73 62 2d 72 65 6c 65 61 73 65 00  "/opt/apps/com.xxxx/misc/libyydevicea.so"
+0x0022bc78:14 00 00 00 00 00 00 00 01 7a 52 00 01 78 10 01 1b 0c 07 08 90 01 00 00 24 00 00 00 1c 00 00 00 e8 b5 e4 ff 50 36 00 00 00 0e 10 46 0e 18 4a 0f 0b 77 08 80 00 3f 1a 3b 2a 33 24 22 00 00 00 00 14 00 00 00 44 00 00 00 10 ec e4 ff a8 00 00 00 00 00 00 00 00 00 00 00 1c  "\x14"
~/d/r/u/v/o/a/c/misc > radiff2 -u libyydevicea.so libyydevicea.so.bak
-0x0000651f:6f 70 74  "opt/apps/com.xxxx/misc/os-release"
+0x0000651f:65 74 63  "etc/os-release"
-0x00006523:61 70 70 73 2f 63 6f 6d 2e 71 71 2e 77  "apps/com.xxxx/misc/os-release"
+0x00006523:6f 73 2d 72 65 6c 65 61 73 65 00 6f 70  "os-release"
-0x00006531:69 78 69 6e 2f 6d 69 73 63 2f  "ixin/misc/os-release"
+0x00006531:6e 20 6f 73 20 76 65 72 73 69  "n os version file error"
-0x0000653c:73 2d 72 65  "s-release"
+0x0000653c:6e 20 66 69  "n file error"
-0x00006542:61 73 65 00 00 00  "ase"
+0x00006542:20 65 72 72 6f 72  " error"

其他所需文件请前往AUR自行下载。

免费评分

参与人数 29威望 +1 吾爱币 +44 热心值 +25 收起 理由
rubnet + 1 谢谢@Thanks!现在失效了吗?登录返回 <error><ret>1203</ret>.
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
66099 + 1 + 1 用心讨论,共获提升!
挖掘机小王子 + 1 我很赞同!
VonLee + 1 + 1 终于可以不用Crossover的微信了
我不管我最帅 + 1 我很赞同!
Jack2002 + 1 + 1 牛B!
蜉蝣天地 + 1 我很赞同!
我真的很狂哦 + 1 + 1 谢谢@Thanks!
plasd + 1 + 1 谢谢@Thanks!
 + 1 + 1 我很赞同!
zhangyazhou + 1 + 1 谢谢@Thanks!
victos + 1 + 1 谢谢@Thanks!
lvyiwuhen + 1 + 1 热心回复!
woyucheng + 1 + 1 谢谢@Thanks!
wxcnbm + 1 + 1 我很赞同!
paradisewing + 1 + 1 我很赞同!
刚柔并济 + 1 + 1 热心回复!
塞活 + 1 + 1 谢谢@Thanks!
longling + 1 + 1 用心讨论,共获提升!
TSF + 1 + 1 用心讨论,共获提升!
zjun777 + 1 用心讨论,共获提升!
dadake + 1 我很赞同!
Dingjiale + 1 + 1 热心回复!
Nicer + 1 + 1 谢谢@Thanks!
WoShiXXX + 1 + 1 用心讨论,共获提升!
江夜CC + 1 鼓励转贴优秀软件安全工具和文档!
yissai + 1 + 1 我很赞同!
cgj08 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

networkdwl 发表于 2021-1-11 09:06
本帖最后由 networkdwl 于 2021-1-12 10:11 编辑

统信,就是基于debian修改的,居然还收费,违背了开源协议。
补充,我知道开源的概念…印象中基于开源的产品也要开源,产品免费,服务可以收费,redhat系统是免费的。服务收费而已。水平足够高可以利用他们开放的源码自己编译。而统信是直接收费。不知道我说的对不对。

免费评分

参与人数 1吾爱币 +1 收起 理由
钢铁侠_123 + 1 不光收费违背,开源产品,修改后商用的话,也必须开源的,这些打着自主研发.

查看全部评分

钢铁侠_123 发表于 2021-1-10 15:22
wait4wuai 发表于 2021-1-10 14:32
wwwlailailai 发表于 2021-1-10 14:43
感谢分享
cqj82815 发表于 2021-1-10 14:44
这个太牛了
列明 发表于 2021-1-10 14:47
系統是又笨土,
應用是喂饞他,
破案了。
DYTRemix 发表于 2021-1-10 15:09
我去, 大佬牛逼, 学习了
c1anc9 发表于 2021-1-10 15:42
感谢楼主分享
KBCHEN 发表于 2021-1-10 15:44
感谢楼主分享
zhangyang580 发表于 2021-1-10 17:36
感谢大佬牛逼, 学习了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-24 04:06

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表