I need to download a file hosted behind a ASP.NET server form using cURL from the Linux shell. However, when I POST the parameters the server returns the webpage notifying that the numeric ID input field appears to be blank.
I've been trying to download a .deb file from here using cURL. I tried to mimic the POST request of selecting the file, filling the serial, accept terms, and finally download.
I already tried:
- Different request headers, useragent, keepalive, sameorigin...
- Storing cookies, in this case ASP.NET_SessionId
- Copying the cURL command (POST request) via browser developer options (this works but I want to generate the __VIEWSTATE and other variables from my shell)
Of all the things I've tried, the one that worked the best was:
1. Define urlencode function
I use this to encode the the __VIEWSTATE, __VIEWSTATEGENERATOR and ____EVENTVALIDATION values.
urlencode() {
ENCODEDURL="$(tr -d '\n' | curl -Gs -w %{url_effective} --data-urlencode @- ./ ||: | sed "s/%0[aA]$//;s/^[^?]*?\(.*\)/\1/")"
printf '%s' "$ENCODEDURL" | sed 's/^http.*?//g'
}
2. GET request the page
Save it to .html, and via shell magic grab the __VIEWSTATE, __VIEWSTATEGENERATOR and ____EVENTVALIDATION values.
curl https://soportefirmadigital.com/sfdj/dl.aspx -o page.html
i=0
ASP_VARS="$(for VAR in __VIEWSTATE __VIEWSTATEGENERATOR __EVENTVALIDATION ; do
VAL="$(grep -o "id=\"$VAR\"\svalue=\".*\"" page.html | cut -d '"' -f 4 | urlencode)"
[ "$i" != 0 ] && printf '&'
printf '%s=%s' "$VAR" "$VAL"
i=+1
done)"
3. POST request with parameters
I do want to keep some parameters the same (for example downloading the same .deb file), I understand the $ASP_VARS have to change each time and of course the $SERIAL has to be a variable as well. These are from the browser's curl copy option, without headers.
curl 'https://soportefirmadigital.com/sfdj/dl.aspx' -X POST \
--data-raw "__EVENTTARGET=ctl00%24certContents%24LinkButton3" \
--data-raw "__EVENTARGUMENT=" \
--data-raw "__LASTFOCUS=" \
--data-raw "$ASP_VARS" \
--data-raw "ctl00%24certContents%24hiddenISO=ClientesLinux_DEB64_Rev25.zip" \
--data-raw "ctl00%24certContents%24hidden_ISO_URL=-" \
--data-raw "ctl00%24certContents%24ddlInstaladores=Usuarios+Linux+%28DEB+64bits%29" \
--data-raw "ctl00%24certContents%24txtDescripcion=Distribuciones+basadas+en+DEB+x64.%0D%0AVersiones+Homologadas%0D%0A-Ubuntu+18.04+LTS+o+superior%28solo+versiones+LTS%29%0D%0A-Debian+10%0D%0A%0D%0ASoporte+%C3%BAnicamente+en+m%C3%A1quinas+F%C3%ADsicas.%0D%0AMD5%3A3a8c11d0273daee7bfc63a17615a8dc9" \
--data-raw "ctl00%24certContents%24txtSerialNumber=$SERIAL" \
--data-raw "ctl00%24certContents%24hiddenABID=" \
--data-raw "ctl00%24certContents%24chkConfirmo=on"
4. Expected vs actual response
Clearly I can't give my personal serial number but the expected response with an invalid id would be:
...
<span id="ctl00_certContents_lblErr" class="fieldErr" style="color:#C00000;">Su tarjeta tiene un número inválido, o bien, no está registrada para soporte. En caso de duda contacte a su Institución Emisora.</span>
...
However, the response I get is (this is the same response you get when leaving the input blank using the browser normally):
...
<span id="ctl00_certContents_lblErr" class="fieldErr"><font color="#C00000">Debe digitar el número de serie de su tarjeta</font></span>
...