
TP-Link Tapo c200 IP 카메라의 uhttpd 바이너리에서 발견된 명령어 삽입 취약점 익스플로잇
CVE-2021-4045는 TP-Link Tapo c200 IP 카메라에서 원격 코드 실행을 가능하게 하는 명령 주입 취약점입니다. 이 취약점은 장치의 주요 바이너리 중 하나인 uhttpd에서 사용자 입력에 대한 충분한 검사가 이루어지지 않아 펌웨어 버전 1.1.16 Build 211209 Rel. 37726N 이전의 모든 버전에 영향을 미칩니다. 전체 분석 내용은 여기에서 확인할 수 있습니다.
이것은 CryptoParty Madrid 2022에서 취약점을 시연하기 위해 만들어진 PoC의 확장 버전입니다. 두 가지 모드를 제공합니다:
shell: 대상에서 루트 셸을 실행합니다

rtsp: RTSP를 통해 실시간 비디오 스트림에 접근할 수 있습니다

함수 exec_and_read_json은 명령을 실행하기 위해 popen을 사용합니다:

exec_and_read_json은 이름이 없는 두 함수에서 사용되는데, 각각 set_language와 wifi_connect라고 명명했습니다. 이 함수들은 각각 언어 및 Wi-Fi 구성을 처리합니다. wifi_connect는 작은따옴표(')를 파싱하는 것으로 보이지만, set_language는 그렇지 않습니다. 이는 set_language 함수에 대한 입력을 제어할 수 있다면, 명령어를 성공적으로 주입할 수 있음을 의미합니다.

set_language 함수는 앞서 언급한 uh_slp_proto_request에 의해 사용되는데, 이 함수는 사용자로부터 수신한 파싱된 데이터를 입력으로 전달합니다.

사용자 데이터를 파싱하기 위해 uh_slp_proto_request는 유효한 JSON 객체인지 확인합니다. 그런 다음 키 "method"로 식별되는 문자열 값과 "params"로 식별되는 딕셔너리 값을 가져옵니다 (적어도 이렇게 동작하는 것으로 보입니다. Ghidra가 함수 호출을 해석하지 못했지만, 이 방식으로 작동하는 것으로 보입니다). 선택된 메소드에 따라 uh_slp_proto_request는 호출될 함수를 선택합니다.
따라서 {"method": "setLanguage", "params":{}}를 전송하면 set_language 함수가 호출되고 {}가 language_json 매개변수로 전달됩니다. 그런 다음 set_language 내부에서 language_json 객체가 문자열로 변환되어 실행될 "ubus call system_state_audio set_language \'%s\'"에 직접 삽입됩니다.
{"method": "setLanguage", "params": {"payload": "'; touch poc;'"}}를 제출하면 ubus call system_state_audio set_language '{"payload": "'; touch poc;'"}'가 실행되는데, 여기에는 실제로 3개의 명령어가 포함됩니다: ubus call system_state_audio set_language '{"payload": "', touch poc, 그리고 '"}'. 두 번째 명령어가 완전한 코드 실행을 제공합니다.
이제 uh_slp_proto_request는 모든 요청을 관리하는 또 다른 이름 없는 함수(제가 main_server_function이라고 명명했습니다)에서 사용됩니다. 요청이 유효하면 (최대 길이를 초과하지 않고, 서버 설정에 따라 http 또는 https를 사용하는 등), main_server_function은 URL에 /cgi-bin/luci 또는 /web-static이 포함되어 있는지 확인합니다. 포함되어 있지 않으면 uh_slp_proto_request가 호출됩니다.

추측하여 카메라에 몇 가지 요청을 보내면, uh_slp_proto_request가 사용하는 데이터가 일반 POST 데이터임을 확인할 수 있습니다. 따라서 이전 페이로드와 함께 /에 POST 요청을 보내면 uh_slp_proto_request가 이 데이터를 처리하고 set_language를 호출하며, 우리의 페이로드는 exec_and_get_result가 실행하는 명령어에 주입됩니다.
보시다시피, 인증에 대해서는 언급하지 않았습니다. setLanguage 메소드는 로그인 없이 호출될 수 있기 때문입니다. 이를 통해 모든 사용자가 단 한 번의 인증되지 않은 요청으로 카메라를 완전히 제어할 수 있습니다.