DIR-882路由固件加解密

百家 作者:Chamd5安全团队 2021-10-17 08:38:09

固件下载

下载固件https://support.dlink.com/resource/PRODUCTS/DIR-882/REVA/DIR-882_REVA_FIRMWARE_v1.10B02.zip,这里下载的版本为DIR-882

解压缩可以看到给了两个版本一个为加密版,一个为未加密版。

加密版

未加密版

固件解包

对未加密的版本进行解包

binwalk?-Me?DIR882A1_FW104B02_Middle_FW_Unencrypt.bin

_DIR882A1_FW104B02_Middle_FW_Unencrypt.bin.extracted/_A0.extracted/_8AB758.extracted/cpio-root目录下可以看到目录结构

$?tree?-d?.
.
├──?bin
├──?dev
│???└──?pts
├──?etc
├──?etc_ro
│???├──?l7-protocols
│???│???├──?not_commit
│???│???└──?untested
│???├──?lighttpd
│???│???├──?lib
│???│???└──?www
│???│???????└──?web
│???│???????????├──?captcha
│???│???????????├──?config
│???│???????????│???└──?deviceinfo
│???│???????????├──?css
│???│???????????├──?hnap
│???│???????????├──?HNAP1
│???│???????????├──?image
│???│???????????├──?info
│???│???????????└──?js
│???│???????????????├──?bootstrap
│???│???????????????│???├──?css
│???│???????????????│???└──?js
│???│???????????????├──?ClientList
│???│???????????????├──?configuration
│???│???????????????├──?ipv6
│???│???????????????├──?localization
│???│???????????????├──?SOAP
│???│???????????????└──?wizard
│???├──?linuxigd
│???├──?onetouch
│???│???└──?scripts
│???├──?ppp
│???│???├──?3g
│???│???├──?peers
│???│???└──?plugins
│???├──?usb
│???├──?web
│???├──?wifi
│???├──?Wireless
│???│???├──?iNIC
│???│???├──?RT2860AP
│???│???├──?RT2870STA
│???│???├──?RT61AP
│???│???└──?WIFI3
│???├──?wlan
│???└──?xml
├──?home
├──?lib
│???├──?firmware
│???├──?ipsec
│???└──?modules
│???????└──?3.10.14+
│???????????└──?kernel
│???????????????└──?net
│???????????????????├──?ipv4
│???????????????????│???└──?netfilter
│???????????????????├──?nat
│???????????????????│???└──?hw_nat
│???????????????????└──?netfilter
├──?media
├──?mnt
├──?private
├──?proc
├──?sbin
├──?share
│???├──?man
│???│???├──?man1
│???│???├──?man5
│???│???└──?man8
│???└──?udhcpc
├──?sys
├──?tmp
├──?usr
│???├──?bin
│???├──?codepages
│???├──?lib
│???│???└──?pppd
│???│???????└──?2.4.5
│???├──?local
│???│???└──?ssl
│???└──?sbin
├──?var
└──?www
????├──?rsstest
????├──?rssui
????│???├──?img
????│???└──?public
????└──?tmp?->?/var/tmp

90?directories

寻找解密点

  • 尝试在后端lighttpd中寻找相关字符串。

    $?sudo?find?.?-name?"*httpd*"?|?xargs?strings?|?grep?"firm"
    strings:?Warning:?'./etc_ro/lighttpd'?is?a?directory

    没有找到。

  • 尝试在CGI中寻找相关字符串。

    $?sudo?find?.?-name?"*cgi*"?|?xargs?strings?|?grep?"firm"
    /tmp/firmware.img
    /bin/imgdecrypt?/tmp/firmware.img
    /tmp/firmware.img
    mtd_write?-r?-w?write?/tmp/firmware.img?Kernel?&
    rm?/tmp/firmware.img
    rm?/tmp/.firmware.orig
    wget?-O?%s?"http://wrpd.dlink.com/router/firmware/query.aspx?model=%s_%s_%s_FW_%s_%s"
    rm?-f?/tmp/firmware.img?&
    http://wrpd.dlink.com/router/firmware/query.aspx?model=%s_%s_%s_FW_%s_%s
    /tmp/firmware.img
    /bin/imgdecrypt?/tmp/firmware.img
    /tmp/firmware.img
    mtd_write?-r?-w?write?/tmp/firmware.img?Kernel?&
    rm?/tmp/firmware.img
    rm?/tmp/.firmware.orig
    wget?-O?%s?"http://wrpd.dlink.com/router/firmware/query.aspx?model=%s_%s_%s_FW_%s_%s"
    rm?-f?/tmp/firmware.img?&
    http://wrpd.dlink.com/router/firmware/query.aspx?model=%s_%s_%s_FW_%s_%s

    可以看到之中存在/bin/imgdecrypt,疑似解密的文件。

分析程序

$?file?imgdecrypt?
imgdecrypt:?ELF?32-bit?LSB?executable,?MIPS,?MIPS32?rel2?version?1?(SYSV),?dynamically?linked,?interpreter?/lib/ld-uClibc.so.0,?stripped

可以看出此程序解密程序

int?__fastcall?decrypt_firmare(int?a1,?int?a2)
{
??int?result;?//?$v0
??const?char?*v3;?//?[sp+18h]?[-1Ch]
??int?i;?//?[sp+1Ch]?[-18h]
??int?aes_key[5];?//?[sp+20h]?[-14h]?BYREF

??qmemcpy(aes_key,?"0123456789ABCDEF",?16);?????//?aes_en_key
??v3?=?"/etc_ro/public.pem";
??i?=?-1;
??if?(?a1?>=?2?)
??{
????if?(?a1?>=?3?)
??????v3?=?*(const?char?**)(a2?+?8);
????if?(?sub_40215C((int)v3,?0)?)???????????????//?检查证书
????{
??????result?=?-1;
????}
????else
????{
??????sub_402554((int)aes_key);?????????????????//?aes加密
??????printf("key:");
??????for?(?i?=?0;?i?<?16;?++i?)
????????printf("%02X",?*((unsigned?__int8?*)aes_key?+?i));//?C05FBF1936C99429CE2A0781F08D6AD8
??????puts("\r");
??????i?=?sub_401780(*(_DWORD?*)(a2?+?4),?(int)"/tmp/.firmware.orig",?(int)aes_key);//?解密函数
??????if?(?!i?)
??????{
????????unlink(*(_DWORD?*)(a2?+?4));
????????rename("/tmp/.firmware.orig",?*(_DWORD?*)(a2?+?4));
??????}
??????RSA_free(dword_4131C0);???????????????????//?RSA?对象地址
??????result?=?i;
????}
??}
??else
??{
????printf("%s?<sourceFile>\r\n",?*(const?char?**)a2);
????result?=?-1;
??}
??return?result;
}

sub_402554函数分析

int?__fastcall?sub_40108C(int?a1,?int?a2,?int?a3,?int?*a4,?int?a5)
{
??int?v5;?//?$a0
??int?v6;?//?$v1
??int?v7;?//?$v0
??char?v9[244];?//?[sp+24h]?[-108h]?BYREF
??int?v10[5];?//?[sp+118h]?[-14h]?BYREF
??int?v12;?//?[sp+134h]?[+8h]

??v12?=?a2?+?(1?-?(a2?&?0xF))?*?((a2?&?0xF)?!=?0);
??AES_set_decrypt_key(a3,?128,?v9);
??v5?=?a4[1];
??v6?=?a4[2];
??v7?=?a4[3];
??v10[0]?=?*a4;
??v10[1]?=?v5;
??v10[2]?=?v6;
??v10[3]?=?v7;
??AES_cbc_encrypt(a1,?a5,?v12,?v9,?v10,?0);
??return?0;
}

sub_401780函数分析

int?__fastcall?sub_401780(int?file,?int?a2,?int?aes_key)
{
??int?file_fp;?//?[sp+20h]?[-108h]
??int?v5;?//?[sp+24h]?[-104h]
??_DWORD?*v6;?//?[sp+28h]?[-100h]
??int?v7;?//?[sp+2Ch]?[-FCh]
??int?file_size;?//?[sp+30h]?[-F8h]
??int?v9;?//?[sp+34h]?[-F4h]
??int?i;?//?[sp+38h]?[-F0h]
??int?v11;?//?[sp+3Ch]?[-ECh]
??int?v12;?//?[sp+40h]?[-E8h]
??int?v13;?//?[sp+44h]?[-E4h]
??_DWORD?*firmware_fp;?//?[sp+48h]?[-E0h]
??char?firmware_de[68];?//?[sp+4Ch]?[-DCh]?BYREF
??int?file_buf[38];?//?[sp+90h]?[-98h]?BYREF

??file_fp?=?-1;
??v11?=?-1;
??v5?=?-1;
??v6?=?0;
??v7?=?0;
??file_size?=?-1;
??v9?=?-1;
??memset(firmware_de,?0,?64);
??v12?=?0;
??v13?=?0;
??memset(file_buf,?0,?sizeof(file_buf));
??firmware_fp?=?0;
??if?(?!stat(file,?file_buf)?)
??{
????file_size?=?file_buf[13];
????file_fp?=?open(file,?0);
????if?(?file_fp?>=?0?)
????{
??????v6?=?(_DWORD?*)mmap(0,?file_size,?1,?1,?file_fp,?0);//?固件映射到内存
??????if?(?v6?)
??????{
????????v11?=?open(a2,?0x102);
????????if?(?v11?>=?0?)
????????{
??????????v9?=?file_size;
??????????if?(?file_size?-?1?==?lseek(v11,?file_size?-?1,?0)?)//?比较写入内存文件和固件文件的大小
??????????{
????????????write(v11,?&unk_402E8C,?1);
????????????close(v11);
????????????v11?=?open(a2,?0x102);
????????????v7?=?mmap(0,?v9,?3,?1,?v11,?0);?????//?以加密固件大小将待解密的固件映射到内存
????????????if?(?v7?)
????????????{
??????????????firmware_fp?=?v6;
??????????????if?(?sub_400C40((int)v6)?)????????//?判断固件开头是否为'SHRS'
??????????????{
????????????????v12?=?htonl(firmware_fp[2]);????//?13265600
????????????????v13?=?htonl(firmware_fp[1]);????//?13265595
????????????????sub_400C94((int)(firmware_fp?+?0x1B7),?v12,?(int)firmware_de);//?从偏移0x6DC计算长度为1326560的SHA512,这里反编译错误($v0+0x6dc)
????????????????if?(?!memcmp(firmware_de,?firmware_fp?+?0x27,?64)?)//?比较消息摘要,这里反编译错误($v0+0x9c)
????????????????{
??????????????????aes((int)(firmware_fp?+?0x1B7),?v12,?aes_key,?firmware_fp?+?3,?v7);//?aes?解密,key为偏移0xC处,这里反编译错误($v0+0xc)
??????????????????sub_400C94(v7,?v13,?(int)firmware_de);//?计算解密后的消息摘要
??????????????????if?(?!memcmp(firmware_de,?firmware_fp?+?0x17,?64)?)//?这里反编译错误($v0+0x5c)
??????????????????{
????????????????????sub_400D34(v7,?v13,?aes_key,?(int)firmware_de);//?计算解密固件+aes_key的SHA512
????????????????????if?(?!memcmp(firmware_de,?firmware_fp?+?7,?0x40)?)//?这里反编译错误($v0+0x1c)
????????????????????{???????????????????????????//?rsa验证摘要
??????????????????????if?(?sub_400E88((int)(firmware_fp?+?0x17),?64,?(int)(firmware_fp?+?0xB7),?0x200)?==?1?)//?这里反编译错误($v0+0x2dc)
??????????????????????{
????????????????????????if?(?sub_400E88((int)(firmware_fp?+?0x27),?64,?(int)(firmware_fp?+?0x137),?0x200)?==?1?)//?这里反编译错误($v0+0x4dc)
??????????????????????????v5?=?0;
????????????????????????else
??????????????????????????v5?=?-1;
??????????????????????}
??????????????????????else
??????????????????????{
????????????????????????v5?=?-1;
??????????????????????}
????????????????????}
????????????????????else
????????????????????{
??????????????????????puts("check?sha512?vendor?failed\r");
????????????????????}
??????????????????}
??????????????????else
??????????????????{
????????????????????printf("check?sha512?before?failed?%d?%d\r\n",?v13,?v12);
????????????????????for?(?i?=?0;?i?<?64;?++i?)
??????????????????????printf("%02X",?(unsigned?__int8)firmware_de[i]);
????????????????????puts("\r");
????????????????????for?(?i?=?0;?i?<?64;?++i?)
??????????????????????printf("%02X",?*((unsigned?__int8?*)firmware_fp?+?i?+?92));
????????????????????puts("\r");
??????????????????}
????????????????}
????????????????else
????????????????{
??????????????????puts("check?sha512?post?failed\r");
????????????????}
??????????????}
??????????????else
??????????????{
????????????????puts("no?image?matic?found\r");
??????????????}
????????????}
??????????}
????????}
??????}
????}
??}
??if?(?v6?)
????munmap(v6,?file_size);
??if?(?v7?)
????munmap(v7,?v9);
??if?(?file_fp?>=?0?)
????close(file_fp);
??if?(?file_fp?>=?0?)
????close(file_fp);
??return?v5;
}

反编译错误分析,函数sub_400C94,其余函数同理

.text:00401AF4                 lw      $gp, 0x128+var_110($sp)
.text:00401AF8 sw $v0, 0x128+var_E4($sp)
.text:00401AFC lw $v0, 0x128+firmware_fp($sp)
.text:00401B00 nop
.text:00401B04 addiu $v1, $v0, 0x6DC ; $v1为参数,$v0存放firmware_fp,所以应为(firmware_fp+0x6DC)
.text:00401B08 addiu $v0, $sp, 0x128+firmware_de

解密

对程序进行仿真运行

$?cp?/usr/bin/qemu-mipsel-static?.
$?sudo?chroot?.?./qemu-mipsel-static?/bin/sh

运行解密程序

#?./bin/imgdecrypt?/home/DIR882A1_FW110B02.bin

查看解密效果

$?sudo?binwalk?DIR882A1_FW110B02.bin

可以看到成功解密

参考链接

  • 加密固件之依据老固件进行解密

  • Breaking the D-Link DIR3060 Firmware Encryption

end


招新小广告

ChaMd5?Venom?招收大佬入圈

新成立组IOT+工控+样本分析?长期招新

欢迎联系admin@chamd5.org



关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接