0x00 概要
日々の侵入訓練では、プロキシが不可欠です。通常、CS では Socks4 に付属する Socks5 プロトコルとプロキシ ツールを使用します。このプロセスではトラフィック回避の問題も考慮する必要があるため、まだ詳細に検討する必要があります。基礎となるプロトコルを分析し、トラフィックの特性を分析および変更します。
0x01 導入とプロセス
以下ウィキペディアより抜粋
SOCKSはネットワーク伝送プロトコルであり、主にクライアントと外部ネットワーク サーバー間の通信の中間伝送に使用されます。SOCKSは「SOCKetS」の略称です[注 1]。ファイアウォールの背後にあるクライアントが外部サーバーにアクセスする場合、SOCKSプロキシ サーバーに接続します。このプロキシ サーバーは、外部ネットワークにアクセスするためのクライアントの資格を制御し、許可されている場合はクライアントのリクエストを外部サーバーに送信します。このプロトコルはもともと David Koblas によって開発され、その後 NEC の Ying-Da Lee によって SOCKS4 に拡張されました。最新のプロトコルはSOCKS5で、以前のバージョンと比べてUDP、認証、IPv6に対応しました。OSI モデルによれば、SOCKS はプレゼンテーション層とトランスポート層の間に位置するセッション層のプロトコルです。SOCKS プロトコルは暗号化を提供しません。
ちょっとした知識ポイント: SOCKS 5 はバージョン 4 を拡張し、UDP プロトコルのサポートを追加します
SOCKS5 プロトコルは主に 3 つの段階に分かれています。
- (1) プロトコルのバージョンと認証方式
- (2) 認証方式に応じて対応する認証を実行する
- (3) 情報の請求
以下はこれらのプロセスの詳細な分析です。便宜上、Go の疑似コードが少し含まれています。
0x02 Socks5Auth認可認証
クライアントは、プロトコルのバージョンとその認証方法を確認するリクエストを開始する必要があります。
クライアントリクエストサーバーのリクエストフォーマットは次のとおりです。
バージョン | このリクエストのプロトコル バージョン番号。socks 5 は固定値 0x05 をとります。 |
---|---|
Nメソッド | クライアントがサポートする認証方法の数。指定可能な値は 1 ~ 255 です。 |
方法 | 利用可能な認証方法のリスト |
次に、サーバーは認証方法を選択し、クライアントに次のように指示する必要があります。
バージョン | VER はここでソックスのバージョンを指定します (0x05)。 |
---|---|
方法 | 選択した認証方法。0x00 は認証が必要ないことを意味し、0x02 はユーザー名/パスワード認証を意味します。 |
通常、METHOD で現在サポートされている認証方法は 2 つあります。
- 0x00 (認証不要)
- 0x20 (ユーザー名、パスワード認証)
, たとえば、ここでsocks5の場合、0x05を受け入れる必要があり、検証は不要であると設定します。その場合、0x00 は検証する必要がありません
//无需认证 直接返回 0x05 0x00 就好了
n, err = client.Write([]byte{
0x05, 0x00})
0x03 接続を確立するための Socks5 プロトコル分析
Socket5 のクライアントとサーバーが双方の認証検証に合格すると、接続の確立が開始されます。接続はクライアントによって開始され、クライアントがアクセスする必要があるリモート サーバー (リモート サーバーのアドレスとポートを含む) を Sokcet サーバーに伝えます。アドレスは IP4、IP6、またはドメイン名です。
バージョン | VER はここでソックスのバージョンを指定します (0x05)。 |
---|---|
担当者 | ステータス コード、0x00 = 成功、0x01 = 不明なエラー、... |
RSV | まだ役に立たない 予約済み |
タイプ | アドレスの種類 |
BND.アドレス | サーバーと DST が接続を作成するために使用するアドレス |
BND.ポート | サーバーと DST が接続を作成するために使用するポート |
-
VER は Socket プロトコルのバージョンを表します。Socket5 のデフォルト値は 0x05 で、値の長さは 1 バイトです。
-
CMDはクライアントリクエストのタイプを表し、値の長さも1バイトで、3つのタイプがあります
- 接続0x01
- バインド0x02
- UDP アソシエイト 0x03'
-
RSV 予約語、値の長さは 1 バイトです
-
ATYP は要求されたリモート サーバー アドレスのタイプを表し、値の長さは 1 バイトで、一般的に使用されるタイプが 3 つあります。
-
1:表示是一个IPV4地址(IP V4 address); 3:表示是一个域名(DOMAINNAME); 4:表示是一个IPV6地址(IP V6 address);
-
DST.ADDR は、ATYP に従って解析されたリモート サーバーのアドレスを表し、値の長さは可変です。
-
DST.PORT はリモート サーバーのポートを表し、アクセスするポートを表します。値の長さは 2 バイトです
サーバーは、クライアントの接続が成功したことに応答して、次のデータをクライアントに返します。
resp := []byte{
0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
ここはさらに興味深い場所で、交通事故を避けて殺人を避けてください
0x03 リンク確立後のデータ転送
最終的に接続が完了した後、データ転送が必要になります。この操作はポート転送の書き込みと同じであり、2 つのポートのトラフィックは io.Copy() によって転送できます。
golang には io.Copy があるので、非常に使いやすいです。
forward := func(src, dest net.Conn) {
defer src.Close()
defer dest.Close()
io.Copy(src, dest)
}
go forward(client, target)
go forward(target, client)
0x04 フロー検出の問題
ここでは SkyEye テストのみを示します。この種の認証は、分析後に一致ルールがすぐに理解できるため、簡単に識別できます。これは、クライアントの接続成功にサーバーが応答するためのルールであるため、SkyEye の検出はこの攻撃が成功した場合のルール。
{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
Skyeye の検出ペイロード:
0x05 渋滞回避
ルールがわかったので、強制終了を避けるのがはるかに簡単です。これは Socks 認証のプロセスであるためです。サーバーは変更できますが、私たちのツールは通常のプロトコルの Socks5 プロトコルであるため、クライアントも変更する必要があります。なので、認証を変更するのは実際には不便です。したがって、これを実装する最も簡単な方法は、真ん中にトンネルを追加することです。
実際にはトラフィック検出を回避できるのですが、書いたときは気にしていませんでした、フォワード接続です、実戦ではまだクライアント側のアクティブな外部リンクとして書かれているので、あまり役に立ちません, なので、また変更します。。。