Scapy: 보내기 기능 분석(매개 변수, 반환 값, 응용 프로그램)

        보내기 기능은 Scapy에서 패킷을 보내기 위한 중요한 기능으로, Scapy를 사용하는 프로그래머라면 자주 다룰 수밖에 없을 것이다. 그러나 우리는 그것을 정말로 이해하고 있습니까? 이런 생각을 하며 특별히 소스코드를 읽고, 여러분과 공유하고자 블로그에 분석글을 작성했습니다. 수위가 높지 않으니 궁금하신 점은 댓글로 남겨주세요.

        다음은 문서에 보내기 기능이 도입된 방식입니다(의심스러운 기계 번역).

scapy.sendrecv.send( x , iface=None , **kargs )

계층 3에서 패킷 보내기

매개변수

  • x -- 패키지

  • inter -- 두 패킷 사이의 초 단위 시간(기본값 0)

  • 루프 -- 무기한 패킷 보내기(기본값 0)(빙은 "패킷 무기한 보내기 기본값 0"으로 번역됨)

  • count -- 전송할 패킷 수(기본값 없음=1)

  • verbose -- 자세한 정보 표시 모드(기본값 none=conf.verbose)(conf.verb 참조)

  • realtime -- 다음 패킷을 보내기 전에 패킷이 이미 전송되었는지 확인

  • return_packets -- 보낸 패킷을 반환합니다.

  • socket – 사용할 소켓 (기본값은 conf.L3socket(kargs))

  • iface -- 패킷을 보낼 인터페이스

  • 모니터 -- (리눅스에서는 아님) 모니터 모드로 전송

반환: 없음(없음을 참조할 수 있음)

(소스코드는 첨부합니다)

        녹색 배경이 있는 것은 내 주석입니다.

        send 함수의 매개변수 목록이 명시적으로 세 부분으로 구성되어 있음을 보는 것은 어렵지 않습니다. x는 전송할 패킷을 나타내고, iface는 데이터 패킷을 보낼 인터페이스를 나타내며, 가변 매개변수를 허용하는 kargs가 있습니다.

문서에 언급된 매개 변수 및 반환 값은 조사 후 결과는 다음과 같습니다.

매개변수 분석:

엑스:

        유형은 _PacketIterable이며 기본값은 없습니다.

        보낼 패키지를 참조하며 패키지, 반복자 또는 저장된 패키지 목록을 전달할 수 있습니다. 튜플을 전달할 수 없습니다(알 수 없는 이유로). send 함수의 맨 아래 계층은 for 루프를 사용하여 x 매개변수를 트래버스하고 반복 가능한 객체를 논리적으로 전달할 수 있습니다.

 

인터:

        유형은 int 또는 float이며 기본값은 0입니다.

        패킷 전송 후 일시 중지 시간(초)입니다. 위의 주석은 int형으로 표시되어 있으며 실제 float도 정상적으로 실행될 수 있습니다. time 모듈에서 sleep 함수를 호출하기 때문입니다.

 

고리:

        유형은 int이고 기본값은 0입니다.

        전송된 패킷의 수는 패킷 전송 while 루프의 조건입니다. loop 값과 count 값이 모두 전달되지 않으면 loop 값은 -1로 설정됩니다. count 값이 전달되면 루프가 -count로 설정됩니다. 루프가 끝날 때마다 루프 값이 1씩 증가하고 0에 도달하면 루프가 멈춥니다.

 

세다:

        유형은 int이고 기본값은 None입니다.

        전송된 패킷 수입니다. count가 None이면 루프는 -1로 설정되고 그렇지 않으면 -count로 설정됩니다. None 또는 int 이외의 값을 전달하지 않도록 주의하세요. 그렇지 않으면 오류가 보고됩니다. 음수가 아닌 숫자가 전달되면 정상적으로 작동합니다. 10진수가 전달되면 루프가 항상 0이 아니기 때문에 while 루프는 멈추지 않습니다. send 함수의 기본 방법은 루프를 -count에 할당하고 루프가 반복되고 루프가 0보다 작을 때마다 루프 += 1을 실행하므로 루프는 항상 0이 아니므로 양수를 전달합니다. 루프가 종료되지 않습니다.

 

말 수가 많은:

        유형은 int이고 기본값은 conf.verb(2)입니다.

        세부 정보 표시 모드를 활성화할지 여부입니다. 값이 true일 경우 컨트랙트 전송 과정의 상세 정보가 출력됩니다(사실 그리 상세하지는 않습니다). 즉, 각각의 방법은 패킷을 보내고, 점을 인쇄하고, 패킷이 전송된 후 전송된 총 패킷 수를 인쇄합니다.

 

실시간:

       유형은 bool이고 기본값은 False입니다.

        다음 패킷을 보내기 전에 패킷이 전송되었는지 여부를 확인할지 여부입니다.

        이 매개변수가 유용한지 회의적입니다. 돌아 다니는 소스 코드를 완성한 후 방정식을 생각해 냈습니다.

첫 번째 패킷 전송 시간 - 첫 번째 패킷이 구성되는 시간 > 두 번째 패킷 전송 시간 - 두 번째 패킷이 구성되는 시간 이 부등식을 만족하는 한 send 기능은 sleep 기능을 사용하여 프로세스를 차단합니다. 두 번째 패킷 구성 시간 - 첫 번째 패킷 구성 시간 + 첫 번째 패킷 전송 시간 - 두 번째 패킷 전송 시간. 패킷이 전송되었는지 확인하기 위해 이 코드가 어떻게 확인하는지 알 수 없습니다.

 

반환_패킷:

        유형은 bool이고 기본값은 False입니다.

        보낸 패킷을 반환할지 여부입니다. 반환되는 것은 패킷이 아니라 PacketList 개체입니다. PacketList는 첨자에 액세스하여 그 안에 있는 요소에 액세스할 수 있습니다. 특정 패키지는 res 멤버에 저장됩니다.

 

소켓:

        유형은 SuperSocket이고 기본값은 conf.L3socket(kargs))입니다.

        사용하는 소켓입니다. 기본적으로 send 함수는 이를 자체적으로 처리합니다.

 

만약에:

        유형은 str이고 기본값은 None입니다. 이 매개변수는 네트워크 카드의 이름을 지정하는 데 사용되며 네트워크 카드 사용은 내부적으로 send 기능에 의해 완료됩니다. "eth0"이 전달되면 send 함수는 eth0 네트워크 카드를 사용하여 패킷을 보냅니다. 기본적으로 보내기 기능은 자체적으로 적절한 네트워크 카드를 선택합니다.

 

자동차:

        (Linux를 사용하여 이것을 찾지 못했습니다)

반환 값 분석:

        설명서에 언급된 반환 값은 None입니다. 그러나 소스 코드를 분석한 후 send 함수의 반환 값은 None 또는 PacketList 두 가지가 있어야 합니다. return_packets 매개변수가 true이면 PacketList 클래스를 반환하고 그렇지 않으면 None을 반환합니다.

        None 값은 많은 것을 설명하지 않습니다.

        PacketList는 plist 모듈에 정의된 클래스입니다. 부모 클래스 중 하나인 _PacketList는 __repr__(유형 변환 및 인쇄 함수 호출을 위한 str 클래스), __iter__(반복 시작 시 호출되는 메서드), __getitem__(인덱스 작업에 사용되는 메서드), __add__(오버로드 추가 연산자), __len__( len 함수에 의해 호출되는 메서드). Scapy에는 연산자, 명령문 및 내장 함수의 많은 응용 프로그램이 있음을 알 수 있습니다.

        따라서 다음 작업을 실현할 수 있습니다.

        1. print 함수를 사용하여 인쇄하거나 str 클래스를 호출하여 send 함수의 반환 값을 변환합니다.

        산출:

                <패킷목록: TCP:0 UDP:0 ICMP:0 기타:1>

        2. 범위 함수의 반환 값을 반복하는 것처럼 보내기 함수의 반환 값을 반복합니다.

        3. 인덱스를 사용하여 send 함수의 반환 값에 저장된 데이터 패킷을 호출합니다. 이것은 res 멤버에 대한 단순한 액세스가 아니라 아직 연구되지 않은 다른 반환 값도 포함합니다.

        4. 더하기 연산자를 사용하여 보내기 기능의 반환 값 사이에서 작동합니다. 이 물건을 사용할 때 조심하십시오. 다음과 같이:

        암호:

                a = b = 보내기(IP(), return_packets=True)

                d = a + b

                인쇄(d)

        산출:

                .(여기에 점이 있습니다)

                1 패킷을 보냈습니다.

                < 패킷목록+패킷목록 : TCP:0 UDP:0 ICMP:0 기타:2>

빨간색 부분 에서         와 같이 많은 PacketList 클래스가 추가되면 여기에 수식에 포함된 요소 수만큼 포함됩니다. 따라서 실제로 send 함수의 반환 값을 추가하려면 신중하게 인쇄하십시오.

        5. len 함수를 사용하여 send 함수의 반환 값에서 패킷 수를 계산합니다.

        또한 PackekList의 summary 메소드를 사용하여 거기에 저장된 패키지의 summary 메소드 결과를 한 줄씩 인쇄할 수 있습니다. 즉, 각 패키지의 요약을 한 줄씩 인쇄할 수 있습니다.

        물론 반환된 PacketList는 좀 맛없긴 한데, 결국 내가 보낸 패킷이다. 그러나 무작위 패킷을 보낼 때 실제로 보낸 패킷을 반환해야 할 수도 있습니다.

        이에 따라 일부 보내기 기능의 사용을 요약할 수 있습니다.

1. 카운트 매개변수를 음수 값으로 설정하여 데이터 패킷이 무한 루프로 전송되도록 한 다음 Ctrl+C로 프로그램을 중지합니다.

from scapy.all import IP, TCP, send

packet = IP() / TCP()

send(packet, count=-1)

산출:

                                                                                                                              
┌──( matriller㉿Hack )-[ ~/Desktop/Practice ]
└─ $  sudo python demo.py
.................................................. .................................................. .................................................. .................................................. .................................................. .................................................. .................................................. .................................................. .................................................. .................................................. .................................................. .................................................. .................................................. .................................................. .................................................. .................................................. .................................................. ^C
850 패킷을 보냈습니다.

        보내기 기능은 특수 변수를 사용하여 보낸 패킷 수를 저장하고 전체 패킷 보내기 프로세스가 try-exept 문에 있기 때문에 Ctrl+C를 누르면 보내기 기능이 KeyboardInterrupt 오류를 캡처한 다음 표시 여부를 결정합니다. 전달된 매개변수에 따른 정보 및 전달 된 Returns None 또는 PacketList 객체.

        얼마나 많은 패킷을 보낼지 미리 알 수 없을 때 사용할 수 있습니다. while 루프를 사용하여 동일한 효과를 얻을 수 있지만 send 함수를 호출하는 비용이 매우 높기 때문에 각 루프에서 send 함수를 한 번만 호출하면 프로그램 성능이 크게 저하됩니다.

2. 각 패킷이 전송된 후 일정 시간 동안 일시 중지되도록 inter 매개 변수를 전달합니다.

from scapy.all import IP, TCP, send
from time import time, sleep

packet = IP() / TCP()

t = time()
send(packet, count=5, inter=0.5)
print(time()-t)

t = time()
for i in range(5):
    send(packet)
    sleep(0.5)
print(time()-t)

산출:

┌──( matriller㉿Hack )-[ ~/Desktop/Practice ]
└─ $  sudo python demo.py
.....
5개의 패킷을 보냈습니다.
2.5401618480682373
.
1 패킷을 보냈습니다.
.
1 패킷을 보냈습니다.
.
1 패킷을 보냈습니다.
.
1 패킷을 보냈습니다.
.
1 패킷을 보냈습니다.
2.712531805038452

        이 방법은 매우 중요합니다. send 함수를 호출하는 비용은 매우 높으며 일시 중지 작업을 send 함수의 맨 아래 계층에 넘겨줌으로써 프로그램의 성능을 향상시킬 수 있습니다. 위의 출력에서는 5개의 패킷만 전송되며 for 루프 일시 중지는 분명히 매개 변수 전달 일시 중지보다 느립니다. 네트워크 프로그래밍에서는 보낼 패킷이 5개 이상 있습니다.

3. verbose에 false 값을 전달하여 send 함수 자체 의 출력을 끕니다.

from scapy.all import IP, TCP, send
from time import time, sleep

packet = IP() / TCP()

send(packet, verbose=0)

산출:

┌──( matriller㉿Hack )-[ ~/Desktop/Practice ]
└─ $  sudo python demo.py

        인쇄할 각 패킷의 끝에는 포인트와 총 수가 없습니다. 때때로 우리는 Scapy를 사용할 때 보내기 기능이 화면에 메시지를 인쇄하는 것을 원하지 않으므로 이 매개변수가 매우 유용할 것입니다.

        send 함수의 최하위 계층은 verbose 매개변수를 if 문의 조건으로 사용하기 때문에 verbose에 다음 값을 전달하여 동일한 효과를 얻을 수 있습니다. (None은 작동하지 않음)

0,0.0,'',b'',False,[],()

4. x 매개변수에 목록을 전달하여 패킷 전송 속도를 높입니다.

from scapy.all import IP, TCP, send
from time import time, sleep

packet = [IP() / TCP() for i in range(5)]
print(len(packet))
print(type(packet))
print(packet)

t = time()
send(packet)
print(time()-t)

t = time()
for i in range(5):
    send(IP() / TCP())
print(time()-t)

산출:

┌──( matriller㉿Hack )-[ ~/桌面/Practice ]
└─ $ sudo python demo.py
5
<class 'list'>
[<IP frag=0 proto=tcp |<TCP |>>, <IP frag =0 proto=tcp |<TCP |>>, <IP 조각=0 proto=tcp |<TCP |>>, <IP 조각=0 proto=tcp |<TCP |>>, <IP 조각=0 proto=tcp |<TCP |>>]
.....
5개의 패킷을 보냈습니다.
0.03799152374267578
.
1 패킷을 보냈습니다.
.
1 패킷을 보냈습니다.
.
1 패킷을 보냈습니다.
.
1 패킷을 보냈습니다.
.
1 패킷을 보냈습니다.
0.1679677963256836

        리스트를 send 함수에 전달하여 한 번에 보내는 것이 for 루프를 사용하여 send 함수를 여러 번 호출하는 것보다 성능이 훨씬 높다는 것을 알 수 있습니다. 자세한 내용은 내 다른 기사를 참조하십시오.

Scapy: Fast Syn Flood 공격(Syn Flood)_Matriller의 블로그 - CSDN 블로그는 SCAPY 기능을 사용하여 Syn Flood 공격(Syn Floor)의 속도를 높입니다 favicon32.ico. 1001.2014.3001.5501

소스 코드 부분:

def __gen_send(s,  # type: SuperSocket
               x,  # type: _PacketIterable
               inter=0,  # type: int
               loop=0,  # type: int
               count=None,  # type: Optional[int]
               verbose=None,  # type: Optional[int]
               realtime=False,  # type: bool
               return_packets=False,  # type: bool
               *args,  # type: Any
               **kargs  # type: Any
               ):
    # type: (...) -> Optional[PacketList]
    """
    An internal function used by send/sendp to actually send the packets,
    implement the send logic...

    It will take care of iterating through the different packets
    """
    if isinstance(x, str):
        x = conf.raw_layer(load=x)
    if not isinstance(x, Gen):
        x = SetGen(x)
    if verbose is None:
        verbose = conf.verb
    n = 0
    if count is not None:
        loop = -count
    elif not loop:
        loop = -1
    sent_packets = PacketList() if return_packets else None
    p = None
    try:
        while loop:
            dt0 = None
            for p in x:
                if realtime:
                    ct = time.time()
                    if dt0:
                        st = dt0 + float(p.time) - ct
                        if st > 0:
                            time.sleep(st)
                    else:
                        dt0 = ct - float(p.time)
                s.send(p)
                if sent_packets is not None:
                    sent_packets.append(p)
                n += 1
                if verbose:
                    os.write(1, b".")
                time.sleep(inter)
            if loop < 0:
                loop += 1
    except KeyboardInterrupt:
        pass
    finally:
        try:
            cast(Packet, x).sent_time = cast(Packet, p).sent_time
        except AttributeError:
            pass
    if verbose:
        print("\nSent %i packets." % n)
    return sent_packets


def _send(x,  # type: _PacketIterable
          _func,  # type: Callable[[NetworkInterface], Type[SuperSocket]]
          inter=0,  # type: int
          loop=0,  # type: int
          iface=None,  # type: Optional[_GlobInterfaceType]
          count=None,  # type: Optional[int]
          verbose=None,  # type: Optional[int]
          realtime=False,  # type: bool
          return_packets=False,  # type: bool
          socket=None,  # type: Optional[SuperSocket]
          **kargs  # type: Any
          ):
    # type: (...) -> Optional[PacketList]
    """Internal function used by send and sendp"""
    need_closing = socket is None
    iface = resolve_iface(iface or conf.iface)
    socket = socket or _func(iface)(iface=iface, **kargs)
    results = __gen_send(socket, x, inter=inter, loop=loop,
                         count=count, verbose=verbose,
                         realtime=realtime, return_packets=return_packets)
    if need_closing:
        socket.close()
    return results


@conf.commands.register
def send(x,  # type: _PacketIterable
         iface=None,  # type: Optional[_GlobInterfaceType]
         **kargs  # type: Any
         ):
    # type: (...) -> Optional[PacketList]
    """
    Send packets at layer 3

    :param x: the packets
    :param inter: time (in s) between two packets (default 0)
    :param loop: send packet indefinitely (default 0)
    :param count: number of packets to send (default None=1)
    :param verbose: verbose mode (default None=conf.verb)
    :param realtime: check that a packet was sent before sending the next one
    :param return_packets: return the sent packets
    :param socket: the socket to use (default is conf.L3socket(kargs))
    :param iface: the interface to send the packets on
    :param monitor: (not on linux) send in monitor mode
    :returns: None
    """
    iface = _interface_selection(iface, x)
    return _send(
        x,
        lambda iface: iface.l3socket(),
        iface=iface,
        **kargs
    )

참조:

scapy.sendrecv 를 오버로드하는 Python 연산자 overloading_viclee108의 블로그-CSDN blog_python 연산자 분석
— Scapy 2.4.4 문서

https://github.com/secdev/scapy/blob/master/scapy/sendrecv.py#L413-L44

 

 

 

 

Guess you like

Origin blog.csdn.net/m0_71713477/article/details/128607762