IMPROPER ASSETS MANAGEMENT
TESTING FOR IMPROPER ASSETS MANAGEMENT
En el módulo Analyzing API Endpoints, creamos una colección Postman para crAPI. En este módulo, utilizaremos esta
colección para comprobar la gestión inadecuada de activos.
La comprobación de la gestión inadecuada de activos consiste en descubrir versiones no compatibles y no
producidas de una API. A menudo, un proveedor de API actualiza los servicios y la versión más reciente de la API
estará disponible en una nueva ruta como la siguiente:
api.target.com/v3
/api/v2/accounts
/api/v3/accounts
/v2/accounts
El versionado de la API también podría mantenerse como cabecera:
Accept: version=2.0
Accept api-version=3
Además, el versionado también podría establecerse en un parámetro de consulta o en el cuerpo de la solicitud.
/api/accounts?ver=2
POST /api/accounts
{
"ver":1.0
"user": "hapihacker"
}
En estos casos, es posible que las versiones anteriores de la API ya no estén parcheadas o actualizadas. Dado que las
versiones anteriores carecen de este soporte, pueden exponer la API a vulnerabilidades adicionales. Por ejemplo, si
la v3 de una API se actualizó para corregir una vulnerabilidad a los ataques de inyección, es muy probable que las
solicitudes en las que intervienen las versiones v1 y v2 sigan siendo vulnerables.
Las versiones no producidas de una API incluyen cualquier versión de la API que no esté destinada al consumo del
usuario final. Las versiones de no producción podrían incluir:
api.test.target.com
api.uat.target.com
beta.api.com
/api/private
/api/partner
/api/test
Una vez descubierta una versión no compatible de la API, realizaremos pruebas en busca de puntos débiles
adicionales. De forma similar a las vulnerabilidades de software no soportado, las vulnerabilidades de gestión de
activos inadecuados son una indicación de que hay una mayor probabilidad de que las debilidades estén presentes.
Encontrar versiones que no están incluidas en la documentación de la API será, en el mejor de los casos, una
vulnerabilidad por documentación técnica insuficiente (CWE-1059) y, en el peor, una puerta de acceso a hallazgos
más graves y al compromiso del proveedor.
Si aún no lo ha hecho, cree una colección Postman de crAPI y obtenga un token válido. Consulte el módulo Setup
para obtener instrucciones.
FINDING IMPROPER ASSETS MANAGEMENT VULNERABILITIES
Puede descubrir vulnerabilidades de asignación masiva encontrando parámetros interesantes en la
documentación de la API y añadiéndolos después a las peticiones. Busque parámetros relacionados con
propiedades de cuentas de usuario, funciones críticas y acciones administrativas. Interceptar las solicitudes y
respuestas de la API también podría revelar parámetros dignos de prueba. Además, puede adivinar los parámetros o
falsearlos en las solicitudes de API que aceptan la entrada del usuario. Recomiendo buscar procesos de registro que
permitan crear y/o editar variables de cuenta.
IMPROPER ASSETS MANAGEMENT TESTING
Ahora podemos empezar a hacer fuzzing (analizar) a las solicitudes de toda la API para detectar la presencia de
otras versiones. A continuación, pasaremos a centrar nuestras pruebas en función de nuestros hallazgos. Cuando se
trata de vulnerabilidades de Gestión de Activos Impropios, siempre es una buena idea realizar pruebas desde
perspectivas autenticadas y no autenticadas.
1. Comprende la información de la versión base de la API que estás probando. Asegúrate de comprobar la ruta,
los parámetros y las cabeceras en busca de información sobre versiones.
2. Para obtener mejores resultados del Postman Collection Runner, configuraremos una prueba utilizando el Editor
de colecciones. Seleccione las opciones de la colección crAPI, elija Editar y seleccione la pestaña Pruebas
(seleccionamos Status Code: Code is 200). Añada una prueba que detecte cuándo se devuelve un código de
estado 200 para que todo lo que no resulte en una respuesta 200 Success pueda destacarse como anómalo.
Puede utilizar la siguiente prueba:
pm.test("El código de estado es 200", function () { pm.response.to.have.status(200); })
3. Ejecute un análisis básico no autenticado de la colección crAPI con Collection Runner. Asegúrese de que la
opción "Guardar respuestas" está marcada, como se muestra a continuación.
4. Revise los resultados de su análisis de referencia no autenticado para hacerse una idea de cómo responde el
proveedor de API a las solicitudes que utilizan versiones de producción compatibles.
5. A continuación, utilice "Buscar y reemplazar" para convertir las versiones actuales de la colección en una
variable. Asegúrese de hacer esto para todas las versiones, en el caso de crAPI eso significa v2 y v3. Escriba la
versión actual en "Find", actualice "Where" a la colección de destino y actualice "Replace With" a una variable.
6. Abre Postman y navega hasta las variables de entorno (utiliza el icono del ojo situado en la parte superior
derecha de Postman como acceso directo). Ten en cuenta que estamos utilizando environmental variables para
que se pueda acceder a esta prueba y reutilizarla para otras colecciones de API. Agrega una variable llamada
"ver" a tu entorno Postman y establece el valor inicial en "v1". Ahora puedes actualizar para probar varias
rutas relacionadas con las versiones, como v1, v2, v3, mobile, internal, test y uat. A medida que te encuentres
con diferentes versiones de la API amplía esta lista de variables.
7. Ahora que la variable de entorno está establecida en v1, utilice de nuevo el gestor de colecciones e investigue
los resultados. Puedes profundizar en cualquiera de las peticiones pulsando sobre ellas. La petición "check-otp"
recibía antes una respuesta 500 y ahora es 404. Vale la pena notar la diferencia, pero cuando un recurso no
existe, entonces este sería realmente el comportamiento esperado.
8. Si las peticiones a rutas que no existen dan como resultado respuestas Success 200, tendremos que buscar
otros indicadores que utilizar para detectar anomalías. Actualiza la variable de entorno a v2. Aunque la mayoría
de las peticiones ya estaban configuradas a v2, merece la pena probarlo porque check-otp estaba previamente
configurado a v3.
Volvemos a lanzar la Collection Runner con el nuevo valor.
La petición /v2 para check-otp está recibiendo ahora la misma respuesta que la petición de línea de base original
(a /v3). Dado que la petición a /v1 recibió un 404 Not Found, esta respuesta es realmente interesante. Dado que la
petición a /v2 no es un 404 y en su lugar refleja la respuesta a /v3, esto es una buena indicación de que hemos
descubierto una vulnerabilidad de Gestión de Activos Impropia. Este es un hallazgo interesante, pero ¿cuál es el
impacto total de esta vulnerabilidad?
9. Investigando más a fondo la solicitud de restablecimiento de contraseña se verá que se emite un error HTTP
500 utilizando la ruta /v3 porque la aplicación tiene un control que limita el número de veces que se puede
intentar enviar el código de acceso de un solo uso (OTP). Enviar demasiadas peticiones a /v3 resultará en una
respuesta 500 diferente.
Como se ve desde el navegador:
Como se ve en Postman:
Enviar la misma petición a /v2 también resulta en un error HTTP 500, pero la respuesta es ligeramente mayor.
Puede valer la pena volver a ver las dos respuestas en Burp Suite Comparer para ver las diferencias puntuales.
Observe cómo la respuesta de la izquierda tiene el mensaje que indica que nos equivocamos pero que podemos
intentarlo de nuevo. La solicitud de la derecha indica un nuevo estado que aparece después de demasiados
intentos.
The /v2 password reset request responds with the body (left):
{"message":"Invalid OTP! Please try again..","status":500}
The /v3 password reset request responds with the body (right):
{"message":"ERROR..","status":500}
El impacto de esta vulnerabilidad es que /v2 no tiene una limitación en el número de veces que podemos adivinar
la OTP. Con una OTP de cuatro dígitos, deberíamos ser capaces de forzar la OTP en 10.000 peticiones.
10. Para probar esto se recomienda que utilice WFuzz, ya que Burp Suite CE será estrangulado. En primer lugar,
asegúrese de enviar una solicitud de restablecimiento de contraseña a la dirección de correo electrónico de
destino. En la página de inicio de crAPI, seleccione "¿Ha olvidado la contraseña?". A continuación, introduzca
una dirección de correo electrónico válida y haga clic en "Enviar OTP".
11. Ahora se emite una OTP y deberíamos ser capaces de forzar el código usando WFuzz. Forzando esta petición,
deberías ver el código exitoso que fue usado para cambiar la contraseña del objetivo a lo que quieras. En el
ataque de abajo, actualizo la contraseña a "NewPassword1". Una vez que recibas una respuesta satisfactoria,
deberías poder iniciar sesión con la dirección de correo electrónico del objetivo y la contraseña que elijas.
- wfuzz -d '{"email": "[email protected]", "otp": "FUZZ", "password": "NewPassword1"}' -H 'Content-
Type: application/json' -z file,/usr/share/wordlists/SecLists-master/Fuzzing/4-digits-0000-9999.txt -u
http://crapi.apisec.ai/identity/api/auth/v2/check-otp --hc 500.
Al cabo de 10.000 solicitudes, recibirás una respuesta de 200 indicando tu victoria. ¡Enhorabuena por llevar esta
vulnerabilidad de Gestión inadecuada de activos al siguiente nivel! Ya que nos desviamos con este interesante
hallazgo durante las pruebas sin autenticación, recomiendo volver a la colección crAPI y realizar las mismas pruebas
como un usuario autenticado.
PRÁCTICA
POSTMAN
- Buscamos rutas con versiones de la API:
- Cambiamos las versiones (v2) en la sección “Find and Replace”, estableciendo una variable general {{ver}} para
cambiarlo desde el “Environment” y que afecte a todas las peticiones. [ARRIBA YA LO HABÍA CAMBIADO]
No os olvideis de activar el Environment para que afecte a las variables.
BURP SUITE COMPARER
- Comparamos la solicitud con v1 y con v2, para ver las diferencias: en una aparece un límite de attempts (v2) y
en otra no (v1).
BURP SUITE INTRUDER [MUY LENTO]
FFUF
- Aprovechamos que la v1 no tiene límite de attempts para lanzar un ataque de fuerza bruta y averiguar el pin
correcto: para saber que es el pin correcto, como todas las solicitudes van a dar OK (Código: 200), observamos la
longitud de la respuesta.
- Comando: ffuf -w /usr/share/wordlists/SecLists/Fuzzing/4-digits-0000-9999.txt:FUZZ -X POST -d
'{"username":"richardbranson","pin":"FUZZ"}' -u 'http://127.0.0.1:80/vapi/api9/v1/user/login' -H "Content-
Type: application/json" -fs 0.