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

19 Responses to “hMailServer script to anonymise internal IP addresses”

  1. 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.

    • 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

  2. It does not seem to be working for me Says:

    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])

  3. It does not seem to be working for me Says:

    mehh, never mind. I figured it out… my bad 😛

  4. Hello, Alec, have you any experience with using the hmailserver listserver script?

  5. Alec, can you explain the pattern matching line:
    myRegExp.Pattern = “\bfrom[\-\sA-Za-z0-9\.\]\[\(\)]*by mail.example.com\b”

    Thanks!
    Edward

    • 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

  6. David Says:

    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.

    • What happens if you EventLog.Write( oClient.IPAddress ) right at the start of OnAcceptMessage(), just as a debugging step? What gets logged?

  7. Do I put that before OnAcceptMessage() ? I’m new to this.

    • 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

  8. Disregard my confusion. Finally figured it all out and its works beautifully. Thank you.

  9. 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

  10. 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.

    • 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

  11. justin Says:

    Thanks mate, been trying to figure this one out!

Leave a reply to Alec Waters Cancel reply