無題の備忘録

IT技術について調べたことや学んだこと、試したこと記録するブログです。Erlang、ネットワーク、 セキュリティ、Linux関係のものが多いです。

パケット生成が簡単にできるhpingコマンド

hpingとは

hpingはコマンドライン指向のTCP/IPパケットアセンブラ/アナライザです。インタフェースはpingコマンドから影響を受けていますが、pingコマンドのようにICMP echoリクエストが送信できるだけではなく、hpingはTCP, UDP, ICMP と IPプロトコルをサポートしている点が特徴的です。 ポイントしては、パケットのフィールドを自分が設定できる点です。

使い道

主にセキュリティツールとして使われてきましたが、セキュリティに限らず多くの用途で使われます。

インストール

Debian/Ubuntuであれば、apt-getでインストールできます。

$ sudo apt-get install hping3

CentOSなら、EPELリポジトリを追加して、yumでインストールできます。

$ sudo yum install -y http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
$ sudo yum install hping3

使い方

# hping3 host [options]

基本オプション

  -h  --help      ヘルプを表示します。
  -v  --version   バージョンを表示します。
  -c  --count     パケット数を指定します。
  -i  --interval  各送信パケット間の時間を指定します。単位はマイクロ秒です。 (uXで指定します。Xはマイクロ秒です。例: -i u1000)
      --fast      -i u10000 のエイリアスです。(1秒間に10パケットを送信します。)
      --faster    -i u1000 のエイリアスです。(1秒間に100パケットを送信します。)
      --flood     可能な限り速くパケットを送信します。返信を表示しません。 
  -n  --numeric   数値のみを出力します。
  -q  --quiet     開始した時と終了した時のサマリーを除いて、結果を出力しません。
  -I  --interface インターフェース名を指定します。指定しない場合はデフォルトルーティングインタフェースを使います。デフォルトルートがない場合は、ループバックアドレス以外の最初のインタフェースを使います。
  -V  --verbose   詳細情報の出力を有効にします。
  -D  --debug     デバッグモードを有効にします。インタフェースの検知、データリンク層のアクセス、インタフェースの設定、オプションのパース、フラグメンテーション、HCMPプロトコルなどの追加情報を取得できます。
  -z  --bind      Ctrl+zを1度(2度)押すことで、送信されるパケットのTTLを1増やす(減す)ことができます。
  -Z  --unbind    Ctrl+zでhping3を停止させることができます。
      --beep      beep for every matching packet received

プロトコル選択オプション

  default mode     TCPモード。ターゲットホストのport 0 へTCPフラグを設定せずwindsize 64のtcpヘッダを送信します。これは"hide ping"としては良い方法です。ターゲットがICMPを破棄するファイアウォールの後ろにある時に役に立ちます。
  -0  --rawip      RAW IP モード。--signatureおよび/もしくは --fileを付けたデータとIPヘッダを送信します。IPプロトコルフィールドを設定できる--ipprotoも参照してください。
  -1  --icmp       ICMP モード。デフォルトではICMPエコー応答を送信します。--icmptype、--icmpcodeオプションを使うことで別のICMP type/codeを設定できます。
  -2  --udp        UDP モード。デフォルトではターゲットホストのport 0へUDPを送信します。UDPヘッダを調整可能なオプションは--baseport、--destport、--keepがあります。
  -8  --scan       SCAN モード。スキャンするポートグループの引数を指定します。ポートはコンマで複数指定でき、ハイフン(-)で範囲を指定できます。allは0-65535のエイリアスで、knownで/etc/servicesのリストにあるポートを指定できます。-Sオプションを設定すれば、SYNスキャンを実行できます。また、TCPのウィンドウサイズや、TTLを変更でき、IPフラグメンテーションを制御できます。
                   例: hping3 --scan 1-30,70-90 -S www.target.host
  -9  --listen     listenモード。このオプションを使うと、パケット中の--listenの後に記述した文字列があると、その文字列以降部分を表示します。
                   例: hping3 --listen TESTの場合、パケットに"234-09sdflkjs45-TESThello_world"が含まれていた場合、"hello_world"を表示します。

IP関連のオプション

  -a  --spoof      送信元のIPアドレスを偽装することができます。このオプションでターゲットホストは実際の送信元IPアドレスを知ることができなくなります。そのため、返信を見ることはできません。
  --rand-dest      random destionation addressモード.ターゲットホストとして記載したアドレスへランダムにパケットを送信します。"10.0.0.x"のように指定します。xは0-255の範囲でランダムに選択されます。このモードを指定した場合、どのインタフェースからパケットが送信されるか検知できません。送信したいインタフェースを指定する場合は、--interfaceオプションを使う必要があります。
  --rand-source    random source addressモード。送信元IPアドレスをランダムに設定します。ファイアウォールのステートテーブルや他のTCP/IPスタックおよびファイアウォールソフトウェア内の各IPアドレスに基づく動的テーブルに負荷をかけることに使えます。
  -t  --ttl        このオプションでTTLを設定できます。デフォルトは 64です。--tracerouteもしくは--bindオプションをと一緒にこのオプションを使います。 "# hping3 some.host.com -t 1 --traceroute"のように使用します。
  -N  --id         idフィールドを設定します。デフォルトはランダムです。
  -W  --winid      Windows2000以前のWindowsシステムは別のバイト順序を持っています。これらのWindowsからの返信のidが適切に表示されます。
  -r  --rel        Display id increments instead of id. See the HPING3-HOWTO for more information. Increments aren't computed as id[N]-id[N-1] but using packet loss compensation. See relid.c for more information.
  -f  --frag       多くのフラグメントにパケットを分割します。これはIPスタックのフラグメンテーションの性能のテストやパケットフィルタに小さなフラグメントを通してしまう弱さがないかをテストするのに有用です。デフォルトの仮想MTUは16バイトです。--mtuオプションを参照してください。
  -x  --morefrag   IPパケットを分割しても良いフラグに設定します。もし、再構築中にICMP time-exceededメッセージをターゲットホストに送信シたい場合は、このオプションを使います。
  -y  --dontfrag   IPパケットを分割してないフラグに設定します。経路MTU探索に使います。パスしなかったルータでICMP到達不能メッセージが送信され、MTUの値がわかります。
  -g  --fragoff    フラグメントオフセットの値いを設定します。
  -m  --mtu        フラグメンテーションが有効な時16以外の仮想MTUの値を設定します。もし、パケットサイズが仮想MTUの値よりも大きい場合、フラグメンテーションが自動的にONになります。
  -o  --tos        Type Of Serviceを設定します。デフォルトは0x00です。16進数でせていします。--tos helpで詳細な情報を得られます。
  -G  --rroute     レコードルート(record route)を設定します。送信される各パケットにレコードルートオプションが含まれ、返信されたパケットの経路バッファを表示します。多くのホストでこのオプションは無視か破棄されます。IPオプションのため、TCPとUDPモードでも利用できます。
  --lsrr           ルーズ・ソース・ルーティング(loose source routing)とレコードルート(record route)を設定します。送信ホストが提供する情報に従ってIPパケットをルーティングするのに使われます。他の中間ルーターを経由するルートを、ルータが選択して使用することができます。
  --ssrr           ストリクト・ソース・ルーティング(strict source routing)とレコードルート(record route)を設定します。送信ホストが提供する情報に従ってIPパケットをルーティングするのに使われます。直接接続されたネットワークを使って指定された次のアドレスまで、直接パケットを送ります。直接送信できない場合はパケットは破棄されます。
  -H  --ipproto    IPプロトコルフィールドを設定します。RAW IPモードの場合のみ有効です。

ICMP関連のオプション

  -C  --icmptype   ICMPタイプを指定します。デフォルトではICMP echo requestです。
  -K  --icmpcode   ICMPコードを指定します。デフォルトでは0です。
      --force-icmp 全てのICMPタイプを送信します。全てのICMPタイプを送信します。
      --icmp-gw    ICMP redirectのゲートウェイアドレスを設定します。デフォルトは0.0.0.0です。
      --icmp-ts    --icmp --icmptype 13 のエイリアスです。ICMP timestamp requestです。
      --icmp-addr  --icmp --icmptype 17 のエイリアスです。 ICMP address mask requestです。
      --icmp-help  他のICMPオプションを表示します。
      --icmp-ipver  ICMPデータ内のIPヘッダのIPバージョンを指定します。デフォルトは4です。
      --icmp-iphlen  ICMPデータ内のIPヘッダのIPヘッダ長を指定します。デフォルトは5です。5は5ワードで32ビットです。
      --icmp-iplen  ICMPデータ内のIPヘッダのIPパケット長を指定します。デフォルトは実際の長さです。
      --icmp-ipid  ICMPデータ内のIPヘッダのIPのidを指定します。デフォルトはランダムです。
      --icmp-ipproto  ICMPデータ内のIPヘッダのプロトコルを指定します。でおフォルトはTCPです。
      --icmp-cksum  ICMPのチェックサムを指定します。デフォルトは有効なチェックサムです。

UDP/TCP関連のオプション

  -s  --baseport   送信元ポートを指定します。シーケンス番号を推測するために送信元ポート番号を使用します。シーケンス番号は送信元ポート番号から開始され、各パケットを送信する毎に増加させます。デフォルトはランダムです。もし、送信元ポートを各パケット送信する毎に増加させたくなければ、--keepオプションを使う必要があります。
  -p  --destport   [+][+]<port> 宛先ポートを指定します。デフォルトは0です。"+1024"のように+が1つの場合は、返信を受ける度に1つ増加します。"++1024"のように+が2つの場合は、各パケットを送信する毎に1つ増加します。Ctrl+zを使うことで対話的に宛先ポート番号を変更できます。
  -k  --keep       送信元ポート維持します。
  -w  --win        TCP window sizeを指定します。デフォルトは64です。
  -O  --tcpoff     TCP data offsetを偽装します。デフォルトはtcphdrlen / 4(4オクテット単位)です。
  -Q  --seqnum     ターゲットホストが生成したシーケンス番号集めるために使用します。TCPシーケンス番号が予測可能かどうかを分析するために有用です。
                   例: # hping3 win98 --seqnum -p 139 -S -i u1 -I eth0
                   HPING uaz (eth0 192.168.4.41): S set, 40 headers + 0 data bytes
                   2361294848 +2361294848
                   2411626496 +50331648
                   2545844224 +134217728
                   2713616384 +167772160
                   2881388544 +167772160
                   3049160704 +167772160
                   3216932864 +167772160
                   3384705024 +167772160

                   初めの列はシーケンス番号で、2つめの列は現在とラストのシーケンス番号の差を表示しています。
  -b  --badcksum   間違ったチェックサムを送信パケットに設定します。
                   多くのシステムではIPチェックサムを修正してパケットを送信するので、修正されたチェックサムを手に入れることができます。
  -M  --setseq     TCPシーケンス番号を設定します。
  -L  --setack     TCP確認応答番号を設定します。
  -F  --fin        FIN flagを設定します。
  -S  --syn        SYN flagを設定します。
  -R  --rst        RST flagを設定します。
  -P  --push       PUSH flagを設定します。
  -A  --ack        ACK flagを設定します。
  -U  --urg        URG flagを設定します。
  -X  --xmas       X unused (ECN-echo)flagを設定します。 (0x40)
  -Y  --ymas       Y unused (CWR)flag を設定します。(0x80)
  --tcpexitcode    Exit with last received packet tcp->th_flag as exit code. Useful for scripts that need, for example, to known if the port 999 of some host reply with SYN/ACK or with RST in response to SYN, i.e. the service is up or down.
  --tcp-mss        指定した値でTCPの最大セグメント長オプションを有効にします。
  --tcp-timestamp  TCPタイムスタンプオプションを有効にします。

共通オプション

  -d  --data       パケットボディのサイズを指定します。デフォルトは0です。
  -E  --file       パケットのデータを満たすために使うファイル名を指定します。
  -e  --sign       Fill first signature length bytes of data with signature. If the signature length is bigger than data size an error message will be displayed. If you don't specify the data size hping will use the signature size as data size. This option can be used safely with --file filename option, remainder data space will be filled using filename.
  -j  --dump       受信したパケットを16進数でダンプします。
  -J  --print      順したパケットを印字可能な文字でダンプします。
  -B  --safe       'safe'プロトコルを有効にします。このオプションを使うとファイルの転送でパケットを紛失した場合再送します。例えば/etc/passwdファイルホストAからホストBへ送信する場合は次のようにします。
                   host_a例: # hping3 host_b --udp -p 53 -d 100 --sign signature --safe --file /etc/passwd
                   host_b例: # hping3 host_a --listen signature --safe --icmp
  -u  --end        --fileオプションを使っている場合、EOFが届くと再送を防ぎます。
  -T  --traceroute traceroute モード。--bind and --ttl 1と同じです。
  --tr-stop        ICMP time exceeded でない最初のパケットを受信した場合は終了します。
  --tr-keep-ttl    Keep the TTL fixed in traceroute mode, so you can monitor just one hop in the route. For example, to monitor how the 5th hop changes or how its RTT changes you can try hping3 host --traceroute --ttl 5 --tr-keep-ttl.
  --tr-no-rtt      tracerouteモードでRTT情報を表示/計算しません。
ARS packet description (new, unstable)
  --apd-send       Send the packet described with APD (see docs/APD.txt)

Wiresharkによるhping3の動作チェック

hping3でパケットを送信するホストや受信するホストでWiresharkを起動して、IPアドレスでフィルタしてパケットをキャプチャすることで、動作チェックできます。

送信元ホスト(送信ホスト)が10.0.1.1のパケットを見たい場合

ip.src_host==="10.0.1.1"

送信先ホスト(受信ホスト)が10.0.1.2のパケットを見たい場合

ip.dst_host==="10.0.1.2"

サンプルコマンド

TCPパケットを指定したIPアドレスに向けて送信します。ただし、0番ポートで各フラグは設定されていません。

# hping3 10.0.1.2

SYNフラグを設定して、80番ポートにTCPパケットを送信します。

# hping3 -S -p 80 10.0.1.2

送信元IPアドレスを10.0.1.3に偽装したパケットを10.0.1.2へ送信します。

# hping3 10.0.1.2 --spoof 10.0.1.3

ACKフラグによるプローブスキャニングの実行します。 下の例では、ACKフラグを設定し、20番ポートから順番にポート番号を増加させ、RSTパケットを受信します。RSTパケットのTTL値やWIN値を見ることで、どのポートがオープンになっているか推測するデータを取得できます。

# hping3 -A -p ++20 10.0.1.2

送信元ポートとしてTCP53番(DNS用ポート)を使用し、10.0.1.1のTCP139番ポートに対して、3つのTCP SYNパケットを送信します。

#  hping3 -c 3 -s 53 -p 139 -S 10.0.1.1