hMailServer script to anonymise internal IP addresses
We all know that (accidentally) exposing private information to all and sundry is a bad thing; information leaked in SMTP Received: headers is a goldmine for pentesters and blackhats alike. Here’s a little script for hMailServer which will anonymise the names and IP addresses of internal SMTP mail clients that would otherwise be placed into a Received: header.
The script might need some tweaking to suit your environment:
- It will anonymise Received: headers only when the connecting client’s IP address starts with 172.16. Alter this check to suit your own environment
- You’ll need to change mail.example.com to whatever hMailServer’s Local host name is set to (under Settings->Protocols->SMTP->Delivery of e-mail)
hMailServer scripts are by default written in VBScript; I’ve had extensive counselling to get over the experience, and I’m fine now.
Tweak the script below, then add it to EventHandlers.vbs. Take care if you already have a handler defined for OnAcceptMessage:
‘ Strips out private IP addresses from Received header
‘ if the client’s IP address is in 172.16.0.0/16
Sub OnAcceptMessage(oClient, oMessage)
‘ Check client’s IP address – we only want to do this work
‘ for internal clients
If Left( oClient.IPAddress, 7 ) = “172.16.” Then
Dim oHeaders
set oHeaders = oMessage.Headers
‘ Iterate over the headers looking for Received:
Dim i
For i = oHeaders.Count -1 To 0 Step -1
Dim oHeader
Set oHeader = oHeaders.Item(i)
‘ Check if this is a header which we should modify.
If LCase(oHeader.Name) = “received” Then
‘ Log the header value in case we need it later on
EventLog.Write(“Pre-anonymisation: ” + oHeader.Value)
‘ Set up the regex
Dim myRegExp
Set myRegExp = New RegExp
myRegExp.Global = False
myRegExp.Pattern = “\bfrom[\-\sA-Za-z0-9\.\]\[\(\)]*by mail.example.com\b”
‘ Do the replacement
oHeader.Value = myRegExp.Replace( oHeader.Value, “from mailclient by mail.example.com” )
‘ Dump the modified header
EventLog.Write(“Post-anonymisation: ” + oHeader.Value)
End If
Next
‘ Save all the changes…
oMessage.Save
End If
End Sub
The before-and-after Received: headers look like this:
Received: from some-machine ([172.16.28.16]) by mail.example.com ; Tue, 8 Jun 2010 11:49:22 +0100
Received: from mailclient by mail.example.com ; Tue, 8 Jun 2010 11:49:22 +0100
…thereby neatly hiding the fact that there is an internal machine called some-machine at IP address 172.16.28.16. The original header is logged to hMailServer’s EventLog file in case it’s needed later on for debugging, or during Incident Response or other forensic activity.
You can download the script here – I hope someone finds it useful!

Alec Waters is responsible for all things security at Dataline Software, and can be emailed at alec.waters(at)dataline.co.uk

8 July, 2010 at 07:54
Could this work to send from multiple IP’s instead of annomyzing? For instance, every 1000 messages sent by hMail switch to a different outgoing IP.
8 July, 2010 at 15:33
Hi John,
The script doesn’t actually alter any of the IP addresses used in handling the message, it just masks information in Received: headers.
That said, there’s no reason why you couldn’t alter the script to make use of some kind of counter (stored in a file? or the registry? I don’t know if hMail scripts have the concept of a global variable…?). When the counter ticks past certain values, you could change what the call to myRegExp.Replace() does to alter the string inserted into the Received: header.
Why might you want to do this?
alec
7 June, 2012 at 06:16
I’ve looked around trying to understand this script to make it work but I’ve been unable to make it run… I’m on a 192.168.1.0/24 test network. I have replaced
If Left( oClient.IPAddress, 7 ) = “172.16.” Then
with:
If Left( oClient.IPAddress, 8 ) = “192.168.” Then
But in mail headers I still see the internal IP address from where it was sent:
Received: from [192.168.1.207] (domain.com [ex.ter.nal.ip])
7 June, 2012 at 06:42
mehh, never mind. I figured it out… my bad
7 June, 2012 at 08:28
Glad you got it working
30 June, 2012 at 21:20
Hello, Alec, have you any experience with using the hmailserver listserver script?
2 July, 2012 at 12:36
Hi,
No, I’m afraid not. Best place to ask might be on the hMail forums: http://www.hmailserver.com/forum/
alec
2 July, 2012 at 13:46
Okay, thank you for answering.
24 April, 2013 at 04:25
Alec, can you explain the pattern matching line:
myRegExp.Pattern = “\bfrom[\-\sA-Za-z0-9\.\]\[\(\)]*by mail.example.com\b”
Thanks!
Edward
25 April, 2013 at 09:10
Hi Edward,
It’s matching the string I want to replace. In the example below, the bit I don’t want to be seen is “some-machine ([172.16.28.16])”, provided it’s been received by mail.example.com:
Received: from some-machine ([172.16.28.16]) by mail.example.com ; Tue, 8 Jun 2010 11:49:22 +0100
So the regex:
myRegExp.Pattern = “\bfrom[\-\sA-Za-z0-9\.\]\[\(\)]*by mail.example.com\b”
…will match on everything from the word “from” up to and including “mail.example.com” (clearly you’d need to change the regex to include your mailserver’s real name rather than mail.example.com.)
Provided the regex matches, the call to .Replace() will swap the mached text for something more benign, leaving you with a much more palatable Received: header, as below:
Received: from mailclient by mail.example.com ; Tue, 8 Jun 2010 11:49:22 +0100
hth,
alec