[SK shieldus Rookies 19기] 시스템/네트워크 보안 기술 3일차

기록하는짱구·2024년 3월 25일
0

SK Shieldus Rookies 19기

목록 보기
18/43
post-thumbnail

📖 인터넷 공간에서 데이터를 전송하는 방식

TCP, UDP

✍ UDP (User Datagram Protocol)

사용자 데이터그램 프로토콜

https://namu.wiki/w/UDP

https://ko.wikipedia.org/wiki/%EC%82%AC%EC%9A%A9%EC%9E%90_%EB%8D%B0%EC%9D%B4%ED%84%B0%EA%B7%B8%EB%9E%A8_%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C

인터넷 프로토콜 스위트의 주요 프로토콜 가운데 하나로, 데이터그램으로 알려진 단문 메시지를 교환하기 위해서 사용

연결을 설정하지 않고 수신자가 데이터를 받을 준비를 확인하는 단계를 거치지 않고 단방향으로 정보 전송

  • 신뢰성
    수신자가 메시지를 수신했는지 확인할 수 없음

  • 순서 정렬
    메시지 도착 순서를 예측할 수 없음

  • 부하
    TCP 보다 속도가 일반적으로 빠르고 오버헤더가 적음

8바이트로 고정

  • 출발지 포트, 목적지 포트
    16비트 → 65,536개

  • 길이
    UDP 페이로드와 UDP 헤더를 더한 데이터그램의 크기

  • 오류 검사
    기본적으로 비활성화

✍ TCP(Transmission Control Protocol)

전송 제어 프로토콜

https://ko.wikipedia.org/wiki/%EC%A0%84%EC%86%A1_%EC%A0%9C%EC%96%B4_%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C

인터넷 프로토콜 스위트(IP)의 핵심 프로토콜 중 하나로, IP와 함께 TCP/IP라는 명칭으로도 널리 불린다. TCP는 근거리 통신망이나 인트라넷, 인터넷에 연결된 컴퓨터에서 실행되는 프로그램 간에 일련의 옥텟을 안정적으로, 순서대로, 에러없이 교환할 수 있게 한다. TCP는 전송 계층에 위치한다. 네트워크의 정보 전달을 통제하는 프로토콜이자 인터넷을 이루는 핵심 프로토콜의 하나로서 국제 인터넷 표준화 기구(IETF)의 RFC 793에 기술되어 있다.

연결 지향형 프로토콜

수신 측이 데이터를 흘려버리지 않게 데이터의 흐름 제어(flow control)와 전송 중 에러가 발생한 경우 자동으로 재전송하는 에러 제어(error control) 등의 기능을 통해 데이터의 확실한 전송을 보장

  • TCP 헤더의 크기는 가변적
    TCP Options에 따라 달라지고 Offset에서 지정

  • 출발지와 목적지 포트
    16비트 → 65,536

  • 일련 번호(sequence number)
    ▫ 전송하는 데이터의 순서를 의미 → 수신 측에서 쪼개진 세그먼트의 순서를 파악해서 재조립 할 수 있도록 제공
    ▫ 최초로 데이터를 전송할 때는 랜덤한 수로 초기화하고, 이후에는 자신이 보낼 데이터의 1바이트 당 일련번호를 1씩 증가시켜서 데이터의 순서를 표현

  • 확인 또는 승인 번호(knowledgement number)
    ▫ 수신자가 예상하는 다음 일련 번호를 의미
    ▫ 데이터를 주고 받을 때는 상대방이 보낸 일련 번호 + 자신이 받은 데이터의 바이트 수를 확인 번호로 설정
    ▫ 연결 설정과 연결 해제 과정에서는 상대방이 보낸 일련 번호 + 1을 확인 번호로 설정 (핸드쉐이킹 과정에서는 데이터를 주고 받지 않음)

  • 오프셋
    전체 세그먼트에서 헤더가 아닌 데이터가 시작되는 위치를 표시

📢 여기서 잠깐!
세그먼트 → TPC 헤더 + TCP 페이로드
데이터가 시작되는 위치 → TCP 헤더의 끝을 의미하는데 이는 TCP 헤더의 크기가 가변적이므로 필요

  • TCP 플래그
    현재 세그먼트의 속성
Flag
CWR (Congestion Window Reduced)혼잡 윈도우 크기 감소 신호
ECN (Explicit Congestion Notification)혼잡 신호 발생
URG (Urgent)긴급 데이터
ACK (Acknowledgement)확인 응답 신호
PSH (Push)수신 측에 데이터를 최대한 빠르게 응용 프로그램에게 전달
RST (Reset)연결을 강제로 초기화해달라는 요청
SYN (Synchronize)연결 생성
FIN (Finish)연결 종료
  • 윈도우 크기
    슬라이딩 윈도우(sliding window) 크기
    = 한번에 전송할 수 있는 데이터의 양(크기)

  • 오류 검사
    데이터 송수신 중에 발생하는 오류를 검출하기 위해 사용

  • 긴급 포인트
    URG 플래그가 설정된 경우, 해당 데이터를 우선 처리

📝 정상적인 트래픽 전송 과정

📝 비정상적인 트래픽 전송 과정

🔍 <참고> 주요정보통신기반시설 기술적 취약점 분석 평가 상세 가이드

https://www.kisa.or.kr/2060204/form?postSeq=12&lang_type=KO&page=1#fnPostAttachDownload

📖 포트 번호

  • 16비트(65536개를 표현하는 것이 가능)로 구성된 가상적 주소

  • 운영체제에서 응용 계층에 속하는 프로토콜을 고유한 식별자 번호로 인식할 때 사용하는 번호

  • IANA(Internet Assigned Numbers Authority) 기구에서 관리

  • 잘 알려진 포트 번호(well known port)
    ▫ 0 ~ 1023
    ▫ 잘 알려진 특정 애플리케이션의 사용을 위해 ICANN(Internet Corporation for Assigned Names and Numbers)에서 할당한 포트
    ▫ 일반적으로 서버에서 사용
    ▫ c:\Windows\system32\drivers\etc\services

프로토콜포트번호비고
ftp21/tcp# FTP. control
ssh22/tcp# SSH Remote Login Protocol
telnet23/tcp
smtp25/tcpmail# Simple Mail Transfer Protocol
domain53/tcp# Domain Name Server
domain53/udp# Domain Name Server
http80/tcpwww www-http# World Wide Web
pop3110/tcp# Post Office Protocol - Version 3
https443/tcpMCom# HTTP over TLS/SSL
  • 등록된 포트 번호(registered port)
    ▫ 1024 ~ 49151
    ▫ 특정 용도로 사용되기 위해 등록된 포트 번호
포트번호이름비고
1433MSQSQL
3306MySQL
8080HTTP개발용도
  • 사설 또는 동적 포트 번호(dynamic port)
    ▫ 49152 ~ 65535
    ▫ 어느 프로그램에서나 사용할 수 있는 포트

📖 포트 스캔

원격지 호스트를 대상으로 어떤 포트를 사용하고 있는지 확인하는 기법

✔ nmap
오픈소스 기반의 포트 스캐닝 도구

💻 kali 및 bee-box 가상머신을 실행하고 호스트 PC에서 C:\FullStack\run.bat 실행 후 Tomcat 실행

┌──(kali㉿kali)-[~]
└─$ nmap -p 80 bee.box
         ~~~~~ ~~~~~~~ 
            |     +-- 호스트  
            +-- 스캔할 포트 번호 

Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-25 04:07 EDT
Nmap scan report for bee.box (192.168.45.3)
Host is up (0.0018s latency).

PORT   STATE SERVICE
80/tcp open  http			# 해당 포트로 서비스 중 

Nmap done: 1 IP address (1 host up) scanned in 0.18 seconds
┌──(kali㉿kali)-[~]
└─$ nmap -p 9999 bee.box
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-25 04:10 EDT
Nmap scan report for bee.box (192.168.45.3)
Host is up (0.0060s latency).

PORT     STATE    SERVICE
9999/tcp closed abyss		 # 해당 포트로 서비스하지 않음

Nmap done: 1 IP address (1 host up) scanned in 0.42 seconds

📖 TCP 연결 설정 (3-way handshaking)

아래 그림에서 (1)~(10)에 들어갈 값은?
SNY, ACK는 TCP 플래그 값을 SN,
AN는 Sequence number와 Acknowlegment number를 의미 

클라이언트							서버
              
SYN=(1)      SN=767				    (1) 1 	 → 연결 요청 시 설정
ACK=(2)      AN=(3)				    (2) 0
-------------------------------->	(3) 0
                      
ACK=(4)      AN=(5)				    (4) 1
SYN=(6)      SN=373				    (5) 768 = 767 + 1
<--------------------------------	(6) 1

SYN=(7)      SN=(8)				    (7) 0
ACK=(9)      AN=(10)				(8) 768
-------------------------------->	(9) 1
								    (10) 374 = 373 + 1

📖 트래픽 흐름제어

📖 연결종료(4-way handshake)

kali 가상머신에서 https://drive.google.com/drive/folders/1JHymvvQZX1x8xkbGuoRqL9yCqv5Jjowq 공유 폴더에 있는 http.pcapng 파일 다운로드

📖 TCP 동작

응용 계층에서 페이로드를 생성하고 전송 전에 3단계 연결 설정을 수행

  • 응용 계층에서 생성한 페이로드를 응용 계층 버퍼에 임시 보관하고 전송 계층에서 SYN 신호를 담은 세그먼트 한 개를 생성

  • SYN 세그먼트는 네트워크 계층, 데이터 링크 계층, 물리 계층을 통과해서 수신지로 전달

  • 수신 측에서는 해당 SYN 신호를 전송 계층까지 끌어올린 후 전송 계층에서 SYN/ACK 신호를 담은 세그먼트를 생성해서 송신지로 전달

  • 송신 측에서는 해당 SYN/ACK 신호를 전송 계층까지 끌어올린 후 전송 계층에서 ACK 신호를 담은 세그먼트를 생성해서 수신지로 전달해서 3단계 설정을 완료

3단계 연결 설정이 완료되면 운영체제는 응용 계층 버퍼에 저장했던 TCP 페이로드를 전송 계층으로 전달

전송 계층은 응용 계층에서 전달된 TCP 페이로드를 대상으로 단편화를 수행

📢 여기서 잠깐! 단편화(fragmentation)란?
전송 효율성과 데이터 기밀성을 위해 TCP 페이로드를 여러 개로 분할하는 기법

단편화가 끝나면 조각난 페이로드 앞에 출발지 포트와 목적지 포트 등을 담은 헤더가 붙으면서 여러 개의 세그먼트를 생성하고 각 세그먼트는 네트워크 계층으로 넘가면서 각각의 패킷을 생성

📖 IP 헤더

네트워크 계층(L3)에서 각 세그먼트/데이터그램 앞에 IP 주소를 추가한 것

일반적으로 IP 헤더는 20바이트 크기를 사용 (IP Option 항목을 이용해 21바이트 이상으로 사용이 가능)

서비스 종류(Type of Service)
해당 패킷의 전송 우선 순위를 지정 (회선이 혼잡할 경우 패킷의 전송 우선 순위를 부여할 때 사용)

전체 길이
IP 헤더를 포함한 패킷 전체의 길이

Identification, IP Flags, Fragement Offset
MTU(Maximum Transmission Unit, 최대 전송 단위)에 따른 패킷 분할 정보

  • IP Flags → 패킷 분할 여부를 표시
    ▫ D: Do not fragement
    ▫ M: More fragement

  • MTU 1500 바이트인 이더넷 구간을 1400 바이크 크기의 패킷이 통과하는 경우 → 패킷 분할 X

ID			           IP flags 			Fragment offset

			          X	  D   M
--------------		----------------		----------------
0			          0   1   0 	        0
  • MTU 1500 바이트인 이더넷 구간을 5900 바이트 크기의 패킷이 통과하는 경우 → 패킷 분할 발생
ID			           IP flags 			Fragment offset

			           X   D   M
--------------		----------------		----------------
1234			       0   0   1 			0
1234			       0   0   1 		    1500
1234			       0   0   1 			3000
1234			       0   0   0 			4500

생존 시간(TTL, Time To Live)
해당 패킷이 통과할 수 있는 라우터의 개수

프로토콜
상위 계층에 속한 프로토콜 번호
→ 수신 측에서 해당 패킷의 속성을 파악하는데 사용

헤더 오류 검사
비활성화 상태

출발지 IP 주소, 목적지 IP 주소
32비트의 IP 주소

📖 Scapy를 이용한 3-Way Handshking

https://scapy.net/
파이썬으로 제작된 패킷 조작 프로그램
패킷 캡처, 전송, 수정, 디코딩 등의 다양한 기능 제공

💻 Kali 가상머신에서 실습

┌──(kali㉿kali)-[~]
└─$ sudo scapy            
[sudo] password for kali: 

INFO: Can't import PyX. Won't be able to use psdump() or pdfdump().
                                      
                     aSPY//YASa       
             apyyyyCY//////////YCa       |
            sY//////YSpcs  scpCY//Pp     | Welcome to Scapy
 ayp ayyyyyyySCP//Pp           syY//C    | Version 2.5.0
 AYAsAYYYYYYYY///Ps              cY//S   |
         pCCCCY//p          cSSps y//Y   | https://github.com/secdev/scapy
         SPPPP///a          pP///AC//Y   |
              A//A            cyP////C   | Have fun!
              p///Ac            sC///a   |
              P////YCpc           A//A   | To craft a packet, you have to be a
       scccccp///pSP///p          p//Y   | packet, and learn how to swim in
      sY/////////y  caa           S//P   | the wires and in the waves.
       cayCyayP//Ya              pY/Ya   |        -- Jean-Claude Van Damme
        sY/PsY////YCc          aC//Yp    |
         sc  sccaCY//PCypaapyCP//YSs  
                  spCPY//////YPSps    
                       ccaacs         
                                       using IPython 8.14.0
>>>

>>> ls()				→ 지원하는 프로트콜 목록

>>> ls(TCP)				→ 현재 설정된 TCP 헤더 정보 출력
sport      : ShortEnumField                      = ('20')
dport      : ShortEnumField                      = ('80')
seq        : IntField                            = ('0')
ack        : IntField                            = ('0')
dataofs    : BitField  (4 bits)                  = ('None')
reserved   : BitField  (3 bits)                  = ('0')
flags      : FlagsField                          = ('<Flag 2 (S)>')
window     : ShortField                          = ('8192')
chksum     : XShortField                         = ('None')
urgptr     : ShortField                          = ('0')
options    : TCPOptionsField                     = ("b''")

>>> TCP().display()
###[ TCP ]### 
  sport     = ftp_data
  dport     = http
  seq       = 0
  ack       = 0
  dataofs   = None
  reserved  = 0
  flags     = S
  window    = 8192
  chksum    = None
  urgptr    = 0
  options   = ''

>>> TCP().show()
###[ TCP ]### 
  sport     = ftp_data
  dport     = http
  seq       = 0
  ack       = 0
  dataofs   = None
  reserved  = 0
  flags     = S
  window    = 8192
  chksum    = None
  urgptr    = 0
  options   = ''

>>> lsc()				→ 사용 가능한 기능 목록 

>>> help(TCP)				→ 도움말

>>> help()
Welcome to Python 3.11's help utility!

If this is your first time using Python, you should definitely check out
the tutorial on the internet at https://docs.python.org/3.11/tutorial/.

Enter the name of any module, keyword, or topic to get help on writing
Python programs and using Python modules.  To quit this help utility and
return to the interpreter, just type "quit".

To get a list of available modules, keywords, symbols, or topics, type
"modules", "keywords", "symbols", or "topics".  Each module also comes
with a one-line summary of what it does; to list the modules whose name
or summary contain a given string such as "spam", type "modules spam".

help> 

https://scapy.readthedocs.io/en/latest/installation.html#windows

1. 현재 설정된 IP 헤더의 정보 출력

>>> IP().show()
###[ IP ]### 
  version   = 4
  ihl       = None
  tos       = 0x0
  len       = None
  id        = 1
  flags     = 
  frag      = 0
  ttl       = 64
  proto     = hopopt
  chksum    = None
  src       = 127.0.0.1
  dst       = 127.0.0.1
  \options   \

>>> ip = IP()

>>> ip.show()
###[ IP ]### 
  version   = 4
  ihl       = None
  tos       = 0x0
  len       = None
  id        = 1
  flags     = 
  frag      = 0
  ttl       = 64
  proto     = hopopt
  chksum    = None
  src       = 127.0.0.1
  dst       = 127.0.0.1
  \options   \

2. 현재 IP 헤더의 목적지 주소 변경

>>> ip.dst = "192.168.40.130"          → ping bee.box 를 통해 확인
								         bee.box 가상머신의 IP 주소
>>> ip.show()
###[ IP ]### 
  version   = 4
  ihl       = None
  tos       = 0x0
  len       = None
  id        = 1
  flags     = 
  frag      = 0
  ttl       = 64
  proto     = hopopt
  chksum    = None
  src       = 192.168.40.129			→ kali.linux 가상머신의 IP 주소
  dst       = 192.168.40.130			→ bee.box 가상머신의 IP 주소
  \options   \

>>> ip = IP(dst="192.168.40.130")       → 생성자에 매개변수의 값을
										  설정하는 방법으로 초기화

>>> ip.show()
###[ IP ]### 
  version   = 4
  ihl       = None
  tos       = 0x0
  len       = None
  id        = 1
  flags     = 
  frag      = 0
  ttl       = 64
  proto     = hopopt
  chksum    = None
  src       = 192.168.40.129
  dst       = 192.168.40.130
  \options   \

3. 스니핑(sniffing)

네트워크 상에서 움직이는 트래픽을 염탐하는 행위

>>> sniff()						            → 시간이 조금 경과한 후 Ctrl+C
<Sniffed: TCP:20 UDP:784 ICMP:0 Other:1>	→ 스니핑 결과를 요약 출력

>>> sf = sniff()					        → Ctrl + C 로 중지

>>> sf.show()
0000 Ether / IP / UDP 3.112.113.156:20003 > 192.168.0.143:53955 / Raw
0001 Ether / IP / UDP 18.183.11.144:20003 > 192.168.0.143:57520 / Raw
0002 Ether / IP / UDP 192.168.0.143:57734 > 18.183.11.144:20003 / Raw
			:
2110 Ether / IP / UDP / DNS Ans "b'googlehosted.l.googleusercontent.com.'"


# 연결 요청
2111 Ether / IP / TCP 192.168.0.143:53808 > 142.250.206.193:https S


2112 Ether / IP / UDP 18.183.11.144:20003 > 192.168.0.143:57734 / Raw
2113 Ether / IP / UDP 3.112.113.156:20003 > 192.168.0.143:53955 / Raw
2114 Ether / IP / UDP 192.168.0.143:57734 > 18.183.11.144:20003 / Raw
			:
2124 Ether / IP / UDP 104.18.23.107:https > 192.168.0.143:50362 / Raw
2125 Ether / IP / UDP 18.183.11.144:20003 > 192.168.0.143:57520 / Raw
2126 Ether / IP / UDP 192.168.0.143:57734 > 18.183.11.144:20003 / Raw
2127 Ether / IP / UDP 192.168.0.143:49297 > 142.250.206.206:https / Raw


# 연결 수락
2128 Ether / IP / TCP 142.250.206.193:https > 192.168.0.143:53808 SA

# 연결 수락 확인
2129 Ether / IP / TCP 192.168.0.143:53808 > 142.250.206.193:https A	


2130 Ether / IP / TCP 192.168.0.143:53808 > 142.250.206.193:https PA / Raw
2131 Ether / IP / UDP 192.168.0.143:53955 > 3.112.113.156:20003 / Raw
2132 Ether / IP / UDP 192.168.0.143:57520 > 18.183.11.144:20003 / Raw
2133 Ether / IP / UDP 192.168.0.143:53955 > 3.112.113.156:20003 / Raw
2134 Ether / IP / UDP 192.168.0.143:57734 > 18.183.11.144:20003 / Raw


>>> sf[2111].show()				 		    → 인덱스 2111번의 패킷 상세 조회
###[ Ethernet ]###
  dst       = 9c:a2:f4:e8:44:3c
  src       = d0:3c:1f:1f:e7:3f
  type      = IPv4
###[ IP ]###
     version   = 4
     ihl       = 5
     tos       = 0x0
     len       = 52
     id        = 59149
     flags     = DF
     frag      = 0
     ttl       = 128
     proto     = tcp
     chksum    = 0x0
     src       = 192.168.0.143
     dst       = 142.250.206.193
     \options   \

###[ TCP ]###        sport     = 53808
        dport     = https
        seq       = 1752058677
        ack       = 0
        dataofs   = 8
        reserved  = 0
        flags     = S
        window    = 64240
        chksum    = 0x1f1a
        urgptr    = 0
        options   = [('MSS', 1460), ('NOP', None), ('WScale', 8), ('NOP', None), ('NOP', None), ('SAckOK', b'')]

>>>

>>> sf = sniff(count=10)				     → 캡쳐할 패킷의 갯수 지정

>>> sf.show()
0000 Ether / IP / UDP 3.112.113.156:20003 > 192.168.0.143:53955 / Raw
0001 Ether / IP / TCP 104.18.22.107:https > 192.168.0.143:57984 PA / Raw
0002 Ether / IP / UDP 192.168.0.143:57734 > 18.183.11.144:20003 / Raw
0003 Ether / IP / UDP 192.168.0.143:57734 > 18.183.11.144:20003 / Raw
0004 Ether / IP / UDP 18.183.11.144:20003 > 192.168.0.143:57520 / Raw
0005 Ether / IP / UDP 192.168.0.143:53955 > 3.112.113.156:20003 / Raw
0006 Ether / IP / UDP 192.168.0.143:57520 > 18.183.11.144:20003 / Raw
0007 Ether / IP / UDP 192.168.0.143:57734 > 18.183.11.144:20003 / Raw
0008 Ether / IP / UDP 192.168.0.143:57734 > 18.183.11.144:20003 / Raw
0009 Ether / IP / TCP 192.168.0.143:57984 > 104.18.22.107:https A

📖 Kali Linux 가상머신에 VSCode 설치

https://code.visualstudio.com/docs/setup/linux

$ sudo apt-get install wget gpg
$ wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > packages.microsoft.gpg
$ ls
Desktop  Documents  Downloads  help.py  Music  packages.microsoft.gpg  Pictures  Public  Templates  test.py  Videos
$ sudo install -D -o root -g root -m 644 packages.microsoft.gpg /etc/apt/keyrings/packages.microsoft.gpg
$ sudo sh -c 'echo "deb [arch=amd64,arm64,armhf signed-by=/etc/apt/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" > /etc/apt/sources.list.d/vscode.list'
$ rm -f packages.microsoft.gpg

$ sudo apt install apt-transport-https
$ sudo apt update
$ sudo apt install code

📖 kali.linux 가상머신에서 bee-box 가상머신으로 연결(3-way handshaking)하는 것을 Scapy로 구현

$ sudo scapy

>>> tcp = TCP()
>>> tcp.show()
###[ TCP ]### 

  sport     = ftp_data	  → 1024 이후의 임의 포트로 설정 
  dport     = http
  
  seq       = 0
  ack       = 0
  dataofs   = None
  reserved  = 0
  
  flags     = S			  → SYN (연결요청) 
  
  window    = 8192
  chksum    = None
  urgptr    = 0
  options   = ''

>>> tcp.sport = RandNum(1024, 65535)
>>> tcp.show()
###[ TCP ]### 

  sport     = <RandNum>
  
  dport     = http
  seq       = 0
  ack       = 0
  dataofs   = None
  reserved  = 0
  flags     = S
  window    = 8192
  chksum    = None
  urgptr    = 0
  options   = ''

>>> ip = IP()

>>> ip.show()
###[ IP ]### 
  version   = 4
  ihl       = None
  tos       = 0x0
  len       = None
  id        = 1
  flags     = 
  frag      = 0
  ttl       = 64
  proto     = hopopt
  chksum    = None
  
  src       = 127.0.0.1
  dst       = 127.0.0.1		 → bee-box 가상머신의 IP 주소로 변경
  
  \options   \

>>> ip.dst = "192.168.40.130"   → 다른 터미널에서 ping bee.box 명령으로 확인

>>> ip.show()
###[ IP ]### 
  version   = 4
  ihl       = None
  tos       = 0x0
  len       = None
  id        = 1
  flags     = 
  frag      = 0
  ttl       = 64
  proto     = hopopt
  chksum    = None
  
  src       = 192.168.40.129
  dst       = 192.168.40.130
  
  \options   \

>>> syn = ip / tcp		    → TCP 세그먼트에 IP 헤더를 덧붙여 SYN 패킷 생성

>>> syn.show()
###[ IP ]### 
  version   = 4
  ihl       = None
  tos       = 0x0
  len       = None
  id        = 1
  flags     = 
  frag      = 0
  ttl       = 64
  proto     = tcp
  chksum    = None
  src       = 192.168.40.129
  dst       = 192.168.40.130
  \options   \
###[ TCP ]### 
     sport     = <RandNum>
     dport     = http
     seq       = 0
     ack       = 0
     dataofs   = None
     reserved  = 0
     flags     = S
     window    = 8192
     chksum    = None
     urgptr    = 0
     options   = ''

>>> syn_ack = sr1(syn)		→ 전송하고 첫번째 응답이 올 때까지 대기 

Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets

>>> syn_ack.show()
###[ IP ]### 
  version   = 4
  ihl       = 5
  tos       = 0x0
  len       = 44
  id        = 0
  flags     = DF
  frag      = 0
  ttl       = 64
  proto     = tcp
  chksum    = 0x6878
  src       = 192.168.40.130
  dst       = 192.168.40.129
  \options   \
###[ TCP ]### 
     sport     = http
     dport     = 3952
     seq       = 2694158463
     ack       = 1
     dataofs   = 6
     reserved  = 0
     flags     = SA
     window    = 5840
     chksum    = 0x661c
     urgptr    = 0
     options   = [('MSS', 1460)]
###[ Padding ]### 
        load      = '\x00\x00'

>>> ack = ip / TCP(sport=syn_ack[TCP].dport, dport=syn_ack[TCP].sport, flags="A", seq=syn_ack[TCP].ack, ack=syn_ack[TCP].seq+1)

>>> send(ack)
.
Sent 1 packets.

📖 위의 과정을 hanshaking.py 파일로 만들어서 실행

kali linux 가상머신에서 진행

from scapy.all import * 

# tcp = TCP()
# tcp.sport = RnadNum(1024, 65535)
# tcp.dport = "80"
# tcp.flags = "S"
tcp = TCP(sport=RandNum(1024, 65535), dport=80, flags='S')


# ip = IP()
# ip.src = "192.168.40.129"
# ip.dst = "192.168.40.130"
ip = IP(src="192.168.40.129", dst="192.168.40.130")

syn = ip / tcp 

syn_ack = sr1(syn)

ack = ip / TCP(sport=syn_ack[TCP].dport, dport=syn_ack[TCP].sport, flags="A", seq=syn_ack[TCP].ack, ack=syn_ack[TCP].seq+1)

send(ack)
┌──(kali㉿kali)-[~]
└─$ sudo python3 handshaking.py        
[sudo] password for kali: 

Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets
.
Sent 1 packets.

📖 wireshark를 실행한 상태에서 hanshaking.py 파일 실행

✍ RST 패킷이 자동으로 전달되는 이유

https://0xbharath.github.io/art-of-packet-crafting-with-scapy/network_recon/service_discovery/index.html

✍ Kali 가상머신에서 RST 패킷이 나가지 않도록 방화벽에 룰 추가

$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination 



$ sudo iptables -A OUTPUT -p tcp --tcp-flags RST RST -s 192.168.40.129 -j DROP
iptables: No chain/target/match by that name.           ~~~~~~~~~~~~~~
                                                           # kali IP


$ sudo iptables -L                                                            
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       tcp  --  kali.linux           anywhere             tcp flags:RST/RST

0개의 댓글