POST
A diferencia de HTTP GET, que coloca los parámetros de usuario dentro de la URL, HTTP POST coloca los parámetros de usuario dentro del cuerpo de la solicitud HTTP. Esto tiene tres beneficios principales:
Lack of Logging: Como las solicitudes POST pueden transferir archivos grandes (por ejemplo, carga de archivos), no sería eficiente que el servidor registre todos los archivos cargados como parte de la URL solicitada, como sería el caso con un archivo cargado a través de una solicitud GET.
Less Encoding Requirements: Las URL están diseñadas para ser compartidas, lo que significa que deben ajustarse a caracteres que se puedan convertir en letras. La solicitud POST coloca datos en el cuerpo que pueden aceptar datos binarios. Los únicos caracteres que deben codificarse son los que se utilizan para separar parámetros.
More data can be sent: La longitud máxima de URL varía entre navegadores (Chrome/Firefox/IE), servidores web (IIS, Apache, nginx), redes de entrega de contenido (Fastly, Cloudfront, Cloudflare) e incluso acortadores de URL (bit.ly, amzn.to). . En términos generales, la longitud de una URL debe mantenerse por debajo de los 2000 caracteres, por lo que no pueden manejar una gran cantidad de datos.
Entonces, veamos algunos ejemplos de cómo funcionan las solicitudes POST y cómo podemos utilizar herramientas como cURL o herramientas de desarrollo del navegador para leer y enviar solicitudes POST.
Formularios de inicio de sesión
El ejercicio al final de esta sección es similar al ejemplo que vimos en la sección GET. Sin embargo, una vez que visitamos la aplicación web, vemos que utiliza un formulario de inicio de sesión PHP en lugar de autenticación básica HTTP:
Si intentamos iniciar sesión con admin: admin, ingresamos y vemos una función de búsqueda similar a la que vimos anteriormente en la sección OBTENER:
Si borramos la pestaña Red en las herramientas de desarrollo de nuestro navegador e intentamos iniciar sesión nuevamente, veremos que se envían muchas solicitudes. Podemos filtrar las solicitudes por la IP de nuestro servidor, por lo que solo mostrará las solicitudes que van al servidor web de la aplicación web (es decir, filtrará las solicitudes externas) y notaremos que se envía la siguiente solicitud POST:
Podemos hacer clic en la solicitud, hacer clic en la pestaña Request (que muestra el cuerpo de la solicitud) y luego hacer clic en el botón Raw para mostrar los datos sin procesar de la solicitud. Vemos que los siguientes datos se envían como datos de solicitud POST:
1
username=admin&password=admin
Con los datos de la solicitud a mano, podemos intentar enviar una solicitud similar con cURL, para ver si esto también nos permitiría iniciar sesión. Además, como hicimos en el apartado anterior, simplemente podemos hacer clic derecho en la solicitud y seleccionar Copy>Copy as cURL. Sin embargo, es importante poder elaborar solicitudes POST manualmente, así que intentemos hacerlo.
Usaremos la Flag -X POST para enviar una solicitud POST. Luego, para agregar nuestros datos POST, podemos usar la Flag -d y agregar los datos anteriores después, de la siguiente manera:
Si examinamos el código HTML, no veremos el código del formulario de inicio de sesión, pero veremos el código de la función de búsqueda, lo que indica que efectivamente nos autenticamos.
Nota: Muchos formularios de inicio de sesión nos redireccionarían a una página diferente una vez autenticados (por ejemplo, /dashboard.php). Si queremos seguir la redirección con cURL, podemos usar la Flag -L.
Cookies Autenticadas
Si nos autenticamos exitosamente, deberíamos haber recibido una cookie para que nuestros navegadores puedan conservar nuestra autenticación y no necesitemos iniciar sesión cada vez que visitamos la página. Podemos usar las Flags -v o -i para ver la respuesta, que debe contener el Header Set-Cookie con nuestra cookie autenticada:
Con nuestra cookie autenticada, ahora deberíamos poder interactuar con la aplicación web sin necesidad de proporcionar nuestras credenciales cada vez. Para probar esto, podemos configurar la cookie anterior con el Flag -b en cURL, de la siguiente manera:
Como podemos ver, efectivamente fuimos autenticados y llegamos a la función de búsqueda. También es posible especificar la cookie como encabezado, de la siguiente manera:
1
curl -H 'Cookie: PHPSESSID=c1nsa6op7vtk7kdis7bcnbadf1' http://<SERVER_IP>:<PORT>/
También podemos intentar lo mismo con nuestros navegadores. Primero cerremos sesión y luego deberíamos volver a la página de inicio de sesión. Luego, podemos ir a la pestaña Storage en devtools con [ SHIFT+F9]. En la pestaña Storage, podemos hacer clic en Cookies en el panel izquierdo y seleccionar nuestro sitio web para ver nuestras cookies actuales. Es posible que tengamos cookies existentes o no, pero si cerramos la sesión, entonces nuestra cookie PHP no debería estar autenticada, razón por la cual si obtenemos el formulario de inicio de sesión y no la función de búsqueda:
Ahora, intentemos utilizar nuestra cookie autenticada anterior y veamos si ingresamos sin necesidad de proporcionar nuestras credenciales. Para hacerlo, simplemente podemos reemplazar el valor de la cookie por el nuestro. De lo contrario, podemos hacer clic derecho en la cookie y seleccionar Delete All, y hacer clic en el icono + para agregar una nueva cookie. Después de eso, debemos ingresar el nombre de la cookie, que es la parte antes de =( PHPSESSID), y luego el valor de la cookie, que es la parte después de =( c1nsa6op7vtk7kdis7bcnbadf1). Luego, una vez configurada nuestra cookie, podemos actualizar la página y veremos que efectivamente nos autenticamos sin necesidad de iniciar sesión, simplemente usando una cookie autenticada:
Como podemos ver, tener una cookie válida puede ser suficiente para autenticarse en muchas aplicaciones web. Esto puede ser una parte esencial de algunos ataques web, como Cross-Site Scripting.
JSON Data
Finalmente, veamos qué solicitudes se envían cuando interactuamos con la City función Search. Para hacerlo, iremos a la pestaña Red en las herramientas de desarrollo del navegador y luego haremos clic en el ícono de la papelera para borrar todas las solicitudes. Luego, podemos realizar cualquier consulta de búsqueda para ver qué solicitudes se envían:
Como podemos ver, el formulario de búsqueda envía una solicitud POST a search.php, con los siguientes datos:
1
{"search":"london"}
Los datos POST parecen estar en formato JSON, por lo que nuestra solicitud debe haber especificado que el Header Content-Type sea application/json. Podemos confirmar esto haciendo clic derecho en la solicitud y seleccionando Copy>Copy Request Headers:
1
2
3
4
5
6
7
8
9
10
11
12
13
POST /search.php HTTP/1.1
Host: server_ip
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:97.0) Gecko/20100101 Firefox/97.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://server_ip/index.php
Content-Type: application/json
Origin: http://server_ip
Content-Length: 19
DNT: 1
Connection: keep-alive
Cookie: PHPSESSID=c1nsa6op7vtk7kdis7bcnbadf1
De hecho, tenemos Content-Type: application/json. Intentemos replicar esta solicitud como lo hicimos antes, pero incluyamos los encabezados de tipo de contenido y de cookie, y enviemos nuestra solicitud a search.php:
1
2
Gohanckz@htb[/htb]$ curl -X POST -d '{"search":"london"}' -b 'PHPSESSID=c1nsa6op7vtk7kdis7bcnbadf1' -H 'Content-Type: application/json' http://<SERVER_IP>:<PORT>/search.php
["London (UK)"]
Como podemos ver, pudimos interactuar con la función de búsqueda directamente sin necesidad de iniciar sesión o interactuar con la interfaz de la aplicación web. Esta puede ser una habilidad esencial al realizar evaluaciones de aplicaciones web o ejercicios de búsqueda de errores, ya que es mucho más rápido probar aplicaciones web de esta manera.