이 OSI 7 계층이 바로 기준이 되었고 이 규칙은 1984년에 국제 표준화기구 (ISO)에서발표되었습니다.
그렇다면 왜 7 계층이라는 단어를 쓰게 되었을까요?
(너무 어렵게 생긴 위 사진을 이해하려 하지 마세요)
쉽게 설명드리겠습다.
군대에서 상급자가 하급자에게 명령을 내릴 때 가장 아래 병사인 이등병까지
명령이 잘 전달되어야 임무를 수행하겠죠?
7 계층 역시 같은 구조입니다.
하지만 순서만 반대로 생각하시면 돼요
맨 아래 1에서부터 상위 6번까지 모든 것이 완벽하게 연결되어야 비로소 7이 동작하게 됩니다.
바로 이러한 모습이
완벽한 수직적 모습을 갖추고 있기 때문에 "계층"이라는 단어를 쓰게 되었습니다.
그래서 우리는 이것을 7 계층이라고 합니다.
이렇게 OSI 7 계층은 통신이 일어나는 과정을 총 7가지로 구분 지어놓고
단계별로 정의하여 네트워크를 구성하고 데이터의 흐름을 파악할 수 있도록 각각 고유한 형태를 이루고 있습니다.
각 계층은 독립되어 있으며 한 부분에서 문제가 생긴다면
빠르게 문제가 생긴 부분을 파악할 수 있고 그 부분을 보안할 수 있도록 모습이 고안되었습니다.
우리는 이미 이걸 이해하고 있을지도 모릅니다.
예를 하나 들어보도록 할게요
컴퓨터에서 인터넷이 갑자기 안됩니다.
왜 이러지? 인터넷 문제인가? 하면서 인터넷 선을 뽑았다 다시 꽂았다 하면서 확인하잖아요?
우리는 이미 OSI 7 계층에서의 3단계 네트워크 단계를 이해하고 있는 겁니다.
만약 접속이 문제가 아니라면 아래 물리계층 1단계 데이터 계층 2단계도 문제가 없는 것이니
4번 전송 계층부터 문제점을 확인해 나아가면 됩니다.
이해가 좀 되시나요?
오늘 이 글에서는 아래 내용만 기억하시고
넘어가시면좋을것같습니다.
1. 모든 장치나 네트워크 통신장비를 만들고 구성할 때 기준으로 약속하고 모습을 정해놓은 7가지 약속이 있고 우리는 이걸 OSI 7계층으로 부르고 있다. 2. 7계층이라고 부르는 이유는 수직적으로 운용되기 때문이다. (1이 되어야 2가 되고 모든 것이 순차적으로 완료되어야 7이 동작한다.) 3. 7계층은 각각 독립된 형태를 유지하고 있어 문제가 발생하면 파악도 빠르고 해결도 빠르다.
Edit : 패킷을 찾거나 표시 / 프로그램 속성 설정 Go : 캡처된 데이터를 특정 위치로 이동 Capture: 캡처 필터 옵션 설정 및 캡처 시작/종료 Analyze: 분석 옵션 설정 Statistics: 통계 데이터 확인 Telephony/Wireless : Telephony 또는 Wireless와 관련된 통계/스트림 확인
그 아래 있는 카테고리를 한번 살펴보도록 하겠습니다
No. : 패킷을 수집한 순서 Time : 패킷이 수집된 시간 Source : 패킷을 보낸 주소 Destination : 패킷 도착 주소 Protocol : 프로토콜 정보 Length : 패킷의 길이 Info : 패킷 정보
필터 (Filter)
와이어 샤크를 실행하고 배우는 이유는
어떠한 네트워크 상의 문제나 특정 데이터의 흐름을 찾아보고 싶어서 실행한 거잖아요?
그런데 네트워크 상의 모든 내용을 캡처하면 내가 보고 싶은 데이터를 보기가 어려울 수 있습니다.
이때 필요한 기능이 바로 필터라는 것입니다.
패킷 필터를 적용하는 것을 패킷 필터링이라고 부릅니다
(어떻게 부르던 자유니 외우시거나 할 필요는 없습니다)
캡처 방법에는 2가지가 있는데,
원하는 내용만 처음부터 캡처하는 캡처 필터 (Capture Filter)와
전체를 캡처하고 필터를 걸어 검색하는 디스플레이 캡처 (Display Filter)가 있습니다.
우리는 캡처 필터는 사용하지 않겠습니다.
위 방법들이 크게 중요하지도 않고
디스플레이 캡처만 알고 계셔도 됩니다
이런방법이있구나알고만넘어갑시다.
프로토콜 (Protocol) 별 필터 검색
프로토콜로 데이터를 검색하는 방법입니다.
DNS: DNS (Domain Name System), 도메인 이름 DHCP: DHCP (Dynamic Host Configuration Protocol), 동적 IP 주소 할당 요청 ICMP: ICMP (Internet Control Message Protocol), 송수신 측의 전송 과정 WLAN: 무선랜
논리 연산자 필터 검색
eth.addr
원하는 MAC 주소 필터
!(eth.addr)
입력한 MAC 주소 예외
eth.src
출발지 MAC 주소 설정
eth.dst
목적지 MAC 주소 설정
tcp.port
TCP 포트 설정
!(tcp.port)
입력한 TCP 포트 주소 예외
tcp.srcport
출발지 TCP 포트 설정
tcp.dstport
목적지 TCP 포트 설정
udp.port
UDP 포트 설정
!udp.port
입력한 UDP 포트 예외
udp.srcport
출발지 UDP 포트 설정
udp.dstport
목적지 UDP 포트 설정
ip.addr
IP 필터
!(ip.addr)
입력한 IP 주소 예외
ip.src
출발지 IP 주소 설정
ip.dst
목적지 IP 주소 필터
쉽게 알려주세요
지금 우리가 원하는 건 지금 위의 내용이 아니라
데이터의 흐름을 직접 검색해서 보고 싶어요
그래서 어떻게 하는건가요??
정말 쉬운 예시 하나로 같이 살펴볼게요!
CMD 프롬프트 혹은 터미널 Terminal에서
nslookup www.naver.com를한번쳐봅시다
아이피가 23.35.221.113이네요?
(아이피는 계속 달라지니 직접 nslookup 해보시고 시도해 주세요)
아이피를알아냈으니와이어샤크로검색해봅시다
위에 논리연산자라고 적어놓은 것 중에 IP 필터라고 있죠?
그걸 앞에 입력하고 위와 같이 입력해 봅시다.
ip.addr == 23.35.221.113
(nslookup에 나온 ip를 치시면 됩니다)
필터를 검색하면 해당 아이피와 통신했던 데이터 패킷만 출력되게 됩니다.
저희가 검색한 패킷에서 Three Way Hand Shake을
한번 찾아볼까요?
3-Way Hand Shake가 뭔지 모르신다면
아래 글을 읽어봐주세요!
(작성중)
위 사진을 보면 오른쪽에 SYN과 ACK를 주고받으며
3-way hand shake를 수행하여 신뢰관계를 맺은 데이터의 흐름을 확인할 수 있습니다.
먼저, 주어진 디렉토리에서 모든 PE 파일을 찾고 이들을 파싱하여 그래프의 노드로 추가합니다.
그런 다음 각 PE 파일의 Import Table을 분석하여 필요한 DLL을 그래프에 추가하고,
이들 사이의 의존성을 간선으로 표현합니다.
PE 파일 의존성 그래프 업데이트 그 다음 단계에서는 모든 PE 파일의 Export Table을 분석합니다.
이를 통해 각 DLL이 제공하는 함수를 알 수 있습니다.
이 함수들을 사용하는 다른 PE 파일을 찾아 그래프에 의존성을 추가합니다.
IAT 정보 출력 마지막으로, 각 PE 파일의 Import Address Table(IAT)를 분석하여
각 함수가 실제로 어떤 메모리 주소에서 호출되는지를 출력합니다.
그래프 시각화 모든 정보를 바탕으로 그래프를 생성한 후에는
networkx와 matplotlib를 이용해서 그래프를 시각화합니다.
이를 통해 각 PE 파일 간의 복잡한 의존성을 한눈에 확인할 수 있습니다.
(아래는 예시 코드입니다)
import os
import pefile
import networkx as nx
import matplotlib.pyplot as plt
def create_dependency_graph(directory):
G = nx.DiGraph()
pe_files = {}
# 모든 PE 파일을 파싱한다.
for filename in os.listdir(directory):
filepath = os.path.join(directory, filename)
# PE 파일이 아닌 경우 건너뛴다.
if not pefile.isPE(filepath):
continue
pe = pefile.PE(filepath)
# 파싱한 PE 파일을 저장한다.
pe_files[filename] = pe
# 현재 파일 노드를 그래프에 추가
G.add_node(filename)
# 모든 PE 파일의 Import 정보를 통해 그래프를 만든다.
for filename, pe in pe_files.items():
if hasattr(pe, "DIRECTORY_ENTRY_IMPORT"):
for entry in pe.DIRECTORY_ENTRY_IMPORT:
dll_name = entry.dll.decode('utf-8')
G.add_node(dll_name)
G.add_edge(filename, dll_name) # 현재 파일에서 DLL로 의존성 표시
# IAT 정보를 출력한다.
for imp in entry.imports:
print(f'{filename} imports function {imp.name} from {dll_name} at address {hex(imp.address)}')
# 모든 PE 파일의 Export 정보를 통해 그래프를 업데이트한다.
for filename, pe in pe_files.items():
if hasattr(pe, "DIRECTORY_ENTRY_EXPORT"):
for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols:
# 해당 PE 파일이 export하는 함수를 사용하는 다른 PE 파일을 찾는다.
for user_filename, user_pe in pe_files.items():
if hasattr(user_pe, "DIRECTORY_ENTRY_IMPORT"):
for entry in user_pe.DIRECTORY_ENTRY_IMPORT:
if entry.dll.decode('utf-8') == filename:
for imp in entry.imports:
if imp.name == exp.name:
G.add_edge(user_filename, filename) # 다른 파일에서 현재 파일로 의존성 표시
return G
# 디렉토리 지정 (PE 파일들이 위치한 디렉토리를 지정해야 함)
directory = './PE_files_directory'
G = create_dependency_graph(directory)
# 그래프를 그림
nx.draw(G, with_labels=True)
plt.show()
정리
이 포스트에서는 PE 파일의 Import Table, Export Table,
그리고 IAT를 이용해 PE 파일 간의 의존성을 분석하고 시각화하는 방법을 살펴봤습니다.
다시 한번 정리해보면,
Import Table: PE 파일이 실행되기 위해 필요한외부 라이브러리(DLL 파일)들의 정보
Export Table: DLL 파일이 외부에 제공하는 함수나 변수의 정보 (다른 PE 파일들이 이 DLL 파일을어떻게 활용할 수 있는지를 알려주는 테이블)
Import Address Table (IAT): PE 파일이 Import Table을 통해 가져온 외부 함수들의 주소를 저장하는 곳
Import Table은 '무엇'이 필요한지
(어떤 DLL과 함수들이 필요한지)
Export Table은 '무엇'을 제공하는지
(어떤 함수와 변수들을 제공하는지),
IAT는 '어디에' 있는지
(각 함수의 메모리 주소는 어디인지)
이 방법을 통해 복잡한 소프트웨어 시스템의 구조를 이해하고, 문제를 분석하고, 솔루션을 찾는 데 도움이 될 수 있습니다.