Host Header Attack – Practical Exploitation and Prevention

The “HOST” header is part of the http protocol, vulnerable applications are vulnerable because they insert the value of this header into the application code without proper validation, this means not only applications hosted on Apache/Nginx can be vulnerable.

For Host Header Attack Exploitation, basically there are two ways through which you can exploit the application i.e. By means of Web Cache Poisoning which manipulates caching systems into storing a page generated with a malicious host and other is via Password Reset Emails when poisoned content is delivered directly to the target.

Why HTTP host header needed ?

According to RFC 2616: A client MUST include a Host header field in all HTTP/1.1 request messages. If the requested URI does not include an Internet host name for the service being requested, then the Host header field MUST be given with an empty value. Any HTTP/1.1 request without host header field must be responded by server with 400(bad request) status code.

Application using virtual host and load balancer identifies request by their host header. Server is assigned to single IP address that may host multiple websites. When request comes to server it will redirect to different websites by identifying request from host field. Thus, must validate host header before redirect to websites.

There are several different types of attacks related to host header injection

  • Unauthorized URL Redirect by Cache poisoning
  • Password Reset Poisoning
  • Access to internal hosts
  • Cross site scripting

In this article, we’re going to demonstrate Password Reset Poisoning.

Practical Demonstration –

Here, we’ve a lab testing environment where we’ve hosted a single PHP file for forgot password page on localhost when user requests a link to reset password, the website sends out a link with secret token to that user’s email address.

Say that link is http://localhost/password.php?token=randomvalue and randomvalue would be a key to a record in database which knows for whom to reset the password.

How we made that link –

Vulnerable Code – Protocol + Host Header + “/password.php?token=” + randomvalue,

Vulnerable Code – Download All Files

<?php
date_default_timezone_set(“Asia/Kolkata”);
if(isset($_POST[‘submit’]))
{
//Retrieving Post Parameters
$email = $_POST[’email’];
require_once(‘class.phpmailer.php’);
include(“class.smtp.php”); // optional, gets called from within class.phpmailer.php if not already loaded
$mail = new PHPMailer();
$body = ‘To Reset the password, please <a href=”http://’.$_SERVER[‘HTTP_HOST’].’/password.php?token=randomvalue”>click here</a>.’;
$mail->IsSMTP(); // telling the class to use SMTP
$mail->Host = “ssl://smtp.gmail.com”; // SMTP server
$mail->SMTPDebug = 1; // enables SMTP debug information (for testing)
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->SMTPSecure = “ssl”; // sets the prefix to the servier
$mail->Host = “smtp.gmail.com”; // sets GMAIL as the SMTP server
$mail->Port = 465; // set the SMTP port for the GMAIL server
$mail->Username = “yourname@gmail.com“; // GMAIL username
$mail->Password = “yourpasswordhere“; // GMAIL password
$mail->SetFrom(‘info@domain.com’, ‘Yeah Hub’);
$mail->Subject = “Password Reset Link – Yeahhub”;
$mail->MsgHTML($body);
$address = $email;
$mail->AddAddress($address, “Yeah Hub”);
if(!$mail->Send()) {
echo “<script>alert(‘Error! Something went wrong.’)</script>”;
} else {
echo “<script>alert(‘Password has been sent to your email!’)</script>”;
}
}
?>
<html>
<head>
<title>Forgot Password – YeahHub</title>
<link href=”style.css” rel=”stylesheet” type=”text/css”>
</head>
<body>
<div class=”elelment”>
<h2>Reset Password Form</h2>
<div class=”element-main”>
<h1>Forgot Password</h1>
<p> Fill the form to reset the password!</p>
<form method=”post” name=”form” action=”<?php echo htmlspecialchars($_SERVER[“PHP_SELF”]);?>”>
<input placeholder=”Your e-mail address” name=”email” type=”text”>
<input value=”Reset my Password” type=”submit” name=”submit”>
</form>
</div>
</div>
<div class=”copy-right”>
<p>&copy; 2018 Yeahhub. All rights reserved | Designed and Developed by <a href=”https://www.yeahhub.com/” target=”_blank”> <u>Yeahhub.com </u></a></p>
</div>
</body>
</html>

The attacker can easily pass host header to his own website, So the genuine site will generate and send email with link like http://evil.com/password.php?token=randomvalue and the attacker would have that site there, and he would be able to get the query string parameters and be able to reset password on behalf of the user, provided that the user actually clicks the link from email.

And this is the email with tampered reset link.

In the image above, pay close attention to the location of the reset link – it points to evil.com’s domain instead of the web application’s domain.

If the “Victim“, follows the link, Evil.com will capture this request with that token value and can easily reset the password of that user without any authorization.

Prevention –

The web application should use the SERVER_NAME instead of the Host header. It should also create a dummy vhost that catches all requests with unrecognised Host headers. This can also be done under Nginx by specifying a non-wildcard SERVER_NAME, and under Apache by using a non-wildcard serverName and turning the UseCanonicalName directive on.

You can also match a whitelist of domains that you owned as per the following code:

$domains = [‘abc.example.com’, ‘foo.bar.com’];
if ( ! in_array($_SERVER[‘SERVER_NAME’], $domains)) {
// error
}

 

You may also like:

Sarcastic Writer

Step by step hacking tutorials about wireless cracking, kali linux, metasploit, ethical hacking, seo tips and tricks, malware analysis and scanning.

Related Posts