ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ip_change 구현하면서 정리
    Network hacking training/Knowledge 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;
    }

    프로그램 구현 순서
    1. nfq_get_payload() 를 호출 한 뒤 IP header, TCP header 영역을 추출한다.
    2. IP heder에서 Dest IP가 Before_IP 인 경우 After_IP로 바꿔준다.
    3. IP Header가 변경되었으므로 checksum도 수정을 해준다.
    4. 필요에 따라 TCP Header, UDP header의 값도 변경해 주도록한다.(checksum, port?)
    5. 변경된 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(); 에 ';'를 빼주면 된다 ㅋ


    반응형

    'Network hacking training > Knowledge' 카테고리의 다른 글

    tcp_data_change 구현하면서 정리  (0) 2018.09.27
    airodump 구현하면서 정리  (0) 2018.09.06
    [CCIT] 8/12 정리  (0) 2018.08.18
Designed by Tistory.