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
8 July, 2013 at 16:57
I have entered the script into my mail server and I’ve been unable to make it run… I’m on a 192.168.1.0/24 network. I have replaced
If Left( oClient.IPAddress, 7 ) = “172.16.” Then
with:
If Left( oClient.IPAddress, 8 ) = “192.168.” Then
but the internal name still shows up as well as the internal computer name.
8 July, 2013 at 22:09
What happens if you EventLog.Write( oClient.IPAddress ) right at the start of OnAcceptMessage(), just as a debugging step? What gets logged?
10 July, 2013 at 01:02
Do I put that before OnAcceptMessage() ? I’m new to this.
10 July, 2013 at 01:36
I tried adding it before, after and below and nothing shows up in the log. I’m also new to hMailserver so I don’t know all the nuances of it. I really would like to figure out where I went wrong so that I can put this into production. Thank You
10 July, 2013 at 02:22
Disregard my confusion. Finally figured it all out and its works beautifully. Thank you.
14 August, 2013 at 21:12
http://www.hmailserver.com/documentation/v5.4/?page=com_example_trigger_remove_headers
I just removed second Received header. Its easy.
Sub OnAcceptMessage(oClient, oMessage)
Dim oHeaders
set oHeaders = oMessage.Headers
EventLog.Write(“Header count: ” + CStr(oHeaders.Count))
Dim i
For i = oHeaders.Count -1 To 0 Step -1
dim oHeader
Set oHeader =oHeaders.Item(i)
EventLog.Write(“Header found: ” + oHeader.Name)
‘ Check i this is a header which we should delete.
if LCase(oHeader.Name) = “received” Then
oHeader.Delete
EventLog.Write(“Header deleted.”)
End If
Next
‘ Save all the changes…
oMessage.Save
End Sub
21 March, 2014 at 04:59
I am not sure why people find out solutions and never post them. Could someone please let me know what I need to do to change this to a 192.168.1.0/24 network. I tried changing left , 10 and value to 192.168.1. .
so..
if Left(oClient.IPAddress, 10) = “192.168.1.”
Is this correct? If not, I would really appreciate some advice.
21 March, 2014 at 09:52
Hi Tony,
What happens if you EventLog.Write( oClient.IPAddress ) right at the start of OnAcceptMessage(), just as a debugging step? What gets logged?
alec
10 July, 2015 at 15:05
Thanks mate, been trying to figure this one out!