- 개요
여러 종류의 D-Link 제품에서 ping test 기능 사용 시 인증되지 않은 사용자의 명령어 삽입이 가능하여 Command Injection 취약점이 발생합니다.
- 취약한 버전
- All Lastest Firmware
DIR-655, DIR-866L, DIR-652, DIR-855L, DIR-862L, DIR-615, DIR-835, DIR-825, DHP-1565, DAP-1533
- 취약점 설명 및 분석
ping test 기능은 아래와 같은 페이지에서 요청할 수 있습니다. 아래 페이지는 admin으로 로그인해야 접근할 수 있는 페이지 입니다.
ping test 기능을 요청할 시 발생하는 요청 패킷 입니다. 아래와 같이 action과 ping_ipaddr이라는 파라미터를 사용해
기능 설정 및 ping을 보낼 host를 설정하는 것을 확인할 수 있습니다.
D-Link 제품 같은 경우 cgi페이지를 www/cgi/ssi binary안에서 처리하게 됩니다.
ssi binary에서는 요청 받은 파일명을 검사해 해당 파일명에 맞는 로직으로 jmp하여 cgi와 같은 기능을 처리하게 됩니다.
먼저 HTTP 요청을 파싱해서 처리하는 함수는 do_ssc() 입니다. 로직을 살펴보면 current_user(login 성공 시 설정되는 id 값)와 user_username의 base64_encode된 값과 비교하는 것을 볼 수 있습니다. 두 개의 값이 같다면 loc_408a94로 jmp하게 됩니다.
jmp 되는 로직은 접속한 계정이 admin이 아닐 경우 error.asp로 반환하기 위한 로직입니다.
취약점은 위의 로직에서 발생하게 됩니다. current_user == base64(user_username) 이어야만 아래 로직으로 jmp하게 되는데 결국 로그인 계정이 base64(user_username)과 같지만 않으면 정상적으로 나머지 코드가 진행되게 됩니다.
두 값이 같지 않다면 아래 로직으로 이동하게 되고 action에 대한 값을 query_vars()로 처리하게 됩니다.
존재하는 action이라면 아래 로직에서 action을 처리하도록 합니다.
존재하지 않는 action이라면 아래 로직에서 error.asp를 반환하게 됩니다.
즉, 인증되지 않은 사용자라도 존재하는 action을 요청했을 때 정상적으로 코드 흐름이 진행된다는 것을 알 수 있습니다.
아래는 ping test 기능을 수행하는 로직입니다. ping_ipaddr이라는 env(==parameter)을 얻어온 후
sprintf로 명령어를 만들어 주고 process open으로 ping을 실행시킵니다. sprintf에 들어가는 값에
명령어를 이어준다면 command injection이 가능합니다.
인증되지 않은 사용자로 특정 action을 요청할 수 있으니 로그인 시 발생되는 apply.cgi 에서 아래와 같이 패킷을 변조하여
shell command를 실행할 수 있습니다.
- 위협요소
인증되지 않은 사용자로 공유기에 shell command를 실행시킬 수 있습니다.
해당 취약점의 경우 현재 기술 지원이 끝난 제품들에서 발생했기 때문에 D-Link에서 취약점에 대한 패치를 진행하지 않습니다.
따라서 다른 시리즈의 제품으로 교체해야 합니다. 기술 지원이 끝난 제품이기 때문에 상당히 높은 critical 점수를 받은 취약점 입니다.
- 대응방안
1) 다른 D-Link 시리즈 제품으로 교체