How to make an HTTP GET request manually with netcat?
Asked Answered
O

6

74

So, I have to retrieve temperature from any one of the cities from http://www.rssweather.com/dir/Asia/India.

Let's assume I want to retrieve of Kanpur's.

How to make an HTTP GET request with Netcat?

I'm doing something like this.

nc -v rssweather.com 80
GET http://www.rssweather.com/wx/in/kanpur/wx.php HTTP/1.1

I don't know exactly if I'm even in the right direction or not. I am not able to find any good tutorials on how to make an HTTP get request with netcat, so I'm posting it on here.

Overnight answered 1/9, 2015 at 21:56 Comment(1)
This isn't a proper answer, but I recommend curl or wget for this sort of thing.Heald
A
54

Of course you could dig in standards searched for google, but actually if you want to get only a single URL, it isn't​‎​‎ worth the effort.

You could also start a netcat in listening mode on a port:

nc -l 64738

(Sometimes nc -l -p 64738 is the correct argument list)

...and then do a browser request into this port with a real browser. Just type in your browser http://localhost:64738 and see.

In your actual case the problem is that HTTP/1.1 doesn't close the connection automatically, but it waits your next URL you want to retrieve. The solution is simple:

Use HTTP/1.0:

GET /this/url/you/want/to/get HTTP/1.0
Host: www.rssweather.com
<empty line>

or use a Connection: request header to say the server you want to close after that:

GET /this/url/you/want/to/get HTTP/1.1
Host: www.rssweather.com
Connection: close
<empty line>

Extension: After the GET header write only the path part of the request. The hostname from which you want to get data belongs to a Host: header as you can see in my examples. This is because multiple websites can run on the same webserver, so the browsers need to say him, from which site it wants to load the page.

Almita answered 1/9, 2015 at 22:5 Comment(2)
Thanks. This helped a lot. Now the result has changed from Bad Request to forbidden. The server is not allowing me to access the file. Is there any way to fix that? HTTP/1.1 403 Forbidden Date: Tue, 01 Sep 2015 22:14:50 GMT Server: Apache Connection: close Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <HTML><HEAD> <TITLE>403 Forbidden</TITLE> </HEAD><BODY> <H1>Forbidden</H1> You don't have permission to access /wx/in/kanpur/wx.php on this server.<P> <HR> <ADDRESS>Apache/1.3.41 Server at www.rssweather.com Port 80</ADDRESS> </BODY></HTML>Overnight
@AvinashBhawnani Thanks. You can always edit your questions and long copy-pastes don't look very well in comments, in similar cases it is better if you edit them into your question. And, if you have another question, you can ask it in a new question, this is not a problem here (only if you ask the same thing twice).Almita
H
31

This works for me:

$ nc www.rssweather.com 80
GET /wx/in/kanpur/wx.php HTTP/1.0
Host: www.rssweather.com

And then hit double <enter>, i.e. once for the remote http server and once for the nc command.

source: pentesterlabs

Heald answered 15/10, 2016 at 18:6 Comment(3)
You should either use HTTP/1.0, or give a Connection: close header, too.Almita
if you get "HTTP/1.1 426 Upgrade Required" try to change HTTP/1.0 to HTTP/1.1Pierson
This worked for me. Hitting double <enter> did the trick.Fortepiano
V
31

You don't even need to use/install netcat

  • Create a tcp socket via an unused file-descriptor i.e I use 88 here

  • Write the request into it

  • use the fd

      exec 88<>/dev/tcp/rssweather.com/80
      echo -e "GET /dir/Asia/India HTTP/1.1\nhost: www.rssweather.com\nConnection: close\n\n\n" >&88
      sed 's/<[^>]*>/ /g' <&88
    

​‎​‎ ​​​​​​​​

Vinna answered 9/12, 2018 at 19:39 Comment(5)
What is this? My Debian doesnt have this tcp directory and the upvotes suggest, that this is actually working. Also, exec is provided by Bash.Dichlorodiphenyltrichloroethane
@Dichlorodiphenyltrichloroethane Afaik debian bash has not this addon on braindamaged reasons.Almita
@Almita What is it called? Does it have a project page?Dichlorodiphenyltrichloroethane
@Dichlorodiphenyltrichloroethane That is not a separate project. That is part of the bash shell. Debian just turned this feature off without any acceptable reason. Thus, bash in your debian, can not initiate network connections and so is it.Almita
@Almita Ok, i'll check that out later. Thank you.Dichlorodiphenyltrichloroethane
T
19

On MacOS, you need the -c flag as follows:

Little-Net:~ minfrin$ nc -c rssweather.com 80
GET /wx/in/kanpur/wx.php HTTP/1.1
Host: rssweather.com
Connection: close
[empty line]

The response then appears as follows:

HTTP/1.1 200 OK
Date: Thu, 23 Aug 2018 13:20:49 GMT
Server: Apache
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html

The -c flag is described as "Send CRLF as line-ending".

To be HTTP/1.1 compliant, you need the Host header, as well as the "Connection: close" if you want to disable keepalive.

Topography answered 23/8, 2018 at 13:27 Comment(1)
This is capital "-C" for linux as something to add to this answer and without it the above suggestions won't work.Usually
O
12

Test it out locally with python3 http.server

This is also a fun way to test it out. On one shell, launch a local file server:

python3 -m http.server 8000

Then on the second shell, make a request:

printf 'GET / HTTP/1.1\r\nHost: localhost\r\n\r\n' | nc localhost 8000

The Host: header is required in HTTP 1.1.

This shows an HTML listing of the directory, just as you would see from:

firefox http://localhost:8000

Next you can try to list files and directories and observe the response:

printf 'GET /my-subdir/ HTTP/1.1\n\n' | nc localhost 8000
printf 'GET /my-file HTTP/1.1\n\n' | nc localhost 8000

Every time you make a successful request, the server prints:

127.0.0.1 - - [05/Oct/2018 11:20:55] "GET / HTTP/1.1" 200 -

confirming that it was received.

example.com

This IANA maintained domain is another good test URL:

printf 'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n' | nc example.com 80

and compare with: http://example.com/

https SSL

nc does not seem to be able to handle https URLs. Instead, you can use:

sudo apt-get install nmap
printf 'GET / HTTP/1.1\r\nHost: github.com\r\n\r\n' | ncat --ssl github.com 443

See also: https://serverfault.com/questions/102032/connecting-to-https-with-netcat-nc/650189#650189

If you try nc, it just hangs:

printf 'GET / HTTP/1.1\r\nHost: github.com\r\n\r\n' | nc github.com 443

and trying port 80:

printf 'GET / HTTP/1.1\r\nHost: github.com\r\n\r\n' | nc github.com 443

just gives a redirect response to the https version:

HTTP/1.1 301 Moved Permanently
Content-Length: 0
Location: https://github.com/
Connection: keep-alive

Tested on Ubuntu 18.04.

Orcutt answered 5/10, 2018 at 9:29 Comment(0)
T
0

After connect using nc, it's only required to specify the path, no need for the HOST name again.

Tetroxide answered 4/11, 2023 at 11:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.