关于Scapy

Scapy的是一个强大的交互式数据包处理程序(使用python编写)。它能够伪造或者解码大量的网络协议数据包,能够发送、捕捉、匹配请求和回复包等等。它可以很容易地处理一些典型操作,比如端口扫描,tracerouting,探测,单元测试,***或网络发现(可替代hping,NMAP,arpspoof,ARP-SK,arping,tcpdump,tethereal,P0F等)。最重要的他还有很多更优秀的特性——发送无效数据帧、注入修改的802.11数据帧、在WEP上解码加密通道(VOIP)、ARP缓存***(VLAN)等,这也是其他工具无法处理完成的。

安装Scapy

这里我没有使用安装包进行安装,而是直接使用 命令 apt-get install python-scapy,根据提示安装相应的数据包,这里我使用的ubuntu 14.04,使用的安装包如下:

tcpreplay  graphviz    p_w_picpathmagick   python-gnuplot    python-pyx    ebtables   python-visual sox xpdf gv hexer librsvg2-binp

[python] view plain copy

  1. >>> conf.verb=2  


ython-pcapy


安装完毕后测试结果如下:


[plain] view plain copy

  1. walfred@walfred-VirtualBox:~/wmw/scapy/test$ sudo scapy  

  2. Welcome to Scapy (2.2.0)  

  3. >>> IP()  

  4.   

  5. >>> target="www.baidu.com"  

  6. >>> ip=IP(dst=target)  

  7. >>> ip  

  8.   

  9. >>> [p for p in ip]  

  10. []  

  11. >>>  



Scapy的使用特性


1、conf 变量保存了配置信息

[python] view plain copy

  1. >>> conf  

  2. ASN1_default_codec = 1]>  

  3. AS_resolver = 0xb5fd4c0c>  

  4. BTsocket   = 

  5. L2listen   = 2 using Linux PF_PACKET ...  

  6. L2socket   = 2 using Linux PF_PACKET ...  

  7. L3socket   = 3 using Linux PF_P...  

  8. auto_fragment = 1  

  9. checkIPID  = 0  

  10. checkIPaddr = 1  

  11. checkIPsrc = 1  

  12. check_TCPerror_seqack = 0  

  13. color_theme =   

  14. commands   = arpcachepoison : Poison target's cache with (your MAC,victim's ...  

  15. debug_dissector = 0  

  16. debug_match = 0  

  17. default_l2 = <class 'scapy.packet.Raw'>  

  18. emph       =   

  19. ethertypes = 

  20. except_filter = ''  

  21. extensions_paths = '.'  

  22. histfile   = '/home/walfred/.scapy_history'  

  23. iface      = 'eth0'  

  24. iface6     = 'eth0'  

  25. interactive = True  

  26. interactive_shell = ''  

  27. ipv6_enabled = True  

  28. l2types    = 0x1 <- Dot3 (802.30x1 <-> Ether (Ethernet) 0xc -> IP (IP) 0x1...  

  29. l3types    = 0x3 -> IP (IP) 0x800 <-> IP (IP) 0x806 <-> ARP (ARP) 0x86dd <->...  

  30. layers     = Packet : None NoPayload : None Raw : Raw Padding : Padding ASN1...  

  31. load_layers = ['l2''inet''dhcp''dns''dot11''gprs''hsrp''inet6'...  

  32. logLevel   = 20  

  33. manufdb    =   

  34. mib        =   

  35. neighbor   = Ether -> Dot1Q Ether -> IP Dot3 -> LLC Dot3 -> SNAP Dot3 -> IP ...  

  36. netcache   = arp_cache: 0 valid items. Timeout=120s in6_neighbor: 0 valid it...  

  37. noenum     =   

  38. padding    = 1  

  39. prog       = display = 'display' dot = 'dot' hexedit = 'hexer' pdfreader = '...  

  40. promisc    = 1  

  41. prompt     = '>>> '  

  42. protocols  = 

  43. raw_layer  = <class 'scapy.packet.Raw'>  

  44. raw_summary = False  

  45. readfunc   = None  

  46. resolve    =   

  47. route      = Network Netmask Gateway Iface Output IP 127.0.0.0 255.0.0.0 0.0...  

  48. route6     = Destination Next Hop iface src candidates 2400:dd01:3000:10::/6...  

  49. services_tcp = 

  50. services_udp = 

  51. session    = ''  

  52. sniff_promisc = 1  

  53. stats_classic_protocols = [<class 'scapy.layers.inet.TCP'>, <class 'scapy.la...  

  54. stats_dot11_protocols = [<class 'scapy.layers.inet.TCP'>, <class 'scapy.laye...  

  55. stealth    = 'not implemented'  

  56. temp_files = []  

  57. teredoPrefix = '2001::'  

  58. teredoServerPort = 3544  

  59. use_dnet   = False  

  60. use_pcap   = False  

  61. verb       = 1  

  62. version    = '2.2.0'  

  63. warning_threshold = 5  

  64. wepkey     = ''  

  65. >>>   

更改这些配置信息也比较方便:比如修改verb属性



[python] view plain copy

  1. >>> conf.verb=2     

2、数据操作



[python] view plain copy

  1. >>> IP()  

  2.   

  3. >>> test_ip=IP(dst="192.168.115.188")"font-family: Arial, Helvetica, sans-serif;">            

[python] view plain copy

  1. >>> test_ip.dst  

  2. '192.168.115.188'  

  3. >>> test_ip.ttl  

  4. 64  

[python] view plain copy

  1. >>> test_ip.ttl=32    修改ttl值  

  2. >>> test_ip  

  3. 32 dst=192.168.115.188 |>  

  4. >>> del(test_ip.ttl)  删除tt值  

  5. >>> test_ip  

  6. 192.168.115.188 |>  

  7. >>> test_ip.ttl       恢复了默认的ttl值  

  8. 64  

[python] view plain copy

  1. >>> test_tcp=TCP()  

  2. >>> test_tcp.flags  

  3. 2  

  4. >>> test_tcp.flags="SA"  

  5. >>> test_tcp.flags  

  6. 18  

  7. >>> test_tcp  

  8.   

  9. >>> test_tcp.flags=23  

  10. >>> test_tcp  

  11.   

  12. >>> i=IP(flags="DF+MF")  

  13. >>> i.flags  

  14. 3  

  15. >>> i.flags=6  

  16. >>> i  

  17.   

  18. >>>   

[python] view plain copy

  1. >>> test_ip.src  

  2. '192.168.115.198'  

  3. >>> test_ip.dst  

  4. '192.168.115.188'  

  5. >>> del(test_ip.dst)                         注意删除后的变化  

  6. >>> test_ip.dst  

  7. '127.0.0.1'  

  8. >>> test_ip.src  

  9. '127.0.0.1'  

  10. >>> test_ip.dst="192.168.115.188"             重新设定目标地址  

  11. >>> test_ip.src  

  12. '192.168.115.198'  

  13. >>>  

  

注:以下的“/”符号表示两个链路层的组合。这样下层可以层重载上一层的默认值或多个字段值。


[python] view plain copy

  1. >>> IP()  

  2.   

  3. >>>> IP()/TCP()  

  4. 0 proto=tcp |>  

  5. >>>> IP(proto=55)/TCP()  

  6. 0 proto=55 |>   

  7.   

  8. >>>> Ether()/IP()/TCP()  

  9. 0 proto=tcp |>>  

  10. >>>> IP()/TCP()/"GET /HTTP/1.0\r\n\r\n"     数据部分可以直接使用字符串  

  11. 0 proto=tcp |'GET /HTTP/1.0\r\n\r\n' |>>>    

  12. >>>> Ether()/IP()/UDP()  

  13. 0 proto=udp |>>  

  14. >>>> Ether()/IP()/IP()/UDP()  

  15. 0 proto=ipencap |0 proto=udp |>>>  

  16.   

  17.   

  18. >>> str(IP())  

  19. 'E\x00\x00\x14\x00\x01\x00\x00@\x00|\xe7\x7f\x00\x00\x01\x7f\x00\x00\x01'  

  20. >>> IP(_)  

  21. 4L ihl=5L tos=0x0 len=20 id=1 flags= frag=0L ttl=64 proto=hopopt   

  22.   

  23. chksum=0x7ce7 src=127.0.0.1 dst=127.0.0.1 |>  

  24. >>> a=Ether()/IP(dst="www.baidu.com")/TCP()/"GET /index.html HTTP/1.0 \n\n"  

  25. >>> hexdump(a)  

  26. 0000   00 03 0F 19 6A 49 08 00  27 FE D8 12 08 00 45 00   ....jI..'.....E.  

  27. 0010   00 43 00 01 00 00 40 06  70 78 C0 A8 73 C6 B4 61   [email protected]  

  28. 0020   21 6C 00 14 00 50 00 00  00 00 00 00 00 00 50 02   !l...P........P.  

  29. 0030   20 00 B3 75 00 00 47 45  54 20 2F 69 6E 64 65 78    ..u..GET /index  

  30. 0040   2E 68 74 6D 6C 20 48 54  54 50 2F 31 2E 30 20 0A   .html HTTP/1.0 .  

  31. 0050   0A                                                 .  

  32. >>> b=str(a)  

  33. >>> b  

  34. "\x00\x03\x0f\x19jI\x08\x00'\xfe\xd8\x12\x08\x00E\x00\x00C\x00\x01\x00\x00@\x06px  

  35.   

  36. \xc0\xa8s\xc6\xb4a!l\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xb3u  

  37.   

  38. \x00\x00GET /index.html HTTP/1.0 \n\n"  

  39. >>> c=Ether(b)  

  40. >>> c  

  41. 00:03:0f:19:6a:49 src=08:00:27:fe:d8:12 type=IPv4 |4L   

  42.   

  43. ihl=5L tos=0x0 len=67 id=1 flags= frag=0L ttl=64 proto=tcp chksum=0x7078   

  44.   

  45. src=192.168.115.198 dst=180.97.33.108 options=[] |

  46.   

  47. seq=0 ack=0 dataofs=5L reserved=0L flags=S window=8192 chksum=0xb375 urgptr=0   

  48.   

  49. options=[] |'GET /index.html HTTP/1.0 \n\n' |>>>>  

  50.   

  51. >>> c.hide_defaults()  如果觉得过于冗长,可以使用这个函数隐藏  

  52. >>> c  

  53. 00:03:0f:19:6a:49 src=08:00:27:fe:d8:12 type=IPv4 |5L len=67   

  54.   

  55. frag=0 proto=tcp chksum=0x7078 src=192.168.115.198 dst=180.97.33.108 |

  56.   

  57. dataofs=5L chksum=0xb375 options=[] |'GET /index.html HTTP/1.0 \n\n' |  

  58.   

  59. >>>>  

  60.   

  61. >>> a=rdpcap("/mnt/share/test1.cap")  我使用的wireshark,保存成pcap的格式  

  62. >>> a  

  63. 13 UDP:53 ICMP:4 Other:3>  

  64. >>> a[9].pdfdump(layer_shift=1)  

  65. >>> a[9].psdump("/mnt/share/test1.eps",layer_shift=1)   

Scapy基础学习之一_第1张图片


[python] view plain copy

  1. 如何产生多个数据包   

  2. >>> a=IP(dst="www.baidu.com/30")  

  3. >>> a  

  4. 'www.baidu.com/30') |>  

  5. >>> [p for p in a]  

  6. [180.97.33.104 |>, 180.97.33.105 |>, 180.97.33.106 |>,   

  7.   

  8. 180.97.33.107 |>]  

  9. >>> b=IP(ttl=[1,2,(5,9)])  

  10. >>> b  

  11. 12, (59)] |>  

  12. >>> [p for p in b]  

  13. [1 |>, 2 |>, 5 |>, 6 |>, 7 |>, 

  14.   

  15. ttl=8 |>, 9 |>]  

  16. >>> c=TCP(dport=[80,443])  

  17. >>> [p for p in a/c]    产生多个数据包  

  18. [0 proto=tcp dst=180.97.33.104 |>, 0   

  19.   

  20. proto=tcp dst=180.97.33.104 |>,  0 proto=tcp   

  21.   

  22. dst=180.97.33.105 |>, 0 proto=tcp dst=180.97.33.105 |  

  23.   

  24. >, 0 proto=tcp dst=180.97.33.106 |

  25.   

  26. >>, 0 proto=tcp dst=180.97.33.106 |>, 0   

  27.   

  28. proto=tcp dst=180.97.33.107 |>, 0 proto=tcp   

  29.   

  30. dst=180.97.33.107 |>]  

  31. >>>    




3、发送数据包


学习send/sendp/sr/sr1/srp  发送数据包函数使用

[python] view plain copy

  1. >>> send(IP(dst="192.168.115.188")/ICMP())  send函数工作在第三层  

  2. .  

  3. Sent 1 packets.  

  4. >>> sendp(Ether()/IP(dst="192.168.115.188",ttl=(1,4)),iface="eth0")  

  5. ....  

  6. Sent 4 packets.  

  7. >>> sendp("hello ,i am walfred ",iface="eth0",loop=1,inter=0.2)  sendp函数工作在第二层,你可以选择网卡和协议  

  8. ..................................................................................................................................................................................................................................................................................................................................^C  

  9. Sent 322 packets.  

fuzz函数的作用:可以更改一些默认的不可以被计算的值(比如校验和checksums),更改的值是随机的,但是类型是符合字段的值的。比如下面的例子,结果如下图对比:

[python] view plain copy

  1. >>> send(IP(dst="www.baidu.com")/UDP()/NTP(version=4),loop=2)  未使用fuzz()  

 >>> send(IP(dst="www.baidu.com")/fuzz(UDP()/NTP(version=4)),loop=2) 使用fuzz() 



SR()函数用来来发送数据包和接收响应。该函数返回有回应的数据包和没有回应的数据包;该函数也算得上是scapy的核心了,他会返回两个列表数据,一个是answer list 另一个是unanswered list


[python] view plain copy

  1. >>> sr(IP(dst="192.168.115.1")/TCP(dport=[21,22,23]))  

  2. Begin emission:  

  3. Finished to send 3 packets.  

  4. ***  

  5. Received 3 packets, got 3 answers, remaining 0 packets  

  6. Results: TCP:3 UDP:0 ICMP:0 Other:0>, Unanswered: TCP:0 UDP:0 ICMP:0 Other:0  



[python] view plain copy

  1. >>> ans,unans=_    这也是scapy的核心了  

  2. >>> ans.show()  

  3. 0000 IP / TCP 192.168.115.198:ftp_data > 192.168.115.1:ftp S ==> IP / TCP 192.168.115.1:ftp > 192.168.115.198:ftp_data RA / Padding  

  4. 0001 IP / TCP 192.168.115.198:ftp_data > 192.168.115.1:ssh S ==> IP / TCP 192.168.115.1:ssh > 192.168.115.198:ftp_data RA / Padding  

  5. 0002 IP / TCP 192.168.115.198:ftp_data > 192.168.115.1:telnet S ==> IP / TCP 192.168.115.1:telnet > 192.168.115.198:ftp_data SA / Padding   

  6. >>>sr(IP(dst="192.168.115.1")/TCP(dport=[21,22,23]),inter=0.5,retry=-2,timeout=1)  网络环境不好时,也可以追加inter retry timeout等附加信息,  




函数sr1()是sr()一个变种,只返回应答发送的分组(或分组集)。这两个函数发送的数据包必须是第3层数据包(IP,ARP等)。而函数SRP()位于第2层(以太网,802.3,等)。

[python] view plain copy

  1. >>> p=sr1(IP(dst="192.168.115.188")/ICMP()/"test")  

  2. Begin emission:  

  3. .....Finished to send 1 packets.  

  4. .*  

  5. Received 7 packets, got 1 answers, remaining 0 packets  

  6. >>> p  

  7. 4L ihl=5L tos=0x0 len=32 id=26000 flags= frag=0L ttl=128 proto=icmp chksum=0x6c79 src=192.168.115.188 dst=192.168.115.198 options=[] |0 chksum=0x1826 id=0x0 seq=0x0 |'test' |'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' |>>>>  

  8. >>> p.show()  

  9. ###[ IP ]###  

  10.   version= 4L  

  11.   ihl= 5L  

  12.   tos= 0x0  

  13.   len= 32  

  14.   id= 26000  

  15.   flags=   

  16.   frag= 0L  

  17.   ttl= 128  

  18.   proto= icmp  

  19.   chksum= 0x6c79  

  20.   src= 192.168.115.188  

  21.   dst= 192.168.115.198  

  22.   \options\  

  23. ###[ ICMP ]###  

  24.      type= echo-reply  

  25.      code= 0  

  26.      chksum= 0x1826  

  27.      id= 0x0  

  28.      seq= 0x0  

  29. ###[ Raw ]###  

  30.         load= 'test'  

  31. ###[ Padding ]###  

  32.            load= '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'  



转自:http://blog.csdn.net/wang_walfred/article/details/40044141