[하루한줄] CVE-2022-24354: TP-Link Wi-Fi 라우터의 root 권한 원격 코드 실행 취약점

URL

https://github.com/0vercl0k/zenith

Target

  • TP-Link AC1750 Smart Wi-Fi Router

Explain

지난 Pwn2Own Austin 2021에 제출된 와이파이 공유기 제조업체 TP-Link 제품의 취약점 정보가 공개되었습니다. 제품명은 AC1750 Smart Wi-Fi 라우터이며 공개된 취약점은 root 권한으로 원격 코드 실행이 가능한 취약점입니다.

취약점은 NetUSB.ko 모듈의 SoftwareBus_dispatchNormalEPMsgOut 함수에 존재합니다.

void *SoftwareBus_dispatchNormalEPMsgOut(SbusConnection_t *SbusConnection, char HostCommand, char Opcode)
{
  // ...
  switch (OpcodeMasked) {
    case 0x50:
        if (SoftwareBus_fillBuf(SbusConnection, ReceiveBuffer, 4)) {
          ReceivedSize = _bswapw(*(uint32_t*)ReceiveBuffer);
            AllocatedBuffer = _kmalloc(ReceivedSize + 17, 208); // (1) 
            if (!AllocatedBuffer) {
                return kc_printf("INFO%04X: Out of memory in USBSoftwareBus", 4296);
            }
        [...]
            if (!SoftwareBus_fillBuf(SbusConnection, AllocatedBuffer + 16, ReceivedSize)) // (2)

ReceivedSize는 32bit 정수이며 ReceivedSize + 17 값이 kmalloc의 인자로 전달되는데, 이때 ReceivedSize + 17 가 32bit 정수의 범위를 넘는지 검사하지 않아 integer overflow가 발생하고 AllocatedBuffer에 훨씬 작은 버퍼가 할당이 됩니다. 때문에 이후 작게 할당된 AllocatedBuffer+16ReceivedSize 만큼의 버퍼를 복사해 Heap Buffer Overflow가 트리거됩니다.

해당 취약점은 인접한 대기 큐 구조체인 wait_queue_head_t.head.next 를 조작된 함수 포인터가 포함된 wait_queue_entry_t 주소로 덮어쓰는 것으로 악용할 수 있습니다. 결과적으로 아래의 __wake_up_common 함수에서 조작된 함수 포인터를 호출하며 root 컨텍스트에서 원격 코드 실행이 가능해집니다.

struct wait_queue_head {
	spinlock_t		lock;
	struct list_head	head;
};

struct wait_queue_entry {
	unsigned int		flags;
	void			*private;
	wait_queue_func_t	func;
	struct list_head	entry;
};

static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
			int nr_exclusive, int wake_flags, void *key)
{
	wait_queue_t *curr, *next;

	list_for_each_entry_safe(curr, next, &q->task_list, task_list) {
		unsigned flags = curr->flags;

		if (curr->func(curr, mode, wake_flags, key) &&   // 
				(flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
			break;
	}
}