web-dev-qa-db-ja.com

netcatから出力を取得し、デコードして出力を返す

Netcatから出力を取得し、デコードして返す必要があります。

入力後:

nc cs2107.spro.ink 9000

私が得る出力はこれです:

Welcome to the Proof of work challenge!  
Rules: i will provide hex encoded byte strings to you.  
Your task is to decode it and calculate the md5 hash in hex encoded format and return it back to me. You will need to do this 500 times!

Ready? Go!

cdde140fffda1da2bc3f

MD5:

したがって、16進数でエンコードされた文字列を取得し、デコードして再度出力する必要があります。これは500回発生するとします。

私は何をしなければならないかはわかっていると思いますが、それをunixでコーディングする方法がわかりません。 .shファイルが必要だと思いますか?しかし、私はよくわかりません。

  1. nc cs2107.spro.ink 9000から始めます

  2. nc出力から16進文字列を検索します

  3. それをデコードし、md5ハッシュを計算します

  4. 最後に、それを送り返します

編集:

そうすることでncの出力を保存できることを知っています

nc cs2107.spro.ink 9000 > somefile.txt  

16進文字列を具体的に検索するにはどうすればよいですか?
16進文字列をデコードするにはどうすればよいですか?
そして最後に、結果をターミナルに返す方法は?

edit2:したがって、pythonを使用してこの割り当てを行うことができます。いくつかのヒントは、サブプロセスモジュールまたはソケットモジュールのいずれかを使用することでした。それを読んで、サブプロセスで実行してみました

subprocess.Popen

コマンドをバックグラウンドで実行し続ける

私は現在これで立ち往生しています

import subprocess
p = subprocess.Popen('nc cs2107.spro.ink 9000', Shell = True, stdin = subprocess.PIPE, stdout = subprocess.PIPE)
a = subprocess.Popen('grep ^[0-9a-f] | xxd -r | md5sum | awk "{print $1}" ', stdin = p.stdout, stdout = subprocess.PIPE)

今私はpに戻ってパイプしようとして立ち往生しています

4
Helpisneeded

サーバーと通信するためにソケットプログラミングを行うことが期待されているのはあなたの言うとおりです。私は前にPython=を試しましたが、代わりに普通の古いBashスクリプトを使用することになりました。

まず、こちらのチュートリアルに従って、Bashでソケットを初期化する方法を確認できます。 http://hacktux.com/bash/socket

ステップ1:ソケットの初期化

Bash execとUNIXリダイレクト<>を使用して、疑似パス上にソケットを作成できます。パス構文は/dev/<protocol>/<Host>/<port>です

exec 3<>/dev/tcp/cs2107.spro.ink/9000;

ステップ2:サーバー出力の読み取り

エンコードされたバイトをサーバー出力から読み取る必要があります。これはcatコマンドで実行できますが、期待どおりに機能しません。これは、サーバーがクライアントからの入力を待っており、EOF文字がないためです(ストリーミングデータに関連していると思います)。これを防ぐには、サーバー出力、つまり、7行目で停止します。

head -7 <&3

ステップ3:データの取得と変換

egrep -o '^[0-9a-f]{20}' | xxd -r -p | md5sum

情報のチャンクを読み取った後、egrepを使用して16進バイトを取得できます。 16進ダンプの長さが固定されているため、正規表現を使用して必要なデータを抽出できます。

Hexdumpをxxd -r -pにパイプすると、hexdumpがバイナリに変換され、プレーンテキストとして出力されます。 md5sumはその後、ダーティーな作業を行い、答えを計算します。

ステップ4:サーバーに書き戻す

awk '{print $1}' >&3;

私の場合、md5sumは文字列の最後に回答と余分な文字を出力するため、awkを使用して最初の列を出力し、サーバーに書き戻します。

ステップ5:さらに499回繰り返します

手順2〜4と同様ですが、サーバーは長い紹介テキストの代わりに後続の応答でのみ「正しい」を出力するため、手順2を変更する必要があります。 headを変更して、2行で読み取るようにします。これをさらに499回行う必要があります。

for i in {1..499}
do
    head -2 <&3 | egrep -o '^[0-9a-f]{20}' | xxd -r -p | md5sum | awk '{print $1}' >&3;
done

ステップ5:フラグをキャプチャします

500個すべての応答が完了すると、ソケットをキャッチすることでフラグを取得できます。

cat <&3

P/S OPと同じモジュールを取り、同じ割り当てを行っていたので、ここで答えを共有します。モジュールが終了した後、たまたまこの投稿を見つけました。

3
kfwong

これが部分的な解決策です。netcatスクリプトの入力を行うことに不満を感じました。

  1. 次に、16進文字列を具体的に検索するにはどうすればよいですか?

簡単な方法は次のとおりです。

$ nc -d cs2107.spro.ink 9000 > file

Welcome to the Proof of Work Challenge.
Rules: I will provide hex encoded byte strings to you.
Your task is to decode it and calculate the md5 hash.
Return the md5 hash in hex encoded format back to me.
You will need to do this 500 times.
Ready? Go!
eeb105fb2f5e24216bd2
MD5:

ここでは、最初に特定の行#7を選択するsedコマンドがありましたが、最初の16進エンコードされたバイト文字列を解決すると、次の出力がすぐに表示されます。だから私はこれを16進文字に一致する正規表現に変更しました:

$ cat file.txt | grep '^[a-f0-9]'

eeb105fb2f5e24216bd2
  1. 16進文字列をデコードするにはどうすればよいですか?

$ cat file.txt | grep '^[a-f0-9]' | xxd -r -p | md5

92b34e4055a92b9ec32b15f89cc22389

だから私はこれが手動で機能することの確認を得ました:

Welcome to the Proof of Work Challenge.
Rules: I will provide hex encoded byte strings to you.
Your task is to decode it and calculate the md5 hash.
Return the md5 hash in hex encoded format back to me.
You will need to do this 500 times.
Ready? Go!
eeb105fb2f5e24216bd2
MD5: 92b34e4055a92b9ec32b15f89cc22389
Correct.
9ecbc2b8d14ae903dce5
  1. そして最後に、結果をターミナルに返す方法は?

この最後の質問は本当に最大の問題です。それを機能させることができませんでした。私はいくつかのスクリプトを書いたが、どれも問題を解決しなかった。 Gilles で言及されている問題は、データを読み取るのに十分な時間接続を開いたままにし、まだ開いているプログラムにフィードバックする必要があることです。これは、上記で投稿したような、パイプされたコマンドをシェルで使用する通常のアプローチを妨げます。

これは、シェルスクリプトで正しく実装できなかった疑似コードです。

  1. forループでは、500回繰り返します。動作します。
  2. cs2107.spro.ink 9000への接続を開いたままにします。進行中です。
  3. サーバーから送信されたビットを読み取ります。動作します。
  4. 16進文字列をデコードします。動作します。
  5. md5ハッシュを計算します。動作します。
  6. 接続を開くために入力を送信します。進行中。
  7. 手順3〜6を繰り返します。
  8. 終わり。

ここに私が試したいくつかのリソースがあります

  1. a TCP接続)にイン/アウト名前付きパイプを使用する
  2. https://serverfault.com/questions/188936/writing-to-stdin-of-background-process/297095#297095
  3. https://stackoverflow.com/questions/21130757/send-commands-to-socket-using-netcat
  4. https://superuser.com/questions/261900/how-can-i-pipe-commands-to-a-netcat-that-will-stay-alive
  5. https://stackoverflow.com/questions/2559076/how-do-i-redirect-output-to-a-variable-in-this-Shell-function
  6. http://www.linuxquestions.org/questions/programming-9/dynamically-supply-input-to-netcat-in-a-script-793526/

あなたがそれを見つけたら、私はその解決策を知りたいと思います。多分後でもう一度やり直します。

2
projectdp

ncを呼び出すシェルでこれを行うのは困難です。接続を開いたままにして、ncからデータを取得し、そのデータを処理して、同じデータをnc。それはできますが、難しいです。

同じ言語でネットワークを操作してデータフローを制御できれば、はるかに簡単です。シェルbash、ksh、またはkshのいずれかを使用する場合、それらのネットワーク機能を使用できます。これらのシェルは、TCPクライアントである場合があります。たとえば、サーバーから行を読み取るスクリプトと、それらを1つずつエコーします。

{
  while IFS= read -r line <&3; do
    echo "$line" >&3
  done
} 3<>/dev/tcp/cs2107.spro.ink/9000

16進文字列をデコードするには、xxdを検索します。データ処理ロジックを理解させましょう。