
/* http://www.anticode.com  for the latest exploits, tools and documents! */

/*========================================================
                    UDP SCAN Ver1.0 
                  Developped by UNYUN
         Presented by The Shadow Penguin Security
          http://base.oc.to/skyscraper/byte/551
  [動作確認]
    TURBO LINUX 3.0
  ========================================================
*/

#include    <stdio.h>
#include    <sys/socket.h>
#include    <netinet/ip_icmp.h>

#define SRC_PORT    10101    /* 応答を得るClient Port   */

/*========================================================
            プログラムエントリ ＆ SCAN 実行
  [Output]
    0 = 正常送信, 1 = エラー
  ========================================================
*/
int main(int argc, char *argv[])
{
    struct icmphdr     *icmp_header;    /* udpヘッダ                */
    struct sockaddr_in target_info;     /* ターゲット情報バッファ   */
    int                target_info_len; /* ターゲット情報バッファ長 */
    fd_set             read_fd;         /* Select用ビットマップ     */
    int                scan_port;       /* ターゲットSCANポート     */
    char               recvbuf[5000];   /* パケット受信バッファ     */
    struct sockaddr_in target_addr;     /* ターゲットサーバ属性     */
    int                icmp_socket;     /* ICMP Socket              */
    int                udp_socket;      /* UDP Socket               */

    /*-----< 使い方表示と引数処理 >---------------------------------*/
    if (argc!=3){
        printf("[usage] %s [TargetIP] [TargetPort] \n",argv[0]);
        return -1;
    }
    /*-----< 各変数の初期化 >----------------------------------------*/
    icmp_header  = (struct icmphdr *)(recvbuf+sizeof(struct iphdr));
    scan_port    = atoi(argv[2]);
    target_addr.sin_family         = AF_INET;
    target_addr.sin_addr.s_addr    = inet_addr(argv[1]);
    target_addr.sin_port           = htons(scan_port);

    /*-----< 生Socketの作成 >---------------------------------------*/
    if ((udp_socket=socket(AF_INET,SOCK_DGRAM,0))==-1){
        printf("UDP Socket Creation Error.\n");
        return -1;
    }
    if ((icmp_socket=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))==-1){
        printf("RAW Socket Creation Error.\n");
        return -1;
    }

    /*-----< ターゲットにパケットを投げて、応答を待つ >-------------*/
    sendto(udp_socket,NULL,0,0,(void *)&target_addr,sizeof(target_addr));
    FD_ZERO(&read_fd);
    FD_SET(icmp_socket,&read_fd);
    select(FD_SETSIZE,&read_fd,NULL,NULL,NULL);
    for (;;){
        if (FD_ISSET(icmp_socket,&read_fd)){
            target_info_len = sizeof(target_info);
            recvfrom(icmp_socket,recvbuf,5000,0,
                     (struct sockaddr *)&target_info,&target_info_len);
            if (target_info.sin_addr.s_addr == target_addr.sin_addr.s_addr
             && icmp_header->type == 3  && icmp_header->code<=12){
                     printf("Port %d : Close\n",scan_port);
                     exit(1);
            }
       }
    }
    return(0);
}
