Sulley - 可选元素和命令检查

信息安全 缓冲区溢出 模糊测试 ftp
2021-08-20 12:21:03

我目前正在使用Sulley来模糊我的 FTP 服务器,但我遇到了问题。我想指定 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),但问题就是这样。它不会尝试省略角色或对其进行模糊处理,这也是我想要的。我知道我可以只指定模糊的参数,但我想模糊参数以及改变有效参数。任何想法如何将可选+模糊参数应用于上述代码?

另一个问题是我不知道如何检查当前正在使用哪个命令 - 我正在使用 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()

而已。欢迎任何想法和建议。谢谢

1个回答

由于您的两个问题都与组有关,我们应该先看看它们是如何使用的。目的是将块数据绑定到一组静态值——sulley 遍历值列表并为每个值生成块数据。

文档中的示例使用 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 会话中时,fuzzer 将为块“body”生成并传输所有可能的值,对于组中定义的每个动词一次

现在对于第一个问题,您只得到 'STRU F' 'STRU R' 和 'STRU P' 字符串,因为提供给 s_group() 的列表中的每个值都被视为与使用 s_static() 创建的字符串相同 - - 他们没有变异。

你可以试试这个:

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())。

对于第二个问题,您无需检查正在使用哪个命令。如果块特定于命令,只需单独定义它们:

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()