httptunnel の代替としての StreamRelay.NET.exe

httptunnel というツールがある。
その代替となるような機能をStreamRelay.NET.exeは有している

---
### httptunnel のクライアントの代替

`htc.exe --no-daemon --forward-port 95 192.0.2.1:96`
⇔
`StreamRelay.NET.exe -LocalPort 95 -RemoteHost 192.0.2.1 -RemotePort 96 -RemoteProxy httptunnel:///?mode=GNU^&HttpHeaderFileName=req.txt^&SeparateTCP`

tcp/95 で待機して、192.0.2.1:96 の httptunnel サーバへつなげる。
その際に、HTTPリクエストのヘッダとして、「req.txt」というファイルをテンプレートとして用いる。
という意味。
テンプレートのサンプルは「Sample\http tunnel sample」にあるので、参照して欲しい。

テンプレートのポイントは「%method%」というマジックワードで、リクエスト方向には「POST」、レスポンス方向には「GET」に置き換わる

この場合、セッションIDは固定値(テンプレートファイルに記述された値で固定)となる。

### httptunnel のクライアントの代替(動的セッションID)

`htc.exe --no-daemon --forward-port 95 192.0.2.1:96`
⇔
`StreamRelay.NET.exe -VerboseMode -LocalPort 95 -RemoteHost 192.0.2.1 -RemotePort 96 -RemoteProxy httptunnel:///?mode=GNU^&HttpHeaderFileName=req1.txt^&SeparateTCP^&SessionID=4-20000%2cCryptoRandom`

テンプレート中の「%sessid%」が「SessionID」で指定した乱数により(この場合は、CryptoRandomアルゴリズムで 4～20000の間で変動)、都度変更される

---
### httptunnel のサーバの代替

`hts.exe --no-daemon --forward-port 192.0.2.2:97 96`
⇔
`StreamRelay.NET.exe -VerboseMode -LocalPort 96 -RemoteHost 192.0.2.2 -RemotePort 97 -LocalProxy httptunnel:///?mode=GNU^&HttpHeaderFileName=res.txt^&SeparateTCP^&SessionID=crap`

tcp/96 で httptunnel サーバとして待機、192.0.2.2:97 へ転送する。
その際に、HTTPレスポンスのヘッダとして、「res.txt」というファイルをテンプレートとして用いる。
という意味。
また、セッションIDの変数名として「crap」ですよ。

---
### httptunnel より偽装度を高める(独自プロトコル)

httptunnel では、リクエスト方向には、POST メソッドを使った HTTPリクエストのボディ。レスポンス方向は、GETメソッドの応答としてのHTTPレスポンスのボディ。
と2本のTCP接続を用いているが、リクエスト方向のボディは独自フォーマットとなっていて、あまり偽装度は高くない。

という事で、リクエスト方向に、WebPostと同じような加工を行わせて、より隠蔽度を高めるコマンドが以下となる。

WebPostのような加工として、データを、「名前1=値1&名前2=値2...」の値の部分に埋め込んでいく(名前は適当なランダムな文字)

クライアント側
`StreamRelay.NET.exe -LocalPort 95 -RemotePort 96 -RemoteHost 192.0.2.1 -RemoteProxy httptunnel:///?SeparateTCP^&mode=simple^&HttpHeaderFileName=req1.txt^&SessionID=4-10000%2cCryptoRandom -RemoteProxy netstream:///?WebFormEncode -RemoteProxy netstream:///?UrlEncode`

サーバ側
`StreamRelay.NET.exe -LocalPort 96 -RemoteHost 192.0.2.2 -RemotePort 97 -Verbose -LocalProxy httptunnel:///?SeparateTCP^&mode=Simple^&HttpHeaderFileName=res.txt^&SessionID=crap -LocalProxy netstream:///?WebFormDecode -LocalProxy netstream:///?UrlDecode`

このクライアントとサーバ間のリクエスト方向は、
データを
1. URLエンコード
2. WebFormフォーマットに偽装する

という事で、より偽装度を高められる

「WebFormEncode」には

- 名前に使う文字の一覧
- 名前の文字数
- 一つの値の文字数

などをランダムに指定する事ができるよ。「[最小値]-[最大値],[アルゴリズム名]」みたいな感じでね。

---
### httptunnel より偽装度を高める(独自プロトコル2)

レスポンス方向も、httpchunk 符号化すれば、より偽装度が高くなる

オプションは、netstream スキームの「HttpChunkdecode/HttpChunkencode」です。

---
### WebForm 符号化とか HttpChunk 符号化とか

[符号化コマンドとしての StreamRelay.NET.exe](http://qiita.com/tomoki0sanaki/items/84e320c078742f8ffd8a) を参照

---
### 具体例

クライアント側
`StreamRelay.NET.exe -LocalPort 0 -RemotePort 96 -RemoteHost 192.0.2.2 -RemoteProxy "httptunnel:///?SeparateTCP&mode=simple&HttpHeaderFileName=Sample\http tunnel sample\req1.txt&SessionID=4-10000%2cCryptoRandom" -RemoteProxy netstream:///?WebFormEncode=name%3d4-6%2cCryptoRandom%26Value%3d5-6%2cCryptoRandom%26CharRandom%3dCryptoRandom%26CharList%3dabcdefghijklmnopqrstuvwxyz -RemoteProxy netstream:///?UrlEncode -verbose -remoteproxy netstream:///?HttpChunkdecode`

オプションが長い場合は、設定ファイルから読み込む「-ConfigFile」オプションが便利だ。
(cmd.exeのエスケープ処理とか気にしなくてよいのもメリットかと思う)


サーバ側
`StreamRelay.NET.exe -LocalPort 96 -RemotePort 0 -Verbose -LocalProxy "httptunnel:///?SeparateTCP&mode=Simple&HttpHeaderFileName=Sample\http tunnel sample\res.txt&SessionID=crap" -LocalProxy netstream:///?WebFormDecode -LocalProxy netstream:///?UrlDecode -localproxy netstream:///?HttpChunkencode=4-10%2cCryptoRandom`

ともにコンソール入出力を相手にして、

- サーバは 192.0.2.2:96 で待機
- クライアントとサーバ間で HttpTunnel の 分割TCP で接続
- リクエストメッセージのヘッダとなるのは、Sample\http tunnel sample\req1.txt
- レスポンスメッセージのヘッダとなるのは、Sample\http tunnel sample\res.txt
- セッションIDは「crap」
- セッションIDは「4-10000」アルゴリズムは「CryptoRandom」
- リクエストメッセージにはURLエンコードを実施後に、WebFormエンコードを実施
- WebFormエンコードの名前に使う文字種は「abcdefghijklmnopqrstuvwxyz」
- WebFormエンコードの名前の長さは「4-6」アルゴリズムは「CryptoRandom」
- WebFormエンコードの値の長さは「5-6」アルゴリズムは「CryptoRandom」
- WebFormエンコードの名前の文字種のランダムアルゴリズムは「CryptoRandom」
- レスポンスメッセージはHttpChunkエンコードを実施
- HttpChunkの長さは「4-10」アルゴリズムは「CryptoRandom」
という内容で通信をしている。

クライアント側の実行画面
![q-httptunnel002.png](https://qiita-image-store.s3.amazonaws.com/0/182822/d2610651-2bd9-0b16-07cf-38891d4aab84.png)

サーバ側の実行画面
![q-httptunnel001.png](https://qiita-image-store.s3.amazonaws.com/0/182822/aa9c59d2-70ab-da3f-99f6-fb75e32a34ef.png)

Wiresharkでパケットキャプチャしてみた結果
![q-httptunnel003.png](https://qiita-image-store.s3.amazonaws.com/0/182822/a65c0906-74f9-bb6d-f4c0-637a1102e9f3.png)

HttpTunnel は上りと下りで2本のTCPストリームを使うので、

上り側のTCPストリーム
![q-httptunnel004.png](https://qiita-image-store.s3.amazonaws.com/0/182822/db90030e-54f7-db2f-7ec7-c2b324805ab6.png)


下り側のTCPストリーム
![q-httptunnel005.png](https://qiita-image-store.s3.amazonaws.com/0/182822/c6418500-7de4-52a0-2f39-97f3852f67e4.png)

どうだろう。GnuHttpTunnelより隠蔽度は高くなっていると思うけど。

(res.txtが、Content-Lengthとか付いているので、よりHttpChunk時のヘッダっぽいHTTPレスポンス・ヘッダのテンプレートを使うとさらによいでしょう)
(近いうちに res1.txtとかで同梱しておく予定)


さらに、暗号系のフィルタも加えれば、そもそも解析できなくする事は可能。

「[zebedee のような vpn の代替としての StreamRelay.NET.exe](http://qiita.com/tomoki0sanaki/items/f399b1266ddaabfa65e9)」を参照


---
### 目次へ戻る

[目次というか最初の一歩](http://qiita.com/tomoki0sanaki/items/85f20cbe18378e33cd6f)