euniclus今回はRubyでルートスキャナーを作ります。Rubyでのプログラミングには慣れていませんが、前回ポートスキャナーを作った時の記憶が残っているのでそれを頼りに実装していきたいと思います。ルートスキャナーについては以前に記事を書きました。前回記事にした時と同様にicmpエコー要求を使う方向で実装したいと思います。そのために必要なことをまとめます。ソケットポートスキャンと違いルートをトレースするためにipパケットのttlフィールドをこちらで設定します。カーネルに「ipパケットもこちらでつくるよ」ということを伝える必要があります。Socket::open(Socket::AF_INET,Socket::SOCK_RAW,Socket::IPPROTO_ICMP)@soc.setsockopt(Socket::IPPROTO_IP,Socket::IP_HDRINCL,1)icmpのソケットを作成し、setsockoptでipヘッダーも作成するよう設定します。パケット今回はipパケットとicmpパケットを作成します。ipパケットを作成する関数です。パケット送信時にttlを指定します。[ver_hl,tos,len,id,off,ttl,p,cksum,saddr,daddr]data.pack('C2n3C2n1N2')endicmpパケットを作成する関数です。icmpエコー要求パケットを送信しますので、タイプに8を指定します。seq]data.pack('C2n3')end以上が今回作るツールの核になる部分です。ソースコード全体RouteScannerというクラスを作成しました。ttlに設定する値として1からスタートし255までインクリメントしていきます。readyの待ち時間を過ぎた場合は初回の込みで3回まで再送信します。パケットを受信したら中身を確認します。icmpのタイプがecho_replyだった場合はターゲットに到達したと判断してループを終了します。time_exceededだった場合は再送信ループを抜けてttlをインクリメントして送信処理を続行します。以上がこのクラスがやってくれる処理の大まかな流れです。1breakendendendendこのクラスは以下のように使います。RouteScanner.new()scanner.scan(target_ip)パケットを受信したルーターによっては時間超過を知らせるパケットを送ってくれないこともあるようです。以前Rustとc言語でも作りましたが、やはりスクリプト言語なのか結構軽めにかけた気がします。この調子でがむしゃらにいろいろ作っていきたいと思います。ポートスキャンの時もそうでしたがPythonでも作ることになりそうな予感がしてます。