4

I'm looking through the CSRF vulnerabilities of the DVWA. I run into the medium level which uses this piece of code to validate if the referer header equals the server name:

if( eregi( $_SERVER[ 'SERVER_NAME' ], $_SERVER[ 'HTTP_REFERER' ] ) ).

If so, my query will be accepted and triggered on a database changing login info. I'm doing this through a malicious webpage.

So far I was able to see what the Referer name is on a response header from the server. From my understanding,that php function is asking the following:

Is the value of $_SERVER[‘SERVER_NAME’] present in $_SERVER[‘HTTP_REFERER’]?

So, my first thought was, trying to manipulate the request URL string and embed the referer header on it. (no results) I'm assuming that the if statement is just looking for a pattern. The thing is that I don't know how to pass it and quiet honestly I don't understand if my GET request is present in $_SERVER[ 'SERVER_NAME' ] or in $_SERVER[ 'HTTP_REFERER' ]. From my investigation I think the referer header cannot be changed in a simple html img tag. So my last question would be: Am I able to forge the string of img tag (HTTP request GET) in a way that the statement evaluates to true? If not, how can I do that in a scenario where a victim always uses this malicious webpage unconsciously?

fish202
  • 119
  • 3
  • 7

1 Answers1

5

It's really straightforward!

Tip:

The check verifies if the requesting URL contains the string localhost, but not if it starts with it. So how do you get the string localhost in the referrer (at any place)?

Solution:

You need to send the request from a page that contains the target hostname in its URL.

So if your DVWA instance is hosted on localhost, you need to embed that string in the URL. Just send the CSRF request from http://evilhost/?localhost. This will produce a referrer header like this:

Referer: http://evilhost/?localhost

That's enough to pass the check.

Arminius
  • 43,922
  • 13
  • 140
  • 136
  • Thanks for feedback. Do you mean something like this `http://localhost:82/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change/?localhost` ? – fish202 Nov 05 '17 at 02:43
  • @fish202 No, the string needs to in the URL of the *requesting* site. What's the URL of the site you send the request from? – Arminius Nov 05 '17 at 02:57
  • Well @Arminius... it's just a path to an html file, something like `file:///home/auser/csrf.html`. You can see that it's a local file on my machine. That's why I'm confused with your answer. I'm pretty sure that this is simple but I'm not getting that. – fish202 Nov 05 '17 at 03:21
  • 1
    @fish202 Local files never send referrers. You need to launch it from a webserver instead. Then, you'd open it with an URL like `http://yourevilserver/csrf.html?localhost`. – Arminius Nov 05 '17 at 03:23
  • ok, I see...I had the feeling that something was missing. I'll give it a try asap and then I'll get back to you. thx – fish202 Nov 05 '17 at 03:31
  • @fish202 Did you have any success? – Arminius Nov 05 '17 at 14:30
  • kind of...Now I can see that **referer** [is sent](https://imgur.com/a/UJuiX) on HTTP request. But query status returns failed. Not sure why... I have dvwa running in a docker container listening on localhost:81 and for this purpose I ran apache2 on localhost:80 and then I made the request like this: `localhost:80/csrf.html?localhost` . Is this approach correct? – fish202 Nov 05 '17 at 16:56
  • 1
    Nevermind, I requesting it on a wrong port. Now it's working @Arminius. Thank you for the precious help! – fish202 Nov 05 '17 at 17:06