본문 바로가기
Network

네트워크 취약점을 이용한 무료 와이파이(에그, 포켓파이, 포켓와이파이) 만들기(SKT, KT , LGU 무관 )

by Dork94 2017. 10. 15.


Project Saver(Savior)






네트워크 취약점(통신사 Retransmission 취약점)을 이용하며, 안드로이드에서 데이터가 과금 되지 않는 것을 이전 포스팅에 한 적이 있습니다.

 

2013년에 KAIST의 김용대 교수님께서 발표하신 논문의 취약점인 TCP Retransmission 취약점의 사용 범위를 확장하여, 특정 모바일에 국한되는 것이 아닌 모든 device가 무료로 이용할 수 있는 와이파이를 만들어 보았습니다.

 

프로젝트를 하면서 가장 많이 든 생각 중 하나가 바로 이 취약점을 "어떻게 발견하고 실행에 옮기셨을까?"에 대한 생각이 가장 많았던 것 같습니다. 제가 그때 당시에 돌아가서 TCP Retransmission이 과금이 되지 않는다는 것을 최초로 알았다고 해도 저라면 아마 "그래 그게 맞는 과금 방식이지"라고 생각하며 넘겼을 것 같은데, 그 상황으로 취약점까지 알아내신 김용대 교수님 존경합니다(꼭 한번 만나 뵙고 싶어요!).

 

Project Saver(Savior)의 의미는 Saver는 데이터를 아끼는 절약의 의미이고, 비슷한 어음인 Savior는 구원자라는 뜻으로 와이파이를 만들어 데이터 없는 자들을 구원해준다는 의미입니다. (사실 좋은 의도의 구원자는 아니네요.)


의도를 분명히 밝히자면, 공유목적이나 배포의 목적은 없으며, 해당 취약점이 얼른 알려져서 패치되길 바라는 바입니다.

또한, 악의적 목적으로 사용한 적이 없으며 심지어 저는 데이터 무제한 이용자입니다. 오히려 테스트하느라 데이터를 더 쓴 것 같네요. 


우선, 이전의 포스팅에서 보여드린 대로 안드로이드에서 해당 취약점을 이용하기 위해서 해당 프로그램을 구동 시키기 위해, 해당 프로그램을 안드로이드에서 구동해야 하며, 이때, 해당 기기의 루팅 또한 불가피합니다.

 

금융 어플리케이션이나 다른 기타 어플리케이션을 사용할 때에, 루팅이 되어 있는 상태라면, 해당 서비스를 이용하는데 제한적이기 때문에, 가용성이 많이 떨어졌습니다.

 

또한, 해당 프로그램을 안드로이드에서 구동시키기 위해 Linux 기반으로 동작하도록 어플을 이용하거나 Nethunter를 이용해야 하며, 해당 설치 과정이 번거롭습니다.

 

해당 취약점을 안드로이드에서 구동할 경우 개인만 사용할 수 있다는 단점이 있습니다(제가 작성한 기존 프로그램으로 핫스팟을 구동 할 경우 동작 방식이 달라져 프로그램 동작에 차질이 있었습니다).

 

하지만 개인이, 이러한 취약점을 이용해 모두가 사용할 수 있는 무료 와이파이(포켓파이,에그)를 만든다면 컴퓨터를 모르는 사람도, 또 루팅이 되어있지 않는 사람도, IOS를 사용하고 있는 아이폰이나, Android를 사용하고 있는 갤럭시 및 대부분의 기기에 종속적이지 않고 해당 취약점을 이용하여 무제한으로 데이터를 사용할 수 있습니다.

 

코드는 아래와 같이 모두 작성해 놓은 상태로 컴퓨터를 잘 모르는 일반인도 간단한 명령어로 실행 및 동작시킬 수 있습니다. 그러나, 법적 문제 및 악의적 의도로 사용될 수 있기 때문에 배포는 하지 않는 것을 원칙으로 합니다.

 


 

 

이렇게 취약점이 있고 개인이 시간을 조금만 투자하면(물론 네트워크와 코딩을 할 줄 알아야 한다는 전제 조건이 있지만) 누구나 해당 취약점을 이용하여 사용 할 수 있는데 국내 3사의 통신사의 높은 보안 수준에도 불구하고, 현실적인 어려움 때문에 패치가 어려운 것이 사실입니다.

 


 저 같은 경우에는 네트워크에 대한 지식이 많이 부족한 상태로 시작하여 iptables, in-path routing, routing table, tunneling, tun tap interface, shell script, fragmentation packet 등 지식을 얻는데 시간이 걸렸습니다.

하지만, 이번 프로젝트에 있어 가장 큰 수확은 LTE 데이터를 무료로 사용하는 것이 아닌 위에 나열한 지식들의 습득인 것 같습니다.

 

본 취약점은 해외의 일부 통신사에도 적용이 되므로, 해당 취약점이 존재하는 해외에 나가시는 분들이라면 데이터 걱정 없이 무제한으로 이용하실 수 있습니다.

 

현재, 구동 및 테스트까지 모두 확인한 상태이며 SKT, KT, LGU+ 국내 3사 통신사 모두 해당 취약점을 확인하였습니다.

 

아래에 프로그램의 프로세스에 대해 간단하게 도식화 하였습니다.

 

 

 

 

 

간단한 도식화이지만 위의 방식대로 구동하는데 생각보다 많은 난관이 있었습니다.

Retransmission 패킷의 과금부터, Fragmentation 발생 및 MTU 처리 방식 또, Raspberry Pi의 Station의 Packet에 대한 Identify과정 Socket의 Bind 문제, DNS 서버의 처리 Tun Interface의 이해 및 Network buffer 문제까지.

 어느 날은 종일 검색하고 생각해서 코드 한줄 적은 날도 있었고, 자면서 생각하다가 될 것 같으면 깨어서 컴퓨터 키보드를 잡은 날도 있었는데 이렇게 완성하고 보니 뿌듯하네요. 그리고 정말 무한한 도움을 주신 luke1337님께 다시 한번 감사드립니다.

 

 

포켓 파이를 만들기 위해서는 라즈베리 파이를 사용하였으며, 외형은 아래 사진과 같습니다.

 

라즈베리 파이란 간단히 말해 아주 작은 소형 컴퓨터(소형 본체)이며, 라즈베리파이에 HDMI 및 USB 포트 LAN 포트가 있어 모니터 및 키보드 마우스를 연결하여 사용하면 컴퓨터처럼 작동하는 기계입니다.

 

 

 

 

 

데이터 취약점을 이용하기 위해 LTE 모듈을 사용하였으며 해당 제품은 Alcatel L800 모델 입니다. 해당 제품은 국내에서 팔지 않는 모델로 해외 배송을 통해 구매하였습니다.

LTE 모듈은 간단히 말해, USIM칩을 모듈 안에 장착하여, 인터넷 통신을 가능하게 해주는 USB입니다.

국내에서 가장 보편적으로 쓰이는 LTE 모듈로 알고 있고, 해당 제품이 라즈베리 파이와 정상적으로 호환이 되며, 국내 LTE망 주파수 대역을 지원하기 때문에 사용하였습니다.

 

해당 제품이 아닌 다른 제품을 구매하시는 경우 사용하시는 통신사의 LTE 주파수 대역을 확인하시고 구매하셔야 합니다.

또한, LTE 모듈이 아닌 라즈베리 파이 LTE Shild가 있는데 해당 제품의 가격은 약 50만 원 선으로 해외에서 구매하셔야 합니다(심지어 국내는 배송도 되지 않았습니다).

 

 

 

 

 

 

 

라즈베리 파이의 장착 모습은 아래와 같습니다.

안드로이드 충전기(5핀 충전기)를 이용해 라즈베리 파이에 전원을 공급할 수 있으며, 전원 공급 시 자동으로 프로그램이 실행되어 와이파이가 동작하게 됩니다.

 

 

 

 

 

 

조만간, 실행 영상 및 데이터 차감 결과를 영상 및 사진으로 올리도록 하겠습니다.


 

아휴.... 실물은 더 나은데 화면발이 잘 안 받네요..^^

 


 

테스트는 LGT에서 했으며, 동영상엔 없지만, SKT도 동작 확인 하였습니다(처음에 SKT USIM을 빌려서 촬영을 모두 완료했었는데, 아이패드에서 화면 녹화가 저장오류로 저장이 되지 않아 올리지 못했네요).

 

도움을 주신 박영진 님, 강보경 님(http://allday22.tistory.com/) 감사합니다. 

질문은 댓글로 받도록 하겠습니다.

 

댓글11

  • 이다민 2018.07.08 20:43

    안녕하세요 너무 의존하는 것 같아 한편으로 죄송하며 감사합니다. c언어로 구현하려 합니다.
    어떤 라이브러리를 추가 해야 할까요?
    dev 에서도 가능할까요?
    또한 구현해야하는 순서와 걸리는 시간을 알려주실수 있으실까요?
    답글

    • Dork94 2018.07.09 12:12 신고

      안녕하세요. 괜찮습니다. 우선 라이브러리는 패킷을 보거나 송수신할때 pcap library가 필요하지만 그 전에 in - path와 out-of-path의 차이점에 대해 공부하셔야합니다. pcap은 packet send시 사용할 수 있으나 packet을 handling(Drop이나 routing)할 수 없는 라이브러리 입니다. dev는 어떤것을 말씀하시는지 모르겠고 구현해야하는 순서는 원하시는걸 먼저 하시기 나름입니다:) 거릴는 시간은 저의 경우에 수 개월이 소요되었습니다.

  • 이다민 2018.07.08 20:47

    #include <stdio.h>
    #include <Windows.h>

    #pragma comment (lib, "ws2_32.lib" )

    struct pseudo_header{
    unsigned int source_address;
    unsigned int dest_address;
    unsigned char placeholder;
    unsigned char protocol;
    unsigned short tcp_length;
    };

    struct tcp_header
    {
    unsigned short source_port;
    unsigned short dest_port;
    unsigned int sequence;
    unsigned int acknowledge;
    unsigned char ns:1;
    unsigned char reserved_part1:3;
    unsigned char data_offset:4;
    unsigned char fin:1;
    unsigned char syn:1;
    unsigned char rst:1;
    unsigned char psh:1;
    unsigned char ack:1;
    unsigned char urg:1;
    unsigned char ecn:1;
    unsigned char cwr:1;
    unsigned short window;
    unsigned short checksum;
    unsigned short urgent_pointer;
    };

    typedef unsigned char u_char;
    typedef short SHORT;

    unsigned short in_checksum(unsigned short *ptr,int nbytes) {
    register long sum;
    unsigned short oddbyte;
    register short answer;

    sum=0;
    while(nbytes>1) {
    sum+=*ptr++;
    nbytes-=2;
    }
    if(nbytes==1) {
    oddbyte=0;
    *((u_char*)&oddbyte)=*(u_char*)ptr;
    sum+=oddbyte;
    }

    sum = (sum>>16)+(sum & 0xffff);
    sum = sum + (sum>>16);
    answer=(SHORT)~sum;

    return(answer);
    }

    void main()
    {
    unsigned int src_port = 46731;
    unsigned int dst_port = 7778;

    char *src_ip = "165.246.67.211";
    char *dest_ip = "165.246.12.215";;
    struct pseudo_header *psh;
    struct tcp_header *myth;
    unsigned short tcpchecksum;

    psh = (pseudo_header*) malloc(sizeof(pseudo_header));
    myth = (tcp_header*)malloc(sizeof(tcp_header));
    psh->source_address=inet_addr(src_ip);
    psh->dest_address=inet_addr(dest_ip);

    psh->placeholder=0; // reserved
    psh->protocol=6; // protocol number for tcp
    psh->tcp_length=htons(20); // tcp header size.

    // build tcp header
    myth->source_port = htons(src_port);
    myth->dest_port = htons(dst_port);
    //0xf101c700 => network byte order => 0x00c701f1
    myth->sequence = 0x00c701f1;
    myth->acknowledge = 0;

    myth->ns = 0;
    myth->reserved_part1 = 0;
    myth->data_offset = 5; // tcp length = 5 * 4, 20
    myth->fin = 0;
    myth->syn = 1;
    myth->rst = 0;
    myth->psh = 0;
    myth->ack = 0;
    myth->urg = 0;
    myth->ecn = 0;
    myth->cwr = 0;
    myth->window = htons(0x2000);
    myth->checksum = 0;
    myth->urgent_pointer = 0x0;

    unsigned char *seudo;
    unsigned int tcp_data_size;
    tcp_data_size = sizeof(struct pseudo_header)+ sizeof(struct tcp_header);
    seudo = (unsigned char *)malloc(tcp_data_size);
    memcpy(seudo, psh, sizeof(struct pseudo_header));
    memcpy(seudo+sizeof(struct pseudo_header), myth, sizeof(struct tcp_header));

    printf("\n");
    printf("tcp pseudo size = %d\n",sizeof(struct pseudo_header));
    printf("tcp hdr size = %d\n",sizeof(struct tcp_header));
    printf("tcp size = %d\n",tcp_data_size);

    myth->checksum = in_checksum((unsigned short*)seudo,tcp_data_size);

    printf("\n%x\n",myth->checksum);

    }

    tcp checksum 을 구현하였는데 필요할까요??
    답글

    • Dork94 2018.07.09 12:13 신고

      TCP Checksum은 저의 경우 필요한 함수였으며, 다만 만들고 필요할지를 생각하는 것이 아니라 어떤 프로젝트를 할때 우선 간단한 구성도를 그리고 그안에 사용되는 함수나 구현해야할 기능들을 정리 하신 후 개발을 하시는 것이 맞습니다.

  • 이다민 2018.07.08 20:57

    http://jmoon.co.kr/63
    답글

    • Dork94 2018.07.09 12:15 신고

      Burp Suite의 경우 IP/TCP를 조작가능한지 모르겠으나 프로젝트와 동떨어진 프로그램입니다. 우선 프로젝트에 대한 이해를 다시한번 정리해 보신 후 진행하는 것을 추천드립니다. 네트워크나 개발에 대해 여러가지로 복합적인 프로젝트라 기초가 선행되어 있지않으면 힘든 프로젝트입니다.

  • 이다민 2018.07.09 15:58

    넵 무한한 도움 감사드립니다
    답글

  • 이다민 2018.08.19 15:32

    Dork94님 제가 아는분과 다시 시도중입니다 혹시 저희의 프로젝트를 봐주실수 있으신가요? 카톡 그룹방에 들어와서 봐주시면 감사하겠습니다
    답글

  • 2018.08.19 15:35

    비밀댓글입니다
    답글

  • 현성용 2019.06.16 15:15

    지금도 가능한건가요?
    답글

    • Dork94 2019.06.16 15:57 신고

      테스트는 최근에 안해보았지만 가능한것으로 생각됩니다. 최근에 tcp retransmisson 이외에도 다른 프로토콜을 이용해 익스플로잇할수있는것을 확인하였습니다