Network hacking training/Knowledge
ip_change 구현하면서 정리
fkillrra
2018. 10. 1. 14:14
목적 및 목표 : Destination IP를 변경
tcp_data_change와 동일하게 in-path의 netfilter를 이용할 것이기 때문에 iptables를 설정해준다.
[iptables 설정]
⚡ root@ubuntu ~ iptables -A OUTPUT -j NFQUEUE --queue-num 0
⚡ root@ubuntu ~ iptables -A INPUT -j NFQUEUE --queue-num 0
⚡ root@ubuntu ~ iptables -F // 이는 iptables에 등록한 규칙을 제거할 때 주는 명령이다. (따라서 위에 2개만 명령하자.)
(참고) checksum에 대해 정리한 내용은 위 링크에 있다.
[개요]
어설픈 proxy를 구현해보자.
만약 아래와 같은 IP를 가지고 있다고 가정했을 때
- naver : 1.1
- local proxy : 2.2
- daum : 3.3
우리가 naver를 요청했을 때 daum에서 응답이 올 수 있게 해야한다.
패킷을 in-path로 관리를 하는데 (netfilter) 우리가 naver(1.1)로 요청을 했을 때의 dest_ip (1.1)를 daum(3.3)으로 바꾸고, daum(3.3)에서 오는 패킷, 즉 response의 패킷은 | src : 3.3 | dst : 2.2 | 일 것이므로 이 패킷의 src_ip(3.3)를 naver(1.1)로 바꾸어준다.
>> 그렇다면 결론적으로 우리는 naver에 요청을 했지만 naver와 통신을 하지 못하고 daum과 통신을 하게 될 것이다.
먼저 ip_change 라는 프로그램에는 인자가 3개(파일 이름, Before_IP, After_IP)가 들어가야하니 main()에 인자값 체크를 한다.
if(argc != 3)
{
printf("Usage : ./ip_change [Before_IP] [After_IP]\n");
return 0;
}
프로그램 구현 순서
- nfq_get_payload() 를 호출 한 뒤 IP header, TCP header 영역을 추출한다.
- IP heder에서 Dest IP가 Before_IP 인 경우 After_IP로 바꿔준다.
- IP Header가 변경되었으므로 checksum도 수정을 해준다.
- 필요에 따라 TCP Header, UDP header의 값도 변경해 주도록한다.(checksum, port?)
- 변경된 IP 패킷의 반대 flow 패킷에 대해서도 적절한 처리를 해준다.
Before IP, After IP 는 ping을 때려서 알아온다.
ex) ping naver.com
Before, After IP의 경우 main() 함수의 인자로 넘어오는데 string으로 넘어온다.
이를 변형하기 위해서 in_addr이라는 구조체로 변환한 뒤 inet_aton()를 이용하여 4byte의 값으로 만들어주면 되는데
좀 알아보다보니 좋은 함수가 있었다.
inet_pton()인데, 이 함수는 IPv4, IPv6 주소를 binary형태로 변환을 하여 저장하는 기능을 한다.
arpa/iinet.h 를 include 하여 사용하면 된다.
inet_pton(AF_INET, argv[1], &before_ip); //uint32_t before_ip
inet_pton(AF_INET, argv[2], &after_ip); //uint32_t after_ip
부가설명을 하자면 원형은 다음과 같다.
int inet_pton(int af, const char *src, void *dst);
af에는 AF_INET or AF_INET6가 들어간다. src가 가리키는 문자열이 IPv4 or IPv6에 따라 다르게 들어간다.
IPv4가 들어가면 in_addr이라는 구조체로 변환된 후 4byte의 크기를 가지는 dst로 복사가 된다.
IPv6라면 in6_addr이라는 구조체로 변환된 후 마찬가지로 크기에 맞게 dst로 복사된다.
이후는 IP의 checksum을 구하는 과정만 더 하면 tcp_data_change와 다를게 많이 없다.
따라서 완성된 코드는 아래 링크에 모셔두었다.
멍청하지만 30분 삽질한 내용
컴파일러가 expected '}' before 'else' 라는 오류를 뿜었다.
해결 : if(); 에 ';'를 빼주면 된다 ㅋ
반응형