Download file behind ASP.NET with cURL

62 Views Asked by At

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>
...
0

There are 0 best solutions below