chouett0's note

掃きだめ的なsomething

Windows上でのDNS詐称プログラムに関する考察とそのメモ

はじめに

 この記事にまとめる内容は8割想像の話であり、まだ実装途中のモノなので実際の環境で可能な技術であると保証するものではありません。また、私自身まだ知識も浅いので至らぬ点も多く存在します。

目次

  • 概要
  • DNSについて
  • 実装方法
  • 今後について

概要

まず初めに、DNSを詐称するためのプロセスについてです。
私は以前の記事ARPポイズニングと組み合わせた攻撃方法について記述しましたが、この手法ではそもそも改ざんしたIPアドレスへ対象がアクセスする事すらできませんでした。 では、ゲートウェイを書き換えるのではなくプロミスキャスモードでスニフィングするツールを作成してDNSリクエストを観測することで前回の問題点を解決できるのではと考えました。
その方法が、「DLLインジェクションを用いた任意のプロセスのスニファー化」です。
この方法を用いることで、ゲートウェイを偽装せずにパケットを盗聴でき、かつ、既存のプロセスをスニフィング機能を追加するので比較的バレいにくいという利点もあります。

DNSについて

DNSパケットには、512byteを超えるリクエストを行うと本来UDPで行われる通信がTCPで行われるという仕様がありますが、
今回はUDPのみでの通信に関する内容のみを取り扱います。 そもそも、DNSリクエストは以下のような構成になっています。 f:id:chouett0:20170731230458j:plain

  • ID -> 名前解決の通信を行う際に設定するID

  • **QR, Opecode, AA, TC, RD, RA, Z, AD, CD, RCODE -> 各種フラグを設定する。 その中でも、Zフラグは常に0を指定する。

  • QDCOUNT, ANCOUNT, NSCOUNT, ARCOUNT -> 以下で説明する各sectionの数(一塊のパケットの中に含まれる各section数)を設定

  • Quesstions -> DNSリクエストを行う際に設定するsection。通常は一回につき一つのAnswer Sectionが含まれている。

  • Answer Section -> DNSレスポンスを送信する際に設定するsection。ここに名前解決を行った際の結果が入る。今回のメイン。

  • Authority Section -> 権威サーバなどの情報が格納されるsection。パケット内に複数存在することがある。

  • Additional Section -> 追加情報などを格納するsection。

以上がDNSパケットの大まかな説明とフォーマットとなります。その中で特にAnswer Sectionは重要な部分であり、 以下が詳しいフォーマットとなります。 f:id:chouett0:20170731232554g:plain
内容は図の通りですが、今回最も重要な部分がRDATAの部分であり、ここに名前解決を行った結果、つまりIPアドレスが入ります。

実装方法

具体的には、上記解説したRDATA部分に任意のIPアドレスを指定したパケットを対象PCへ連続で投げ続けるというイメージであり、前回のプログラムと根本では相違ありませんが、今回は一からフォーマットを定義した構造体に値を設定していくようにしました。したがって、今回の実装ではC言語にて行う予定です。 通信を行う部分にはWinsock2を利用し、プロミスキャスモードにてネットワーク内のパケットを監視します。
そして、DNSリクエストを検知した場合は以下のように定義した構造体に、DNSリクエストのQuesstion Sectionの内容をコピーして対象PCへ送信するといった内容です。 以下はDNSヘッダーのフォーマットに従って定義した構造体です。

typedef struct QuerySection {
    LPSTR qsname;
    short qstype;
    short qsclass;

} QuerySection;

typedef struct AnswerSection {
    LPSTR ansname;
    short anstype;
    short ansclass;
    int ansttl;
    short anslen;
    LPSTR ansrdata;

} AnswerSection;

typedef struct AuthoritySection {
    LPSTR asname;
    short astype;
    short asclass;
    int asttl;
    short aslen;
    LPSTR asrdata;

} AuthoritySection;

typedef struct AddSection {
    LPSTR adsname;
    short adstype;
    short adsclass;
    int adsttl;
    short adslen;
    LPSTR adsrdata;

} AddSection;

typedef struct FakeDNSHeader {
    int id;
    char qr;
    short opcode;
    char aa;
    char tc;
    char rd;
    char ra;
    struct z {
        unsigned int flags : 1;

    }z;
    char rcode;
    short qdcount;
    short ancount;
    short nscount;
    short arcount;
    struct QuerySection;
    struct AnswerSection;
    struct AuthoritySection;
    struct AddSection;

} FakeDNSHeader;

肝心のスニフィングとDNS詐称を行うパケット送信プログラムはDLLとして開発し、何らかの方法(メールへ添付したりwordファイルに偽装して実行させるなど)を用いて対象へ感染させ、任意のプロセスへインジェクションすることで行います。
よって、DLLをインジェクトするプログラムも作成する必要がありますがそちらの説明は今回は省かせていただきます。
これらの事柄を踏まえて実装することで対象ネットワークの構成や疎通の妨害を行うことなく、対象のAレコードを改ざんできると思われます。以下はわかりづらいですが全体構造です。 f:id:chouett0:20170731235336p:plain

今後について

まだ実装途中であり、まだDNSヘッダについても理解しきれていない部分も多くあるので近いうちに完成を目指したいと考えています。また、このテーマに関する研究もそろそろ一年になってしまうのでなるべく速く形にし、更に上の研究も行いたいと考えています。(Crackmeの記事も書かないといけないので)
またこの内容も更新せずに終わりそうな気もしますがなるべく終わらせられるようにしたいです…ほんと