現在、FTPサーバーをファズするために Sulley を使用していますが、問題があります。次の構文を持つSTRUコマンドを指定したいと思います。
STRU [<SP> F|R|P] <CRLF>
次のように、STRUコマンドにオプションのF、R、P引数を指定しようとしました。
s_initialize('DataSTRU')
s_static('STRU ')
s_group('struv', values=['F', 'R', 'P'])
s_block_start('strub', group='struv')
s_block_end()
s_repeat('strub', min_reps=0, max_reps=1, fuzzable=True)
s_static('\r\n')
これは、FTPサーバー(STRU F; STRU R; STRU P)に正しいコマンドを送信しますが、問題はそれです。キャラクターを省略したりファズしたりしないのもいいですね。引数をfuzzに指定するだけでよいことはわかっていますが、有効な引数を変更するだけでなく、引数をファジングしたいと思います。上記のコードにoptional + fuzzable引数を適用する方法はありますか?
もう1つの問題は、現在使用されているコマンドを確認する方法がわからないことです。s_block_start内のコマンドを使用しており、次のようにs_group要素を繰り返し処理しています。
s_initialize('DataSet')
s_group('commands', values=['MODE', 'PROT', 'STRU'])
s_block_start('DataBlock', group='commands')
s_delim(' ')
// TODO: how to check whether:
// if [current_command == 'MODE'] do this
// Elif [current_command == 'PROT'] do this
// else [current_command == 'STRU'] do this
s_static('\r\n')
s_block_end()
それでおしまい。どんなアイデアや提案も大歓迎です。ありがとう
どちらの質問もグループに関連しているため、最初にそれらがどのように使用されるかを確認する必要があります。目的は、ブロックデータを一連の静的な値にバインドすることです。サリーは値のリストを反復処理し、それぞれのブロックデータを生成します。
ドキュメントの例ではHTTPを使用しており、ブロックデータは単純なHTTPリクエストであり、グループ値はHTTP動詞( 'GET'、 'POST'、 'PUT'など)です。この例では、sulleyがs_group内の各HTTP動詞のデータブロック(リクエスト)を生成してファジングします。
# define a new block named "HTTP BASIC".
s_initialize("HTTP BASIC")
# define a group primitive listing the various HTTP verbs we wish to fuzz.
s_group("verbs", values=["GET", "HEAD", "POST", "TRACE"])
# define a new block named "body" and associate with the above group.
if s_block_start("body", group="verbs"):
# break the remainder of the HTTP request into individual primitives.
s_delim(" ")
s_delim("/")
s_string("index.html")
s_delim(" ")
s_string("HTTP")
s_delim("/")
s_string("1")
s_delim(".")
s_string("1")
# end the request with the mandatory static sequence.
s_static("\r\n\r\n")
# close the open block, the name argument is optional here.
s_block_end("body")
ドキュメントから:
この定義された要求がSulleyセッションにロードされると、ファザーは、グループで定義された動詞ごとに1回、ブロック「body」のすべての可能な値を生成して送信します
最初の質問では、s_group()に提供されたリストの各値はs_static()で作成された文字列と同じように扱われるため、「STRU F」、「STRU R」、「STRU P」の文字列のみが表示されます。 -それらは変異していません。
あなたはこれを試すことができます:
s_initialize('DataSTRU')
for op in ['', 'F', 'R', 'P']: # trying to include your missing-arg case
s_block_start('stru-%s' % op)
s_static('STRU')
s_delim(' ')
s_string(op)
s_static('\r\n')
s_block_end()
それはあなたが目指していたものに近いですが、おそらくこれだけでうまくいくでしょう:
s_initialize('DataSTRU')
s_block_start('stru')
s_static('STRU')
s_delim(' ')
s_string('F')
s_static('\r\n')
s_block_end()
スペース(s_delim())とパラメーター(s_string())をファジングします。
2番目の質問では、どのコマンドが使用されているかを確認する必要はありません。ブロックがコマンドに固有の場合は、それらを個別に定義するだけです。
s_initialize('DataSet')
s_block_start('mode')
s_static('MODE')
# MODE-specific primitives
s_block_end()
s_block_start('prot')
s_static('PROT')
# PROT-specific primitives
s_block_end()
for op in ['', 'F', 'R', 'P']:
s_block_start('stru-%s' % op)
s_static('STRU')
s_delim(' ')
s_string(op)
s_static('\r\n')
s_block_end()