a
    kÄ#d&S  ã                   @   s¤  d Z ddlmZ ddlmZ ddlZddlZddlZddlZddlZddl	m
Z
mZ ddlmZ ddlmZ ddlmZmZmZ dd	lmZmZ dd
lmZmZmZ ddlmZmZmZmZm Z  ddl!m"Z" ddl#m$Z$ ej%du rêddl&Z'g d¢Z(ee(dƒe_)ee(dƒe_*ee(dƒe_+ee(dƒe_,G dd„ de
ƒZ-d\a.a/a0a1dd„ Z2e2ƒ  dd„ Z3dd„ Z4dd„ Z5ej6j7dd„ ƒZ8d d!„ Z9ej6j7d*d#d$„ƒZ:d+d&d'„Z;d(d)„ Z<dS ),z+
Clone of p0f v2 passive OS fingerprinting
é    )Úabsolute_import)Úprint_functionN)ÚKnowledgeBaseÚselect_path)Úconf)Úraw)ÚIPÚTCPÚ
TCPOptions)Ú	NoPayloadÚPacket)ÚwarningÚScapy_ExceptionÚlog_runtime)ÚRandIntÚRandByteÚRandNumÚ	RandShortÚ
RandString)Úsniff)Úsix)z/etc/p0fz/usr/share/p0fz
/opt/localzp0f.fpzp0fa.fpzp0fr.fpzp0fo.fpc                   @   s   e Zd Zdd„ Zdd„ ZdS )Úp0fKnowledgeBasec                 C   s   t  | |¡ d S ©N)r   Ú__init__)ÚselfÚfilename© r   úJ/var/www/html/gsl.tools/lib/python3.9/site-packages/scapy/modules/p0fv2.pyr   9   s    zp0fKnowledgeBase.__init__c                    s  zt | jƒ}W n  ty.   td| jƒ Y d S 0 z¤g | _|D ]”}|d dv rNq<t| d¡ƒ}t|ƒdk rjq<dd„ ‰ ‡ fdd	„|d
d… D ƒ}| j |d |d |d
 |d |d |d |d |d d d… f¡ q<W n  t	yô   tdƒ d | _Y n0 | 
¡  d S )NzCan't open base %sr   )ú#Ú
ú:é   c                 S   s   |   ¡ rt| ƒS | S r   )ÚisdigitÚint)Úxr   r   r   Úa2iL   s    z'p0fKnowledgeBase.lazy_init.<locals>.a2ic                    s   g | ]}ˆ |ƒ‘qS r   r   )Ú.0Úe©r%   r   r   Ú
<listcomp>P   ó    z.p0fKnowledgeBase.lazy_init.<locals>.<listcomp>é   é   é   é   é   é   éÿÿÿÿz,Can't parse p0f database (new p0f version ?))Úopenr   ÚIOErrorr   ÚbaseÚtupleÚsplitÚlenÚappendÚ	ExceptionÚclose)r   ÚfÚlineZlir   r(   r   Ú	lazy_init=   s,    $ÿzp0fKnowledgeBase.lazy_initN)Ú__name__Ú
__module__Ú__qualname__r   r=   r   r   r   r   r   8   s   r   )NNNNc                   C   s,   t tjƒat tjƒat tjƒat tjƒa	d S r   )
r   r   Úp0f_baseÚp0f_kdbÚ	p0fa_baseÚp0fa_kdbÚ	p0fr_baseÚp0fr_kdbÚ	p0fo_baseÚp0fo_kdbr   r   r   r   Úp0f_load_knowledgebases_   s    


rI   c                 C   sH   | d@ dkrt S | d@ dkr tS | d@ dv r0tS | d@ dkr@tS d S d S )Né   r-   é   )r,   é   é   )rB   rD   rF   rH   )Úflagsr   r   r   Úp0f_selectdbj   s    rO   c                 C   s  |   ¡ } |  t| ƒ¡} |  t¡rJ|  t¡rJ|  t¡} t| jtƒrBqJ| j} qt| tƒr`t| jtƒsht	dƒ‚t
| jjƒ}| j}t| ƒ}|dkrœ|tkr˜d}nd}|tkr¨d}d}d}d}d}| jjd> d	 }| jjD �]^}	|d
8 }|	d dk�r|dt|	d
 ƒ d 7 }|	d
 }|d8 }qÐ|	d dk�rF|dt|	d
 ƒ d 7 }|d8 }qÐ|	d dk�r˜|	d
 d dk�rp|d7 }n|d7 }|	d
 d
 dk�rŽd}|d8 }qÐ|	d dk�r¸|d7 }|d
8 }qÐ|	d dk�rÐ|d7 }qÐ|	d dk�rö|d7 }|dk�r0d}qÐt|	d tƒ�r |dtd
 |	d   7 }qÐ|d|	d  7 }qÐ|d d… }|dk�rLd}| jj}
|dk�r®|dk�rˆ|
| dk�rˆdt|
| ƒ }
n&|
|d  dk�r®d t|
|d  ƒ }
t|
ƒ}
d}|tk�rÞ| jjd!@ d!k�rÞ|d"7 }| jj| jjk�rø|d#7 }| jjdk�r|d$7 }|�r|d%7 }| jdk�r0|d&7 }| jg k�rD|d'7 }| jjdk�rZ|d(7 }| jjdk�rp|d)7 }| jjdk�r†|d*7 }|�r”|d 7 }|tk�rº| jjd+@ dk�rÔ|d,7 }n| jjd@ dk�rÔ|d,7 }|tk�röt| jjtƒ�sö|d-7 }|dk�rd}||
|| jj|||ffS ).NúNot a TCP/IP packetéd   Ú*r   Ú r1   Fr-   rL   r+   ÚMSSÚMú,é   ÚWScaleÚWÚ	TimestampzT0,zT,Té	   ÚSAckOKzS,ÚNOPzN,ÚEOLzE,z?%i,Ú.ÚSé(   ÚTrM   ÚKÚQÚ0ÚPÚZÚIÚUÚXÚAé    ÚFÚD)ÚcopyÚ	__class__r   Úhaslayerr   r	   ÚgetlayerÚ
isinstanceÚpayloadÚ	TypeErrorrO   rN   Úttlr7   rF   rH   ZdataofsÚoptionsÚstrr
   ÚwindowÚseqÚackÚidÚurgptrÚreservedr   ZDF)ÚpktÚdbrv   ÚssZoooÚmssZqqTZqqPZilenÚoptionÚwinÚqqr   r   r   Ú
packet2p0f|   sº    













r†   c                 C   s  d}|| d |d kp`|d dkp`|d d dko`| d   ¡ o`t| d ƒt|d dd … ƒ dk7 }||d | d koˆ|d | d  dk 7 }dD ]$}|| | || kp°|| dk7 }q�|| d |d k7 }| d  d	¡}|d  d	¡}t|ƒt|ƒk�rd
}tt|ƒƒD ]ð}|| || k�st|| ƒdk�rnt|| ƒdk�rn|| d dk�rn|| d || d k�st|| ƒdk�rìt|| ƒdk�rì|| d dk�rì|| d || d k�rìt|| dd … ƒt|| dd … ƒ dk�sd} �qú�q|�r|t|ƒ7 }|S )Nr   rR   ú%r+   rl   )r-   r.   rW   r,   rV   Tr-   F)r"   r#   r6   r7   Úrange)r$   ÚyÚdÚiZxoptZyoptZsamer   r   r   Ú
p0f_correl	  sF    `("ÿÿþþýýüü*û
rŒ   c                 C   sŽ   t | ƒ\}}|r| ¡ }ng }|s.tdƒ g S g }t|d  d¡ƒd }|D ]<}t||ƒ}||krL| |d |d |d | t j f¡ qL|S )ziPassive OS fingerprinting: which OS emitted this TCP packet ?
p0f(packet) -> accuracy, [list of guesses]
zp0f base empty.r,   rV   r.   r/   r0   r+   )	r†   Úget_baser   r7   r6   rŒ   r8   r   rv   )r   r€   ÚsigÚpbÚrÚmaxÚbrŠ   r   r   r   Úp0f&  s    

(r“   c                 C   s  zt | ƒ}W n ty    Y dS 0 |g krRddd ttt| ƒd ƒ¡ d df}n|d }d}zt| ƒ}W n ty|   Y n0 |dkrŠd}|  d|d  d	 |d  ¡}|durÐ||  d
t|d ƒ d ¡7 }n||  d¡7 }|d du�r|dt|d ƒ d 7 }t|ƒ dS )z,Calls p0f and returns a user-friendly outputNÚUNKNOWNú[r    r+   z:?:?]r   z%IP.src%:%TCP.sport% - ú z (up: i  z- hrs)
  -> %IP.dst%:%TCP.dport% (%TCP.flags%)z(
  -> %IP.dst%:%TCP.dport% (%TCP.flags%)r-   z (distance ú))	r“   r9   ÚjoinÚmaprx   r†   Ú
pkt2uptimeZsprintfÚprint)r   r�   ÚuptimeÚresr   r   r   Úprnp0f=  s*    ( rž   rQ   c                 C   st   t | tƒstdƒ‚t | tƒr$tdƒ‚t | tƒs8t| jƒS | jD ](}|d dkr>|d d | }|  S q>tdƒ‚dS )zzCalculate the date the machine which emitted the packet booted using TCP timestamp  # noqa: E501
pkt2uptime(pkt, [HZ=100])zNot a TCP packetr   rZ   r+   zNo timestamp optionN)rs   r   ru   r   r	   rš   rt   rw   )r   ZHZÚoptÚtr   r   r   rš   Y  s    





rš   éÜ  c                    sÒ  |   ¡ } |  t¡r<|  t¡r<|  t¡} t| jtƒr4q<| j} qt| tƒrRt| jtƒsZtdƒ‚t| jj	ƒ}ˆr¨| 
¡ }|du r~g }‡fdd„|D ƒ}ˆr¾‡fdd„|D ƒ}n|r´|g}n
tƒ | }|tkrô| jj	d@ dkrædd„ |D ƒ}ndd„ |D ƒ}|�std	ƒ‚|t d
t|ƒd ¡ }	t| jjƒ}
dd„ ‰ ˆ |
 d¡ƒ}ˆ |
 d¡ƒ}‡ fdd„|
 dd¡D ƒ}g }|	d dk�r||	d  d¡D �]ô}|d
 dk�r´|	d
 d
 dk�rÄdt|	d
 dd… ƒ }nd}|�rìd
|  k�ræ|k�sìn d}|dd… dk�r0|du�r| d|f¡ n| dt d|¡f¡ n€|d dk�r–t|dd… ƒ}|du�rv|| d
k�rv| d|f¡ n| d|t d|| ¡ f¡ n| dt|dd… ƒf¡ �n¼|d
 dk�r¨|�ræd
|  k�ràdk �sæn d}|dd… dk�r$|du�r| d|f¡ n| dtƒ f¡ n€|d dk�rŠt|dd… ƒ}|du�rj|| d
k�rj| d|f¡ n| d|tdd| d� f¡ n| dt|dd… ƒf¡ �nÈ|dk�rÀ| d ¡ �n°|d!k�r‚|du�rÚ|}n@|d
 �rd
|d
   k �r d"k �rn n
|d
 }nt d#d$¡}d!|	d% v�r.d
}n@|d �rbd
|d   k �rTd"k �rbn n
|d }nt dd&¡}| d||ff¡ nî|dk�r˜| d'¡ nØ|d(k�r®| d)¡ nÂ|d*k�rÄ| d+¡ n¬|d
 d,k�rft|dd… ƒtd
 v �rJtd
 t|dd… ƒ d
 }td
 t|dd… ƒ d }| |t |tt |¡ƒ ¡ ¡f¡ n| t|dd… ƒd-f¡ n
td.|ƒ || j_�q„|	d
 dk�r–t ƒ | j_!nì|	d
  "¡ �r¶t|	d
 ƒ| j_!nÌ|	d
 d
 dk�röt|	d
 dd… ƒ}|tdd| d� | j_!nŒ|	d
 d
 d!k�r&|t|	d
 dd… ƒ | j_!n\|	d
 d
 dk�rzd/d„ |D ƒ}|�sTtd0ƒ‚|d
 d t|	d
 dd… ƒ | j_!ntd1ƒ‚|	d | | _#|  j	d|	d  O  _	|	d% dk�rŒ|	d% D ]Î}|d2k�rÒd
| _$n¶|d3k�rèt ƒ | j_%n |d4k�rþt&ƒ | j_'nŠ|d5k�r@|t(k�r$| j j	d6O  _	n| j j	t )g d7¢¡O  _	nH|d8k�rr|t(k�rr| t*j+tt dd9¡ƒd:� } n|d;k�r¼| jj'| j_,�q¼d<|	d% v �r¤d
| j_,n| jj,d
k�r¼t&ƒ | j_,| j-�rÎ| j-} �q¼| S )=aŸ  Modifies pkt so that p0f will think it has been sent by a
specific OS.  If osdetails is None, then we randomly pick up a
personality matching osgenre. If osgenre and signature are also None,
we use a local signature (using p0f_getlocalsigs). If signature is
specified (as a tuple), we use the signature.

For now, only TCP Syn packets are supported.
Some specifications of the p0f.fp file are not (yet) implemented.rP   Nc                    s   g | ]}|d  ˆ kr|‘qS )r/   r   ©r&   r$   )Úosgenrer   r   r)   †  r*   z#p0f_impersonate.<locals>.<listcomp>c                    s   g | ]}|d  ˆ kr|‘qS )r0   r   r¢   )Ú	osdetailsr   r   r)   ˆ  r*   r,   c                 S   s   g | ]}d |d v r|‘qS ©rc   r.   r   r¢   r   r   r   r)   �  r*   c                 S   s   g | ]}d |d vr|‘qS r¥   r   r¢   r   r   r   r)   ’  r*   zNo match in the p0f databaser   r+   c                 S   s   t | tjƒr| S d S r   )rs   r   Úinteger_types)Úvalr   r   r   Ú<lambda>œ  r*   z!p0f_impersonate.<locals>.<lambda>rT   rX   c                    s   g | ]}ˆ |ƒ‘qS r   r   )r&   Úo)Úint_onlyr   r   r)   Ÿ  r*   rZ   )NNr_   rV   rU   r`   iÿÿ  rR   r‡   r-   rY   é   éÿ   )Úminr‘   ZT0)rZ   )r   r   rb   l        éx   l    ðw r.   l   ÿÿ )r\   rS   ÚN)r]   NÚE)r^   Nú?rS   zunhandled TCP option %sc                 S   s   g | ]}|d  dkr|‘qS )r   rT   r   r¢   r   r   r   r)     r*   z5TCP window value requires MSS, and MSS option not setz#Unhandled window size specificationrg   ri   rk   rm   rl   )r!   rl   ra   rn   é
   )Úloadrd   re   ).ro   rq   r   r	   rr   rs   rt   ru   rO   rN   r�   Úp0f_getlocalsigsrF   r   ÚrandomÚrandintr7   Údictrw   Úgetr6   r#   r8   r   r   r
   ÚstructÚunpackr   ÚcalcsizeÚ_fixr   r   ry   r"   rv   r|   r}   r   r{   rH   Úchoicer   Z	raw_layerrz   Z
underlayer)r   r£   r¤   Ú	signatureZ	extrahopsZmturœ   r€   r�   ZpersZ	orig_optsZmss_hintZwscale_hintZts_hintrw   rŸ   ZmaxmssZcoefZts_aZts_bÚoptnameZ	optstructr‚   r…   r   )rª   r¤   r£   r   Úp0f_impersonatel  s   


 
ÿ 
ÿ


*
*



ÿÿ
&








rÀ   c            	         s  t  ¡ } t dd¡}| dkr†i ‰ ‡ fdd„}tj d¡d }d}t|dt|ƒ |d	d
�}|D ]}t|ƒD ]}||ƒ qhq\t  	| d¡ n†| dk ršt
 d¡ nrt d¡ tjtjtjd�}z| d|f¡ W n tjyÜ   Y n0 | d|f¡ | d|f¡ | ¡  t  d¡ ˆ S )a¤  This function returns a dictionary of signatures indexed by p0f
db (e.g., p0f_kdb, p0fa_kdb, ...) for the local TCP/IP stack.

You need to have your firewall at least accepting the TCP packets
from/to a high port (30000 <= x <= 40000) on your loopback interface.

Please note that the generated signatures come from the loopback
interface and may (are likely to) be different than those generated on
"normal" interfaces.i0u  i@œ  r   c                    sN   | d ˆ vr | d gˆ | d < n*| d ˆ | d  vrJˆ | d    | d ¡ d S )Nr   r+   )r8   )r�   ©Úresultr   r   Ú	addresultJ  s    z#p0f_getlocalsigs.<locals>.addresultz	127.0.0.1é   ztcp and port rW   )ÚifaceÚfilterÚcountÚtimeoutz
fork errorr+   )Útype)ÚosÚforkrµ   r¶   r   Úrouter   rx   r†   Úwaitpidr   ÚerrorÚtimeÚsleepÚsocketÚAF_INETÚSOCK_STREAMÚconnectÚbindr:   Ú_exit)	ÚpidÚportrÃ   rÅ   rÇ   Úplr   ÚeltÚs1r   rÁ   r   r´   :  s2    
	

r´   )rQ   )NNNr   r¡   N)=Ú__doc__Ú
__future__r   r   rÏ   r¹   rÊ   rÑ   rµ   Z
scapy.datar   r   Zscapy.configr   Zscapy.compatr   Zscapy.layers.inetr   r	   r
   Zscapy.packetr   r   Zscapy.errorr   r   r   Zscapy.volatiler   r   r   r   r   Zscapy.sendrecvr   Z
scapy.libsr   rÌ   Zscapy.routeZscapyZ	_p0fpathsrA   rC   rE   rG   r   rB   rD   rF   rH   rI   rO   r†   rŒ   ÚcommandsÚregisterr“   rž   rš   rÀ   r´   r   r   r   r   Ú<module>   sR   
$ 
  ÿ
 O