これは、C# & .Net Framework 2.0 で作成しました
これは、C# & .Net Framework 4.0 で作成しました


はじめに
ver1.0より拡張され、「ある Stream から、別の Stream へ転送する」ツールとなりました。

名前も、「UrlRewriteProxy」→「StreamRelay.net」に変更しました(ver2.0)

Stream として、TCP/UDP/名前付きパイプ/コンソール/子プロセスの標準入出力/シリアルポート(COMポート) などです。

Stream のフィルタ機能として、圧縮/暗号化/ハッシュ計算/チェックサム計算/プロキシなどの機能も実装しました。

MD4 は MD4 Hash Algorithm in C# を拝借しました

CRC16/CRC32 は HashAlgorithmの実装(CRC32,CRC16) を拝借しました。

LZ4 圧縮アルゴリズムのために LZ4.dll(LZ4 for .NET)を使わせていただきました。

LZMZA 圧縮アルゴリズムのために SevenZipSharp.dll(SevenZipSharp)を使わせていただきました。

さまざまなハッシュアルゴリズムのために Classless.Hasher.dll(classless-hasher)を使わせていただきました。

BZip2 圧縮アルゴリズム、StrangeCRC チェックアルゴリズムのために、ICSharpCode.SharpZipLib.dll(SharpZipLib)を使わせていただきました。

Snappy 圧縮アルゴリズムのために SnappyPI.dll(SnappyDL.x86.dll/SnappyDL.x64.dll)(Snappy for .NET)を使わせていただきました。

XZ 圧縮アルゴリズムのために XZ.NET.dll(liblzma.dll/liblzma64.dll)(XZ.NET)を使わせていただきました。

Zstandard 圧縮アルゴリズムのために ZstdNet.dll(zstdlib_x86.dll/zstdlib_x64.dll)(ZstdNet)を使わせていただきました。

Brotli 圧縮アルゴリズムのために Brotli.NET.dll(brolib32.dll/brolib64.dll)(Brotli.NET)を使わせていただきました。

Mersenne Twister 乱数アルゴリズムは http://meisui.psk.jp/software.html の mt19937ar.cs を拝借しました。

C#乱数ライブラリ を使っています。

さまざまな暗号アルゴリズムのために BouncyCastle.Crypto.dll(The Legion of the Bouncy Castle)を使わせていただきました。

Intel CPU の Ivy Bridge 命令を使う乱数のために RdRandLib.dll(rdrand_msvc_2010) を使わせていただきました。


SlimDX を用いて録音するプラグインを同梱していますが、利用にあたっては SlimDX End User Runtime が必要です。

x86 版については、DirectSound(Managed DirectX : MDX) で録音することもできるようにしてみました。


ver2.2.0.4 から ShinoEncode/Decode を実装した。
若干、互換性がないが・・・
基本的に、0〜15 に +2 して、2〜17 文字の単語に置換する方法で、1Byteを2つの単語に置換する符号化方法だが、本家では記号もデリミタとしているが、StreamRelay.NET では記号は無視。
つまり、「semi-long」は本家では、4文字と4文字の二つの単語。StreamRelay.NETでは 8文字の一つの単語。
StreamRelay.NET では 2〜17文字以外の単語は無視(ノイズとして処理される)

エンコードには、辞書ファイルを外部ファイルとして指定するオプション(Exe内部には必要最低限の辞書のみ)、そのまま/先頭のみ大文字/全部大文字にする乱数オブジェクトの指定(30/40/50として指定すると、3:4:5で変化する)。
ノイズとなる単語の乱数オブジェクトの指定が可能(NoiseRandomで指定する数値は、変化させない比率を指定)。
互換性を持たせる為には、ShinoEncode指定時の辞書に途中に記号のある単語のない物を使えばよいでしょう。
ShinoDecode時には、「Original」というオプションを指定することで、記号を半角スペースと同じデリミタとして認識するようになります。

ver2.2.0.4 から ShinoEncode/Decode にインスパイヤされて、0〜15 を漢字の画数(+4して、4〜19の画数)にする StrokeEncode を実装。基本的に EXE 本体に辞書を内蔵しているが、オプションで、辞書を外部ファイル指定する事も可能。


Base65536 を実装した。
https://github.com/ferno/base65536gen/blob/master/index.js によると、第一バイトの値から、UNICODE コードポイントの基準点を取得して、その基準点から第二バイトの値を使って「+0〜+255」する。というような符号化を実施しています。
データ終端の最後の場合は、パディングとして使うUNICODEポイントの基準点から「+0〜+255」するようにしています。

Link



ver2.2.0.5 に NLuaInterface 1.3.2 を呼び出せるようにした。


ver2.7.0.0 で Boo0.9.7 をスクリプティング呼び出しできるようにした。


ver2.2.0.5 に分離ストレージと標準入出力を取り持つツール(IsolatedStorageCUI.exe)を同梱したので、ハードウェアストリームとして分離ストレージも使えるようになったと思う。

参考



ver2.2.0.5 から 「4Byte⇔5文字」を単位とする Bse85/Ascii85 を実装。

ver2.2.0.5 から 「9Byte⇔11文字」を単位とする Base94 を実装。


ver2.2.0.6 から 完全にバッファリングが必要とするBase62/Base58/Base91 を実装してみた。
オプション「bBase62[En|De]code」など、「bBase」を接頭とする符号化は、完全バッファリングするので、ストリームっぽくはない。


ver2.2.0.7 から uuencode/Xeencoding/6PACK ­ a "real time" PC to TNC protocol に書かれている「3Byte⇔4Byte(下位6bitのみ)」の符号化に対応。

「4Byte(32Bit)⇔7文字」または「8Byte(64Bit)⇔13文字」のBase36の実装。

オプション説明
Base36[En|De]code3232Bit を単位
Base36[En|De]code6464Bit を単位
Base36[En|De]code[32|64]Custom=「[36|64]文字のシード」「文字コード」


完全にバッファリングが必要とする Base36/Base58/Base62/Base65/Base85(圧縮のないタイプのみ)/Base91/Base94/Base95 の実装
つまり、バイト配列を BigInteger クラスにプッコンで、NN進数変換を実施する
オプション説明
bBase36[En|De]code
bGeohash36[En|De]code
36進数
bBase62[En|De]code62進数
bBase65[En|De]code65進数
bBase58[En|De]code[BitCoin|Flickr|Ripple]58進数
bBase85[En|De]code[RFC1924|Z85|ZMODEM]85進数
bBase91[En|De]code91進数
bBase94[En|De]code94進数(0x21〜0x7e)
bBase95[En|De]code95進数(0x20〜0x7e)
bBaseNN[En|De]code=「[文字コード,]」「NN個の文字」



ver2.2.0.8 で、「4Byte⇔5文字」を単位とするAdobe バージョンの Base85(Ascii85)を実装。

Ascii85 Wikipedia
オプション説明
Base85[En|De]codeRFC1924上記 Wikipedia の RFC1924 の項に書かれているシード
Base85[En|De]codeZ85上記 Wikipedia の ZeroMQ Version (Z85) の項に書かれているシード
Base85[En|De]codeZMODEM上記 Wikipedia の btoa version の項に書かれているシード
Base85[En|De]codeBTOA上記 Wikipedia の btoa version の項に書かれているシード
「z」による圧縮あり
Base85[En|De]codeBTOA42上記 Wikipedia の btoa version の項に書かれているシード
「z」「y」による圧縮あり
Base85[En|De]codeAdobe上記 Wikipedia の btoa version の項に書かれているシード
「z」による圧縮あり。最終ブロックのパディングが特殊
Base85[En|De]codeCustom=「85文字のシード」「文字コード」[,「85文字未満の圧縮文字(圧縮しない場合はスペースにする)」]


参考 : Ascii85 Wikipedia

ver2.7.1.1 からも Base122 を実装してみた。


ver2.16.0.7 から
ケンシロウ進数」「ケンシロウ進数3」「ドクロちゃん進数」「Base2」の二進数変換に対応した。
3バイトで1ブロックとする「Base8」を実装してみた。




StreamRelay003.png
基本的には二つの "ストリーム" のデータ交換を行う
つまり、「ネットワーク|コンソール|外部コマンド|シリアルポート|名前付きパイプ」⇔「ネットワーク|コンソール|外部コマンド|シリアルポート|名前付きパイプ」で通信する


StreamRelay004.png
基本的には二つのストリームは対等だけど、
ネットワークストリームに関して、「サーバ」と「クライアント」と対等ではなくなるので、
片方(サーバとして動作する側)を「Local」。
もう片方(クライアントとして動作する側)を「Remote」と呼称している
オプション指定は、
片方のストーム(ネットワークでサーバとなる方)を「LocalXXXX」、もう片方(ネットワークでクライアントとなる方)を「RemoteXXXX」
「クライアント」→「サーバ」への流れに対して「RequestXXXX」
「サーバ」→「クライアント」への流れに対して「ResponseXXXX」
(とりあえず命名されているStream の)"Local" の入力側ということで「-LocalInoutXXXX」というオプション指定が可能なものもある。
(とりあえず命名されているStream の)"Local" の出力側ということで「-LocalOuoutXXXX」というオプション指定が可能なものもある。
(とりあえず命名されているStream の)"Remote" の入力側ということで「-RemoteInoutXXXX」というオプション指定が可能なものもある。
(とりあえず命名されているStream の)"Remote" の出力側ということで「-RemoteOuoutXXXX」というオプション指定が可能なものもある。



-LocalPort で、自分自身のポート番号を指定します。
-RemotePort で、転送先のポート番号を指定します。

-LocalPort/-RemotePort 共に 「0」に指定すると、標準入出力へリダイレクトします。
例えば「-LocalPort=0」で netcat のクライアント・モードのようになります。
「-RemotePort=0」とすると netcat のサーバ・モードのようになります。

また、「-LocalInputFile/-LocalOutputFile」や「-RemoteInputFile/-RemoteOutputFile」を指定することで、
標準入出力(-[Local|Remote]Port=0)から、ファイルへリダイレクトできます。


StreamRelay005.png
フィルタ機能として、Base64エンコード/デコードや、文字コード変換や、SOCKS Proxy 機能、ハッシュ計算、暗号化処理などを用意


StreamRelay007.png


StreamRelay009.png



基本的には、TCP サーバとして待機し、通信メッセージの先頭行に「/」があると、それを特定の文字列に置き換えつつ、指定されたホスト:ポートへリダイレクトするプログラムです。

TCP サーバ/クライアント機能以外に、UDPサーバ/クライアント、外部コマンドの標準入出力、ファイルの入出力、コンソールの入出力、シリアルポート(COMポート)の入出力、名前付きパイプなどに対応しました。

例えば、リバース・プロキシ環境などでは、URL に「/WebApp/../cgi-bin/test-cgi」などの URL で非公開のWeb サーバに繋げる場合があります(※)。
Web セキュリティ検査時に、それらのある意味で特殊な URL にも各種検査ツール(nikto 等)が対応できるようにする Web Proxy かも知れません。

(※)
リバースプロキシは、「/WebApp/」で始まる URL を内部の Web サーバ(ホストA)の「/WebApp/」にリダイレクトする
リバースプロキシは、「/WebApp/」以外で始まる URL は内部の Web サーバ(ホストB)へ転送している。
こういう状況で、「/WebApp/../cgi-bin/test-cgi」をリバースプロキシに渡すと、Web サーバ(ホストA)に対して「/WebApp/../cgi-bin/test-cgi」が URL として渡り、結果的に想定外の「/cgi-bin/test-cgi」にアクセスできる場合がある


ただし、実際に行っているのは、受信処理した際のバッファの先頭行(先頭から Lf までの領域)に「/」があるかどうか調べているだけです。
受信処理(および受信バッファ)の状況によっては、変なところで、置き換えられるかも知れません。
(きちんと、Kepp-Alive 処理を実装しているわけではないので、確実性を期待したい場合は、Keep-Alive を無効{Connection: close ヘッダ}にした方がいいかもしれません)


ついでに、3way HandShake 後に数秒間待機するオプションもあります。
(FireWall の通信ログは 3way HandShake の時で、Web サーバの通信ログは HTTP リクエストを受信した時なので、フォレンジック解析者が少しでも悩んでしまうかもしれない)


ついでに、TCP のデータを分割して送る(フラグメント)オプションもあります。
単純なフラグメントなので "上書き" とか "送信順" などをいじってはいません
Socket の Send メソッドを細かく実行しているだけです。

ただし、Socket の Send メソッドを細かく実行していても、状況によっては、データを一つのパケットにまとめて送る場合があるので、そのためのインターバルの時間をオプションで設定する必要があります。
VB6 の WinSock.ocx には、SendComplete() イベントがありましたが、.NET Framework にはないようです...orz


DPAPI(DataProtectionAPI)(データ保護API)を楽しめるようにしてみました(ver2.1.0.12)。
ただし、DPAPI自体がストリームではないので、完全バッファリングするようにしています。
よって、通信などのリアルタイム性を必要とするような場合は、不向きかと思います。
既に全てのデータが存在しているファイルなどを入力源とすると、使い道があるかと思います。

無駄に MemoryProtection も追加した(ver2.1.0.13)。
MemoryProtection は 16 の倍数である必要があるようです(DPAPIを使用して暗号化する)。

DPAPI を使うCOM


STARTTLSに対応してみました。
プロキシに「starttls」スキームを新設しました。
StreamRelay017.png

例:
(ポイントは、クライアント側は「command」も「SuccessMessage」も監視対象{含まれていればいい}なのに対し、
サーバ側は「command」は監視対象だけど、「SuccessMessage」は相手に返すメッセージそのものであるという点です)
SMTP の STARTTLS
POP3 の STARTTLS
IMAP の STARTTLS



動作環境
Microsoft .NET Framework2.0
Microsoft .NET Framework4.0


インストール方法

まず、ランタイム(.NET Framework2.04.0)をセットアップします。

StreamRelay.net.lzh をダウンロードします。

ダウンロードしたファイルを解凍しします。
(LHAは、吉崎栄泰氏が、著作権を所有)

Classless.Hasher.dll, ICSharpCode.SharpZipLib.dll, LZ4.dll, Rei.Random.dll をパスの通っているフォルダにコピーしてください。
(または、最新版を本家の Web サイトよりダウンロード、インストールしてください)

SlimDX を用いて録音するプラグインを利用する場合は、SlimDX End User Runtime をインストールしてください。

sCommonNET.dll CRandom.dll(CRandom32.dll/CRandom64.dll) をパスの通っているフォルダにコピーしてください。
(StreamRelay.net.lzh に同梱しているCRandom.dllはCRandom64.dllをリネームしたものです。Win32環境の場合、CRandom32.dll を CRandom.dll にリネームしてください)(ver2.2.0.0)

AnyCPU 用のプラグインは「Plugins」に配置します
x86 用のプラグインは「Plugins\Win32」に配置します
x64 用のプラグインは「Plugins\Win64」に配置します

プラグインの代替ストリーム "ZoneID" を削除しておきます。

StreamRelay.NET.exe または StreamRelay.NET.x86.exe を、実行します。
あとは、画面の指示に従ってください。

当然ですが、悪用厳禁です。


使用方法
起動して使ってみれば分かると思います。

当然ですが、悪用厳禁です。

ver2.20.0.0
C:\>StreamRelay.NET.x86.exe
StreamRelay.NET.x86.exe ver 2.20.0.0
                            created by active@window.goukaku.com

StreamRelay.NET.x86.exe [options]

      Compiled ver.v4.0.30319
           Run ver.v4.0.30319(Win32)
-----------------------------------------
-[Local|Remote]Port "num"
if LocalPort=0 then StdIn/Out Redirect Network (like netcat)
if RemotePort=0 then Redirect to stdin/stdout (like netcat -l)
  -[Local|Remote][Input|Output]File <<Path>>
  -[Local|Remote][Input][Output]NamedPipe <<pipeName>>
  -[Local|Remote][Input][Output]AnonymousPipeServer
  -[Local|Remote][Input][Output]AnonymousPipeClient <<pipeId>>
  -[Local|Remote]SpeachVoiceRecognizerName <<CultureName>>
  -[Local|Remote]SpeachVoiceName <<EngineName>>
  -[Local|Remote]SpeachVoiceRate <<-10〜+10>>
  -[Local|Remote]SpeachVoiceVolume <<0〜+100>>
  -[Local|Remote]([Input|Output])TCPHost <<host>>
  -[Local|Remote]([Input|Output])TCPPort <<port>>
  -[Local|Remote]([Input|Output])TCPSourceHost <<host>>
  -[Local|Remote]([Input|Output])TCPSourcePort <<port>>
  -[Local|Remote][Input|Output]FileC <<path>>
  -[Local|Remote]SoundRecord [<<GUID>>]
  -[Local|Remote]SoundRecordBit <<8|16>>
  -[Local|Remote]SoundRecordHz <<8000|11025|22050|44100>>
  -[Local|Remote]SoundRecordBufSec <<sec>>
  -[Local|Remote]InputMic     : stdin Redirect from Mic (SoundRecord)
if [Local|Remote]Port=-1 then Redirect to program
  -[Local|Remote]Program "ProgramPath"
  -[Local|Remote]TempDirectory "DirectoryPath"
  -[Local|Remote]Arguments "args"
if [Local|Remote]Port=-2 then NamedPipe Stream
  -[Local|Remote]Name "Name"
if [Local|Remote]Port=-4 then SerialPort Stream
  -[Local|Remote]COMName "ComPortName"
  -[Local|Remote]BaudRate "BaudRate(9600)"
  -[Local|Remote]Parity "Parity(None)" [None|Odd|Even|Mark|Space]
  -[Local|Remote]DataBits "DataBits(8)"
  -[Local|Remote]StopBits "StopBits(1)" [0|1|1.5|2]
  -[Local|Remote]DtrDisable
  -[Local|Remote]RtsDisable
if 0 < LocalPort then TCP/IP port
  -[Local|Remote]Udp         : Use UDP (Default : TCP)
  -[Local|Remote]Udp2nd      : 2nd Connection Use UDP (Default : TCP)
  -[Local|Remote]UdpTimeout  : UdpConnection Timeout (UdpTimeout*ThreadInterval(ms))
  -[Local|Remote]SourceAddress "IPAddress" : Allowed/mySelf SourceAddress
  -[Local|Remote]SourcePort "num" : Allowed/mySelf SourcePort
-----------------------------------------
  -LocalHost "Hostname" : Bind Address
        default   : "0.0.0.0"
  -RemoteHost "Hostname" : Redirect Host or NamedPipe Server
  -[Local|Remote]SeparateConnection     : use 2nd Connection(1st:Read,2nd:Write)
  -[Local|Remote]Host2nd "2ndHostname"        : 2nd Redirect/Bind Host(Writing)
  -[Local|Remote]Port2nd "num"                : 2nd Redirect/Bind Port
  -[Local|Remote]SourceAddress2nd "IPAddress" : 2nd SourceAddress
  -[Local|Remote]SourcePort2nd "num"          : 2nd SourcePort
  -ZeroIO : Connected only (like netcat -z)
  -NonBroadcast  : noBroadcast mode
  -Broker        : Broker mode
-----------------------------------------
-[Input|Output][Request|Response]Charset "name"
-[Local|Remote]Charset "name"
                 : SetCharset [Input|Output][Request|Response]
-----------------------------------------
-[Local|Remote]Proxy  "uri"  : Set Proxy
    uri is "<<scheme>>://[<<username>>[:<<password>>]@]<<host>>:<<port>>"
    scheme :
     (-RemoteProxy only)
       socks4://[<<username>>[:<<password>>]@]<<host>>:<<port>>
       socks4a://[<<username>>@]<<host>>:<<port>>
       socks5://[<<username>>[:<<password>>]@]<<host>>:<<port>>
       connect://[<<username>>[:<<password>>]@]<<host>>:<<port>>
       WebSocket://[<<username>>[:<<password>>@<<Host>>:<<port>>]/<<URI>>?][<<name>>=value],...
             [hostname=<<hostname>>]& (default:localhost)
             [uri=<<URI>>]& (         (default:/)
             [method=<<value>>]&      (default:GET)
             [Sec-WebSocket-Key=<<base64encoded>>]&
             [Sec-WebSocket-Key-Auto=<<RandomOptions>>]&
             [Sec-WebSocket-Protocol=<<protocolName>>]&
             [Sec-WebSocket-Extensions=<<options>>]&
             [origin=<<value>>]&
        username default : "anonymous"
       http2://[<<username>>[:<<password>>@<<Host>>:<<port>>]/<<URI>>?][<<name>>=value],...
             [hostname=<<hostname>>]& (default:localhost)
             [uri=<<URI>>]& (         (default:/)
             [method=<<value>>]&      (default:GET)
             [http2mode=<<h2|h2c>>]&  (default:h2c)
        username default : "anonymous"
     (-LocalProxy only)
       http://[/?]                             (LocalServer is HTTP Proxy)
             [DropConnect=true]&
             [AutoSSL([Server|Client])=true]&
             [NeedClientCert=true]&
             [[Local|Remote]CertFile=<<FilePath>>]&
             [[Local|Remote]CertPassword=<<password>>]&
             [[Local|Remote]UseCertRevocationList=True]
             [[Local|Remote]Protocol=[NONE|SSL2|SSL3|TLS|DEFAULT|TLS11|TLS12]]
     (-LocalProxy/-RemoteProxy)
       ssl://
             [<<host>>]/?                      (only RemoteClient)
                  no Host is no SSL Server Check
             [CertFile=<<FilePath>>]&
             [CertPassword=<<password>>]&
             [NeedClientCert=true]&            (only LocalServer)
             [UseCertRevocationList=true]&
             [Protocol=[NONE|SSL2|SSL3|TLS|DEFAULT|TLS11|TLS12]]&
             [Server|Client]
       starttls://?command=<<StartCommand>>&SuccessMessage=<<Message>>
             [<<host>>]/?                      (only RemoteClient)
                  no Host is no SSL Server Check
             [CertFile=<<FilePath>>]&
             [CertPassword=<<password>>]&
             [NeedClientCert=true]&            (only LocalServer)
             [UseCertRevocationList=true]&
             [Protocol=[NONE|SSL2|SSL3|TLS|DEFAULT|TLS11|TLS12]]&
             [Server|Client]
             [StartTLSServer|StartTLSClient]
       netstream://[/?][/[option][&[option]...]
             ([Encrypt|Decrypt])CipherAlgorithm=<<name>>
             ([Encrypt|Decrypt])CipherAlgorithm=<<name>>/<<mode>>/<<padding>>
             ([Encrypt|Decrypt])CipherPassword(Hex)=<<Value|HexValue>>
             ([Encrypt|Decrypt])CipherPasswordHashAlgorithm=<<value>>
             ([Encrypt|Decrypt])CipherIV(Hex)=<<Value|HexValue>>
             ([Encrypt|Decrypt])CipherRounds=<<num>>    : (0<) Only RC5/64Bit
             CipherECDH
             [Input|Output]HashAlgorithm=<<name>>
             [Input|Output]KeyMacAlgorithm(Hex)=<<name>>;<<Key|HexKey>>
             [Input|Output]AllHashAlgorithm(Hex)(=<<Key>>)
             NTLM
             DPAPI                            : use DPAPI
             DPAPIEntropy[Hex]=<<(Hex)value>> : Set DPAPIEntropy
             DPAPIScope=<Option>  Set DPAPI Scope (default:CurrentUser)
                    DataProtection=[CurrentUser|LocalMachine]
                  MemoryProtection=[CrossProcess|SameLogon|SameProcess]
       httptunnel://[/?][option]
             [mode=[GNU|Simple]]&
             [SeparateTCP]&
             [SessionID=<<SessIDName(blank is SimpleMode)>>]&              <- ServerOnly
             [SessionID=("num")|("min"-"max")[,"RandomizeOption"]& <- ClientOnly
             [HttpHeaderFileName=<<file>>]&                                <- need
-ProxyList "uri list File"
-----------------------------------------
-DebugMode/-Debug    : DebugMode
-Debug(Mode)NoRead   : DebugMode but no Read Method in Stream
-VerboseMode/Verbose : VerboseMode
-VerboseSSLMode      : SSL VerboseMode
-nochecklocalhost    : don't check source host argument
-AllowHalfOpen       : Allowed Half Stream Open
-ListMyIPAddress     : Display MyIPAddresss
-ListNIC             : Display My Network Interface Card
-ListEnvironment     : Display Environment Variables
-ListCharset         : Display Character Set List
-ListCipher          : Display Cipher List
-ListHash            : Display Hash List
-ListHMAC            : Display HMAC List
-ListPasswordStirring: Display PasswordStirring List
-ListRandomize       : Display List Randomize Option
-ListFilter          : Display List Filter/Compression Algorithm Option
-ListPlugins         : Display List Loading Plugins
-ListRndNumber <"min"-"max","RandomizeOption">
                     : Display RandomNumber
-ListRndNumberCount <num> : Display RandomNumber Execute Count
-ListVoice           : Display Installed VoiceEngine List
-ListVoiceRecognizer : Display Installed VoiceRecognizerEngine List
-ListAllCulture      : Display List CultureInfo List(All)
-ListInstalledCulture: Display List CultureInfo List(InstalledOnly)
-ListNeutralCulture  : Display List CultureInfo List(Neutral)
-ListSpecificCulture : Display List CultureInfo List(Specific)
-ListMicrophone : Display List InputSoundDevice
-ListSpeaker    : Display List OutputSoundDevice
-Logging                       : Loging to stdout
-LoggingHex                    : Loging to stdout(Hex)
-LoggingFile "Filename"      : Loging to "File"
-LoggingCharSet "ChasetName" : Loging CharSet
-----------------------------------------
-r "ReplaceURL" : Add URL String
-----------------------------------------
-JScriptFile <<FilePath>> : Script File(JScript.NET)
-BooFile <<FilePath>> : Script File(Boo0.9.7)
-iPythonFile <<FilePath>> : Script File(IronPython2.7)
-iRubyFile <<FilePath>> : Script File(IronRuby1.1)
-LuaFile <<FilePath>> : Script File(NLua(Lua5.2))
-VBScriptFile <<FilePath>> : Script File(ActiveScript{VBScript/x86})
-----------------------------------------
-BufferSize "Num" : Recv buffer size (byte)(<32)
       (default is 2048
-ThreadInterval "Num" : "While" Loop IntervalTime in Thread (msec)
       (default is 500
-MaxConnection "Num" : (0 is Infinity)(default is 0)
-----------------------------------------
-ConnectedDelayTime ("num")|("min"-"max")[,"RandomizeOption"]
       delay time of between Connect/ProxyExecute and 1st data packet (sec)
-[Remote|Local]FragmentSize ("num")|("min"-"max")[,"RandomizeOption"]
       FragmentSize (byte)
-[Remote|Local]FragmentDelayTime ("num")|("min"-"max")[,"RandomizeOption"]
       interval time of fragment packet sending (sec)
-----------------------------------------
-ConfigFile "FileName" : Setting per line in file
-Registry "SubKeyName": Setting from Registry(HTLM\SOFTWARE\UrlRewriteProxy\<SubKey>)
-----------------------------------------
-install   : Install to NTService
-uninstall : Uninstall to NTService
-service   : only NTService mode
-----------------------------------------



使用例
シリアルポート(COM9)へ接続する
StreamRelay.NET.exe -LocalPort 0 -RemotePort -4 -RemoteCOMName COM9


名前付きパイプ(StreamRelay)へ接続する
StreamRelay.NET.exe -VerboseMode -LocalPort -2 -RemotePort 0 -LocalName StreamRelay
StreamRelay.NET.exe -VerboseMode -LocalPort 0 -RemotePort -2 -RemoteName StreamRelay -RemoteHost 192.0.2.1


netcat のクライアント・モード
nc.exe -nvv 192.0.2.1 90
StreamRelay.NET.exe -VerboseMode -LocalPort 0 -RemoteHost 192.0.2.1 -RemotePort 90


netcat のポート開閉確認
nc.exe -nvv -z 192.0.2.1 90
StreamRelay.NET.exe -VerboseMode -LocalPort 0 -RemoteHost 192.0.2.1 -RemotePort 90 -ZeroIO


netcat のサーバ・モード
nc.exe -nvv -L -p 90
StreamRelay.NET.exe -VerboseMode -LocalPort 90 -RemotePort 0


ncat のようなブローカーモード
StreamRelay.NET.exe -localport 90 -remoteport 0 -Broker


ncat のようなブローカーモードでログを記録
StreamRelay.NET.exe -localport 90 -remoteport 0 -Broker -LoggingFile log.txt


netcat のリモートシェル・サーバ・モード
nc.exe -nvv -L -p 90 -e cmd.exe
StreamRelay.NET.exe -VerboseMode -LocalPort 90 -RemoteProgram cmd.exe -RemotePort -1


netcat のリバース・リモートシェル・サーバ・モード
nc.exe -nvv 192.0.2.1 90 -e cmd.exe
StreamRelay.NET.exe -VerboseMode -LocalProgram cmd.exe -LocalPort -1 -RemoteHost 192.0.2.1 -RemotePort 90


OpenSSL のクライアント・モード
openssl.exe s_client -host 192.0.2.1 -port 443
StreamRelay.NET.exe -VerboseMode -LocalPort 0 -RemoteHost 192.0.2.1 -RemotePort 443 -RemoteProxy ssl:///?


クライアント認証のある SSL サーバへアクセス
StreamRelay.NET.exe -VerboseMode -LocalPort 0 -RemoteHost 192.0.2.1 -RemotePort 443 -RemoteProxy ssl://《サーバ証明書のCN名》/?CertFile=《クライアント証明書ファイル》^&CertPassword=《証明書ファイルのパスワード》
クライアント証明書を提示する前にサーバ証明書の検証が入るらしい


SSL サーバへ SSL2 のみでアクセス
StreamRelay.NET.exe -VerboseMode -LocalPort 0 -RemoteHost 192.0.2.1 -RemotePort 443 -RemoteProxy ssl:///?Protocol=SSL2


二つの TCP の方向と SSL の方向を逆にして接続する
StreamRelay.NET.exe -VerboseMode -LocalPort 91 -RemoteHost 192.0.2.1 -RemotePort 444 -RemoteProxy ssl:///?Server^&CertFile=《クライアント証明書ファイル》^&CertPassword=《証明書ファイルのパスワード》
StreamRelay.NET.exe -VerboseMode -LocalPort 444 -RemoteHost 192.0.2.2 -RemotePort 80 -LocalProxy ssl:///?Client^&
StreamRelay019.png


winrelay と同等
winrelay.exe -lp 90 -dip 192.0.2.1 -dp 80
StreamRelay.NET.exe -VerboseMode -LocalPort 90 -RemoteHost 192.0.2.1 -RemotePort 80


sTunnel と同等
StreamRelay.NET.exe -VerboseMode -LocalPort 80 -RemoteHost 192.0.2.1 -RemotePort 443 -RemoteProxy ssl://


ZeBeDee のような VPN
localhost -(平文)- localhost:90 -(暗号化)- 192.0.2.1:10990 -(平文)- サーバ(192.0.2.2)(80/tcp)
StreamRelay.NET.exe -VerboseMode -LocalPort 90 -RemoteHost 192.0.2.1 -RemotePort 10990 -RemoteProxy netstream:///?CipherAlgorithm=AES^&CipherECDH
StreamRelay.NET.exe -VerboseMode -LocalPort 10990 -RemoteHost 192.0.2.2 -RemotePort 80 -LocalProxy netstream:///?CipherAlgorithm=AES^&CipherECDH
Java 版を使用した方がいいと思う


ファイル転送
StreamRelay.NET.exe -VerboseMode -LocalPort 0 -LocalInputFile abc.txt -RemoteHost 192.0.2.1 -RemotePort 90
StreamRelay.NET.exe -VerboseMode -LocalPort 90 -RemotePort 0 -RemoteOutputFile abc.txt


netcat のクライアント・モードで、ファイルから入力
c:\> type abc.txt
HEAD / HTTP/1.0


c:\> nc.exe -nvv 192.0.2.1 90 < abc.txt
c:\> type abc.txt
HEAD / HTTP/1.0


c:\> StreamRelay.NET.exe -VerboseMode -LocalPort 0 -LocalInputFile abc.txt -AllowHalfOpen -RemoteHost 192.0.2.1 -RemotePort 90


netcat のサーバ・モードで、疑似 Web サーバ
c:\> type index.htm
HTTP/1.0 200 OK
Content-Type: text/html
Content-Length: 5

Hello
c:\> nc.exe -nvv -L -p 80 192.0.2.1 < index.htm
c:\> type index.htm
HTTP/1.0 200 OK
Content-Type: text/html
Content-Length: 5

Hello
c:\> StreamRelay.NET.exe -VerboseMode -LocalPort 80 -RemotePort 0 -RemoteInputFile index.htm -NonBroadCast


HTTP Proxy(Connect) Server(192.0.2.3:8080) を経由して、192.0.2.4:80 へ接続する(自分は 91/tcp で待機)
StreamRelay.NET.exe -VerboseMode -LocalPort 91 -RemoteHost 192.0.2.4 -RemotePort 80 -RemoteProxy connect://192.0.2.3:8080
StreamRelay016.png


SOCKSv4a(192.0.2.3:90) で接続して、さらに HTTP Proxy(Connect) Server(192.0.2.5:8080) を経由して、192.0.2.4:80 へ接続する(自分は 91/tcp で待機)
StreamRelay.NET.exe -VerboseMode -LocalPort 91 -RemoteHost 192.0.2.4 -RemotePort 80 -RemteProxy socks4a://192.0.2.3:90 -RemoteProxy connect://192.0.2.5:8080
StreamRelay018.png


StreamRelay012.png
StreamRelay014.png


GNU HTTP Tunnel のクライアントと同等(固定セッションID)(95/tcpで待機して、HTTPTunnelサーバの192.0.2.1:96/tcpへ転送する)
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=req.txt^&SeparateTCP
req.txt is Sample\req.txt


GNU HTTP Tunnel のクライアントと同等(動的セッションID)(95/tcpで待機して、HTTPTunnelサーバの192.0.2.1:96/tcpへ転送する)
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
req.txt is Sample\req1.txt


GNU HTTP Tunnel のサーバと同等(動的セッションID)(96/tcpで待機して、192.0.2.2:97/tcpへ転送する)
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
res.txt is Sample\res.txt


GNU HTTP Tunnel よりも隠蔽度の高くしてみた(95/tcp→192.0.2.1:96)
StreamRelay.NET.exe -LocalPort 95 -RemotePort 96 -RemoteHost 192.0.2.1 -Verbose -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
req.txt is Sample\req1.txt
res.txt is Sample\res.txt
StreamRelay013.png


二つの netcat に接続する bash と同等
nc.exe -nvv -L -p 81
nc.exe -nvv -L -p 82
bash < /dev/tcp/192.0.2.1/81 > /dev/tcp/192.0.2.1/82
StreamRelay.NET.exe -VerboseMode -LocalPort -1 -RemoteHost 192.0.2.1 -RemotePort 81 -RemoteSeparateConnection -RemotePort2nd 82 -LocalProgram cmd.exe


HttpProxy サーバ(8082/tcp)(HTTPonly)として動作させる
StreamRelay.NET.exe -VerboseMode -LocalPort 8082 -LocalProxy http://


HttpProxy サーバ(8082/tcp)(HTTP&HTTPS)として動作させる
StreamRelay.NET.exe -VerboseMode -LocalPort 8082 -LocalProxy http://?DropConnect=true


HttpProxy サーバ(8082/tcp)として動作させる(CONNECT の場合は、SSL終端としてSSLも代理する)
StreamRelay.NET.exe -VerboseMode -LocalPort 8082 -LocalProxy http:///?AutoSSLClient=true^&AutoSSLServer=true^&LocalCertFile=《証明書ファイル》^&LocalCertPassword=《証明書ファイルのパスワード》
StreamRelay.NET.exe -VerboseMode -LocalPort 8082 -LocalProxy http:///?AutoSSL=true^&LocalCertFile=《証明書ファイル》^&LocalCertPassword=《証明書ファイルのパスワード》


HttpProxy サーバ(8082/tcp)として動作させるが特定の HTTPS サーバ(192.0.2.1:443)へ転送させる(よって CONNECT メソッドは捨てる)
StreamRelay.NET.exe -VerboseMode -LocalPort 8082 -LocalProxy http:///?AutoSSLClient=true^&AutoSSLServer=true^&LocalCertFile=《証明書ファイル》^&LocalCertPassword=《証明書ファイルのパスワード》^&DropConnect=true -RemoteHost 192.0.2.1 -RemotePort 443
StreamRelay.NET.exe -VerboseMode -LocalPort 8082 -LocalProxy http:///?AutoSSL=true^&LocalCertFile=《証明書ファイル》^&LocalCertPassword=《証明書ファイルのパスワード》^&DropConnect=true -RemoteHost 192.0.2.1 -RemotePort 443


HttpProxy サーバ(8082/tcp)として動作させるが特定の HTTP サーバ(192.0.2.1:80)へ転送させる(よって CONNECT メソッドは捨てる)
StreamRelay.NET.exe -VerboseMode -LocalPort 8082 -LocalProxy http:///?AutoSSLServer=true^&LocalCertFile=《証明書ファイル》^&LocalCertPassword=《証明書ファイルのパスワード》^&DropConnect=true -RemoteHost 192.0.2.1 -RemotePort 80


HttpProxy サーバ(8082/tcp)として動作させるが上位 HTTP サーバ(192.0.2.1:8080)へ転送させる
StreamRelay.NET.exe -VerboseMode -LocalPort 8082 -LocalProxy http:///?AutoSSL=true^&LocalCertFile=《証明書ファイル》^&LocalCertPassword=《証明書ファイルのパスワード》^& -RemoteHost 192.0.2.1 -RemotePort 8080


tcp/90→192.0.2.1:91までを画数エンコードを実施する(乱数は「Random」。ノイズ発生確率は「ノイズ文字数/(ノイズ文字数+10)」で乱数は「Random」)。tcp/91で受信した内容は画面に出力する
StreamRelay.NET.exe -LocalPort 90 -RemotePort 91 -RemoteHost 192.0.2.1 -RemoteProxy netstream:///?StrokeEncode=VocabRandom%3dRandom%26NoiseRandom%3d10%2crandom
StreamRelay.NET.exe -LocalPort 92 -RemotePort 0 -LocalProxy netstream:///?StrokeDecode


tcp/90→192.0.2.1:91までをShinoEncodeを実施する(乱数は「Random」。ノイズ発生確率は「ノイズ文字数/(ノイズ文字数+10)」で乱数は「Random」。辞書ファイルは「D:\ShinoEncodeDictionary.txt(ノイズの単語含)」。「そのまま/先頭大文字/全部大文字」乱数は「Random」でそれぞれ「10:20:30」の比。単語の最後に記号を付与する乱数は「Random」で辞書ファイルは「D:\ShinoEncodeSymbolDictionary.txt」)。tcp/91で受信した内容は画面に出力する
StreamRelay.NET.exe -LocalPort 90 -RemotePort 91 -RemoteHost 192.0.2.1 -RemoteProxy netstream:///?ShinoEncode=VocabRandom%3dRandom%26NoiseRandom%3d10%2crandom%26VocabDicFile%3dD:\ShinoEncodeDictionary.txt%26CaseRandom%3d10/20/30%2crabdom%26SymbolRandom%3drandom%26SymbolDicFile%3dD:\ShinoEncodeSymbolDictionary.txt
StreamRelay.NET.exe -LocalPort 92 -RemotePort 0 -LocalProxy netstream:///?ShinoDecode


互いに NTLM 認証([ワークグループ|ドメイン]\ユーザ名)を実施する
StreamRelay.NET.exe -LocalPort 90 -RemotePort 91 -RemoteHost 192.0.2.1 -RemoteProxy netstream:///?NTLM
StreamRelay.NET.exe -LocalPort 91 -RemotePort 80 -RemoteHost 192.0.2.2 -LocalProxy netstream:///?NTLM


文字コードの変換
nkf.exe -S -e input.txt < output.txt
StreamRelay.NET.exe -VerboseMode -LocalPort 0 -LocalInputFile a.txt -InputRequestCharset Shift_JIS -RemotePort 0 -OutputRequestCharset EUC-JP -RemoteOutputFile output.txt


ファイルの内容を表示
type a.txt
StreamRelay.NET.exe -VerboseMode -LocalPort 0 -RemotePort 0 -LocalInputFile a.txt
StreamRelay.NET.exe -VerboseMode -LocalPort 0 -RemotePort 0 -LocalInputFileC a.txt


ファイルのNTFS代替ストリーム内容を表示
type a.txt:HEHEHE
StreamRelay.NET.exe -VerboseMode -LocalPort 0 -RemotePort 0 -LocalInputFileC a.txt:HEHEHE


キーボードからの入力をファイルのNTFS代替ストリームに保存
notepad.exe a.txt:HEHEHE
StreamRelay.NET.exe -VerboseMode -LocalPort 0 -RemotePort 0 -RemoteOutputFileC a.txt:HEHEHE


ファイルコピー(代替ストリームは消えてしまうはず)
copy a.txt b.txt
StreamRelay.NET.exe -VerboseMode -LocalPort 0 -LocalInputFile a.txt -RemotePort 0 -RemoteOutputFile b.txt


二つのファイルコピー
copy a.txt b.txt && copy x.txt y.txt
StreamRelay.NET.exe -VerboseMode -LocalPort 0 -LocalInputFile a.txt -LocalOutputFile y.txt -RemotePort 0 -RemoteOutputFile b.txt -RemoteInputFile x.txt -AllowHalfOpen


スクリプト・コマンドっぽく
script outputLog.txt
StreamRelay.NET.exe -LocalPort 0 -RemotePort -1 -RemoteProgram cmd.exe -LoggingFile outputLog.txt


ファイルの圧縮
gzip.exe a.txt
StreamRelay.NET.exe -LocalPort 0 -LocalInputFile a.txt -RemotePort 0 -RemoteOutputFile a.txt.gz -RemoteProxy netstream:///?gzipCompress


ファイルの解凍(gzip の解凍)
gzip.exe -d a.txt.gz
StreamRelay.NET.exe -LocalPort 0 -LocalInputFile a.txt.gz -RemotePort 0 -RemoteOutputFile log.txt -LocalProxy netstream:///?gzipDeCompress


ハッシュ値の計算
md5sum.exe a.txt
StreamRelay.NET.exe -LocalPort 0 -LocalInputFile a.txt -RemotePort 0 -RemoteProxy netstream:///?OutputHashAlgorithm=MD5


対応している全てのハッシュ値/チェックサム/カウンティングの計算
StreamRelay.NET.exe -LocalPort 0 -LocalInputFile a.txt -RemotePort 0 -RemoteProxy netstream:///?OutputAllHashAlgorithm
FOR /F "usebackq skip=2" %I in (`StreamRelay.NET.exe -ListHash 2^>^&1`) do @StreamRelay.NET.exe -LocalPort 0 -LocalInputFile a.txt -RemotePort 0 -RemoteProxy netstream:///?OutputHashAlgorithm=%I


対応している全てのハッシュ値/チェックサム/カウンティング/HMACの計算
StreamRelay.NET.exe -LocalPort 0 -LocalInputFile a.txt -RemotePort 0 -RemoteProxy netstream:///?OutputAllHashAlgorithm=《鍵》


NodeJS っぽくサーバサイドスクリプトを実現する (動かすスクリプトは ECHO サーバ)(スクリプトは JScript.NET)
StreamRelay.NET.exe -LocalPort 91 -RemotePort 0 -JScriptFile echo.js -VerboseMode


ファイルを圧縮しつつ、圧縮前と圧縮後のチェックサムとハッシュ値を表示
StreamRelay.NET.exe -LocalPort 0 -LocalInputFile a.txt -RemotePort 0 -RemoteOutputFile a.txt.gz -RemoteProxy netstream:///?gzipCompress^&OutputHashAlgorithm=MD5^&OutputHashAlgorithm=CRC32 -LocalProxy netstream:///?InputHashAlgorithm=MD5^&InputHashAlgorithm=CRC32


BinHEX エンコードを実施
StreamRelay.NET.exe -LocalPort 0 -RemotePort 0 -LocalInputFile binhexsource2.txt -RemoteOutputFile binhexsource2.out -RemoteProxy netstream:///?BinHexEncode -RemoteProxy netstream:///?BinHexCompress
StreamRelay.NET.exe -LocalPort 0 -RemotePort 0 -LocalInputFile binhexsource2.txt -RemoteOutputFile binhexsource2.out2 -RemoteProxy netstream:///?BinHexEnCorate -RemoteProxy netstream:///?BinHexEnCode -RemoteProxy netstream:///?BinHexCompress
BinHexCUI.exe En binhexsource.txt | StreamRelay.NET.exe -LocalPort 0 -RemotePort 0 -RemoteProxy netstream:///?BinHexEnCorate -RemoteProxy netstream:///?BinHexEnCode -RemoteProxy netstream:///?BinHexCompress


BinHEX デコードを実施
StreamRelay.NET.exe -LocalPort 0 -RemotePort 0 -LocalInputFile binhexraw2.txt -RemoteOutputFile binhexraw2.out -LocalProxy netstream:///?BinHexDecode -LocalProxy netstream:///?BinHexDeCompress
StreamRelay.NET.exe -LocalPort 0 -RemotePort 0 -LocalInputFile binhexraw.txt -RemoteOutputFile binhexraw.out -LocalProxy netstream:///?BinHexDeCorate -LocalProxy netstream:///?BinHexDeCode -LocalProxy netstream:///?BinHexDeCompress
binhexraw2.out
BinHexCUI.exe En binhexsource.txt | StreamRelay.NET.exe -LocalPort 0 -RemotePort 0 -RemoteProxy netstream:///?BinHexEnCorate -RemoteProxy netstream:///?BinHexEnCode -RemoteProxy netstream:///?BinHexCompress | StreamRelay.NET.exe -LocalPort 0 -RemotePort 0 -LocalProxy netstream:///?BinHexDeCorate -LocalProxy netstream:///?BinHexDeCode -LocalProxy netstream:///?BinHexDeCompress | BinHexCUI.exe De binhexsource.txt.out


テキストファイル(EnglishText.txt)を音声として読み上げを行う
StreamRelay.NET.exe -LocalPort 0 -LocalInputFile EnglishText.txt -RemotePort 0 -RemoteSpeachVoiceName "Microsoft Anna"


テキストファイル(EnglishText.txt)を音声として読み上げを行う
StreamRelay.NET.exe -LocalPort 0 -LocalInputFile EnglishText.txt -RemotePort 0 -RemoteSpeachVoiceName "Microsoft Anna"


テキストファイル(JapaneseText.txt)を音声として読み上げを行う(Microsoft Office がインストールされている場合)
StreamRelay.NET.exe -LocalPort 0 -LocalInputFile JapaneseText.txt -RemotePort 0 -RemoteSpeachVoiceName "Microsoft Haruka Desktop"


SlimDX ランタイムがインストールされている状況で既定の録音デバイスで録音を実施し、最後に出力ファイルにWAVEヘッダを追加する
StreamRelay.NET.exe -LocalPort 0 -RemotePort 0 -RemoteOutputFile rec.wav -Verbose -LocalSoundRecord 0
SoundChange.exe rec.wav


DPAPI(Data Protection API)を使って(エントロピー 0x001122、スコープ(範囲)を現在のユーザ)、ファイルを保護する
StreamRelay.NET.exe -LocalPort 0 -LocalInputFile file -RemotePort 0 -RemoteProxy netstream:///?DPAPI^&DPAPIEntropyHex=001122^&DPAPIScope=CurrentUser -RemoteOutputFile file.out


レジストリ(HTLM\SOFTWARE\UrlRewriteProxy\<<SubKeyName>>)から設定を読み込んで起動する
StreamRelay.NET.exe -Registry <<SubKeyName>>


ファイルから設定を読み込んで起動する
StreamRelay.NET.exe -ConfigFile <<FilePath>>


Windows サービスへ登録
StreamRelay.NET.exe -install


Windows サービスからアンインストール
StreamRelay.NET.exe -uninstall


URL Rewrite ツール
StreamRelay.NET.exe -VerboseMode -LocalPort 80 -RemoteHost 192.0.2.3 -RemotePort 80 -r /webApp/../
StreamRelay020.png



BouncyCastle / .NET Framework / SharpZipLib の暗号化処理の引数の指定制限について

暗号処理機能を利用する際には、いろいろと引数に制限があるので、その情報

アルゴリズムによる制限
名前 オプション 鍵長(byte) IV(byte) ライブラリ 方式 C:\>StreamRelay.NET.exe -ListCipher
------------------------------------------------
Cipher Algorithm is
RC2
AES
Rijndael
DES
TripleDES
BC_AES
BC_AESFast
BC_AESLight
BC_Blowfish
BC_Camellia
BC_CamelliaLight
BC_CAST5
BC_CAST6
BC_DES
BC_DESEDE
BC_GOST28147
BC_IDEA
BC_Threefish
BC_RC2
BC_RC5_32
BC_RC5_64
BC_Rijndael
BC_SEED
BC_Serpent
BC_Tnepres
BC_SKIPJACK
BC_TEA
BC_Twofish
BC_XTEA
BC_Noekeon
BC_RC6
BC_RC4
BC_HC128
BC_HC256
BC_Salsa20
BC_XSalsa20
BC_CHACHA
BC_ISAAC
BC_VMPC
BC_VMPCKsa3
PkZip
RC2 RC2 5-16 8 標準 ブロック
AES AES 16/24/32 16 標準 ブロック
Rijndael Rijndael 16/24/32 16 標準 ブロック
DES DES 8 8 標準 ブロック
3DES TripleDES 16/24 8 標準 ブロック
AES BC_AES 16/24/32 ブロックサイズ Bouncy Castle ブロック
AES BC_AESFast 16/24/32 ブロックサイズ Bouncy Castle ブロック
AES BC_AESLight 16/24/32 ブロックサイズ Bouncy Castle ブロック
Camellia BC_Camellia 16/24/32 ブロックサイズ Bouncy Castle ブロック
Camellia BC_CamelliaLight 16/24/32 ブロックサイズ Bouncy Castle ブロック
CAST5 BC_CAST5 -16 ブロックサイズ Bouncy Castle ブロック
CAST6 BC_CAST6 1- ブロックサイズ Bouncy Castle ブロック
DES BC_DES 8-(おそらく8以上は無視している) 8 Bouncy Castle ブロック
3DES BC_DESEDE 16/24 8 Bouncy Castle ブロック
GOST28147 BC_GOST28147 32 ブロックサイズ Bouncy Castle ブロック
IDEA BC_IDEA 1- ブロックサイズ Bouncy Castle ブロック
RC2 BC_RC2 1- ブロックサイズ Bouncy Castle ブロック
RC5(32bit) BC_RC5_32 1- ブロックサイズ Bouncy Castle ブロック
RC5(64bit) BC_RC5_64 -255 ブロックサイズ Bouncy Castle ブロック
Rijndael BC_Rijndael 16/20/24/32 ブロックサイズ Bouncy Castle ブロック
SEED BC_SEED 16- ブロックサイズ Bouncy Castle ブロック
Serpent BC_Serpent 4の倍数 ブロックサイズ Bouncy Castle ブロック
Tnepres BC_Tnepres 4の倍数 ブロックサイズ Bouncy Castle ブロック
SKIPJACK BC_SKIPJACK 10- ブロックサイズ Bouncy Castle ブロック
TEA BC_TEA 16- ブロックサイズ Bouncy Castle ブロック
Blowfish BC_Blowfish 1- ブロックサイズ Bouncy Castle ブロック
Twofish BC_Twofish 1- ブロックサイズ Bouncy Castle ブロック
Threefish BC_Threefish 32/64/128 ブロックサイズ Bouncy Castle ブロック
XTEA BC_XTEA 16- ブロックサイズ Bouncy Castle ブロック
Noekeon BC_Noekeon 16- ブロックサイズ Bouncy Castle ブロック
RC6 BC_RC6 1- ブロックサイズ Bouncy Castle ブロック
RC4 BC_RC4 1- 不要 Bouncy Castle ストリーム
HC128 BC_HC128 16 不要 Bouncy Castle ストリーム
HC256 BC_HC256 16/32 10- Bouncy Castle ストリーム
Salsa20 BC_Salsa20 16- 8 Bouncy Castle ストリーム
XSalsa20 BC_XSalsa20 32 24 Bouncy Castle ストリーム
ChaCha BC_CHACHA 16/32 8 Bouncy Castle ストリーム
ISAAC BC_ISAAC -14 不要 Bouncy Castle ストリーム
VMPC BC_VMPC 1- 1- Bouncy Castle ストリーム
VMPC Ksa3 BC_VMPCKsa3 1- 1- Bouncy Castle ストリーム
ZIPパスワード保護 PkZip 12 不要 SharpZipLib


暗号化モードによる制限
名前 オプション IV(byte) 標準 Bouncy Castle 備考 C:\>StreamRelay.NET.exe -ListCipherMode
------------------------------------------------
Cipher Mode is
none
ECB
CBC
CFB
GOFB
OFB
OpenPgpCfb
CTS
SIC
CCM
EAX
GCM
OCB
ECB ECB ブロックサイズ ×
不要 ×
CFB CFB ブロックサイズ ×
0-ブロックサイズ ×
CBC CBC ブロックサイズ ×
不要、またはブロックサイズ ×
OFB OFB ブロックサイズ ×
不要、または任意のサイズ ×
GOFB GOFB 不要、または任意のサイズ × BlockSize=8byteのみ
GCTR
OpenPgpCfb OpenPgpCfb 不要、または任意のサイズ ×
CTS CTS × × 疑似ストリーム
CTR
不要、または任意のサイズ ×
SIC SIC 8-16 × CTR/SIC
EAX EAX 8-16 × AEAD block cipher mode
CCM CCM 不要 × AEAD block cipher mode
BlockSize=16byteのみ
GCM GCM 不要 × AEAD block cipher mode
BlockSize=16byteのみ
OCB OCB 不要 × AEAD block cipher mode
BlockSize=16byteのみ


暗号化モードによる制限(.NET Framework 標準)
CTS モードは共通鍵アルゴリズム(RC2,AES,Rijndael,DES,TripleDES)では使えないようだ

StreamRelay.NET.exe の注意事項




行きと戻りの両方を暗号化した場合、以下のような状況(「Remote」→「」)になり、ゴミデータ(NULLの暗号処理)が出力されるかもしれません
StreamRelay015.png



削除方法
StreamRelay.net.exe を削除して、.NET Framework4.0 ランタイムを削除すればよいです。


実行権限
NT サービスに対応していたり、シリアルポートに対応していたりと、結構高い権限が必要です。


スクリプト呼び出し
「-JScriptFile」オプションで、JSCript.NET スクリプト・ファイルを読み込む事が可能です(ver2.1.0.2 以降)。

「-VBScriptFile」オプションで、ActiveScript スクリプト・ファイルを読み込む事が可能です(ver2.2.0.0 以降)。
(Vista などインストールされていない場合は、Windows Script Control からダウンロード)

同梱の「test.js」や「echo.js」を参考にしてください。

他にも IronPython/IronRuby/Boo 言語に対応しています。

パッケージ名「URLRewriteProxy」で、
クラス「StreamRelay」を作成し、
Object型を引数にとるメソッド「ExecScript」を作成していただくと、
データ受信時に呼び出されます。

ExecScript メソッドの引数オブジェクトには、以下のプロパティ/メソッドを公開しました。
logWrite(String)ログとして出力します
String InputStr文字コード指定の場合、ストリームデータを文字列に置換した状態でこれに格納されてる。また、これに格納しておくことで、ストリームへ出力される
byte[] InputByteArray文字コードを指定していない場合、ストリームデータをバイト列としてこれに格納されている。また、これに格納しておくことで、ストリームへ出力される
String BufferStr
byte[] BufferByteArray
一時格納用、次の呼び出しでも保持される。TCPの接続とストリームの方向ごとに独立で保持される
Boolean IsSendこのスクリプト呼び出し後に InputByteArray/InputStr のデータを転送したい場合 true をセットする(既定はtrue)
String InputStrReverse
byte[] InputByteArrayReverse
返信したい場合、こちらに格納する。文字コードを指定した場合は String 型の変数へ、そうでない場合は、byte配列型の変数へ格納すること
Boolean IsSendReverseこのスクリプト呼び出し後に InputByteArrayReverse/InputStrReverse のデータを返信したい場合 true をセットする(既定はfalse)
Boolean IsCloseこのスクリプト呼び出し後に、コネクションを切断したい場合 true をセットする(既定はfalse)
Boolean IsInputこのスクリプトが入力側で呼び出された場合 true。出力側で呼び出された場合 false
int count呼び出された回数。(「count=0」は接続直後なので、データ(InputByteArray/InputStr)は空のはず)
void CountUp()count をインクリメントする(スクリプト側から使う場面はないだろう)
String InputCallerAddress入力側の相手のアドレス、またはプログラム、ファイル、標準入力
int InputCallerPort入力側の相手のポート番号
String InputMyselfAddress入力側の自分自身のアドレス、またはプログラム、ファイル、標準入力
int InputMyselfPort入力側の自分自身のポート番号
String OutputCallerAddress出力側の相手のアドレス、またはプログラム、ファイル、標準入力
int OutputCallerPort出力側の相手のポート番号
String OutputMyselfAddress出力側の自分自身のアドレス、またはプログラム、ファイル、標準入力
int OutputMyselfPort出力側の自分自身のポート番号
String ErrorStrスクリプトの実行エラーを格納する
void ShowDialog(String)ダイアログを表示する(CUIなのに、GUIのダイアログが表示されます)
void SendMessageWindow(String)
void Speak(String)音声を発生させる
String SpeakVoiceName音声エンジンの名前
int SpeakVoiceRat音声の速さ(-100〜100)
int SpeakVoiceVolume音声の大きさ(0〜100)
Object LocalTagスクリプトのセッションで保持される、Object 型の変数を用意してみた。バッファとして使えると思う
void LocalLock()LocalTag をロックする
void LocalUnLock()LocalTag のロックをはずす
String LocalGetDictionary(String)タグをディクショナリオブジェクトとして用いて、キーの値を取得
void LocalSetDictionary(String key, String value)タグをディクショナリオブジェクトとして用いて、キーと値をセットする
Object GlobalTagアプリケーション全体でのセッションで保持される、Object 型の変数を用意してみた。バッファとして使えると思う
void GlobalLock()GlobalTag をロックする
void GlobalUnLock()GlobalTag のロックをはずす
String GlobalGetDictionary(String)タグをディクショナリオブジェクトとして用いて、キーの値を取得
void GlobalSetDictionary(String key, String value)タグをディクショナリオブジェクトとして用いて、キーと値をセットする



プラグイン
以下のディレクトリにプラグインがあるかどうか確認して、プラグインの場合は起動時に読み込みます。
実行ファイル
既定のプラグイン機能(.NET Framework 標準の乱数ライブラリや、標準の文字コードなど)

実行ファイルと同じディレクトリの IPlugin.dll
IPlugin.dll に実装されている既定のプラグイン機能

実行ファイル下の「Plugins」ディレクトリ下
32bit/64bit で動作している際に直下の DLL ファイルを読み込む

実行ファイル下の「Plugins\Win32」ディレクトリ下
32bit で動作している際に直下の DLL ファイルを読み込む

実行ファイル下の「Plugins\Win64」ディレクトリ下
64bit で動作している際に直下の DLL ファイルを読み込む


プラグインと ZoneID
ZoneID がついている DLL はプラグインとして読み込まれないようです。

プラグインが信用できるのであれば、ZoneIDを削除することで、プラグインを読み込めるようになります。

ZoneIDの説明画像
赤枠で囲まれた部分が存在すればZoneIDが存在。信用できるDLLであれば「ブロックの解除」押下で削除すればプラグインとして読み込み可能となる



標準のプラグイン



プラグインのインターフェイス
IPlugin.DLL を参照設定して、Microsoft VisualStudio などで作成してください。

API リファレンスの XML ファイルを用意した。

インターフェイス(名前空間 : jp.dip.rocketeer.Plugins)
IPluginStdioout
標準入力(-[Local|Remote]Port=0 指定)時のリダイレクト先のインターフェイス

IPluginListing
なにか一覧(例えば、音声合成エンジンの一覧など)を表示する必要がある場合のインターフェイス

IPluginScript
スクリプティング機能のインターフェイス

IPluginScriptEntity
スクリプティングエンジンと、スクリプトコードを読み込んだ状態のオブジェクトのインターフェイス

IPluginScriptBean
スクリプトを呼ぶ際の通信データなどのメソッド呼び出しの引数となるオブジェクト定義
IPluginScript.GetExecuteResult の引数用

IPluginRandom
乱数ライブラリのプラグイン・インターフェイス

IPluginRandomEntity
乱数ライブラリのインターフェイス
IPluginRandom.CreateRandomEntity() によって、乱数アルゴリズムのインスタンスが生成される

IPluginPasswordStirring
パスワード(共通鍵)を攪拌するためのアルゴリズムのライブラリのプラグイン・インターフェイス

IPluginPasswordStirringEntity
パスワード(共通鍵)を攪拌するためのアルゴリズムの乱数ライブラリのインターフェイス
IPluginPasswordStirring.CreatePasswordStirringEntity() によって、パスワード攪拌アルゴリズムのインスタンスが生成される

IPluginFilterStream
フィルタストリーム(圧縮とか、符号化とか)オブジェクトのライブラリのプラグイン・インターフェイス

IPluginFilterStreamEntity
フィルタストリーム(圧縮とか、符号化とか)オブジェクトのインターフェイス
IPluginFilterStream.CreateHashEntity() によって、フィルタ・アルゴリズムのインスタンスが生成される

IPluginCipher
暗号化オブジェクトのライブラリのプラグイン・インターフェイス

IPluginCipherEntity
暗号化オブジェクトのインターフェイス
IPluginCipher.CreateCipherEntity() によって、暗号アルゴリズムのインスタンスが生成される

IPluginHashList
Hash/Mac ライブラリのプラグイン・インターフェイス

IPluginHashMacEntity
Hash/Mac ライブラリのインターフェイス
IPluginHashList.CreateHashEntity() によって、Hash/Mac アルゴリズムのインスタンスが生成される

IPluginCharset
文字コード・オブジェクトのライブラリのプラグイン・インターフェイス

InOutStream
in/out の片方向ストリームを合わせて双方向ストリームにするクラス

HashMacStream
InOutStream を継承し、IPluginHashMacEntity.CreateStream() によって、生成される Hash/Mac 計算付きの双方ストリーム

Scope
最小値と最大値間で、乱数を生成するクラス




IronRuby/IronPython
IronRuby/IronPython ともに、ライブラリを同梱していませんので、 それぞれ本家からダウンロードして個別にインストールする必要があります。

IronPython は、GAC を汚してくれるので、インストールだけで済みますが、IronRuby は GAC を汚さないので、以下のファイルを GAC または、STreamRelay.NET.exe のカレントにコピーしてください。
(スクリプト言語などは、アプリケーションというよりもインフラとして捉えれるのであれば、GAC を汚してもいいと思うけどな)



Boo0.9.7
Boo 言語をスクリプトとして呼び出すには、以下の DLL が必要です。


免責など
著作権は放棄します。
このソフトを使用したことによって生じた、
いかなる損害についても責任は持ちません。

このソフトを使用したいかなる不正使用に関する責任は、
すべて、本プログラムの利用者に属します。

ソースコードについても、各自の責任において、
自由にいじってくれてもいいです。


当然ですが、悪用厳禁です。

プログラムの改変については、各自の責任で行う分については、自由に行って結構です。(参考になりましたメールをくれると、うれしい...(*^_^*))

ver2.0から修正BSDライセンスで配布します。

(修正BSDライセンスにしても、あまり、ライセンス条項って変わっていないような気がするんだよなぁ〜)


Version1.0DownLoad(UrlRewriteProxy.lzh as 9,632byte)(開発中止)
Version2.20.0.0DownLoad(StreamRelay.net.lzh as 5,756,012byte)

履歴



BouncyCastle_KeyLen_Test.exe

BouncyCastle/.NET Framework 標準の暗号オブジェクトの鍵長や IV 長、モード/パディングの組み合わせを試せるツール
不適切な場合は、ログが画面に出力されるので、その例外を読めばよい。
SharpZipLib の PkZip も試用可能

BouncyCastle_KeyLen_Test.exe の画面例



BinHexCUI.exe

第一引数「En」では、第二引数で指定されたファイルを読み込み、BinHexフォーマットにして標準出力へ出力する

第一引数「De」では、標準入力から受信した BinHex フォーマットなデータから、第二引数で指定されたファイルにファイルの内容を書き込む

C:\>BinHexCUI.exe
BinHexCUI.exe ver 1.0.0.0
                            created by active@window.goukaku.com

BinHexCUI.exe <<Mode([En|De])>> <<FileName>>



SoundChange.exe

第一引数に「RAW形式のファイル名」

C:\>SoundChange.exe
SoundChange.exe ver 1.0.0.0
                            created by active@window.goukaku.com

SoundChange.exe <<FileName>> [<<bit(16)>> <<Hz(8000)>> <<channel(1)>>]



IsolatedStorageCUI.exe

「標準入力→分離ストレージ」または「分離ストレージ→標準出力」するようなツール

C:\>IsolatedStorageCUI.exe
IsolatedStorageCUI.exe ver 1.0.0.0
                            created by active@window.goukaku.com

IsolatedStorageCUI.exe <<Scope>> <<Mode>> [<<FilePath>>]
     Scope : MachineStoreForDomain
             MachineStoreForAssembly
             MachineStoreForApplication
             UserStoreForApplication
             UserStoreForAssembly
             UserStoreForDomain
             UserStoreForSite
     Mode  : List
             Read <<FileName>>
             Append <<FileName>>



DeleteNullPadding.exe

ヌルパディングされた部分を排除するツール

第一引数
正しいものとして参照するファイルのファイルパス、またはファイルサイズ。(符号化処理前のファイルとか)
第二引数
コピー元のファイルパス(符号化解除した後のファイルとか)
第三引数
コピー先のファイルパス


C:\>DeleteNullPadding.exe
DeleteNullPadding.exe ver 1.0.0.0
                            created by active@window.goukaku.com

DeleteNullPadding.exe [FileSize|ReferenceFile] <<SourceFileName>> <<TargetFileName>>



Java 版

ここ


Qiita に記事他を書いた

二つのストリームで双方向で通信するツール「StreamRelay.NET.exe」と「StreamRelay.jar」


mail to active@window.goukaku.com