When we connect to the server, we are greeted by a superb ASCII-art captcha :
```
 _____            ___|____ |          /   |  ______    / / __  __  / /| | |______|    \ \ \ \/ / / /_| |  ______.___/ /  >  <  \___  | |______|\____/  /_/\_\     |_/
>```
Yep, no way my browser can handle that : as the problem description states,we're going to have to write HTTP requests by hand.
### Writing HTTP requests
Mozilla has a pretty good guide to get started on the protocol :"[An overview of HTTP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview)".
An HTTP request has the following content:
```{METHOD} {PATH} {PROTOCOL_VERSION}{HEADERS}
{BODY}```
The headers and the body are separated by a newline, the body being optional.
Here's a basic example `GET` request :
```GET /index.html HTTP 1.1```
And here's an example `POST` request :
```POST /login.php HTTP 1.1Content-Length: 30
username=iodbh&password=secret```
The `Content-Length` header is mandatory if the request has a body, as it tellsthe server how many bytes are part of the body. (So in the example above, if Ipassed a `Content-Length` of 30, the server would read`username=iodbh&password=secre` - missing the last byte/character).
So let's try getting the root page :
**Request:**
```GET / HTTP 1.1```
**Response:**
```HTTP/1.1 400 Missing Host headerDate: Mon, 15 Oct 2018 14:00:08 GMTConnection: keep-aliveTransfer-Encoding: chunked
0```
Hmmm, looks like the `Host` header is missing.
### The Host header
As you probably know, the DNS protocol helps us resolve hostnames to IPaddresses. But if several domains are hosted on the same machine (or, likein this problem, behind the same proxy), how does the server know what resourceto return ? It reads the host header.
_Note : This has very interesting security implications, I highly recommend the talk"[cracking the lens : Targeting HTTP's Hidden Attack-Surface](https://www.youtube.com/watch?v=zP4b3pw94s0)"([text version](https://portswigger.net/blog/cracking-the-lens-targeting-https-hidden-attack-surface))by James Kettle on the subject._
The host we want is given in the task description : `flag.local`. So let'stry with the header :
**Request:**
```GET / HTTP 1.1Host: flag.local```
**Response:**
```HTTP/1.1 200 OKx-powered-by: Expresscontent-type: text/html; charset=utf-8content-length: 321etag: W/"141-LuTf9ny9p1l454tuA3Un+gDFLWo"date: Mon, 15 Oct 2018 14:21:53 GMTconnection: close``````html<html>    <head>        <link rel="stylesheet" type="text/css" href="main.css" />    </head>    <body>        <header>            <h1>Real Business Internal Flag Server</h1> Login        </header>        <main> You need to log in before you can see today's flag.        </main>    </body></html>```
You need to log in before you can see today's flag.
This time we have some HTML back, with a link to `/login`.
### Handling forms
If we follow the link, we get a form :
**Request:**
```GET /login HTTP 1.1Host: flag.local```
**Response:**
```GET /login HTTP 1.1Host: flag.local
HTTP/1.1 200 OKx-powered-by: Expresscontent-type: text/html; charset=utf-8content-length: 498etag: W/"1f2-UE5AGAqbLVQn1qrfKFRIqanxl9I"date: Mon, 15 Oct 2018 14:26:34 GMTconnection: close```
```html<html>    <head>        <link rel="stylesheet" type="text/css" href="main.css" />    </head>    <body>        <header>            <h1>Real Business Internal Flag Server</h1> Login        </header>        <main>            <h2>Log In</h2>
            <form method="POST" action="login">                <input type="text" name="user" placeholder="Username" />                <input type="password" name="pass" placeholder="Password" />                <input type="submit" />            </form>        </main>    </body></html>```
There are several things to look for here :
- the `method` attribute on the `form` tag :  it tells us what methode to use. Here, it's `POST`.- the `action` attribute on the `form` tag : it tells us what path we should send the data to. Here, it's `login`.- the `name` attributes on `input` tags. They tell us what fields we're supposed to send. Here, it's `user` and `pass`.
With that and the credentials provided in the task we can construct the nextrequest. Don't forget the `Content-Length` header since our request has a body !
We also need a [`Content-Type` header](https://en.wikipedia.org/wiki/Media_type) indicating what format the body is in.Here, it's `application/x-www-form-urlencoded`.
**Request:**
```POST /login HTTP 1.1Host: flag.localContent-Type: application/x-www-form-urlencodedContent-Length: 38
user=realbusinessuser&pass=potoooooooo```
**Response:**
```HTTP/1.1 302 Foundx-powered-by: Expressset-cookie: real_business_token=PHNjcmlwdD5hbGVydCgid2F0Iik8L3NjcmlwdD4%3D; Path=/location: /vary: Acceptcontent-type: text/plain; charset=utf-8content-length: 23date: Mon, 15 Oct 2018 14:44:27 GMTconnection: close
Found. Redirecting to /```
Great, we successfully logged in !
### Managing cookies
So, we got a redirect response to `/`. If we were using a browser, it wouldautomatically follow the redirect and take us to `/`. So we have to do that byhand. But it's not the only thing the browser would by doing for us.
HTTP is a stateless protocol, meaning the server is not keeping any statebetween the requests at the protocol level - if we just requested `/`, therewould be no trace of our previous login.
The state is instead referenced to by a cookie. We can see it in the previousresponse's `Set-Cookie` header. Our browser would automatically save thatcookie, and automatically send it in the request when the host and path matchthose of the cookie.
So the last thing we need to do is request `/` again, this time with the cookie.How do we attach a cookie ? Just use the `Cookie` header :
**Request:**
```GET / HTTP 1.1Host: flag.localCookie: real_business_token=PHNjcmlwdD5hbGVydCgid2F0Iik8L3NjcmlwdD4%3D```
**Response: **
```HTTP/1.1 200 OKx-powered-by: Expresscontent-type: text/html; charset=utf-8content-length: 438etag: W/"1b6-eYJ8DUTdkgByyfWFi6OJJSjopFg"date: Mon, 15 Oct 2018 15:02:11 GMTconnection: close```
```html<html>    <head>        <link rel="stylesheet" type="text/css" href="main.css" />    </head>    <body>        <header>            <h1>Real Business Internal Flag Server</h1>            <div class="user">Real Business Employee</div> Logout        </header>        <main> Hello Real Business Employee!  Today's flag is: picoCTF{0nLY_Us3_n0N_GmO_xF3r_pR0tOcol5_2e14}.        </main>    </body></html>```
Hello Real Business Employee!  Today's flag is: picoCTF{0nLY_Us3_n0N_GmO_xF3r_pR0tOcol5_2e14}.
And our flag is in the response : `picoCTF{0nLY_Us3_n0N_GmO_xF3r_pR0tOcol5_2e14}`