博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Playing with sockets (port scanning)
阅读量:6998 次
发布时间:2019-06-27

本文共 37565 字,大约阅读时间需要 125 分钟。

hot3.png

=-|================================================-{ www.enye-sec.org }-====|=-[ Playing with sockets (port scanning) ]-==================================|=-|==========================================================================|=-[ by Pepelux 
 ]-======================-[13/11/2007]-=|------[ 0.- Index ]0.- Index1.- Quickly introduction  1.1.- Open Scan  1.2.- Half Open Scan  1.3.- Stealth Scan2.- Playing with sockets  2.1.- TCP Sockets  2.2.- UDP / ICMP Sockets3.- Operating system detection  3.1.- Some tests4.- Files5.- References6.- End------[ 1.- Introduction ]Many time ago we scanned the different ports making telnet manually. Todaypeople use more soffisticated programs with massive methods to scan IPranges searching a lot of ports.I'm going to write very quickly the different methods of scanning because youcan found on Internet a lot of information about this. Furthermore, thefinally of this paper is to have fun showing and studing how the socketsworks.------[ 1.1.- Open Scan ]Known as TCP Scan and normally used to program sockets, this technique isthe oldest and works making a full connection with the server. Is similar tomake a telnet to each port but automatically.For that it makes an autentication with 3 packets. Is known asthree-way-handshake:For the ports opened:      Client ---->   SYN   ---->             <---- SYN/ACK <---- Server      Client ---->   ACK   ---->For the ports closed:      Client ---->   SYN   ---->             <----   RST   <---- ServerAdvantages   : very easy to program.Disadvantages: is very easy to detect and make logs on each connection.------[ 1.2.- Half Open Scan ]This technique works making only the start of the connection. Sending a SYNbut without send the ACK in the case that the port is opened.Using RAW sockets we can program manually the socket headers and send onlythe start of the connection. Lately we'll see better with some examples.------[ 1.3.- Stealth Scan ]Is similar to the previous method but sending another flag, or a combinationof flags.The most known and used by nmap are:      SYN      SYN+ACK      FIN      ACK      NULL (all flags with 0)      XMAS (FIN=URG=PSH=1)In the examples we'll see clearly.------[ 2.- Playing with sockets ]Is time to have fun. We are going to send different packets changing flagsand studing results.For the tests I have used two computers:Client: 192.168.2.5 (Linux Debian - kernel 2.6.18.1)Server: 192.168.2.7 (Linux Debian - kernel 2.6.21.2)Opened ports in the server: 22(TCP), 80(TCP), 111(UDP)------[ 2.1.- TCP Sockets ]To probe TCP ports we are going to use a program to send and receive RAWsockets, allowing us to choose the flag values:- sendsock.c -> Usage: ./sendsocket [s|a|r|p|u|f] [-x host_source] -d host_destination -c port            -s SYN flag enabled            -a ACK flag enabled            -r RST flag enabled            -p PSH flag enabled            -u URG flag enabled            -f FIN flag enabledSend SYN (half open connection)-------------------------------Consists in make a half connection, sending a SYN, and when we obtain anyresponse (ACK+SYN or RST) sending a RST to end the comunication (using RAWsockets, the RST packet is sent automatically by the kernel).Original idea consists in send a SYN and if the resver response with anACK+SYN, we send a RST packet saying that we don't want to make a connection... all is a wrong and the server doesn't save any log.Today many computers can detect it and save a log or block this kind ofattacks with a firewall.Advantages   : workss in all operating systems and ports, if don't use afirewall.Disadvantages: is very easy to detect and log it.     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 80 -s      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  1  |  0  |  0  |  0  |  0  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=39553 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  1  |  1  |  0  |  0  |  0  |  0  | 64  | 53270     seq=-1378930670 - ack_seq=863708102 - doff=6 - check=8049 - ID=0Port opened. We obtain SYN+ACK and Window<>0     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 23 -s      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  1  |  0  |  0  |  0  |  0  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=54145 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  1  |  1  |  0  |  0  |  0  | 64  | 0     seq=0 - ack_seq=863708102 - doff=5 - check=49281 - ID=0Port closed. We obtain ACK+RST and Window=0Send ACK--------This method only affect to some old BSD and Unix operating systems andconsists in check Window field. If we obtain a Window=0 the port is openedand if we obtain a Window<>0 the port is closed.Advantages   : is more difficult to detect.Disadvantages: doesn't work in all operating systems.     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 80 -a      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  1  |  0  |  0  |  0  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=35969 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  1  |  0  |  0  |  0  | 64  | 0     seq=0 - ack_seq=0 - doff=5 - check=61122 - ID=0     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 23 -a      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  1  |  0  |  0  |  0  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=50561 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  1  |  0  |  0  |  0  | 64  | 0     seq=0 - ack_seq=0 - doff=5 - check=10179 - ID=0In this case my linux is not vulnerable and we have obtained the same resultwith opened and cloed ports.Send RST--------This attack affect only some systems and is not effective always. In thecase we obtain only an ACK or if we don't obtain response, the port isopened and if we obtain a RST, the port is closed.Advantages   : is more diffcult to detect.Disadvantages: doesn't work in all systems neither ports.     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 80 -r      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  1  |  0  |  0  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=39041 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  1  |  0  |  1  |  0  |  0  | 53  | 37920     seq=1193401395 - ack_seq=908914171 - doff=5 - check=43532 - ID=4979Port opened. We obtain ACK+PSH, TTL<64 and Window<>0     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 23 -r      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  1  |  0  |  0  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=53633 - ID=27032Without response ... Port closed     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 22 -r      SENT DATA     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  1  |  0  |  0  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=53889 - ID=27032Without response ... Response is not trustworthy because the port is openedAs we can see, if we obtain any response the port is opened and if we don'tobtain response, we can't know if the port is opened or closed.Send PSH--------This attack affect only some systems and is not effective always. In thecase we obtain a ACK+PSH and a Windows<>0 or don't obtain response, the portis opened and iif we obtain a RST, the port is closed.Advantages   : is more diffcult to detect.Disadvantages: doesn't work in all systems.     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 80 -p      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  0  |  1  |  0  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=38017 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  1  |  0  |  1  |  0  |  0  | 53  | 17447     seq=1710733151 - ack_seq=1317887646 - doff=5 - check=32634 - ID=4439Port opened. We obtain ACK+PSH, TTL<64 and Window<>0     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 23 -p      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  0  |  1  |  0  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=52609 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  1  |  1  |  0  |  0  |  0  | 64  | 0     seq=0 - ack_seq=846930886 - doff=5 - check=49537 - ID=0Port closed. We obtain RST, TTL=64 and Window=0     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 22 -p      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  0  |  1  |  0  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=52865 - ID=27032Without response ... port closedSend URG--------This attack affect only some systems and is not effective always. In thecase we obtain an ACK without a RST or if we don't obtain response, the portis opened and if we obtain a RST, the port is closed.Advantages   : is more difficult to detect.Disadvantages: works in my Linux but I don't know if works in other systems.     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 80 -u      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  0  |  0  |  1  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=31873 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  1  |  0  |  1  |  0  |  0  | 53  | 37920     seq=-716127216 - ack_seq=1741636632 - doff=5 - check=41524 - ID=59663Port opened. We obtain ACK+PSH, TTL<64 and Window<>0     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 23 -u      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  0  |  0  |  1  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=46465 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  1  |  1  |  0  |  0  |  0  | 64  | 0     seq=0 - ack_seq=846930886 - doff=5 - check=49537 - ID=0Port closed. We obtain ACK+RST, TTL=64 and Window=0     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 22 -u      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  0  |  0  |  1  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=3968 - ID=27032Without response ... port openedSend FIN--------This attack affect only some systems and is not effective always. In thecase we obtain an ACK or if we don't obtain response, the port is opened andif we obtain a RST, the port is closed.If other systems you can see the difference in the RST flag. If is activatedthe port is closed and if RST value is zero the port is opened.Advantages   : is more difficult to detect.Disadvantages: doesn't work in all operating systems because is based on a               bug.     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 80 -f      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  0  |  0  |  0  |  1  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=39809 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  1  |  0  |  1  |  0  |  1  | 53  | 37920     seq=-1722694640 - ack_seq=1741636632 - doff=5 - check=39751 - ID=56001Port opened. We obtain ACK+PSH+FIN, TTL<64 and Window<>0     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 23 -f      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  0  |  0  |  0  |  1  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=54401 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  1  |  1  |  0  |  0  |  0  | 64  | 0     seq=0 - ack_seq=863708102 - doff=5 - check=49281 - ID=0Port closed. We obtain ACK+RST, TTL=64 and Window=0     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 22 -f      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  0  |  0  |  0  |  1  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=54657 - ID=27032Without response ... port openedSend SYN+ACK------------We are going to use some combinations of flags. This attack only work insome systems. When it works, if you don't obtain any response, the port isopened and if you obtain a RST, the port is closed.Advantages   : is more difficult to detect.Disadvantages: doesn't work in all systems.     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 80 -s -a      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  1  |  1  |  0  |  0  |  0  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=35457 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  1  |  0  |  0  |  0  | 64  | 0     seq=0 - ack_seq=0 - doff=5 - check=61122 - ID=0     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 23 -s -a      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  1  |  1  |  0  |  0  |  0  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=50049 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  1  |  0  |  0  |  0  | 64  | 0     seq=0 - ack_seq=0 - doff=5 - check=10179 - ID=0In this case we obtain the same result and we don't know if the port isopened or closed. As I saw before, only affect some systems :)Send SYN+PSH------------When we don't obtain a RST and Windows<>0, the port is opened and with a RSTand Window=0, the port is clised.Advantages   : is more difficult to detect.Disadvantages: works in my Linux but I don't know if works in other systems.     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 80 -s -p      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  1  |  0  |  0  |  1  |  0  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=37505 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  1  |  1  |  0  |  0  |  0  |  0  | 64  | 53270     seq=1874969709 - ack_seq=863708102 - doff=6 - check=51491 - ID=0Port opened. We obtain SYN+ACK and Window<>0     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 22 -s -p      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  1  |  0  |  0  |  1  |  0  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=52353 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  1  |  1  |  0  |  0  |  0  |  0  | 64  | 53270     seq=1445991790 - ack_seq=863708102 - doff=6 - check=52148 - ID=0Port opened. We obtain SYN+ACK and Window<>0     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 23 -s -p      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  1  |  0  |  0  |  1  |  0  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=52097 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  1  |  1  |  0  |  0  |  0  | 64  | 0     seq=0 - ack_seq=863708102 - doff=5 - check=49281 - ID=0Port closed. We obtain ACK+RST and Window=0Send URG+FIN------------In this case, if we don't obtain response, the port is opened and with aRST, the port is closed.Advantages   : is more difficult to detect.Disadvantages: works in my Linux but I don't know if works in other systems.     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 80 -u -f      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  0  |  0  |  1  |  1  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=31617 - ID=27032Without response ... port opened     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 23 -u -f      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  0  |  0  |  1  |  1  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=46209 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  1  |  1  |  0  |  0  |  0  | 64  | 0     seq=0 - ack_seq=863708102 - doff=5 - check=49281 - ID=0Port closed. We obtain ACK+RST     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 22 -u -f      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  0  |  0  |  1  |  1  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=46465 - ID=27032Without response ... port openedSend URG+FIN+PSH----------------More known as XMAS scan, when we don't obtain response or don't obtain a RSTthe port is open. Is closed when we obtain a RST.Advantages   : is more difficult to detect.Disadvantages: only for some systems.     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 80 -p -u -f      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  0  |  1  |  1  |  1  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=23938 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  1  |  1  |  0  |  0  |  0  |  0  | 47  | 10262     seq=128745367 - ack_seq=338264191 - doff=10 - check=49414 - ID=0Port opened. We obtain SYN+ACK     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 22 -p -u -f      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  0  |  1  |  1  |  1  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=38786 - ID=27032Without response ... port opened     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 22 -u -f      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  0  |  1  |  1  |  1  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=38530 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  1  |  1  |  0  |  0  |  0  | 56  | 0     seq=0 - ack_seq=863708102 - doff=5 - check=43650 - ID=56815Port closed. We obtain ACK+RSTSend null---------Known as null scan, it consist in send all flags with zero. In this case,when response is an ACK or if we don't obtain response, the port is openedand with a RST, the port is closed.Advantages   : is more difficult to detect.Disadvantages: only for some systems.     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 80      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  0  |  0  |  0  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=40065 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  1  |  0  |  0  |  0  |  0  | 53  | 22560     seq=-515721121 - ack_seq=1706581918 - doff=5 - check=55050 - ID=61453Port opened. We obtain ACK     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 23      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  0  |  0  |  0  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=54657 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  1  |  1  |  0  |  0  |  0  | 64  | 0     seq=0 - ack_seq=846930886 - doff=5 - check=49537 - ID=0Port closed. We obtain ACK+RST     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 22      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  0  |  0  |  0  |  0  |  0  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=54913 - ID=27032Without response ... port openedSend SYN+ACK+RST+PSH+URG+FIN----------------------------Consist in send all flags activated (with 1). In this case, when theresponse is an ACK or if we don't obtain response, the port is opened. With a RST the port is closed.Advantages   : is more difficult to detect.Disadvantages: only for Unix.     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 80 -s -a -r                   -p -u -f      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  1  |  1  |  1  |  1  |  1  |  1  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=23937 - ID=27032      RECEIVED DATA      -------------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  1  |  0  |  1  |  0  |  1  | 53  | 37920     seq=2033962504 - ack_seq=-1093275500 - doff=5 - check=8061 - ID=35468Port opened. We obtain ACK+PSH     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 23 -s -a -r                   -p -u -f      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  1  |  1  |  1  |  1  |  1  |  1  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=38529 - ID=27032Without response ... result not valid because the port is closed really     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 22 -s -a -r                   -p -u -f      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  1  |  1  |  1  |  1  |  1  |  1  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=38785 - ID=27032Without response ... result not valid because the port is opened reallyIf this case the technique is not valid for us because the responses ar notfiables. As I have saw befote, only works on Unix.------[ 2.2.- UDP / ICMP Sockets ]To check UDP ports we are going to play a little more sending packets. UDPprotocol is not oriented into a connection, not as TCP, and we can't wait fora response after send a packet. For that, using only UDP we can't known ifthe port is opened.To do the scan we are going to aid us with ICMP packets. Why? because whenyou try to make a connection with an UDP port the server will response withan ICP packet in case of error; justly a type 3 / code 3 packet , that ifyou show RFC papers you can know: type 3 = destination unreachable message /code 3 = port unreachable.As we love to make this things manually, we are going to use two programs:- checkicmp.c -> listen for ICMP connection with our computer- sendudp.c   -> send an UDP packet into a host / port     flashgordon# ./checkicmp     Waiting data ...While program is waiting, we open another terminal and send into a closedport:     flashgordon# ./sendudp 192.168.2.7 100     Sending UDP packet to 192.168.2.7:100If we show the other terminal we can see:     flashgordon# ./checkicmp     Waiting data ...     Received:       type 3  code 3This tell us that the port is closed ... check for an opened port to seewhat happend:     flashgordon# ./sendudp 192.168.2.7 111     Sending UDP packet to 192.168.2.7:111And in the other terminal:     flashgordon# ./checkicmp     Waiting data ...     Received:       type 3  code 3Not changes (the message is of the last packet :P) ... as we don't reciveany packet we can say that the port is opened.Test another time with a closed port:     flashgordon# ./sendudp 192.168.2.7 101     Sending UDP packet to 192.168.2.7:101And in the other terminal:     flashgordon# ./checkicmp     Waiting data ...     Received:       type 3  code 3     Received:       type 3  code 3We have obtain another ICMP packet saying us that 101 port is closed too.------[ 3.- Operationg system detection ]We can known the operating system running into a server without make a TCPconnection. As occurs with scan methods showed before, different servers canresponse different packets (we saw that the TCP connection send a SYN andwait for a SYN+ACK or a RST) because each system can response differently.Occurs the same sending UDP or ICMP packets that not are tipical to do anstandard connection.I'm not show all differences between operating systems because it require alos of test with a lot of operating systems and a lot of free time :) ...furthermore, nmap has a very good database of operating systems detectables,based in the famouse QueSO of Savage.But we are going to play a little more with the sockets to see any exampleand understand all that.For the tests I have used four computers:Client : 192.168.2.5 (Linux Debian - kernel 2.6.18.1)Server1: 192.168.2.7 (Linux Debian)Server2: 192.168.2.6 (Windows 2000 Server)Server3: 192.168.2.8 (Solaris)Pport opened in the three servers: 80(TCP)Before to do anything to know that for operating systems detection you canplay with more header fields of each packet, but for not change the programsand as this is only a test, we are going to use the same flags as before.------[ 3.1.- Some tests ]To do the tests we are going to send a TCP packet to the port 80 (opened)with flags SYN+URG+FIN activated.Fist server, under Linux:     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.7 -c 80 -s -u -f      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  1  |  0  |  0  |  0  |  1  |  1  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=31617 - ID=27032      RECEIVED DATA     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  1  |  1  |  0  |  0  |  0  |  0  | 64  | 6272     seq=24764339 - ack_seq=863708102 - doff=6 - check=32130 - ID=0Second server, under Windows:     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.6 -c 80 -s -u -f      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  1  |  0  |  0  |  0  |  1  |  1  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=17292 - ID=27032      RECEIVED DATA     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  0  |  1  |  0  |  1  |  0  |  0  | 48  | 33820     seq=2043592525 - ack_seq=772288166 - doff=5 - check=30285 - ID=15717Third server, under Solaris:     flashgordon# ./sendsocket -x 192.168.2.5 -d 192.168.2.8 -c 80 -s -u -f      SENT DATA      ---------     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  1  |  0  |  0  |  0  |  1  |  1  | 64  | 65535     seq=846930886 - ack_seq=0 - doff=5 - check=50815 - ID=27032      RECEIVED DATA     | SYN | ACK | RST | PSH | URG | FIN | TTL | Window     |  1  |  1  |  0  |  0  |  0  |  0  | 41  | 65535     seq=1684159920 - ack_seq=1278904408 - doff=6 - check=34271 - ID=62243If we analyze differences:- Linux  : SYN+ACK - TTL=64 - Window= 6272- Windows: ACK+PSH - TTL=48 - Window=33820- Solaris: SYN+ACK - TTL=41 - Window=65535As I said before, this is only a test to understand as operating systemsdetection works. Really we have to change more fields and combine with UDPand ICMP packets. The differences between Linux, Windows and Solaris isevident, but using more tests we can see differences between differentsversionsof each operating system, for example between Windows 98 and Windows200, or see differences between each Linux distributions or kernels.------[ 4.- Files ]Programs used to do the tests:--- sendsocket.c --------------------------8<---------------------------------// sendsocket.c// By Pepelux// Change DEFAULT_HOST writing your private IP if you want to use always the // same IP address#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define Error(msg) { perror(msg); exit -1; }#define DEFAULT_HOST "PUT HERE YOUR PRIVATE IP"#define PBUFFER 10000#define BUFFER_LONG 65536#define DEFAULT_LEN     (sizeof(struct tcphdr)+sizeof(struct iphdr))void usage(char *nom);unsigned short cksum(unsigned short *, int);void SendPacket(struct sockaddr_in saddr, struct sockaddr_in daddr, int dport, int syn, int ack, int psh, int rst, int urg, int fin);int main(int argc, char *argv[]) { int dport; char *host_dest, *host_source; struct sockaddr_in saddr, daddr; struct hostent *hostentry; int i, c; int h = 0; // destination flag int x = 0; // Source flag int syn = 0; // SYN flag int ack = 0; // ACK flag int rst = 0; // RST flag int urg = 0; // URG flag int fin = 0; // FIN flag int psh = 0; // PSH flag        if (geteuid() != 0) {                printf("You must be root to use RAW Sockets\n");                exit(0);        } // Check params while((c = getopt(argc, argv, "saprufd:x:c:")) != -1) { switch(c) { case 'd': // destination host if(strlen(optarg) == 0) usage(argv[0]); host_dest = optarg; h++; break; case 's': // SYN syn = 1; break; case 'a': // ACK ack = 1; break; case 'r': // RST rst = 1; break; case 'p': // PUSH psh = 1; break; case 'u': // URG urg = 1; break; case 'f': // FIN fin = 1; break; case 'x': // source host if(strlen(optarg) == 0) usage(argv[0]); host_source = optarg; x++; break; case 'c': // destination port if(strlen(optarg) == 0) usage(argv[0]); dport = atoi(optarg); break; default: usage(argv[0]); break; } } if (x == 0) host_source = DEFAULT_HOST; if (h == 0) usage(argv[0]);  // you must write destination host. Error // IP source if((hostentry = gethostbyname(host_source)) == NULL)  Error("Error solving source address"); bzero(&saddr, sizeof(struct sockaddr)); saddr.sin_family = AF_INET; saddr.sin_addr = *((struct in_addr *)hostentry->h_addr); // IP destination if((hostentry = gethostbyname(host_dest)) == NULL)  Error("Error solving destination address"); bzero(&daddr, sizeof(struct sockaddr)); daddr.sin_family = AF_INET; daddr.sin_addr = *((struct in_addr *)hostentry->h_addr); // Send data SendPacket(saddr, daddr, dport, syn, ack, psh, rst, urg, fin);}void SendPacket(struct sockaddr_in saddr, struct sockaddr_in daddr, int dport, int syn, int ack, int psh, int rst, int urg, int fin) { int                 destination_port, source_port, on, s, rs, pid; int status, i; char                buffer[BUFFER_LONG], rbuffer[BUFFER_LONG]; char string[BUFFER_LONG]; struct iphdr        *iphdr, *riphdr; struct tcphdr       *tcphdr, *rtcphdr; struct sockaddr     from; int                 fromlen, ethlen; struct pseudohdr { struct in_addr saddr; struct in_addr daddr; unsigned char zero; unsigned char protocol; unsigned short length; } *pseudoheader; ethlen = sizeof(struct ethhdr); on = 1; source_port = htons(random()); destination_port = htons(dport); setvbuf(stdout, NULL, _IONBF, 0); fflush(stdout); if((pid=fork()) == -1) Error("fork"); if(pid) { if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) Error("socket"); if(setsockopt(s, IPPROTO_IP, IP_HDRINCL,(char *)&on,  sizeof(on)) < 0) Error("setsockopt"); bzero(buffer, BUFFER_LONG); // TCP header tcphdr =                       (struct tcphdr *)(buffer+ sizeof(struct iphdr)); tcphdr->source =               htons(source_port); // puerto origen tcphdr->dest =                 destination_port; // puerto destino tcphdr->window =               htons(65535); // ventana tcphdr->seq =                  random(); // numero de secuencia aleatorio tcphdr->syn =                  syn; // flag SYN tcphdr->ack =                  ack; // flag ACK tcphdr->rst =                  rst; // flag RST tcphdr->psh =                  psh; // flag PSH tcphdr->urg =                  urg; // flag URG tcphdr->fin =                  fin; // flag FIN tcphdr->doff =                 sizeof(struct tcphdr) / 4; // TCP pseudoheader pseudoheader =                 (struct pseudohdr *) ((unsigned char *)tcphdr-sizeof(struct pseudohdr)); pseudoheader->saddr =          saddr.sin_addr; // direccion origen pseudoheader->daddr =          daddr.sin_addr; // direccion destino pseudoheader->protocol =       IPPROTO_TCP; // protocolo pseudoheader->length =         htons(sizeof(struct tcphdr)); tcphdr->check =                cksum((unsigned short *) pseudoheader, sizeof(struct pseudohdr)+sizeof(struct tcphdr)); // IP header bzero(buffer, sizeof(struct iphdr)); iphdr =                        (struct iphdr *)buffer; iphdr->ihl =                   5; // IHL (longitud de cabecera) iphdr->version =               4; // version iphdr->tot_len =               htons(DEFAULT_LEN); // longitud del datagrama iphdr->id =                    htons(random()); // numero de identifiacion (aleatorio) iphdr->ttl =                   IPDEFTTL; // tiempo de vida iphdr->protocol =              IPPROTO_TCP; // protocolo iphdr->daddr =                 daddr.sin_addr.s_addr; // direccion origen iphdr->saddr =                 saddr.sin_addr.s_addr; // direccion destino printf(" SENT DATA\n"); printf(" ---------\n"); printf("| SYN | ACK | RST | PSH | URG | FIN | TTL |  Window\n"); printf("|  %d  |  %d  |  %d  |  %d  |  %d  |  %d  | %d   | %d\n", syn, ack, rst, psh, urg, fin, iphdr->ttl,  tcphdr->window); printf("seq=%d - ack_seq=%d - doff=%d - check=%d - ID=%d\n\n", tcphdr->seq, tcphdr->ack_seq, tcphdr->doff,  tcphdr->check, iphdr->id); if(sendto(s, buffer, DEFAULT_LEN, 0x0, (struct sockaddr *) &daddr, sizeof(struct sockaddr) ) != DEFAULT_LEN) Error("sendto"); wait(&status); close(s); exit(0); } else { if((rs = socket(AF_INET, SOCK_PACKET, htons(ETH_P_IP))) < 0) Error("socket input"); if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) Error("socket"); if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) < 0) Error("setsockopt"); while(1) { if(recvfrom(rs, rbuffer, BUFFER_LONG, 0x0,  (struct sockaddr *)&from, &fromlen) <= 0) Error("recvfrom"); riphdr = (struct iphdr *)(rbuffer+ethlen); if(riphdr->protocol == IPPROTO_TCP) { rtcphdr = (struct tcphdr *)(rbuffer+ethlen+ sizeof(struct iphdr)); if(rtcphdr->source == destination_port) { bzero(buffer, BUFFER_LONG); printf(" RECEIVED DATA\n"); printf(" -------------\n"); printf("| SYN | ACK | RST | PSH | URG  | FIN | TTL | Window\n"); printf("|  %d  |  %d  |  %d  |  %d   |  %d  |  %d  | %d  | %d\n",  rtcphdr->syn, rtcphdr->ack,  rtcphdr->rst, rtcphdr->psh,  rtcphdr->urg, rtcphdr->fin,  riphdr->ttl, rtcphdr->window); printf("seq=%d - ack_seq=%d -  doff=%d - check=%d - ID=%d\n\n",  rtcphdr->seq, rtcphdr->ack_seq,  rtcphdr->doff, rtcphdr->check,  riphdr->id); return; } } } close(rs); close(s); } return;}unsigned short cksum(unsigned short *ptr,int nbytes){ register long sum; unsigned short oddbyte; register unsigned short anwser; sum = 0; while(nbytes>1) { sum += *ptr++; nbytes -= 2; } if(nbytes==1) { oddbyte = 0; *((unsigned char *) & oddbyte) = *(unsigned char *)ptr; sum += oddbyte; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); anwser = ~sum; return(anwser);}void usage(char *nom) { printf("Usage: %s [s|a|r|p|u|f] [-x host_source] -d host_destination  -c port\n", nom); printf("\t-s SYN flag enabled\n"); printf("\t-a ACK flag enabled\n"); printf("\t-r RST flag enabled\n"); printf("\t-p PSH flag enabled\n"); printf("\t-u URG flag enabled\n"); printf("\t-f FIN flag enabled\n"); exit(-1);}-------------------------------------------8<------------------------------------ checkicmp.c ---------------------------8<---------------------------------// checkicmp.c// By Pepelux#include 
#include 
#include 
#include 
#include 
#define Error(msg) { perror(msg); exit -1; }int main(void) { int s;        struct sockaddr_in dir = {AF_INET, 0, 0 };        char buff[1024];        int len = sizeof(dir);        struct icmphdr *rec = (struct icmphdr*) (buff + sizeof(struct iphdr));        if (geteuid() != 0) {                printf("You must be root\n");                exit(0); } if ((s = socket(AF_INET, SOCK_RAW, 1)) < 0) Error("socket");        printf("Waiting data ...\n"); while (1) {         bzero(buff, 1024);         while (recvfrom(s, buff, 1024, 0, (struct sockaddr_in*) &dir,          &len) > 0) printf("Received:\ttype %d\tcode %d\n", rec->type,  rec->code);        }}-------------------------------------------8<------------------------------------ sendudp.c -----------------------------8<---------------------------------// sendudp.c// By Pepelux#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define Error(msg) { perror(msg); exit -1; }main (int argc, char *argv[]){ int s; int dport; struct sockaddr_in addr_dest; if (argc!=3) { printf ("Usage: %s ip port\n", argv[0]); exit(0); } dport = atoi(argv[2]); printf ("Sending UDP packet to %s:%d\n",argv[1], dport); if ((s=socket(AF_INET,SOCK_DGRAM,0)) < 0) Error("socket"); addr_dest.sin_addr.s_addr=inet_addr(argv[1]); addr_dest.sin_family=AF_INET; addr_dest.sin_port=htons(dport); if (sendto(s,"\n",1,0,(struct sockaddr*)&addr_dest,sizeof(struct  sockaddr_in)) < 0) Error("sendto"); close (s);}-------------------------------------------8<---------------------------------------[ 5.- References ]I've wrotten here links of interesting pages that I've used to write thispaper:Standards (RFCs):TCP Protocol : http://www.rfc-editor.org/rfc/rfc793.txtIP Protocol  : http://www.rfc-editor.org/rfc/rfc791.txtUDP Protocol : http://www.rfc-editor.org/rfc/rfc768.txtICMP Protocol: http://www.rfc-editor.org/rfc/rfc792.txtNmap documentation: http://insecure.org/nmap/man/------[ 6.-End ]Well, yes, all that is maked by nmap, more beutiful, more quickly and better... but, this is funny, isn't it? :PNmap has a lot of scan methods but sometimes the response is unforseeable,depending of the operating system running. For that is necessary to scanmanually, furthermore you'll leave less logs and you'll learn more.Regards!!!Pepelux 
http://www.enye-sec.org=-|================================================================ EOF =====|

转载于:https://my.oschina.net/u/1188877/blog/599371

你可能感兴趣的文章