DisabledMonkey Posted April 12, 2009 Posted April 12, 2009 Using f1iqf's winpcap udf it was simple to create a packet and get it sent off.Now the only thing I have had trouble getting to work properly is calculating the checksum's for the packet.Here is a link about how to calculate the checksums, but I've failed in my attempts.http://www.avrportal.com/?page=avrnet-checksum Example from the link:45 00 + 00 34 = 4534+ 48 18 = 8d4c+ 40 00 = cd4c+ 40 06 = 10d52+ 00 00 = 10d52+ 0a 01 = 11753+ 01 4c = 1189f+ 0a 01 = 122a0+ 01 01 = 123a123a1 + 0001 = 23a21's complement of 23a2 = dc5dI would like to be able to pass in a hex header (in string form) like "4500003448184000400600000a01014c0a010101" and get that correct checksum out ("dc5d").If anyone has any suggestions, or could point me in the correct direction your help would be much appreciated.Also if you would like to see my example (an ICMP messenger) of using f1iqf's winpcap udf just let me know.Thanks for your time,Disabled Monkey
ProgAndy Posted April 12, 2009 Posted April 12, 2009 (edited) Is this right? (didn't look at your link) $bin = Binary("0x4500003448184000400600000a01014c0a010101") $Number = 0 For $i = 1 To BinaryLen($bin) Step 2 $chunk = Hex(BinaryMid($bin,$i,2),2) $Number += Dec($chunk) Next $Number = Hex($Number,8) $Number = Dec(StringLeft($Number,4)) + Dec(StringRight($Number,4)) MsgBox(0, '', Hex(0xFFFF - $Number, 4)) Edited April 12, 2009 by ProgAndy *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes
DisabledMonkey Posted April 12, 2009 Posted April 12, 2009 (edited) Thank You ProgAndy, The checksum function worked like a charm.Thank You f1iqf for the winpcap udf.Here is my ICMP messenger if you guys want to try it out.expandcollapse popup#Include <Array.au3> #include <GUIConstants.au3> #Include <GuiEdit.au3> #Include <EditConstants.au3> #include <WindowsConstants.au3> #include <Constants.au3> #include <GuiIPAddress.au3> #include <String.au3> #include <ComboConstants.au3> #include <GDIPlus.au3> #include <Winpcap.au3> ; GUI $GUI = GuiCreate("ICMP Messenger", 410, 290, -1, -1, -1, $WS_EX_TOOLWINDOW+$WS_EX_TOPMOST) ; MENU's $filemenu = GuiCtrlCreateMenu("File") $aboutmenu = GuiCtrlCreateMenu("About") ; File Menu $Broadcastmenu = GuiCtrlCreateMenuItem("Set IP to Broadcast Address", $filemenu) $Quitmenu = GuiCtrlCreateMenuItem("Quit", $filemenu) ; About Menu $aboutmenuselect = GuiCtrlCreateMenuItem("About", $aboutmenu) ; CONTEXT MENU $contextMenu = GuiCtrlCreateContextMenu() GuiCtrlCreateMenuItem("Context Menu", $contextMenu) GuiCtrlCreateMenuItem("", $contextMenu) GuiCtrlCreateMenuItem("&Properties", $contextMenu) ; CTRLS $IP = _GUICtrlIpAddress_Create($GUI,85,5,135,23) GUICtrlCreateLabel ( "Send To IP :", 20, 9, 60) GUICtrlSetFont(-1,8) GUICtrlSetBkColor(-1, 0x000000) GUICtrlSetColor(-1, 0xC4C4C4) $message = GUICtrlCreateEdit("", 20, 75, 370, 140, $ES_MULTILINE + $ES_READONLY + $WS_VSCROLL) GUICtrlSetBkColor(-1, 0x000000) GUICtrlSetColor(-1, 0xC4C4C4) $text = GuiCtrlCreateInput("", 20, 230, 300, 20) GUICtrlSetBkColor(-1, 0x000000) GUICtrlSetColor(-1, 0xC4C4C4) GUISetBkColor(0x000000) GUISetFont(9, 400, 0, "Tahoma") WinSetTrans("ICMP Messenger", "", 230) $start = GUICtrlCreateButton ( "Start", 250, 5, 60) GUICtrlSetBkColor(-1, 0x000000) GUICtrlSetColor(-1, 0xC4C4C4) $stop = GUICtrlCreateButton ( "Stop", 330, 5,60) GUICtrlSetBkColor(-1, 0x000000) GUICtrlSetColor(-1, 0xC4C4C4) $send = GUICtrlCreateButton ( "Send", 330, 227,60) GUICtrlSetBkColor(-1, 0x000000) GUICtrlSetColor(-1, 0xC4C4C4) $winpcap=_PcapSetup() If ($winpcap=-1) Then MsgBox(16,"Pcap error !","WinPcap not found !") exit EndIf $pcap_devices=_PcapGetDeviceList() If ($pcap_devices=-1) Then MsgBox(16,"Pcap error !",_PcapGetLastError()) exit EndIf GUICtrlCreateLabel ( "Interface :", 20, 45, 60) GUICtrlSetFont(-1,8) GUICtrlSetBkColor(-1, 0x000000) GUICtrlSetColor(-1, 0xC4C4C4) $interface=GUICtrlCreateCombo("", 85, 42, 305,default,$CBS_DROPDOWNLIST) GUICtrlSetBkColor(-1, 0x000000) GUICtrlSetColor(-1, 0xC4C4C4) For $i = 0 to Ubound($pcap_devices)-1 GUICtrlSetData(-1, $pcap_devices[$i][1]) Next GUISetState() $i=0 $pcap=0 $packet=0 $pcapfile=0 Global $MACS[500] Opt("GuiOnEventMode", 1) GUICtrlSetOnEvent($start,"Start") GUICtrlSetOnEvent($stop,"Stop") GUICtrlSetOnEvent($send,"Packetize") HotKeySet("{Enter}","Packetize") GUICtrlSetOnEvent($aboutmenuselect,"About") GUISetOnEvent($GUI_EVENT_CLOSE, "Quit") GUICtrlSetOnEvent($broadcastmenu, "SetBroadcast") GUICtrlSetOnEvent($Quitmenu,"Quit") While 1 $ICMPmessage = "" If IsPtr($pcap) Then ; If $pcap is a Ptr, then the capture is running $time0=TimerInit() While (TimerDiff($time0)<500) ; Retrieve packets from queue for maximum 500ms before returning to main loop, not to "hang" the window for user $packet=_PcapGetPacket($pcap) If IsInt($packet) Then ExitLoop If IsArray($packet) = 1 Then $ICMPmessage = evalPacket($packet[3]) EndIf If $ICMPmessage <> "" Then _GUICtrlEdit_AppendText($message, $ICMPmessage & @CRLF) EndIf Wend EndIf WEnd Func evalPacket($data) ; Quick example packet dissector.... Local $macdst=StringMid ($data,3,2)&":"&StringMid ($data,5,2)&":"&StringMid ($data,7,2)&":"&StringMid ($data,9,2)&":"&StringMid ($data,11,2)&":"&StringMid ($data,13,2) Local $macsrc=StringMid ($data,15,2)&":"&StringMid ($data,17,2)&":"&StringMid ($data,19,2)&":"&StringMid ($data,21,2)&":"&StringMid ($data,23,2)&":"&StringMid ($data,25,2) Local $ethertype=BinaryMid ( $data, 13 ,2 ) If $ethertype="0x0800" Then Local $src=Number(BinaryMid ($data, 27 ,1))&"."&Number(BinaryMid ($data, 28 ,1))&"."&Number(BinaryMid ($data, 29 ,1))&"."&Number(BinaryMid ($data, 30 ,1)) Local $dst=Number(BinaryMid ($data, 31 ,1))&"."&Number(BinaryMid ($data, 32 ,1))&"."&Number(BinaryMid ($data, 33 ,1))&"."&Number(BinaryMid ($data, 34 ,1)) Switch BinaryMid ($data, 24 ,1) Case "0x01" ; Match ICMP Packet $got = StringTrimLeft($data,86) If StringLeft($got,26) = "69636D704D657373656E676572" Then ; If Matches icmpMessenger $cutcode = _HexToString(StringTrimLeft($got,26)) If $cutcode <> "" Then return $src & ": " & $cutcode EndIf EndIf EndSwitch EndIf return "" EndFunc Func Packetize() If _GUICtrlIpAddress_IsBlank($IP) <> True Then $sip = StringSplit(@IPAddress1,".") $dip = _GUICtrlIpAddress_GetArray($IP) ;Ethernet Header $etherHeader = GetDestinationMac(_GUICtrlIpAddress_Get($IP)) ;Destination Mac $etherHeader &= GetLocalMac(@IPAddress1) ;Source Mac $etherHeader &= "0800" ;Protocol ;IP Header $ipHeader = "45" ;Version / Header Length $ipHeader &= "00" ;Type of Service $ipHeader &= "3440" ;Length $ipHeader &= "00a5" ;Identification $ipHeader &= "0000" ;Flags / Fragment offset $ipHeader &= "80" ;Time to Live $ipHeader &= "01" ;Protocol $ipHeader &= "0000" ;IP Checksum $ipHeader &= hex($sip[1],2) & hex($sip[2],2) & hex($sip[3],2) & hex($sip[4],2) ;Source IP Address $ipHeader &= hex($dip[0],2) & hex($dip[1],2) & hex($dip[2],2) & hex($dip[3],2) ;Destination IP Address ;IP Checksum $ipChecksum = GetChecksum($ipHeader) ;Gets Checksum, Thank you ProgAndy $ipHeader = StringReplace($ipHeader,21,$ipChecksum) ;ICMP Header $icmpHeader = "08" ;Type $icmpHeader &= "00" ;Code $icmpHeader &= "0000" ;ICMP Checksum $icmpHeader &= "0200" ;ID $icmpHeader &= "0100" ;Sequence number ;Data $data = _StringToHex("icmpMessenger") $data &= _StringToHex(GUICtrlRead($text)) ;ICMP Checksum $icmpChecksum = GetChecksum($icmpHeader & $data);Gets Checksum, Thank you ProgAndy $icmpHeader = StringReplace($icmpHeader,5,$icmpChecksum) ;Create Packet $packet = $etherHeader & $ipHeader & $icmpHeader & $data ;Send Packet $success = _PcapSendPacket($pcap,_HexToString($packet)) If $pcap = 0 Then _GUICtrlEdit_AppendText($message, "Error: Please Start Messenger." & @CRLF) Else Clear() EndIf Else _GUICtrlEdit_AppendText($message, "Error: Please enter an IP Address to send messages to." & @CRLF) EndIf EndFunc Func Start() $prom=0 $int="" If (GUICtrlRead($interface)="Pcap capture file") Then $file=FileOpenDialog ( "Pcap file to open ?", ".", "Pcap (*.pcap)|All files (*.*)" ,1 ) $int="file://"&$file Else For $n = 0 to Ubound($pcap_devices)-1 If $pcap_devices[$n][1]=GUICtrlRead($interface) Then $int = $pcap_devices[$n][0] EndIf Next EndIf $pcap=_PcapStartCapture($int,"",$prom) If ($pcap=-1) Then _GUICtrlEdit_AppendText($message, "Error: " & _PcapGetLastError() & @CRLF) Else $linktype=_PcapGetLinkType($pcap) If ($linktype[1]<>"EN10MB") Then _GUICtrlEdit_AppendText($message, "Error: This example only works for Ethernet captures." & @CRLF) Endif GUICtrlSetState ($stop, $GUI_ENABLE) GUICtrlSetState ($start, $GUI_DISABLE) _GUICtrlEdit_AppendText($message, "----------------------------------------------------------------------------------------------------" & @CRLF) _GUICtrlEdit_AppendText($message, "Session Started: " & @Hour & ":" & @Min & " - " & @MON & "/" & @MDAY & "/" & @YEAR & @CRLF) _GUICtrlEdit_AppendText($message, "----------------------------------------------------------------------------------------------------" & @CRLF) EndIf EndFunc Func Stop() If $pcap <> -1 Then _PcapStopCapture($pcap) $pcap=-1 GUICtrlSetState ($stop, $GUI_DISABLE) GUICtrlSetState ($start, $GUI_ENABLE) _GUICtrlEdit_AppendText($message, "----------------------------------------------------------------------------------------------------" & @CRLF) _GUICtrlEdit_AppendText($message, "Session Ended: " & @Hour & ":" & @Min & " - " & @MON & "/" & @MDAY & "/" & @YEAR & @CRLF) _GUICtrlEdit_AppendText($message, "----------------------------------------------------------------------------------------------------" & @CRLF) EndIf EndFunc Func GetDestinationMac($ip) $Pos = _ArraySearch($MACS, $ip, 0, 0, 0, True) If $Pos <> -1 Then $split = StringSplit($MACS[$Pos],"|") return $split[2] Else Ping($ip) $foo = Run(@ComSpec & " /c arp -g " & $ip, @SystemDir, @SW_HIDE, $STDOUT_CHILD) While 1 $line = StdoutRead($foo) If $line <> "" Then $split = StringSplit($line,$ip,1) $strip = StringLeft(StringStripWS($split[2],8),17) $mac = StringReplace($strip,"-","") _ArrayAdd($MACS, $ip & "|" & $mac) return $mac EndIf WEnd EndIf EndFunc Func GetLocalMac($ip) $Pos = _ArraySearch($MACS, $ip, 0, 0, 0, True) If $Pos <> -1 Then $split = StringSplit($MACS[$Pos],"|") return $split[2] Else $foo = Run(@ComSpec & " /c nbtstat -A " & $ip, @SystemDir, @SW_HIDE, $STDOUT_CHILD) While 1 $line = StdoutRead($foo) If $line <> "" Then $mac = StringSplit($line,"MAC Address = ",1) If $mac[0] <> 1 Then $mac = StringStripWS(StringReplace($mac[2],"-",""),8) _ArrayAdd($MACS, $ip & "|" & $mac) return $mac EndIf EndIf WEnd EndIf EndFunc Func GetChecksum($data) ;Thank you ProgAndy $bin = Binary("0x" & $data) $Number = 0 For $i = 1 To BinaryLen($bin) Step 2 $chunk = Hex(BinaryMid($bin,$i,2),2) $Number += Dec($chunk) Next $Number = Hex($Number,8) $Number = Dec(StringLeft($Number,4)) + Dec(StringRight($Number,4)) return Hex(0xFFFF - $Number, 4) EndFunc Func Clear() GUICtrlSetData($text, "") EndFunc Func SetBroadcast() _GUICtrlIpAddress_Set($IP,_BroadcastIP()) EndFunc Func Quit() Exit EndFunc Func About() Opt("GuiOnEventMode", 0) GUISetState(@SW_DISABLE,$GUI) $AboutGUI = GUICreate("ABOUT ICMP Messenger", 410, 350,-1,-1,-1,-1,$GUI) $hWnd = WinGetHandle("ABOUT ICMP Messenger") WinSetTrans("ABOUT ICMP Messenger", "", 230) GUISetState(@SW_SHOW) ;Create Monkey _GDIPlus_Startup () $Graphic = _GDIPlus_GraphicsCreateFromHWND ($hWnd) FileInstall("C:\monkey.gif", @scriptdir&"\monkey.gif",0) $ParticleBitmap = _GDIPlus_BitmapCreateFromFile(@scriptdir & "\monkey.gif") _AntiAlias($Graphic, 4) _GDIPlus_GraphicsDrawImageRect($Graphic, $ParticleBitmap, 0, 0, 410, 350) _GDIPlus_GraphicsFillEllipse ($Graphic, 206 , 168, 4, 7) _GDIPlus_GraphicsFillEllipse ($Graphic, 216 , 168, 4, 7) ;End Create Monkey $lastPos = MouseGetPos() While 1 $mp = MouseGetPos() $newx = $mp[0] $newy = $mp[1] If $newx <> $lastpos[0] Or $newy <> $lastpos[1] Then $winPos = WinGetPos("ABOUT ICMP Messenger") $eyeXlocation = $winPos[0] + 251 $eyeYlocation = $winPos[1] + 233 $percentx = (($newx - $eyeXlocation) / @DesktopWidth) $percenty = (($newy - $eyeYlocation) / @DesktopHeight) $positionx = Int(5*$percentx) $positiony = Int(4*$percenty) _GDIPlus_GraphicsDrawImageRect($Graphic, $ParticleBitmap, 0, 0, 410, 350) If $positionx = 0 Then _GDIPlus_GraphicsFillEllipse ($Graphic, 216+$positionx, 168+$positiony, 4, 7) $positionx +=1 _GDIPlus_GraphicsFillEllipse ($Graphic, 206+$positionx, 168+$positiony, 4, 7) Else _GDIPlus_GraphicsFillEllipse ($Graphic, 216+$positionx, 168+$positiony, 4, 7) _GDIPlus_GraphicsFillEllipse ($Graphic, 206+$positionx, 168+$positiony, 4, 7) EndIf EndIf $lastPos[0] = $newx $lastPos[1] = $newy $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop EndIf sleep(20) Wend Opt("GuiOnEventMode", 1) _GDIPlus_BitmapDispose($ParticleBitmap) _GDIPlus_GraphicsDispose ($Graphic) _GDIPlus_Shutdown() GUIDelete($AboutGUI) GUISetState(@SW_ENABLE,$GUI) EndFunc Func _SubnetMask($strIP = @IPAddress1) Local $strEnumKey, $nEnum Local $strKey = "HKLM\SYSTEM\CurrentControlSet\" & _ "Services\Tcpip\Parameters\Interfaces\" While 1 $nEnum += 1 $strEnumKey = RegEnumKey($strKey, $nEnum) If @error <> 0 Then ExitLoop If RegRead($strKey & $strEnumKey, "DhcpIPAddress") = $strIP Then Return RegRead($strKey & $strEnumKey, "DhcpSubnetMask") EndIf WEnd Return SetError(1, 0, 0) EndFunc Func _BroadcastIP() $submask = _SubnetMask() $split_sub = stringsplit($submask,".") $split_ip = stringsplit(@IPAddress1,".") $Broadcast = "" If $split_sub[1] <> 0 Then for $i = 1 to 4 $Broadcast &= "."&bitOR((255-$split_sub[$i]),$split_ip[$i]) next Else return -1 EndIf $Broadcast = stringmid($Broadcast,2) return $Broadcast Endfunc Func _AntiAlias($Graphics, $iMode) Local $aResult $aResult = DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $Graphics, "int", $iMode) If @error Then Return SetError(@error, @extended, False) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFuncIt should work if you have winpcap installed, although sometime's I have to restart to get it to work, something to do with thewinpcap udf I think. (You'll obviously need the winpcap udf also.) UDF HereAlso theres an about page, which is just a picture of a monkey with it's eye's following the mouse.You'll have to download the picture and edit line 301 to get the about page to work right. Picture HereIf you have any suggestions at all please let me know, I've been programming for less than a year, so any help is appreciated.One thing that could probably be done better is getting the MAC addresses, so if you have a better way of doing that then I do, that would be a wonderful addition.Guess thats just about it.Thanks for your time,Disabled Monkey Edited April 12, 2009 by DisabledMonkey
SoulA Posted April 12, 2009 Posted April 12, 2009 (edited) I liked what you did here its good interesting stuff especially the checksum stuff provided by progandy. That will definitely come in handy later on in my other scripts. Concerning getting the MAC of the machine you are trying to talk to I have some ideas. Obviously you want to do what you did by first checking the local route ARP tables but if the entry isn't in there then you could send out a typical ARP packet and get a response that should have the MAC address. Here is what I have been fooling around with that kind of shows that off... must be compiled and run from command line look for packets sent in wireshark and what not. EDIT: Program now goes through and checks local ARP table, if no luck then sends out an ARP packet to try and get MAC address if the host is on local network. Finally, if all those options fail then we get the default gateway and give the ICMP packet the default gateways MAC address as the destination with the IP that we want to ping since it is probably outside of the network. expandcollapse popup#NoTrayIcon #AutoIt3Wrapper_Change2CUI=y #include <winpcap.au3> $STDOUT_CHILD = 0x2 ; initialise the Library $winpcap=_PcapSetup() If ($winpcap=-1) Then ConsoleWrite("WinPcap not found !") Exit EndIf ; Get the interfaces list for which a capture is possible $pcap_devices = _PcapGetDeviceList() If ($pcap_devices=-1) Then ConsoleWrite(_PcapGetLastError()) Exit EndIf For $i = 0 to UBound($pcap_devices) - 1 $sAdapterName = StringMid($pcap_devices[$i][1], StringInStr($pcap_devices[$i][1], "'", 0, 1) + 1) $sAdapterName = StringMid($sAdapterName, 1, StringInStr($sAdapterName, "'", 0, 1) -1) ConsoleWrite($i + 1 & ". " & $sAdapterName & @CRLF) Next ConsoleWrite("Choose Adapter: ") $iInput = Number(cmdRead()) ;$iInput = 1 ;debug If $iInput > $i - 1 Or $iInput < 1 Then usage() $iInput -= 1 If Not IsIPAddress($pcap_devices[$iInput][7]) Then ConsoleWrite("This device has no IP") Exit EndIf If ($pcap_devices[$iInput][3]<>"EN10MB") Then ConsoleWrite("This example only accepts Ethernet devices...") Exit Endif ConsoleWrite("Type in single IP address: ") $sIPReso = cmdRead() ;$sIPReso = "192.168.1.50" ;debug ConsoleWrite(@CRLF) $aIPReso = StringSplit($sIPReso, ".") $aIPAddr = StringSplit($pcap_devices[$iInput][7], ".") $sMAC = getMac($sIPReso) ;check ARP table to see if host is on local network If $sMAC == 0 Then $sMAC = ARPCheck($aIPReso, $aIPAddr) ;if not in ARP table send out ARP packet to see if we can get info If $sMAC == 0 Then $sMAC = getMac(get_default_gateway()) ;if ARP packet comes up with nothing get mac of the default gateway and send there If $sMAC == 0 Then ConsoleWrite("Host unreachable") Exit EndIf StringReplace($sMAC, ":", "") $sMAC = StringUpper($sMAC) ;make the packet Dim $aPacket[74] = [ _ Number(Dec(StringMid($sMAC, 1, 2))), _ ;dest mac Number(Dec(StringMid($sMAC, 3, 2))), _ Number(Dec(StringMid($sMAC, 5, 2))), _ Number(Dec(StringMid($sMAC, 7, 2))), _ Number(Dec(StringMid($sMAC, 9, 2))), _ Number(Dec(StringMid($sMAC, 11, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 1, 2))), _;source mac Number(Dec(StringMid($pcap_devices[$iInput][6], 4, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 7, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 10, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 13, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 16, 2))), _ 0x08, 0x00, _ ;IP HEADER type 0x45, _;version and length 0x00, _;diff services 0x00, 0x3C, _ ;total length 0x70, 0xf2, _;id 0x00, _;flags 0x00, _;fragment offset 0x80, _;time to live 0x01, _;protocol 0, 0, _;checksum Number($aIPAddr[1]), _ ;source ip Number($aIPAddr[2]), _ Number($aIPAddr[3]), _ Number($aIPAddr[4]), _ Number($aIPReso[1]), _ ;dest ip Number($aIPReso[2]), _ Number($aIPReso[3]), _ Number($aIPReso[4]), _ 0x08, _;type 0x00, _;code 0x00, 0x00, _;checksum 0x00, 0x01, _;identifier 0x00, 0x14];sequence number ;fill in alphabet for data 32 byts worth $i1 = 0 For $i = 42 to 73 $aPacket[$i] = 97 + $i1 $i1 += 1 If $i1 = 23 Then $i1 = 0 Next #Region checksum for ip headers $sCheckSum = "" For $i = 14 to 23 $sCheckSum &= Hex($aPacket[$i], 2) Next For $i = 26 to 33 $sCheckSum &= Hex($aPacket[$i], 2) Next $sCheckSum = checksum($sCheckSum) $aPacket[24] = Dec(StringMid($sCheckSum, 1, 2)) $aPacket[25] = Dec(StringMid($sCheckSum, 3, 2)) #EndRegion #Region checksum for ICMP $sCheckSum = Hex($aPacket[34], 2) $sCheckSum &= Hex($aPacket[35], 2) For $i = 38 to 73 $sCheckSum &= Hex($aPacket[$i], 2) Next $sCheckSum = checksum($sCheckSum) $aPacket[36] = Dec(StringMid($sCheckSum, 1, 2)) $aPacket[37] = Dec(StringMid($sCheckSum, 3, 2)) #EndRegion $sPacket = makePacket($aPacket) If $sPacket == 0 Then ConsoleWrite("Error") Exit EndIf startCapture() If _PcapSendPacket($pcap,$sPacket) = 0 Then ConsoleWrite("Packet sent") Else ConsoleWrite("Error sending packet") EndIf _PcapStopCapture($pcap) ; Stop capture _PcapFree() Func IsIPAddress($text) Return StringRegExp($text, "(((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))") EndFunc Func cmdRead() Local $input = "" $file = FileOpen("con", 4) While 1 $chr = FileRead($file, 1) If $chr = @LF Then ExitLoop $input &= BinaryToString($chr) Sleep(50) WEnd FileClose($file) $input = StringReplace($input, @CR, "") Return $input EndFunc Func usage() ConsoleWrite("Usage: Enter single ip") Exit EndFunc Func checksum($data) $bin = Binary("0x" & $data) $Number = 0 For $i = 1 To BinaryLen($bin) Step 2 $chunk = Hex(BinaryMid($bin,$i,2),2) $Number += Dec($chunk) Next $Number = Hex($Number,8) $Number = Dec(StringLeft($Number,4)) + Dec(StringRight($Number,4)) Return Hex(0xFFFF - $Number, 4) EndFunc Func getMac($ip) $foo = Run(@ComSpec & " /c arp -g " & $ip, @SystemDir, @SW_HIDE, $STDOUT_CHILD) While 1 $line = StdoutRead($foo) $line = StringReplace($line, @CRLF, "") If StringCompare($line, "No ARP Entries Found") = 0 Then Return 0 If StringCompare($line, "") <> 0 Then $split = StringSplit($line,$ip,1) $strip = StringLeft(StringStripWS($split[2],8),17) $mac = StringReplace($strip,"-","") Return $mac EndIf WEnd EndFunc Func ARPCheck($aIPReso, $aIPAddr) Dim $aARPacket[60] = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, _ Number(Dec(StringMid($pcap_devices[$iInput][6], 1, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 4, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 7, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 10, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 13, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 16, 2))), _ 0x08, 0x06, 0x00, 0x01, _ 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, _ Number(Dec(StringMid($pcap_devices[$iInput][6], 1, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 4, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 7, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 10, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 13, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 16, 2))), _ Number($aIPAddr[1]), _ Number($aIPAddr[2]), _ Number($aIPAddr[3]), _ Number($aIPAddr[4]), _ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, _ Number($aIPReso[1]), _ Number($aIPReso[2]), _ Number($aIPReso[3]), _ Number($aIPReso[4]), _ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, _ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, _ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] AdlibEnable("getPacket", 1) startCapture() $sPacket = makePacket($aARPacket) If $sPacket == 0 Then ConsoleWrite("Error") Exit EndIf _PcapSendPacket($pcap,$sPacket) Sleep(200) _PcapStopCapture($pcap) ; Stop capture AdlibDisable() EndFunc Func getPacket() $packet=_PcapGetPacket($pcap) If IsArray($packet) Then Local $aData[$packet[2]] ;get info into array of the packet $packet[3] = StringTrimLeft($packet[3], 2) For $i = 0 to $packet[2] - 1 $aData[$i] = Dec(StringLeft($packet[3], 2)) $packet[3] = StringTrimLeft($packet[3], 2) Next ;start checking if it is that packet we want $iHWType = $aData[14] & $aData[15] $iProtocolType = $aData[16] & $aData[17] $iOPCode = $aData[20] & $aData[21] $sSenderIP = $aData[28] & "." & $aData[29] & "." & $aData[30] & "." & $aData[31] $iSenderIP = Number($aData[28] & $aData[29] & $aData[30] & $aData[31]) $sDestMac = "" For $i = 32 to 37 $sDestMac &= Hex($aData[$i], 2) & ":" Next $sDestMac = StringTrimRight($sDestMac, 1) $sDestIP = $aData[38] & "." & $aData[39] & "." & $aData[40] & "." & $aData[41] ;make sure it was the type of packet we wanted If $iHWType = 01 And $iProtocolType = 80 And $iOPCode = 02 And _ StringCompare($sDestMac, $pcap_devices[$iInput][6]) = 0 And _ StringCompare($sDestIP, $pcap_devices[$iInput][7]) = 0 Then ;do nothing Else Return 0 EndIf ;if this was the right packet output the data For $i = 22 to 27 $sMAC &= Hex($aData[$i], 2) & ":" Next $sMAC = StringTrimRight($sMAC, 1) Return $sMAC EndIf EndFunc ;==>PacketX_OnPacket Func makePacket($aArray) If IsArray($aArray) Then $sPacket = "0x" For $i = 0 to UBound($aArray) - 1 $sPacket &= Hex($aArray[$i], 2) Next Return $sPacket Else Return 0 EndIf EndFunc Func startCapture() Global $pcap = _PcapStartCapture($pcap_devices[$iInput][0], "", 1) If ($pcap=-1) Then ConsoleWrite(_PcapGetLastError()) Exit EndIf EndFunc Func get_default_gateway() $foo = Run(@ComSpec & " /c netstat -rn", @SystemDir, @SW_HIDE, $STDOUT_CHILD) While 1 Sleep(50) If Not ProcessExists($foo) Then ExitLoop WEnd $line = StringStripCR(StdoutRead($foo)) If StringCompare($line, "") <> 0 Then $arr = StringSplit($line, "0.0.0.0", 1) $arr2 = StringStripWS($arr[3], 1) $arr2 = StringSplit($arr2, " ") Return $arr2[1] EndIf EndFunc Edited April 13, 2009 by SoulA
DisabledMonkey Posted April 13, 2009 Posted April 13, 2009 (edited) Thanks SoulA for your suggestion with using ARP. After looking at your example I made it so my ICMP messenger uses arp to get the remote computer's MAC address instead of pinging it. Thanks for the example because even though I didn't take alot directly from it, it helped alot. Heres the updated Code. expandcollapse popup#Include <Array.au3> #include <GUIConstants.au3> #Include <GuiEdit.au3> #Include <EditConstants.au3> #include <WindowsConstants.au3> #include <Constants.au3> #include <GuiIPAddress.au3> #include <String.au3> #include <ComboConstants.au3> #include <GDIPlus.au3> #include <Winpcap.au3> ; GUI $GUI = GuiCreate("ICMP Messenger", 410, 290, -1, -1, -1, $WS_EX_TOOLWINDOW+$WS_EX_TOPMOST) ; MENU's $filemenu = GuiCtrlCreateMenu("File") $aboutmenu = GuiCtrlCreateMenu("About") ; File Menu $Broadcastmenu = GuiCtrlCreateMenuItem("Set IP to Broadcast Address", $filemenu) $Quitmenu = GuiCtrlCreateMenuItem("Quit", $filemenu) ; About Menu $aboutmenuselect = GuiCtrlCreateMenuItem("About", $aboutmenu) ; CONTEXT MENU $contextMenu = GuiCtrlCreateContextMenu() GuiCtrlCreateMenuItem("Context Menu", $contextMenu) GuiCtrlCreateMenuItem("", $contextMenu) GuiCtrlCreateMenuItem("&Properties", $contextMenu) ; CTRLS $IP = _GUICtrlIpAddress_Create($GUI,85,5,135,23) GUICtrlCreateLabel ( "Send To IP :", 20, 9, 60) GUICtrlSetFont(-1,8) GUICtrlSetBkColor(-1, 0x000000) GUICtrlSetColor(-1, 0xC4C4C4) $message = GUICtrlCreateEdit("", 20, 75, 370, 140, $ES_MULTILINE + $ES_READONLY + $WS_VSCROLL) GUICtrlSetBkColor(-1, 0x000000) GUICtrlSetColor(-1, 0xC4C4C4) $text = GuiCtrlCreateInput("", 20, 230, 300, 20) GUICtrlSetBkColor(-1, 0x000000) GUICtrlSetColor(-1, 0xC4C4C4) GUISetBkColor(0x000000) GUISetFont(9, 400, 0, "Tahoma") WinSetTrans("ICMP Messenger", "", 230) $start = GUICtrlCreateButton ( "Start", 250, 5, 60) GUICtrlSetBkColor(-1, 0x000000) GUICtrlSetColor(-1, 0xC4C4C4) $stop = GUICtrlCreateButton ( "Stop", 330, 5,60) GUICtrlSetBkColor(-1, 0x000000) GUICtrlSetColor(-1, 0xC4C4C4) $send = GUICtrlCreateButton ( "Send", 330, 227,60) GUICtrlSetBkColor(-1, 0x000000) GUICtrlSetColor(-1, 0xC4C4C4) $winpcap=_PcapSetup() If ($winpcap=-1) Then MsgBox(16,"Pcap error !","WinPcap not found !") exit EndIf $pcap_devices=_PcapGetDeviceList() If ($pcap_devices=-1) Then MsgBox(16,"Pcap error !",_PcapGetLastError()) exit EndIf GUICtrlCreateLabel ( "Interface :", 20, 45, 60) GUICtrlSetFont(-1,8) GUICtrlSetBkColor(-1, 0x000000) GUICtrlSetColor(-1, 0xC4C4C4) $interface=GUICtrlCreateCombo("", 85, 42, 305,default,$CBS_DROPDOWNLIST) GUICtrlSetBkColor(-1, 0x000000) GUICtrlSetColor(-1, 0xC4C4C4) For $i = 0 to Ubound($pcap_devices)-1 GUICtrlSetData(-1, $pcap_devices[$i][1]) Next GUISetState() $i=0 $pcap=0 $packet=0 $pcapfile=0 Global $MACS[500] Opt("GuiOnEventMode", 1) GUICtrlSetOnEvent($start,"Start") GUICtrlSetOnEvent($stop,"Stop") GUICtrlSetOnEvent($send,"Packetize") HotKeySet("{Enter}","Packetize") GUICtrlSetOnEvent($aboutmenuselect,"About") GUISetOnEvent($GUI_EVENT_CLOSE, "Quit") GUICtrlSetOnEvent($broadcastmenu, "SetBroadcast") GUICtrlSetOnEvent($Quitmenu,"Quit") While 1 $messageReceived = "" If IsPtr($pcap) Then ; If $pcap is a Ptr, then the capture is running $time0=TimerInit() While (TimerDiff($time0)<500) ; Retrieve packets from queue for maximum 500ms before returning to main loop, not to "hang" the window for user $packet=_PcapGetPacket($pcap) If IsInt($packet) Then ExitLoop If IsArray($packet) = 1 Then $messageReceived = evalPacket($packet[3]) EndIf If $messageReceived <> "" and $messageReceived <> "gotMACAddress" Then _GUICtrlEdit_AppendText($message, $messageReceived & @CRLF) EndIf Wend EndIf WEnd Func evalPacket($data) ; Quick example packet dissector.... Local $macdst=StringMid ($data,3,2)&":"&StringMid ($data,5,2)&":"&StringMid ($data,7,2)&":"&StringMid ($data,9,2)&":"&StringMid ($data,11,2)&":"&StringMid ($data,13,2) Local $macsrc=StringMid ($data,15,2)&":"&StringMid ($data,17,2)&":"&StringMid ($data,19,2)&":"&StringMid ($data,21,2)&":"&StringMid ($data,23,2)&":"&StringMid ($data,25,2) Local $ethertype=BinaryMid ( $data, 13 ,2 ) Switch $ethertype ; Match ICMP Packet Case "0x0800" Local $src=Number(BinaryMid ($data, 27 ,1))&"."&Number(BinaryMid ($data, 28 ,1))&"."&Number(BinaryMid ($data, 29 ,1))&"."&Number(BinaryMid ($data, 30 ,1)) If BinaryMid($data, 24 ,1) = "0x01" Then $got = StringTrimLeft($data,86) If StringLeft($got,26) = "69636D704D657373656E676572" Then ; If Matches icmpMessenger $cutcode = _HexToString(StringTrimLeft($got,26)) If $cutcode <> "" Then return $src & ": " & $cutcode EndIf EndIf EndIf Case "0x0806" ; Match ARP Packet Local $src=Number(BinaryMid ($data, 29 ,1))&"."&Number(BinaryMid ($data, 30 ,1))&"."&Number(BinaryMid ($data, 31 ,1))&"."&Number(BinaryMid ($data, 32 ,1)) If $src = _GUICtrlIpAddress_Get($IP) Then ; If is ARP Reply from right IP $mac = BinaryMid($data, 23, 6) $mac = StringTrimLeft($mac,2) _ArrayAdd($MACS, $src & "|" & $mac) return "gotMACAddress" EndIf EndSwitch return "" EndFunc Func Packetize() If _GUICtrlIpAddress_IsBlank($IP) <> True Then $sip = StringSplit(@IPAddress1,".") $dip = _GUICtrlIpAddress_GetArray($IP) ;Ethernet Header $etherHeader = GetDestinationMac(_GUICtrlIpAddress_Get($IP)) ;Destination Mac $etherHeader &= GetLocalMac(@IPAddress1) ;Source Mac $etherHeader &= "0800" ;Protocol ;IP Header $ipHeader = "45" ;Version / Header Length $ipHeader &= "00" ;Type of Service $ipHeader &= "3440" ;Length $ipHeader &= "00a5" ;Identification $ipHeader &= "0000" ;Flags / Fragment offset $ipHeader &= "80" ;Time to Live $ipHeader &= "01" ;Protocol $ipHeader &= "0000" ;IP Checksum $ipHeader &= hex($sip[1],2) & hex($sip[2],2) & hex($sip[3],2) & hex($sip[4],2) ;Source IP Address $ipHeader &= hex($dip[0],2) & hex($dip[1],2) & hex($dip[2],2) & hex($dip[3],2) ;Destination IP Address ;IP Checksum $ipChecksum = GetChecksum($ipHeader) ;Gets Checksum, Thank you ProgAndy $ipHeader = StringReplace($ipHeader,21,$ipChecksum) ;ICMP Header $icmpHeader = "08" ;Type $icmpHeader &= "00" ;Code $icmpHeader &= "0000" ;ICMP Checksum $icmpHeader &= "0200" ;ID $icmpHeader &= "0100" ;Sequence number ;Data $data = _StringToHex("icmpMessenger") $data &= _StringToHex(GUICtrlRead($text)) ;ICMP Checksum $icmpChecksum = GetChecksum($icmpHeader & $data);Gets Checksum, Thank you ProgAndy $icmpHeader = StringReplace($icmpHeader,5,$icmpChecksum) ;Create Packet $packet = $etherHeader & $ipHeader & $icmpHeader & $data ;Send Packet $success = _PcapSendPacket($pcap,_HexToString($packet)) If $pcap = 0 Then _GUICtrlEdit_AppendText($message, "Error: Please Start Messenger." & @CRLF) Else Clear() EndIf Else _GUICtrlEdit_AppendText($message, "Error: Please enter an IP Address to send messages to." & @CRLF) EndIf EndFunc Func Start() $prom=0 $int="" If (GUICtrlRead($interface)="Pcap capture file") Then $file=FileOpenDialog ( "Pcap file to open ?", ".", "Pcap (*.pcap)|All files (*.*)" ,1 ) $int="file://"&$file Else For $n = 0 to Ubound($pcap_devices)-1 If $pcap_devices[$n][1]=GUICtrlRead($interface) Then $int = $pcap_devices[$n][0] EndIf Next EndIf $pcap=_PcapStartCapture($int,"",$prom) If ($pcap=-1) Then _GUICtrlEdit_AppendText($message, "Error: " & _PcapGetLastError() & @CRLF) Else $linktype=_PcapGetLinkType($pcap) If ($linktype[1]<>"EN10MB") Then _GUICtrlEdit_AppendText($message, "Error: This example only works for Ethernet captures." & @CRLF) Endif GUICtrlSetState ($stop, $GUI_ENABLE) GUICtrlSetState ($start, $GUI_DISABLE) _GUICtrlEdit_AppendText($message, "----------------------------------------------------------------------------------------------------" & @CRLF) _GUICtrlEdit_AppendText($message, "Session Started: " & @Hour & ":" & @Min & " - " & @MON & "/" & @MDAY & "/" & @YEAR & @CRLF) _GUICtrlEdit_AppendText($message, "----------------------------------------------------------------------------------------------------" & @CRLF) EndIf EndFunc Func Stop() If $pcap <> -1 Then _PcapStopCapture($pcap) $pcap=-1 GUICtrlSetState ($stop, $GUI_DISABLE) GUICtrlSetState ($start, $GUI_ENABLE) _GUICtrlEdit_AppendText($message, "----------------------------------------------------------------------------------------------------" & @CRLF) _GUICtrlEdit_AppendText($message, "Session Ended: " & @Hour & ":" & @Min & " - " & @MON & "/" & @MDAY & "/" & @YEAR & @CRLF) _GUICtrlEdit_AppendText($message, "----------------------------------------------------------------------------------------------------" & @CRLF) EndIf EndFunc Func ARPRequest() ;Thanks for the Example SoulA $sip = StringSplit(@IPAddress1,".") $dip = _GUICtrlIpAddress_GetArray($IP) ;Ethernet Header $etherHeader = "ffffffffffff" ;Destination Mac $etherHeader &= GetLocalMac(@IPAddress1) ;Source Mac $etherHeader &= "0806" ;Protocol ;ArpRequest $arpRequest = "0001" ;Hardware Type: Ethernet $arpRequest &= "0800" ;Protocol Type: IP $arpRequest &= "06" ;Hardware Size $arpRequest &= "04" ;Protocol Size $arpRequest &= "0001" ;Opcode: Request $arpRequest &= GetLocalMac(@IPAddress1) ;Sender's MAC Address $arpRequest &= hex($sip[1],2) & hex($sip[2],2) & hex($sip[3],2) & hex($sip[4],2) ;Sender's IP Address $arpRequest &= "000000000000" ; Target MAC Address $arpRequest &= hex($dip[0],2) & hex($dip[1],2) & hex($dip[2],2) & hex($dip[3],2) ;Target IP Address $Trailer = "000000000000000000" ;Trailer ;Create Packet $packet = $etherHeader & $arpRequest & $Trailer ;Send Packet $success = _PcapSendPacket($pcap,_HexToString($packet)) If $pcap = 0 Then _GUICtrlEdit_AppendText($message, "Error: Please Start Messenger." & @CRLF) EndIf EndFunc Func GetDestinationMac($ip) $Pos = _ArraySearch($MACS, $ip, 0, 0, 0, True) If $Pos <> -1 Then $split = StringSplit($MACS[$Pos],"|") return $split[2] Else ARPRequest() $messageReceived = "" $mac = "000000000000" $time0=TimerInit() While (TimerDiff($time0)<5000) ; Retrieve packets from queue for maximum 5000ms before returning to main loop, not to "hang" the window for user $packet=_PcapGetPacket($pcap) If IsInt($packet) Then ExitLoop If IsArray($packet) = 1 Then $messageReceived = evalPacket($packet[3]) EndIf If $messageReceived = "gotMACAddress" Then ; If ARP Reply is received, return the MAC from the MACS array $mac = GetDestinationMac($ip) return $mac EndIf Wend return $mac EndIf EndFunc Func GetLocalMac($ip) $Pos = _ArraySearch($MACS, $ip, 0, 0, 0, True) If $Pos <> -1 Then $split = StringSplit($MACS[$Pos],"|") return $split[2] Else $foo = Run(@ComSpec & " /c nbtstat -A " & $ip, @SystemDir, @SW_HIDE, $STDOUT_CHILD) While 1 $line = StdoutRead($foo) If $line <> "" Then $mac = StringSplit($line,"MAC Address = ",1) If $mac[0] <> 1 Then $mac = StringStripWS(StringReplace($mac[2],"-",""),8) _ArrayAdd($MACS, $ip & "|" & $mac) return $mac EndIf EndIf WEnd EndIf EndFunc Func GetChecksum($data) ;Thank you ProgAndy $bin = Binary("0x" & $data) $Number = 0 For $i = 1 To BinaryLen($bin) Step 2 $chunk = Hex(BinaryMid($bin,$i,2),2) $Number += Dec($chunk) Next $Number = Hex($Number,8) $Number = Dec(StringLeft($Number,4)) + Dec(StringRight($Number,4)) return Hex(0xFFFF - $Number, 4) EndFunc Func Clear() GUICtrlSetData($text, "") EndFunc Func SetBroadcast() _GUICtrlIpAddress_Set($IP,_BroadcastIP()) EndFunc Func Quit() Exit EndFunc Func About() Opt("GuiOnEventMode", 0) GUISetState(@SW_DISABLE,$GUI) $AboutGUI = GUICreate("ABOUT ICMP Messenger", 410, 350,-1,-1,-1,-1,$GUI) $hWnd = WinGetHandle("ABOUT ICMP Messenger") WinSetTrans("ABOUT ICMP Messenger", "", 230) GUISetState(@SW_SHOW) ;Create Monkey _GDIPlus_Startup () $Graphic = _GDIPlus_GraphicsCreateFromHWND ($hWnd) FileInstall("C:\monkey.gif", @scriptdir&"\monkey.gif",0) $ParticleBitmap = _GDIPlus_BitmapCreateFromFile(@scriptdir & "\monkey.gif") _AntiAlias($Graphic, 4) _GDIPlus_GraphicsDrawImageRect($Graphic, $ParticleBitmap, 0, 0, 410, 350) _GDIPlus_GraphicsFillEllipse ($Graphic, 206 , 168, 4, 7) _GDIPlus_GraphicsFillEllipse ($Graphic, 216 , 168, 4, 7) ;End Create Monkey $lastPos = MouseGetPos() While 1 $mp = MouseGetPos() $newx = $mp[0] $newy = $mp[1] If $newx <> $lastpos[0] Or $newy <> $lastpos[1] Then $winPos = WinGetPos("ABOUT ICMP Messenger") $eyeXlocation = $winPos[0] + 251 $eyeYlocation = $winPos[1] + 233 $percentx = (($newx - $eyeXlocation) / @DesktopWidth) $percenty = (($newy - $eyeYlocation) / @DesktopHeight) $positionx = Int(5*$percentx) $positiony = Int(4*$percenty) _GDIPlus_GraphicsDrawImageRect($Graphic, $ParticleBitmap, 0, 0, 410, 350) If $positionx = 0 Then _GDIPlus_GraphicsFillEllipse ($Graphic, 216+$positionx, 168+$positiony, 4, 7) $positionx +=1 _GDIPlus_GraphicsFillEllipse ($Graphic, 206+$positionx, 168+$positiony, 4, 7) Else _GDIPlus_GraphicsFillEllipse ($Graphic, 216+$positionx, 168+$positiony, 4, 7) _GDIPlus_GraphicsFillEllipse ($Graphic, 206+$positionx, 168+$positiony, 4, 7) EndIf EndIf $lastPos[0] = $newx $lastPos[1] = $newy $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop EndIf sleep(20) Wend Opt("GuiOnEventMode", 1) _GDIPlus_BitmapDispose($ParticleBitmap) _GDIPlus_GraphicsDispose ($Graphic) _GDIPlus_Shutdown() GUIDelete($AboutGUI) GUISetState(@SW_ENABLE,$GUI) EndFunc Func _SubnetMask($strIP = @IPAddress1) Local $strEnumKey, $nEnum Local $strKey = "HKLM\SYSTEM\CurrentControlSet\" & _ "Services\Tcpip\Parameters\Interfaces\" While 1 $nEnum += 1 $strEnumKey = RegEnumKey($strKey, $nEnum) If @error <> 0 Then ExitLoop If RegRead($strKey & $strEnumKey, "DhcpIPAddress") = $strIP Then Return RegRead($strKey & $strEnumKey, "DhcpSubnetMask") EndIf WEnd Return SetError(1, 0, 0) EndFunc Func _BroadcastIP() $submask = _SubnetMask() $split_sub = stringsplit($submask,".") $split_ip = stringsplit(@IPAddress1,".") $Broadcast = "" If $split_sub[1] <> 0 Then for $i = 1 to 4 $Broadcast &= "."&bitOR((255-$split_sub[$i]),$split_ip[$i]) next Else return -1 EndIf $Broadcast = stringmid($Broadcast,2) return $Broadcast Endfunc Func _AntiAlias($Graphics, $iMode) Local $aResult $aResult = DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $Graphics, "int", $iMode) If @error Then Return SetError(@error, @extended, False) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc Thanks for your time, Disabled Monkey Edited April 13, 2009 by DisabledMonkey
JRowe Posted April 13, 2009 Posted April 13, 2009 Arp, the seal packet. And jeez, this is like a nuclear arsenal for AutoIt. Kudos, f1iqf, very very well done. [center]However, like ninjas, cyber warriors operate in silence.AutoIt Chat Engine (+Chatbot) , Link Grammar for AutoIt , Simple Speech RecognitionArtificial Neural Networks UDF , Bayesian Networks UDF , Pattern Matching UDFTransparent PNG GUI Elements , Au3Irrlicht 2Advanced Mouse Events MonitorGrammar Database GeneratorTransitions & Tweening UDFPoker Hand Evaluator[/center]
oMBRa Posted April 13, 2009 Posted April 13, 2009 (edited) with this UDF is possible to intercept a packet and prevent it to be sent? or change some packet... Edited April 13, 2009 by oMBra
SoulA Posted April 13, 2009 Posted April 13, 2009 I don't think so. If you see a packet when capturing than it has already been sent. You can get into ARP spoofing and things that might do what you want but that is malicious and probably shouldn't be talked about.
SoulA Posted April 13, 2009 Posted April 13, 2009 (edited) Yeah so figuring out TCP checksums is pretty difficult. Here is what I have tried. I think it is doing the pseudo header that you have to add that is messing me up. Where are you progandy!!! expandcollapse popup#NoTrayIcon #AutoIt3Wrapper_Change2CUI=y #include <winpcap.au3> #include <array.au3> $STDOUT_CHILD = 0x2 ; initialise the Library $winpcap=_PcapSetup() If ($winpcap=-1) Then MsgBox(16,"Pcap error !","WinPcap not found !") Exit EndIf ; Get the interfaces list for which a capture is possible $pcap_devices = _PcapGetDeviceList() If ($pcap_devices=-1) Then MsgBox(16,"Pcap error !",_PcapGetLastError()) Exit EndIf For $i = 0 to UBound($pcap_devices) - 1 $sAdapterName = StringMid($pcap_devices[$i][1], StringInStr($pcap_devices[$i][1], "'", 0, 1) + 1) $sAdapterName = StringMid($sAdapterName, 1, StringInStr($sAdapterName, "'", 0, 1) -1) ConsoleWrite($i + 1 & ". " & $sAdapterName & @CRLF) Next ConsoleWrite("Choose Adapter: ") ;$iInput = Number(cmdRead()) $iInput = 1 ;debug If $iInput > $i - 1 Or $iInput < 1 Then usage() $iInput -= 1 If Not IsIPAddress($pcap_devices[$iInput][7]) Then ConsoleWrite("This device has no IP") Exit EndIf If ($pcap_devices[$iInput][3]<>"EN10MB") Then MsgBox(16,"Pcap error !","This example only accepts Ethernet devices...") Exit Endif If ($pcap_devices[$iInput][3]<>"EN10MB") Then MsgBox(16,"Pcap error !","This example only accepts Ethernet devices...") Exit Endif $pcap=_PcapStartCapture($pcap_devices[$iInput][0], "", 1) If ($pcap=-1) Then MsgBox(16,"Pcap error !",_PcapGetLastError()) Exit EndIf ConsoleWrite("Type in single IP address: ") ;$sIPReso = cmdRead() $sIPReso = "192.168.1.1" ConsoleWrite(@CRLF) $aIPReso = StringSplit($sIPReso, ".") $aIPAddr = StringSplit($pcap_devices[$iInput][7], ".") $sMAC = getMac($sIPReso) ;check ARP table to see if host is on local network If $sMAC == 0 Then $sMAC = ARPCheck($aIPReso, $aIPAddr) ;if not in ARP table send out ARP packet to see if we can get info If $sMAC == 0 Then $sMAC = getMac(get_default_gateway()) ;if ARP packet comes up with nothing get mac of the default gateway and send there If $sMAC == 0 Then ConsoleWrite("Host unreachable") Exit EndIf ;make the packet Dim $aPacket[62] = [ _ Number(Dec(StringMid($sMAC, 1, 2))), _ ;dest mac Number(Dec(StringMid($sMAC, 3, 2))), _ Number(Dec(StringMid($sMAC, 5, 2))), _ Number(Dec(StringMid($sMAC, 7, 2))), _ Number(Dec(StringMid($sMAC, 9, 2))), _ Number(Dec(StringMid($sMAC, 11, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 1, 2))), _;source mac Number(Dec(StringMid($pcap_devices[$iInput][6], 4, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 7, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 10, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 13, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 16, 2))), _ 0x08, 0x00, _ ;IP HEADER type 0x45, _;version and length 0x00, _;diff services 0x00, 0x30, _ ;total length 0x16, 0x79, _;id 0x40, _;flags 0x00, _;fragment offset 0x80, _;time to live 0x06, _;protocol 0, 0, _;checksum Number($aIPAddr[1]), _ ;source ip Number($aIPAddr[2]), _ Number($aIPAddr[3]), _ Number($aIPAddr[4]), _ Number($aIPReso[1]), _ ;dest ip Number($aIPReso[2]), _ Number($aIPReso[3]), _ Number($aIPReso[4]), _ 0x39, 0xb5, _ ;source port 0x00, 0x50, _ ;dest port 0xbc, 0x23, 0x15, 0x5e, _ ;seq number 0x00, 0x00, 0x00, 0x00, _ ;not sure what this is 0x70, _ ;header length 0x02, _ ;flags 0x20, 0x00, _ ;window size 0x00, 0x00, _ ;checksum 0x00, 0x00, _ ;not sure what this is 0x02, 0x04, 0x05, 0xB4, _ ;max segment size 0x01, _ ;nop 0x01, _ ;nop 0x04, 0x02] ;sack permitted _ArrayDisplay($aPacket) #Region checksum for ip headers $sCheckSum = "" For $i = 14 to 33 $sCheckSum &= Hex($aPacket[$i], 2) Next $sCheckSum = checksum($sCheckSum) $aPacket[24] = Dec(StringMid($sCheckSum, 1, 2)) $aPacket[25] = Dec(StringMid($sCheckSum, 3, 2)) #EndRegion #Region checksum for TCP $sCheckSum = "" For $i = 27 to 34 $sCheckSum &= Hex($aPacket[$i], 2) Next $sCheckSum &= Hex($aPacket[47], 2) $sCheckSum &= Hex($aPacket[48], 2) For $i = 34 to 61 $sCheckSum &= Hex($aPacket[$i], 2) Next $sCheckSum = checksum($sCheckSum) $aPacket[50] = Dec(StringMid($sCheckSum, 1, 2)) $aPacket[51] = Dec(StringMid($sCheckSum, 3, 2)) #EndRegion $sPacket = makePacket($aPacket) If $sPacket == 0 Then ConsoleWrite("Error") Exit EndIf _PcapSendPacket($pcap,$sPacket) _PcapStopCapture($pcap) ; Stop capture _PcapFree() Func IsIPAddress($text) Return StringRegExp($text, "(((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))") EndFunc Func cmdRead() Local $input = "" $file = FileOpen("con", 4) While 1 $chr = FileRead($file, 1) If $chr = @LF Then ExitLoop $input &= BinaryToString($chr) Sleep(50) WEnd FileClose($file) $input = StringReplace($input, @CR, "") Return $input EndFunc Func usage() ConsoleWrite("Usage: Enter single ip") Exit EndFunc Func checksum($data) $bin = Binary("0x" & $data) $Number = 0 For $i = 1 To BinaryLen($bin) Step 2 $chunk = Hex(BinaryMid($bin,$i,2),2) $Number += Dec($chunk) Next $Number = Hex($Number,8) $Number = Dec(StringLeft($Number,4)) + Dec(StringRight($Number,4)) Return Hex(0xFFFF - $Number, 4) EndFunc Func getMac($ip) $foo = Run(@ComSpec & " /c arp -g " & $ip, @SystemDir, @SW_HIDE, $STDOUT_CHILD) While 1 $line = StdoutRead($foo) $line = StringReplace($line, @CRLF, "") If StringCompare($line, "No ARP Entries Found") = 0 Then Return 0 If StringCompare($line, "") <> 0 Then $split = StringSplit($line,$ip,1) $strip = StringLeft(StringStripWS($split[2],8),17) $mac = StringReplace($strip,"-","") Return $mac EndIf WEnd EndFunc Func ARPCheck($aIPReso, $aIPAddr) Dim $aARPacket[60] = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, _ Number(Dec(StringMid($pcap_devices[$iInput][6], 1, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 4, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 7, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 10, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 13, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 16, 2))), _ 0x08, 0x06, 0x00, 0x01, _ 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, _ Number(Dec(StringMid($pcap_devices[$iInput][6], 1, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 4, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 7, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 10, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 13, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 16, 2))), _ Number($aIPAddr[1]), _ Number($aIPAddr[2]), _ Number($aIPAddr[3]), _ Number($aIPAddr[4]), _ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, _ Number($aIPReso[1]), _ Number($aIPReso[2]), _ Number($aIPReso[3]), _ Number($aIPReso[4]), _ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, _ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, _ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] AdlibEnable("getPacket", 1) $sPacket = makePacket($aARPacket) If $sPacket == 0 Then ConsoleWrite("Error") Exit EndIf _PcapSendPacket($pcap,$sPacket) Sleep(200) AdlibDisable() EndFunc Func getPacket() $packet=_PcapGetPacket($pcap) If IsArray($packet) Then Local $aData[$packet[2]] ;get info into array of the packet $packet[3] = StringTrimLeft($packet[3], 2) For $i = 0 to $packet[2] - 1 $aData[$i] = Dec(StringLeft($packet[3], 2)) $packet[3] = StringTrimLeft($packet[3], 2) Next ;start checking if it is that packet we want $iHWType = $aData[14] & $aData[15] $iProtocolType = $aData[16] & $aData[17] $iOPCode = $aData[20] & $aData[21] $sSenderIP = $aData[28] & "." & $aData[29] & "." & $aData[30] & "." & $aData[31] $iSenderIP = Number($aData[28] & $aData[29] & $aData[30] & $aData[31]) $sDestMac = "" For $i = 32 to 37 $sDestMac &= Hex($aData[$i], 2) & ":" Next $sDestMac = StringTrimRight($sDestMac, 1) $sDestIP = $aData[38] & "." & $aData[39] & "." & $aData[40] & "." & $aData[41] ;make sure it was the type of packet we wanted If $iHWType = 01 And $iProtocolType = 80 And $iOPCode = 02 And _ StringCompare($sDestMac, $pcap_devices[$iInput][6]) = 0 And _ StringCompare($sDestIP, $pcap_devices[$iInput][7]) = 0 Then ;do nothing Else Return 0 EndIf ;if this was the right packet output the data For $i = 22 to 27 $sMAC &= Hex($aData[$i], 2) & ":" Next $sMAC = StringTrimRight($sMAC, 1) Return $sMAC EndIf EndFunc ;==>PacketX_OnPacket Func makePacket($aArray) If IsArray($aArray) Then $sPacket = "0x" For $i = 0 to UBound($aArray) - 1 $sPacket &= Hex($aArray[$i], 2) Next Return $sPacket Else Return 0 EndIf EndFunc Func startCapture() Global $pcap = _PcapStartCapture($pcap_devices[$iInput][0], "", 1) If ($pcap=-1) Then ConsoleWrite(_PcapGetLastError()) Exit EndIf EndFunc Func get_default_gateway() $foo = Run(@ComSpec & " /c netstat -rn", @SystemDir, @SW_HIDE, $STDOUT_CHILD) While 1 Sleep(50) If Not ProcessExists($foo) Then ExitLoop WEnd $line = StringStripCR(StdoutRead($foo)) If StringCompare($line, "") <> 0 Then $arr = StringSplit($line, "0.0.0.0", 1) $arr2 = StringStripWS($arr[3], 1) $arr2 = StringSplit($arr2, " ") Return $arr2[1] EndIf EndFunc Edited April 13, 2009 by SoulA
DisabledMonkey Posted April 14, 2009 Posted April 14, 2009 Hey SoulA, Just something I noticed quick and am not sure if it's your problem but take a look. Line 184, When I send my packet into that function it is in the string form. If your not sending it in the string form, you shouldn't have to add the "0x". I actually don't even think you need the Binary. You could probably just take the first line out, and replace $bin with $data and it would work. Try this maybe. Func checksum($data) $Number = 0 For $i = 1 To BinaryLen($data) Step 2 $chunk = Hex(BinaryMid($data,$i,2),2) $Number += Dec($chunk) Next $Number = Hex($Number,8) $Number = Dec(StringLeft($Number,4)) + Dec(StringRight($Number,4)) Return Hex(0xFFFF - $Number, 4) EndFunc I'm not completely sure though. Disabled Monkey
SoulA Posted April 14, 2009 Posted April 14, 2009 (edited) I am pretty sure that is not my problem. The checksums come up fine with the other packets. The main thing is that TCP requires a "pseudo" header to be calculated with the checksum but I'm not entirely sure what all that includes. I thought I had them all but I guess not... any help would be awesome. I'm hoping someone can go through and check to see what info I added or did not add that is causing my checksum to come out incorrect. EDIT: okay I think I got this to work. Note I am just sending a syn packet here. If this were a packet with data then when doing the packet length you would have to get the length of the header AND the data. expandcollapse popup#NoTrayIcon #AutoIt3Wrapper_Change2CUI=y #include <winpcap.au3> #include <array.au3> $STDOUT_CHILD = 0x2 ; initialise the Library $winpcap=_PcapSetup() If ($winpcap=-1) Then MsgBox(16,"Pcap error !","WinPcap not found !") Exit EndIf ; Get the interfaces list for which a capture is possible $pcap_devices = _PcapGetDeviceList() If ($pcap_devices=-1) Then MsgBox(16,"Pcap error !",_PcapGetLastError()) Exit EndIf For $i = 0 to UBound($pcap_devices) - 1 $sAdapterName = StringMid($pcap_devices[$i][1], StringInStr($pcap_devices[$i][1], "'", 0, 1) + 1) $sAdapterName = StringMid($sAdapterName, 1, StringInStr($sAdapterName, "'", 0, 1) -1) ConsoleWrite($i + 1 & ". " & $sAdapterName & @CRLF) Next ConsoleWrite("Choose Adapter: ") ;$iInput = Number(cmdRead()) $iInput = 1 ;debug If $iInput > $i - 1 Or $iInput < 1 Then usage() $iInput -= 1 If Not IsIPAddress($pcap_devices[$iInput][7]) Then ConsoleWrite("This device has no IP") Exit EndIf If ($pcap_devices[$iInput][3]<>"EN10MB") Then MsgBox(16,"Pcap error !","This example only accepts Ethernet devices...") Exit Endif If ($pcap_devices[$iInput][3]<>"EN10MB") Then MsgBox(16,"Pcap error !","This example only accepts Ethernet devices...") Exit Endif $pcap=_PcapStartCapture($pcap_devices[$iInput][0], "", 1) If ($pcap=-1) Then MsgBox(16,"Pcap error !",_PcapGetLastError()) Exit EndIf ConsoleWrite("Type in single IP address: ") ;$sIPReso = cmdRead() $sIPReso = "192.168.1.1" ConsoleWrite(@CRLF) $aIPReso = StringSplit($sIPReso, ".") $aIPAddr = StringSplit($pcap_devices[$iInput][7], ".") $sMAC = getMac($sIPReso) ;check ARP table to see if host is on local network If $sMAC == 0 Then $sDefGatewayIP = get_default_gateway() ;get dfg IP $sMAC = getMac($sDefGatewayIP) ;get mac of the default gateway and send there EndIf If $sMAC == 0 Then $sMAC = ARPCheck(StringSplit($sDefGatewayIP, "."), $aIPAddr) ;if def gw not in arp table send out arp packet to get MAC If $sMAC == 0 Then ConsoleWrite("Host unreachable") Exit EndIf $sMAC = StringReplace($sMAC, ":", "") $sMAC = StringUpper($sMAC) ;make the packet Dim $aPacket[62] = [ _ Number(Dec(StringMid($sMAC, 1, 2))), _ ;dest mac Number(Dec(StringMid($sMAC, 3, 2))), _ Number(Dec(StringMid($sMAC, 5, 2))), _ Number(Dec(StringMid($sMAC, 7, 2))), _ Number(Dec(StringMid($sMAC, 9, 2))), _ Number(Dec(StringMid($sMAC, 11, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 1, 2))), _;source mac Number(Dec(StringMid($pcap_devices[$iInput][6], 4, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 7, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 10, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 13, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 16, 2))), _ 0x08, 0x00, _ ;IP HEADER type 0x45, _;version and length 0x00, _;diff services 0x00, 0x30, _ ;total length 0x16, 0x79, _;id 0x40, _;flags 0x00, _;fragment offset 0x80, _;time to live 0x06, _;protocol 0, 0, _;checksum Number($aIPAddr[1]), _ ;source ip Number($aIPAddr[2]), _ Number($aIPAddr[3]), _ Number($aIPAddr[4]), _ Number($aIPReso[1]), _ ;dest ip Number($aIPReso[2]), _ Number($aIPReso[3]), _ Number($aIPReso[4]), _ 0x39, 0xb5, _ ;source port 0x00, 0x50, _ ;dest port 0x00, 0x00, 0x00, 0x00, _ ;seq number 0x00, 0x00, 0x00, 0x00, _ ;not sure what this is 0x70, _ ;header length 0x02, _ ;flags 0x20, 0x00, _ ;window size 0, 0, _ ;checksum 0x00, 0x00, _ ;not sure what this is 0x02, 0x04, 0x05, 0xB4, _ ;max segment size 0x01, _ ;nop 0x01, _ ;nop 0x04, 0x02] ;sack permitted _ArrayDisplay($aPacket) #Region checksum for ip headers $sCheckSum = "" For $i = 14 to 33 $sCheckSum &= Hex($aPacket[$i], 2) Next $sCheckSum = checksum($sCheckSum) $aPacket[24] = Dec(StringMid($sCheckSum, 1, 2)) $aPacket[25] = Dec(StringMid($sCheckSum, 3, 2)) #EndRegion #Region checksum for TCP $sCheckSum = "" #Region PSEUDO HEADER For $i = 26 to 33 ;source and dest ip $sCheckSum &= Hex($aPacket[$i], 2) Next $sCheckSum &= Hex(0x00, 2) ;reserved field?!?!?! $sCheckSum &= Hex($aPacket[23], 2) ;IP protocol... always 06 since that is TCP $sCheckSum &= Hex($aPacket[46] - 84, 4) ;seems like this may work... have to test in other trials ;$sCheckSum &= Hex(0x00, 2) & Hex($aPacket[46], 2) ;tcp length #EndRegion For $i = 34 to 61 ;take in rest of the packet $sCheckSum &= Hex($aPacket[$i], 2) Next $sCheckSum = checksum($sCheckSum) $aPacket[50] = Dec(StringMid($sCheckSum, 1, 2)) $aPacket[51] = Dec(StringMid($sCheckSum, 3, 2)) #EndRegion $sPacket = makePacket($aPacket) If $sPacket == 0 Then ConsoleWrite("Error") Exit EndIf _PcapSendPacket($pcap,$sPacket) _PcapStopCapture($pcap) ; Stop capture _PcapFree() Func IsIPAddress($text) Return StringRegExp($text, "(((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))") EndFunc Func cmdRead() Local $input = "" $file = FileOpen("con", 4) While 1 $chr = FileRead($file, 1) If $chr = @LF Then ExitLoop $input &= BinaryToString($chr) Sleep(50) WEnd FileClose($file) $input = StringReplace($input, @CR, "") Return $input EndFunc Func usage() ConsoleWrite("Usage: Enter single ip") Exit EndFunc Func checksum($data) $bin = Binary("0x" & $data) $Number = 0 For $i = 1 To BinaryLen($bin) Step 2 $chunk = Hex(BinaryMid($bin,$i,2),2) $Number += Dec($chunk) Next $Number = Hex($Number,8) $Number = Dec(StringLeft($Number,4)) + Dec(StringRight($Number,4)) Return Hex(0xFFFF - $Number, 4) EndFunc Func getMac($ip) $foo = Run(@ComSpec & " /c arp -g " & $ip, @SystemDir, @SW_HIDE, $STDOUT_CHILD) While 1 Sleep(50) If Not ProcessExists($foo) Then ExitLoop WEnd $line = StdoutRead($foo) If StringCompare(StringReplace($line, @CRLF, ""), "No ARP Entries Found") == 0 Then Return 0 $line = StringStripWS($line, 8) If StringCompare($line, "") <> 0 Then $position = StringInStr($line, $ip, 0, -1) + StringLen($ip) $sMAC = StringReplace(StringMid($line, $position, 17), "-", ":") Return $sMAC Else Return 0 EndIf EndFunc Func ARPCheck($aIPReso, $aIPAddr) Dim $aARPacket[60] = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, _ Number(Dec(StringMid($pcap_devices[$iInput][6], 1, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 4, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 7, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 10, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 13, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 16, 2))), _ 0x08, 0x06, 0x00, 0x01, _ 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, _ Number(Dec(StringMid($pcap_devices[$iInput][6], 1, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 4, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 7, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 10, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 13, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 16, 2))), _ Number($aIPAddr[1]), _ Number($aIPAddr[2]), _ Number($aIPAddr[3]), _ Number($aIPAddr[4]), _ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, _ Number($aIPReso[1]), _ Number($aIPReso[2]), _ Number($aIPReso[3]), _ Number($aIPReso[4]), _ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, _ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, _ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] AdlibEnable("getPacket", 1) $sPacket = makePacket($aARPacket) If $sPacket == 0 Then ConsoleWrite("Error") Exit EndIf _PcapSendPacket($pcap,$sPacket) Sleep(200) AdlibDisable() EndFunc Func getPacket() $packet=_PcapGetPacket($pcap) If IsArray($packet) Then Local $aData[$packet[2]] ;get info into array of the packet $packet[3] = StringTrimLeft($packet[3], 2) For $i = 0 to $packet[2] - 1 $aData[$i] = Dec(StringLeft($packet[3], 2)) $packet[3] = StringTrimLeft($packet[3], 2) Next ;start checking if it is that packet we want $iHWType = $aData[14] & $aData[15] $iProtocolType = $aData[16] & $aData[17] $iOPCode = $aData[20] & $aData[21] $sSenderIP = $aData[28] & "." & $aData[29] & "." & $aData[30] & "." & $aData[31] $iSenderIP = Number($aData[28] & $aData[29] & $aData[30] & $aData[31]) $sDestMac = "" For $i = 32 to 37 $sDestMac &= Hex($aData[$i], 2) & ":" Next $sDestMac = StringTrimRight($sDestMac, 1) $sDestIP = $aData[38] & "." & $aData[39] & "." & $aData[40] & "." & $aData[41] ;make sure it was the type of packet we wanted If $iHWType = 01 And $iProtocolType = 80 And $iOPCode = 02 And _ StringCompare($sDestMac, $pcap_devices[$iInput][6]) = 0 And _ StringCompare($sDestIP, $pcap_devices[$iInput][7]) = 0 Then ;do nothing Else Return 0 EndIf ;if this was the right packet output the data For $i = 22 to 27 $sMAC &= Hex($aData[$i], 2) & ":" Next $sMAC = StringTrimRight($sMAC, 1) Return $sMAC EndIf EndFunc ;==>PacketX_OnPacket Func makePacket($aArray) If IsArray($aArray) Then $sPacket = "0x" For $i = 0 to UBound($aArray) - 1 $sPacket &= Hex($aArray[$i], 2) Next Return $sPacket Else Return 0 EndIf EndFunc Func startCapture() Global $pcap = _PcapStartCapture($pcap_devices[$iInput][0], "", 1) If ($pcap=-1) Then ConsoleWrite(_PcapGetLastError()) Exit EndIf EndFunc Func get_default_gateway() $foo = Run(@ComSpec & " /c netstat -rn", @SystemDir, @SW_HIDE, $STDOUT_CHILD) While 1 Sleep(50) If Not ProcessExists($foo) Then ExitLoop WEnd $line = StringStripCR(StdoutRead($foo)) If StringCompare($line, "") <> 0 Then $arr = StringSplit($line, "0.0.0.0", 1) $arr2 = StringStripWS($arr[3], 1) $arr2 = StringSplit($arr2, " ") Return $arr2[1] EndIf EndFunc Edited April 14, 2009 by SoulA
SoulA Posted April 14, 2009 Posted April 14, 2009 (edited) Okay getting a weird problem and hopefully someone can spot what I am not seeing. This is the beginning of a complete network scan type program. I'm working on TCP right now to detect what ports if any are open. When I put in a range of IP's however the checksums will come up messed up. For instance if I put in 192.168.1.1-192.168.1.10 then every other IP scanned the TCP and IP checksums will come up incorrect but the IP after that will come up correct and work just fine. If I put in just a single IP the checksum will always come up correct. What is it about my code that is making my checksums not work every other packet when it is run multiple times? Am I not setting something back to zero why are the numbers coming out the same? Here is the code... for parameters put in -ip 192.168.1.1-192.168.1.10 (ip range) -ps -p 80 and have wireshark open to get an idea what I'm talking about. expandcollapse popup#NoTrayIcon #AutoIt3Wrapper_Change2CUI=y #include <winpcap.au3> #include <array.au3> Global $STDOUT_CHILD = 0x2 Global $iScan = 0 Global $iAlive = 0 ;declare array that will be filled with what ip's we will be scanning Dim $aIPSendArray[2] = [1, 0] Global $bAlive = False Global $bPortScan = False Global $bUDP = False $bIPRange = False $bPortOpt = False $bPortOptFast = False $bIP = False $bHost = False $sIP = "" $iNum = 0 If $CmdLine[0] < 3 Then usage() If $CmdLine[1] = "/?" Then usage() For $i = 1 to $CmdLine[0] Select Case $CmdLine[$i] = "-ip" $i += 1 ;increment $bIP = True $sIPReso = String($CmdLine[$i]) Case $CmdLine[$i] = "-h" $i += 1 ;increment $bHost = True $sIP = String($CmdLine[$i]) TCPStartup() $sIP = TCPNameToIP($sIP) If @error Then ConsoleWrite("Could not resolve host name" & @CRLF) usage() EndIf TCPShutdown() Case $CmdLine[$i] = "-a" $bAlive = True Case $CmdLine[$i] = "-ps" $bPortScan = True Case $CmdLine[$i] = "-udp" $bUDP = True Case $CmdLine[$i] = "-p" $i += 1 ;increment $aPort = StringSplit($CmdLine[$i], ",") $bPortOpt = True Case $CmdLine[$i] = "-F" $bPortOptFast = True Case Else usage() EndSelect Next If $bIP <> True And $bHost <> True Then usage() ;must have one If $bIP = True And $bHost = True Then usage() ;can't have both If $bPortScan <> True And $bAlive <> True Then usage() If $bPortOpt = True and $bPortOptFast = True Then usage() If Not $bPortOpt and Not $bPortOptFast Then Dim $aPort[65536] For $i = 1 to 65535 $aPort[$i] = $i Next $aPort[0] = 65535 EndIf If $bPortOptFast Then Dim $aPort[1025] For $i = 1 to 1024 $aPort[$i] = $i Next $aPort[0] = 1024 EndIf If $bPortScan = True Then ; initialise the Library $winpcap=_PcapSetup() If ($winpcap=-1) Then MsgBox(16,"Pcap error !","WinPcap not found !") Exit EndIf ; Get the interfaces list for which a capture is possible $pcap_devices = _PcapGetDeviceList() If ($pcap_devices=-1) Then MsgBox(16,"Pcap error !",_PcapGetLastError()) Exit EndIf $iInput = 0 If Not IsIPAddress($pcap_devices[$iInput][7]) Then ConsoleWrite("This device has no IP") Exit EndIf If ($pcap_devices[$iInput][3]<>"EN10MB") Then MsgBox(16,"Pcap error !","This example only accepts Ethernet devices...") Exit EndIf $pcap=_PcapStartCapture($pcap_devices[$iInput][0], "", 1) If ($pcap=-1) Then MsgBox(16,"Pcap error !",_PcapGetLastError()) Exit EndIf $aIPAddr = StringSplit($pcap_devices[$iInput][7], ".") $sMAC = getMac($sIP) ;check ARP table to see if host is on local network If $sMAC == 0 Then $sDefGatewayIP = get_default_gateway() ;get dfg IP $sMAC = getMac($sDefGatewayIP) ;get mac of the default gateway and send there EndIf If $sMAC == 0 Then $sMAC = ARPCheck(StringSplit($sDefGatewayIP, "."), $aIPAddr) ;if def gw not in arp table send out arp packet to get MAC If $sMAC == 0 Then ConsoleWrite("Host unreachable") Exit EndIf $sMAC = StringReplace($sMAC, ":", "") $sMAC = StringUpper($sMAC) ;make the packet Dim $aPacket[62] = [ _ Number(Dec(StringMid($sMAC, 1, 2))), _ ;dest mac Number(Dec(StringMid($sMAC, 3, 2))), _ Number(Dec(StringMid($sMAC, 5, 2))), _ Number(Dec(StringMid($sMAC, 7, 2))), _ Number(Dec(StringMid($sMAC, 9, 2))), _ Number(Dec(StringMid($sMAC, 11, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 1, 2))), _;source mac Number(Dec(StringMid($pcap_devices[$iInput][6], 4, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 7, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 10, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 13, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 16, 2))), _ 0x08, 0x00, _ ;IP HEADER type 0x45, _;version and length 0x00, _;diff services 0x00, 0x30, _ ;total length 0x16, 0x79, _;id 0x40, _;flags 0x00, _;fragment offset 0x80, _;time to live 0x06, _;protocol 0, 0, _;checksum Number($aIPAddr[1]), _ ;source ip Number($aIPAddr[2]), _ Number($aIPAddr[3]), _ Number($aIPAddr[4]), _ 0, _ ;dest ip 0, _ 0, _ 0, _ 0x39, 0xb5, _ ;source port 0, 0, _ ;dest port 0x00, 0x00, 0x00, 0x00, _ ;seq number 0x00, 0x00, 0x00, 0x00, _ ;not sure what this is 0x70, _ ;header length 0x02, _ ;flags 0x20, 0x00, _ ;window size 0, 0, _ ;checksum 0x00, 0x00, _ ;not sure what this is 0x02, 0x04, 0x05, 0xB4, _ ;max segment size 0x01, _ ;nop 0x01, _ ;nop 0x04, 0x02] ;sack permitted EndIf $time = TimerInit() If $bHost = True Then selection($sIP) ElseIf $bIP = True Then If StringInStr($sIPReso, "-") Then $bIPRange = True $aIP = StringSplit($sIPReso, "-") If UBound($aIP) > 3 Then usage() If Not IsIPAddress($aIP[1]) Then usage() If Not IsIPAddress($aIP[2]) Then usage() If StringCompare($aIP[1], $aIP[2]) = 0 Then usage() $aIP1 = StringSplit($aIP[1], ".") $aIP2 = StringSplit($aIP[2], ".") For $i = 1 to 4 If Number($aIP1[$i]) <> Number($aIP2[$i]) Then ExitLoop Next If Number($aIP1[$i]) > Number($aIP2[$i]) Then usage() Select Case $i = 1 $aIPSendArray[1] = 1 For $iIP = Number($aIP1[$i]) to Number($aIP2[$i]) For $i1 = Number($aIP1[$i + 1]) to 255 For $i2 = Number($aIP1[$i + 2]) to 255 For $i3 = Number($aIP1[$i + 3]) to 255 $sIPReso = (String($iIP & "." & $i1 & "." & $i2 & "." & $i3)) selection($sIPReso) If $i3 = Number($aIP2[4]) AND $i2 = Number($aIP2[3]) Then ExitLoop Next $aIP1[$i + 3] = 1 If $i2 = Number($aIP2[3]) AND $i1 = Number($aIP2[2]) Then ExitLoop Next $aIP1[$i + 2] = 1 If $i1 = Number($aIP2[2]) AND $iIP = Number($aIP2[$i]) Then ExitLoop Next $aIP1[$i + 1] = 1 Next Case $i = 2 $aIPSendArray[1] = 2 For $iIP = Number($aIP1[$i]) to Number($aIP2[$i]) For $i1 = Number($aIP1[$i + 1]) to 255 For $i2 = Number($aIP1[$i + 2]) to 255 $sIPReso = (String($aIP2[1] & "." & $iIP & "." & $i1 & "." & $i2)) selection($sIPReso) If $i2 = Number($aIP2[4]) AND $i1 = Number($aIP2[3]) Then ExitLoop Next $aIP1[$i + 2] = 1 If $i1 = Number($aIP2[3]) AND $iIP = Number($aIP2[$i]) Then ExitLoop Next $aIP1[$i + 1] = 1 Next Case $i = 3 $aIPSendArray[1] = 3 For $iIP = Number($aIP1[$i]) to Number($aIP2[$i]) For $i1 = Number($aIP1[$i + 1]) to 255 $sIPReso = (String($aIP2[1] & "." & $aIP2[2] & "." & $iIP & "." & $i1)) selection($sIPReso) If $i1 = Number($aIP2[4]) AND $iIP = Number($aIP2[$i]) Then ExitLoop Next $aIP1[$i + 1] = 1 Next Case $i = 4 $aIPSendArray[1] = 4 For $iIP = Number($aIP1[$i]) to Number($aIP2[$i]) $sIPReso = (String($aIP2[1] & "." & $aIP2[2] & "." & $aIP2[3] & "." & $iIP)) selection($sIPReso) Next EndSelect Else If Not IsIPAddress($sIPReso) Then usage() selection($sIPReso) EndIf EndIf scan() If $bAlive = True Then If $iAlive = 1 Then ConsoleWrite("There is " & $iAlive & " alive host." & @CRLF) Else ConsoleWrite("There are " & $iAlive & " alive hosts." & @CRLF) EndIf EndIf ;how many hosts we scanned and how long If $iScan = 1 Then ConsoleWrite("Scanned " & $iScan & " address in " & round(TimerDiff($time) / 1000, 2) & " seconds") Else ConsoleWrite("Scanned " & $iScan & " addresses in " & round(TimerDiff($time) / 1000, 2) & " seconds") EndIf Func scan() For $i = 2 to $aIPSendArray[0] Select Case $bAlive = True And $bPortScan = True alive($aIPSendArray[$i]) If Not @error Then If $bUDP = True Then udp($aIPSendArray[$i], $aPort) Else tcp($aIPSendArray[$i], $aPort) EndIf EndIf Case $bAlive = True And $bPortScan = False alive($aIPSendArray[$i]) Case $bAlive = False And $bPortScan = True If $bUDP = True Then udp($aIPSendArray[$i], $aPort) Else tcp($aIPSendArray[$i], $aPort) EndIf EndSelect Next $iScan += $aIPSendArray[0] - 1 EndFunc ;fill in array of ips that we are going to scan Func selection($sIPReso) $aIPSendArray[0] += 1 ReDim $aIPSendArray[$aIPSendArray[0] + 1] $aIPSendArray[$aIPSendArray[0]] = $sIPReso If $aIPSendArray[0] = 10000 Then scan() Local $iTemp = $aIPSendArray[1] Dim $aIPSendArray[2] = [1, $iTemp] EndIf EndFunc ;==>selection Func alive($sIP) $itime = Ping($sIP, 200) If $iTime <> 0 Then ConsoleWrite($sIP & " is alive " & $itime & "ms" & @CRLF) $iAlive += 1 Else Switch @error Case 1 ConsoleWrite($sIP & " is offline" & @CRLF) Case 2 ConsoleWrite($sIP & " is unreachable" & @CRLF) Case 3 ConsoleWrite($sIP & " is a bad destination" & @CRLF) Case 4 ConsoleWrite($sIP & " had other error" & @CRLF) EndSwitch SetError(1) EndIf EndFunc Func tcp($sIP, $aPort) ConsoleWrite("Scanning " & $sIP & @CRLF) $timeport = TimerInit() For $i = 1 To $aPort[0] $aIPReso = StringSplit($sIP, ".") $aPacket[30] = Number($aIPReso[1]) $aPacket[31] = Number($aIPReso[2]) $aPacket[32] = Number($aIPReso[3]) $aPacket[33] = Number($aIPReso[4]) $hPort = Hex($aPort[$i], 4) $aPacket[36] = Dec(StringMid($hPort, 1, 2)) $aPacket[37] = Dec(StringMid($hPort, 3, 2)) #Region checksum for ip headers $sCheckSum = "" For $i1 = 14 to 33 $sCheckSum &= Hex($aPacket[$i1], 2) Next $sCheckSum = checksum($sCheckSum) $aPacket[24] = Dec(StringMid($sCheckSum, 1, 2)) $aPacket[25] = Dec(StringMid($sCheckSum, 3, 2)) #EndRegion #Region checksum for TCP $sCheckSum = "" #Region PSEUDO HEADER For $i1 = 26 to 33 ;source and dest ip $sCheckSum &= Hex($aPacket[$i1], 2) Next $sCheckSum &= Hex(0x00, 2) ;reserved field?!?!?! $sCheckSum &= Hex($aPacket[23], 2) ;IP protocol... always 06 since that is TCP $sCheckSum &= Hex($aPacket[46] - 84, 4) ;seems like this may work... have to test in other trials ;$sCheckSum &= Hex(0x00, 2) & Hex($aPacket[46], 2) ;tcp length #EndRegion For $i1 = 34 to 61 ;take in rest of the packet $sCheckSum &= Hex($aPacket[$i1], 2) Next ;MsgBox(0, "", $sCheckSum) $sCheckSum = checksum($sCheckSum) $aPacket[50] = Dec(StringMid($sCheckSum, 1, 2)) $aPacket[51] = Dec(StringMid($sCheckSum, 3, 2)) #EndRegion $sPacket = makePacket($aPacket) If $sPacket == 0 Then ConsoleWrite("Error") Exit EndIf _PcapSendPacket($pcap,$sPacket) Next ConsoleWrite("Scanned " & $aPort[0] & " ports in " & round(TimerDiff($timeport) / 1000, 2) & " seconds" & @CRLF & @CRLF) EndFunc Func udp($sIP, $aPort) TCPStartup() ConsoleWrite($sIP & @CRLF) $timeport = TimerInit() For $i = 1 To $aPort[0] $socket = UDPOpen($sIP, $aPort[$i]) If $socket <> -1 Then ConsoleWrite("Port " & $aPort[$i] & " is open" & @CRLF) UDPCloseSocket($socket) EndIf Next ConsoleWrite("Scanned " & $aPort[0] & " ports in " & round(TimerDiff($timeport) / 1000, 2) & " seconds" & @CRLF) TCPShutdown() EndFunc Func checksum($data) $bin = Binary("0x" & $data) $Number = 0 For $index = 1 To BinaryLen($bin) Step 2 $chunk = Hex(BinaryMid($bin,$index,2),2) $Number += Dec($chunk) Next $Number = Hex($Number,8) $Number = Dec(StringLeft($Number,4)) + Dec(StringRight($Number,4)) Return Hex(0xFFFF - $Number, 4) EndFunc Func usage() ConsoleWrite("Usage: -ip 192.168.1.1[-192.168.1.255] or [-h hostname] [-ps] [-a] optional: [-udp] [-p 80[,81[,..]] or [-F]" & @CRLF & @CRLF _ & " -ip " & @TAB & @TAB & "... allows you to enter a single ip or ip range" & @CRLF _ & " -h " & @TAB & @TAB & "... lets you enter a hostname instead of an ip" & @CRLF _ & " -a " & @TAB & @TAB & "... checks to see if hosts are alive" & @CRLF _ & " -ps " & @TAB & @TAB & "... does a port scan of all ports" & @CRLF _ & " -udp" & @TAB & @TAB & "... will scan target hosts udp ports" & @CRLF _ & " -p " & @TAB & @TAB & "... specifies single port or multiple... -p 21,22,23" & @CRLF _ & " -F " & @TAB & @TAB & "... Specifies a fast scan of well known ports between 1 and 1024." & @CRLF _ & " " & @TAB & @TAB & " Otherwise all 65535 ports are scanned" & @CRLF & @CRLF) Exit EndFunc Func IsIPAddress($text) Return StringRegExp($text, "(((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))") EndFunc Func getMac($ip) $foo = Run(@ComSpec & " /c arp -g " & $ip, @SystemDir, @SW_HIDE, $STDOUT_CHILD) While 1 Sleep(50) If Not ProcessExists($foo) Then ExitLoop WEnd $line = StdoutRead($foo) If StringCompare(StringReplace($line, @CRLF, ""), "No ARP Entries Found") == 0 Then Return 0 $line = StringStripWS($line, 8) If StringCompare($line, "") <> 0 Then $position = StringInStr($line, $ip, 0, -1) + StringLen($ip) $sMAC = StringReplace(StringMid($line, $position, 17), "-", ":") Return $sMAC Else Return 0 EndIf EndFunc Func ARPCheck($aIPReso, $aIPAddr) Dim $aARPacket[60] = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, _ Number(Dec(StringMid($pcap_devices[$iInput][6], 1, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 4, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 7, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 10, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 13, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 16, 2))), _ 0x08, 0x06, 0x00, 0x01, _ 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, _ Number(Dec(StringMid($pcap_devices[$iInput][6], 1, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 4, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 7, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 10, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 13, 2))), _ Number(Dec(StringMid($pcap_devices[$iInput][6], 16, 2))), _ Number($aIPAddr[1]), _ Number($aIPAddr[2]), _ Number($aIPAddr[3]), _ Number($aIPAddr[4]), _ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, _ Number($aIPReso[1]), _ Number($aIPReso[2]), _ Number($aIPReso[3]), _ Number($aIPReso[4]), _ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, _ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, _ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] AdlibEnable("getARPPacket", 1) $sPacket = makePacket($aARPacket) If $sPacket == 0 Then ConsoleWrite("Error") Exit EndIf _PcapSendPacket($pcap,$sPacket) Sleep(200) AdlibDisable() EndFunc Func getARPPacket() $packet=_PcapGetPacket($pcap) If IsArray($packet) Then Local $aData[$packet[2]] ;get info into array of the packet $packet[3] = StringTrimLeft($packet[3], 2) For $i = 0 to $packet[2] - 1 $aData[$i] = Dec(StringLeft($packet[3], 2)) $packet[3] = StringTrimLeft($packet[3], 2) Next ;start checking if it is that packet we want $iHWType = $aData[14] & $aData[15] $iProtocolType = $aData[16] & $aData[17] $iOPCode = $aData[20] & $aData[21] $sSenderIP = $aData[28] & "." & $aData[29] & "." & $aData[30] & "." & $aData[31] $iSenderIP = Number($aData[28] & $aData[29] & $aData[30] & $aData[31]) $sDestMac = "" For $i = 32 to 37 $sDestMac &= Hex($aData[$i], 2) & ":" Next $sDestMac = StringTrimRight($sDestMac, 1) $sDestIP = $aData[38] & "." & $aData[39] & "." & $aData[40] & "." & $aData[41] ;make sure it was the type of packet we wanted If $iHWType = 01 And $iProtocolType = 80 And $iOPCode = 02 And _ StringCompare($sDestMac, $pcap_devices[$iInput][6]) = 0 And _ StringCompare($sDestIP, $pcap_devices[$iInput][7]) = 0 Then ;do nothing Else Return 0 EndIf ;if this was the right packet output the data For $i = 22 to 27 $sMAC &= Hex($aData[$i], 2) & ":" Next $sMAC = StringTrimRight($sMAC, 1) Return $sMAC EndIf EndFunc ;==>PacketX_OnPacket Func makePacket($aArray) If IsArray($aArray) Then $sPacket = "0x" For $i = 0 to UBound($aArray) - 1 $sPacket &= Hex($aArray[$i], 2) Next Return $sPacket Else Return 0 EndIf EndFunc Func get_default_gateway() $foo = Run(@ComSpec & " /c netstat -rn", @SystemDir, @SW_HIDE, $STDOUT_CHILD) While 1 Sleep(50) If Not ProcessExists($foo) Then ExitLoop WEnd $line = StringStripCR(StdoutRead($foo)) If StringCompare($line, "") <> 0 Then $arr = StringSplit($line, "0.0.0.0", 1) $arr2 = StringStripWS($arr[3], 1) $arr2 = StringSplit($arr2, " ") Return $arr2[1] EndIf EndFunc Edited April 15, 2009 by SoulA
ptrex Posted April 15, 2009 Posted April 15, 2009 @SoulA I could run some tests. But I don't like CUI applications ! This is just my personal taste. So for the moment I am not much into testing. Regards ptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New
SoulA Posted April 15, 2009 Posted April 15, 2009 (edited) You don't have to compile it... just put the code into SCiTe and then go to view -> parameters and put in the parameters I specified in there. Run the program through scite... output should come out to the console like normal and look at the results of a scan of ips like 192.168.1.1-192.168.1.50 in wireshark and you'll see the alternating weird pattern I have been talking about. Edited April 15, 2009 by SoulA
f1iqf Posted April 18, 2009 Posted April 18, 2009 (edited) Hello !Please find below some crc functions I'm using (for ip,icmp,tcp,udp). Those functions will be shortly incorporated in my winpcap UDF as "utility functions". Please report any bug to opensource (at) grisambre (dot) netexpandcollapse popup; Extract a $bytes bytes value from a $data binary string, starting from offset $offset (1 for first byte) Func BinaryVal($data,$offset,$bytes); 1 for first byte as $offset return Dec(StringMid($data, 3+($offset-1)*2 ,$bytes*2)) EndFunc ; $data is the packet data as a binary string ; $ipoffset is offset to the ip header; 14 bytes by default for an ethernet frame ; one should check before calling this function that data actualy contains an IP packet ! Func IpCheckSum ($data,$ipoffset=14) Local $iplen=BitAnd(BinaryVal($data,$ipoffset+1,1),0xF)*4 Local $sum=0,$i For $i=1 To $iplen step 2 $sum+=BitAnd(0xFFFF,BinaryVal($data,$ipoffset+$i,2)) Next $sum-=BinaryVal($data,$ipoffset+11,2) While $sum>0xFFFF $sum = BitAnd($sum,0xFFFF)+BitShift($sum,16) Wend return BitXOR($sum,0xFFFF) EndFunc ; $data is the packet data as a binary string ; $ipoffset is offset to the ip header; 14 bytes by default for an ethernet frame ; one should check before calling this function that data actualy contains an ICMP packet ! Func IcmpCheckSum ($data,$ipoffset=14) Local $iplen=BitAnd(BinaryVal($data,$ipoffset+1,1),0xF)*4 Local $len=BinaryVal($data,$ipoffset+3,2)-$iplen; ip len - ip header len Local $sum=0,$i For $i=1 To BitAnd($len,0xFFFE) step 2 $sum+=BitAnd(0xFFFF,BinaryVal($data,$ipoffset+$iplen+$i,2)) Next If BitAnd($len,1) Then $sum+=BitAnd(0xFF00,BitShift(BinaryVal($data,$ipoffset+$iplen+$len,1),-8)) EndIf $sum-=BinaryVal($data,$ipoffset+$iplen+3,2) While $sum>0xFFFF $sum = BitAnd($sum,0xFFFF)+BitShift($sum,16) Wend return BitXOR($sum,0xFFFF) EndFunc ; $data is the packet data as a binary string ; $ipoffset is offset to the ip header; 14 bytes by default for an ethernet frame ; one should check before calling this function that data actualy contains a TCP packet ! Func TcpCheckSum ($data,$ipoffset=14) Local $iplen=BitAnd(BinaryVal($data,$ipoffset+1,1),0xF)*4 Local $len=BinaryVal($data,$ipoffset+3,2)-$iplen; ip len - ip header len Local $sum=0,$i For $i=1 To BitAnd($len,0xFFFE) step 2 $sum+=BitAnd(0xFFFF,BinaryVal($data,$ipoffset+$iplen+$i,2)) Next If BitAnd($len,1) Then $sum+=BitAnd(0xFF00,BitShift(BinaryVal($data,$ipoffset+$iplen+$len,1),-8)) EndIf $sum+=BinaryVal($data,$ipoffset+13,2)+BinaryVal($data,$ipoffset+15,2)+BinaryVal($data,$ipoffset+17,2)+BinaryVal($data,$ipoffset+19,2)+$len+6-BinaryVal($data,$ipoffset+$iplen+17,2); tcp pseudo header While $sum>0xFFFF $sum = BitAnd($sum,0xFFFF)+BitShift($sum,16) Wend return BitXOR($sum,0xFFFF) EndFunc ; $data is the packet data as a binary string ; $ipoffset is offset to the ip header; 14 bytes by default for an ethernet frame ; one should check before calling this function that data actualy contains a UDP packet ! ; Also, if the packet UDP value is set to 0x0000, no need to call this function, it means the CRC is not used in this packet. Func UdpCheckSum ($data,$ipoffset=14) Local $iplen=BitAnd(BinaryVal($data,$ipoffset+1,1),0xF)*4 Local $len=BinaryVal($data,$ipoffset+3,2)-$iplen; ip len - ip header len Local $sum=0,$i For $i=1 To BitAnd($len,0xFFFE) step 2 $sum+=BitAnd(0xFFFF,BinaryVal($data,$ipoffset+$iplen+$i,2)) Next If BitAnd($len,1) Then $sum+=BitAnd(0xFF00,BitShift(BinaryVal($data,$ipoffset+$iplen+$len,1),-8)) EndIf $sum+=BinaryVal($data,$ipoffset+13,2)+BinaryVal($data,$ipoffset+15,2)+BinaryVal($data,$ipoffset+17,2)+BinaryVal($data,$ipoffset+19,2)+$len+17-BinaryVal($data,$ipoffset+$iplen+7,2); udp pseudo header While $sum>0xFFFF $sum = BitAnd($sum,0xFFFF)+BitShift($sum,16) Wend Local $crc=BitXOR($sum,0xFFFF) If $crc=0x0000 Then return 0xFFFF return $crc EndFunc Edited April 25, 2009 by f1iqf
SoulA Posted April 18, 2009 Posted April 18, 2009 Again f1iqf you have come through with some EXCELLENT code I thank you very much.
SoulA Posted April 19, 2009 Posted April 19, 2009 (edited) here is something cool I whipped up tonight that captures packets and outputs the headers and data. Code was mostly stolen from f1iqf and the packetx examples so props to them I just compiled it. expandcollapse popup#NoTrayIcon #AutoIt3Wrapper_Change2CUI=y #include <winpcap.au3> If $CmdLine[0] > 2 Or $CmdLine[0] < 1 Then usage() If $CmdLine[1] = "/?" Then usage() For $i = 1 to $CmdLine[0] Select Case $CmdLine[$i] == "-L" listAdapters() Exit Case $CmdLine[$i] == "-i" $i += 1 ;increment $iInput = $CmdLine[$i] Case Else usage() EndSelect Next ; initialise the Library $winpcap=_PcapSetup() If ($winpcap=-1) Then ConsoleWrite("WinPcap not found !") Exit EndIf ; Get the interfaces list for which a capture is possible $pcap_devices=_PcapGetDeviceList() If ($pcap_devices=-1) Then ConsoleWrite(_PcapGetLastError()) Exit EndIf $i = UBound($pcap_devices) - 1 If $iInput > $i Or $iInput < 1 Then ConsoleWrite("Not a valid number") Exit EndIf $iInput -= 1 If Not IsIPAddress($pcap_devices[$iInput][7]) Then ConsoleWrite("This device has no IP") Exit EndIf ConsoleWrite(@CRLF) If ($pcap_devices[$iInput][3]<>"EN10MB") Then ConsoleWrite("This example only accepts Ethernet devices...") Exit EndIf $pcap=_PcapStartCapture($pcap_devices[$iInput][0], "", 1) If ($pcap=-1) Then ConsoleWrite(_PcapGetLastError()) Exit EndIf While 1 Sleep(10) $packet=_PcapGetPacket($pcap) If IsArray($packet) Then dissect($packet) EndIf Wend ; Stop capture _PcapStopCapture($pcap) ; release ressources _PcapFree() Func usage() ConsoleWrite("Usage: -L initiates a list of interfaces to capture on -i [number] to specifiy adapter from list "& @CRLF & @CRLF _ & " -L " & @TAB & @TAB & "... brings up list of devices to capture from" & @CRLF _ & " -h " & @TAB & @TAB & "... lets you specify by number the adapter you want to capture from" & @CRLF & @CRLF) Exit EndFunc Func IsIPAddress($text) Return StringRegExp($text, "(((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))") EndFunc Func dissect($packet) Local $aData[$packet[2]] Local $sDestMac = "", $sSourceMAC = "" ;get info into array of the packet $packet[3] = StringTrimLeft($packet[3], 2) For $i = 0 To $packet[2] - 1 $aData[$i] = Dec(StringLeft($packet[3], 2)) $packet[3] = StringTrimLeft($packet[3], 2) Next $iTypeEth = $aData[12] & $aData[13] If $iTypeEth == 86 Then For $i = 32 To 37 $sDestMac &= Hex($aData[$i], 2) & ":" Next $sDestMac = StringTrimRight($sDestMac, 1) ;if this was the right packet output the data For $i = 22 To 27 $sSourceMAC &= Hex($aData[$i], 2) & ":" Next $sSourceMAC = StringTrimRight($sSourceMAC, 1) $iOPCode = $aData[20] & $aData[21] $sSenderIP = $aData[28] & "." & $aData[29] & "." & $aData[30] & "." & $aData[31] $sDestIP = $aData[38] & "." & $aData[39] & "." & $aData[40] & "." & $aData[41] If $iOPCode = 01 Then ConsoleWrite("ARP Request " & $sSourceMAC & " -> " & $sDestMac & @CRLF) ConsoleWrite("Who has " & $sDestIP & "? Tell " & $sSenderIP & "." & @CRLF & @CRLF) Return 1 ElseIf $iOPCode = 02 Then ConsoleWrite("ARP Reply " & $sSourceMAC & " -> " & $sDestMac & @CRLF) ConsoleWrite($sSenderIP & " is at " & $sSourceMAC & "." & @CRLF & @CRLF) Return 1 Else Return 0 ;didn't match any opcodes EndIf EndIf If $iTypeEth == 80 Then $sSenderIP = $aData[26] & "." & $aData[27] & "." & $aData[28] & "." & $aData[29] $sDestIP = $aData[30] & "." & $aData[31] & "." & $aData[32] & "." & $aData[33] Switch $aData[23] Case 06 Local $flags=Binary($aData[47]) Local $f="" If BitAND($flags,0x01) Then $f="Fin " If BitAND($flags,0x02) Then $f&="Syn " If BitAND($flags,0x04) Then $f&="Rst " If BitAND($flags,0x08) Then $f&="Psh " If BitAND($flags,0x10) Then $f&="Ack " If BitAND($flags,0x20) Then $f&="Urg " If BitAND($flags,0x40) Then $f&="Ecn " If BitAND($flags,0x80) Then $f&="Cwr " $f=StringTrimRight(StringReplace($f," ",","),1) ConsoleWrite("TCP (" & $f & ") " & $sSenderIP & ":" & Dec(Hex($aData[34] & $aData[35], 4)) & " -> " & $sDestIP & ":" & _ Dec(Hex($aData[36] & $aData[37],4)) & @CRLF) If Hex($aData[46], 2) == 70 Then PrintData($aData, 34 + 28, $packet[2] - 1) ElseIf Hex($aData[46], 2) == 50 Then PrintData($aData, 34 + 20, $packet[2] - 1) EndIf Case 17 ConsoleWrite("UDP " & $sSenderIP & ":" & Dec(Hex($aData[34] & $aData[35], 4)) & " -> " & $sDestIP & ":" & _ Dec(Hex($aData[36] & $aData[37], 4)) & @CRLF) PrintData($aData, 34 + 8, $packet[2] - 1) Case 01 If $aData[34] == 8 Then $flag = "request" If $aData[34] == 0 Then $flag = "reply" ConsoleWrite("ICMP (" & $flag & ") " & $sSenderIP & " -> " & $sDestIP & @CRLF) PrintData($aData, 34 + 8, $packet[2] - 1) Case Else ConsoleWrite("IP " & $sSenderIP & " -> " & $sDestIP & @CRLF & @CRLF) EndSwitch EndIf EndFunc Func PrintData($aPacket, $iBegin, $iEnd) Dim $sline = '' Local $tline = '' For $i = $iBegin to $iEnd $bByte = $aPacket[$i] If StringLen($sline) >= 48 Then ConsoleWrite($sline & @LF) $sline = "" EndIf If $bByte <= Chr(4) Then $tline = $tline & "0" ;~ $sline = $sline & "0" EndIf $sline = $sline & Hex($bByte, 2) & " " $tline = $tline & Hex($bByte, 2) & " " Next If StringLen($sline) > 0 Then Local $wLine = '' Local $hesadecimale = StringSplit($tline, ' ') For $i = 1 To $hesadecimale[0] $wLine &= _HexToString($hesadecimale[$i]) Next ConsoleWrite($sline & @LF) ConsoleWrite($wLine & @LF) Else ConsoleWrite("" & @LF) EndIf ConsoleWrite(@CRLF) EndFunc ;==>PrintData Func _HexToString($strHex) Local $strChar, $aryHex, $i, $iDec, $Char, $iOne, $iTwo $aryHex = StringSplit($strHex, "") If Mod($aryHex[0], 2) <> 0 Then SetError(1) Return -1 EndIf For $i = 1 To $aryHex[0] $iOne = $aryHex[$i] $i = $i + 1 $iTwo = $aryHex[$i] $iDec = Dec($iOne & $iTwo) If @error <> 0 Then SetError(1) Return -1 EndIf $Char = Chr($iDec) $strChar &= $Char Next Return $strChar EndFunc ;==>_HexToString Func listAdapters() ; initialise the Library $winpcap=_PcapSetup() If ($winpcap=-1) Then ConsoleWrite("WinPcap not found !") Exit EndIf ; Get the interfaces list for which a capture is possible $pcap_devices=_PcapGetDeviceList() If ($pcap_devices=-1) Then ConsoleWrite(_PcapGetLastError()) Exit EndIf For $i = 0 to UBound($pcap_devices) - 1 $sAdapterName = StringMid($pcap_devices[$i][1], StringInStr($pcap_devices[$i][1], "'", 0, 1) + 1) $sAdapterName = StringMid($sAdapterName, 1, StringInStr($sAdapterName, "'", 0, 1) -1) ConsoleWrite($i + 1 & ". " & $sAdapterName & @CRLF) Next _PcapFree() EndFunc Edited April 19, 2009 by SoulA
f1iqf Posted April 22, 2009 Posted April 22, 2009 The Winpcap UDF has been updated to 1.2a on its website.No bug correction so far; Only added 6 utility functions (read an write easily a value inside a binary string, and checksum computation functions for IP, ICMP, TCP, UDP almost as given in my last post, minus a few bugs and renaimed to match the UDF naming rules).As usual, please report any bug or comment to opensource (arobas) grisambre (dot) net !
ptrex Posted April 23, 2009 Posted April 23, 2009 (edited) @f1iqfI tested some of your examples posted on your website.I was able to :- List the devices- Capture some HTTP packets - Create a PCAP file- Read a PCAP fileThe data coming out of the PCAP file doesn't tell me a lot ?Time ----------- Length - Packet - Data 12:32:47.945233 62 62 0x00907F2E06DF000FB040CA8F080045000030A33E4000800625360A0000470FC91844218B0050918F40ED000000007002FC0060D700000204055001010402When I open the PCAP file using Ethereal I does read it well !!But can I find the data structure I see in here compared to what I see in the read PCAP function.The Ethereal output is Time - Source - Destination - Protocol - Info DataOutput if the Function is Time - Lenght - Packet - Data ? Can you give an example on how to read the output comparable to what I see in Etherial ?PS : Good UDF so far !! Edit : nevermind my question. I figured out how to read the data. Thanks again.Thanksptrex Edited April 23, 2009 by ptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New
f1iqf Posted April 25, 2009 Posted April 25, 2009 Hello !I just released another winpcap autoit3 demo script, to capture http files. It supports and recovers from missing TCP packets, crc errors, SACKs, packets in wrong order... (but not yet for ip fragmentation). It is available on its own webpage.As usual, comments or bug repports to opensource (arobase) grisambre (dot) net wakillon 1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now