feat: added first commit malpacks
parent
98cba0c8c2
commit
a88420f2d9
|
@ -0,0 +1,22 @@
|
|||
import json
|
||||
|
||||
with open('/path/to/list/malicious/pkgs.txt', 'r') as file:
|
||||
lines = file.read().splitlines()
|
||||
|
||||
with open('database.json', 'r') as file:
|
||||
existing_data = json.load(file)
|
||||
|
||||
for line in lines:
|
||||
new_object = {
|
||||
"type": "pypi",
|
||||
"name": line,
|
||||
"url": "https://github.com/DataDog/malicious-software-packages-dataset"
|
||||
}
|
||||
existing_data.append(new_object)
|
||||
|
||||
with open('database_new.json', 'w') as file:
|
||||
json.dump(existing_data, file, indent=4)
|
||||
|
||||
print("Data appended and saved to database_new.json")
|
||||
|
||||
# This script is used to append data to the database.json file
|
|
@ -0,0 +1,17 @@
|
|||
import json
|
||||
|
||||
with open("../../database.json", "r") as json_file:
|
||||
data = json.load(json_file)
|
||||
|
||||
type_counts = {}
|
||||
|
||||
for item in data:
|
||||
item_type = item.get("type")
|
||||
if item_type:
|
||||
if item_type in type_counts:
|
||||
type_counts[item_type] += 1
|
||||
else:
|
||||
type_counts[item_type] = 1
|
||||
|
||||
for item_type, count in type_counts.items():
|
||||
print(f"{item_type}: {count}")
|
54
README.md
54
README.md
|
@ -1,2 +1,52 @@
|
|||
# malware-package-scanner
|
||||
Tools to find malicious packages
|
||||
# Malpacks
|
||||
Tools to find malicious packages inside package manager (PyPI, npm, and Gem)
|
||||
|
||||
## Total data
|
||||
* npm: 1823
|
||||
* pypi: 5985
|
||||
* gem: 725
|
||||
|
||||
## Installation
|
||||
Simply clone the repository, install requirements and run the script
|
||||
|
||||
* $ git clone https://github.com/daffainfo/malpacks
|
||||
* $ pip3 install -r requirements.txt
|
||||
* $ python3 main.py
|
||||
|
||||
## Usage
|
||||
Available options:
|
||||
* `--all` option
|
||||
|
||||
To scan all the package managers (PyPI, npm, and Gem)
|
||||
|
||||
Example:
|
||||
```bash
|
||||
$ python3 main.py --all
|
||||
```
|
||||
|
||||
* `--packages` option
|
||||
|
||||
Define package manager to test (PyPI, npm, and Gem)
|
||||
|
||||
Example:
|
||||
```bash
|
||||
$ python3 main.php --packages npm,pypi
|
||||
```
|
||||
|
||||
## To-Do List
|
||||
- [ ] Scan a file that contain list of packages
|
||||
- [ ] Scan requirements.txt (Python)
|
||||
- [ ] Scan package.json (npm)
|
||||
- [ ] More output options
|
||||
- [ ] JSON
|
||||
- [ ] YAML
|
||||
- [ ] Add more package manager
|
||||
- [x] PyPI
|
||||
- [x] npm
|
||||
- [x] Gem
|
||||
- [ ] Go
|
||||
- [ ] Composer
|
||||
- [ ] Add more malicious packages
|
||||
- [x] https://blog.phylum.io/phylum-discovers-another-attack-on-pypi/
|
||||
- [x] https://www.reversinglabs.com/blog/mining-for-malicious-ruby-gems
|
||||
- [ ] https://github.com/DataDog/malicious-software-packages-dataset
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,16 @@
|
|||
from colorama import Fore, Style
|
||||
|
||||
def banner():
|
||||
banner = Fore.BLUE + """
|
||||
# # ## # ##### ## #### # # ####
|
||||
## ## # # # # # # # # # # # #
|
||||
# ## # # # # # # # # # #### ####
|
||||
# # ###### # ##### ###### # # # #
|
||||
# # # # # # # # # # # # # #
|
||||
# # # # ###### # # # #### # # ####
|
||||
|
||||
Version: 1.0.0
|
||||
Author: daffainfo
|
||||
"""
|
||||
|
||||
print(banner + Style.RESET_ALL)
|
|
@ -0,0 +1,55 @@
|
|||
import json
|
||||
from colorama import Fore, Style
|
||||
from packages import npm, pypi, gem
|
||||
|
||||
npm_packages = []
|
||||
pypi_packages = []
|
||||
gem_packages = []
|
||||
|
||||
def scan(args):
|
||||
|
||||
if args.all:
|
||||
npm_packages = npm.list_all_npm_packages()
|
||||
pypi_packages = pypi.list_all_pypi_packages()
|
||||
gem_packages = gem.list_all_gem_packages()
|
||||
check('npm', npm_packages)
|
||||
check('pypi', pypi_packages)
|
||||
check('gem', gem_packages)
|
||||
|
||||
if args.packages:
|
||||
packages_type = args.packages.split(',')
|
||||
for package_type in packages_type:
|
||||
if package_type == 'npm':
|
||||
npm_packages = npm.list_all_npm_packages()
|
||||
check('npm', npm_packages)
|
||||
elif package_type == 'pypi':
|
||||
pypi_packages = pypi.list_all_pypi_packages()
|
||||
check('pypi', pypi_packages)
|
||||
elif package_type == 'gem':
|
||||
gem_packages = gem.list_all_gem_packages()
|
||||
check('gem', gem_packages)
|
||||
else:
|
||||
print(Fore.RED + f"[!] Unknown package type: {package_type}")
|
||||
print(Style.RESET_ALL)
|
||||
|
||||
def check(package_type, package_names):
|
||||
with open('database.json') as json_file:
|
||||
database = json.load(json_file)
|
||||
|
||||
print(Fore.YELLOW + f"[!] Checking {package_type} packages...")
|
||||
|
||||
found_count = 0
|
||||
for package in database:
|
||||
package_type_in_db = package.get('type', '')
|
||||
package_name = package.get('name', '')
|
||||
package_url = package.get('url', '')
|
||||
|
||||
if package_type == package_type_in_db and package_name in package_names:
|
||||
print(Fore.RED + f"[+] Package found: {package_name}")
|
||||
print(Fore.RED + f"[+] Advisory: {package_url}")
|
||||
print(Style.RESET_ALL)
|
||||
found_count = found_count + 1
|
||||
|
||||
if found_count == 0:
|
||||
print(Fore.GREEN + f"[+] No malicious {package_type} packages found.")
|
||||
print(Style.RESET_ALL)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,20 @@
|
|||
import argparse
|
||||
from colorama import Fore, Style
|
||||
from core import scanner, cli
|
||||
|
||||
def main():
|
||||
cli.banner()
|
||||
parser = argparse.ArgumentParser(description='Specify scan parameters.')
|
||||
|
||||
parser.add_argument('--all', action='store_true', help='Scanning all package managers')
|
||||
parser.add_argument('--packages', type=str, help='Define package manager to test', default="")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.all and not args.packages:
|
||||
parser.error('Please specify either --all or --packages')
|
||||
|
||||
scanner.scan(args)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,30 @@
|
|||
import subprocess
|
||||
|
||||
def list_all_gem_packages():
|
||||
try:
|
||||
result = subprocess.run(['gem', 'list'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
||||
|
||||
if result.returncode == 0:
|
||||
# Split the captured output into lines to get package lines
|
||||
package_lines = result.stdout.split('\n')
|
||||
|
||||
# Initialize an empty list to store package names
|
||||
package_names = []
|
||||
|
||||
# Print only the package names
|
||||
for package_line in package_lines:
|
||||
package_info = package_line.strip().split(' ')
|
||||
if len(package_info) > 0:
|
||||
package_name = package_info[0]
|
||||
package_names.append(package_name)
|
||||
|
||||
return package_names # Return the list of package names
|
||||
|
||||
else:
|
||||
print("Error:", result.stderr)
|
||||
|
||||
except Exception as e:
|
||||
print("An error occurred:", e)
|
||||
|
||||
# packages_array = list_all_gem_packages()
|
||||
# print(packages_array)
|
|
@ -0,0 +1,32 @@
|
|||
import subprocess
|
||||
|
||||
def list_all_npm_packages():
|
||||
try:
|
||||
result = subprocess.run(['npm', 'ls', '-g'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
||||
|
||||
if result.returncode == 0:
|
||||
# Split the captured output into lines to get package lines
|
||||
package_lines = result.stdout.split('\n')
|
||||
|
||||
# Initialize an empty list to store package names
|
||||
package_names = []
|
||||
|
||||
# Print only the package names without directory structure
|
||||
for package_line in package_lines:
|
||||
package_name = package_line.strip()
|
||||
if package_name and package_name != '/usr/local/lib':
|
||||
package_name = package_line.split('@')[0].strip()
|
||||
package_name = package_name.replace('├──', '').replace('└──', '').strip()
|
||||
if package_name:
|
||||
package_names.append(package_name)
|
||||
|
||||
return package_names # Return the list of package names
|
||||
|
||||
else:
|
||||
print("Error:", result.stderr)
|
||||
|
||||
except Exception as e:
|
||||
print("An error occurred:", e)
|
||||
|
||||
#packages_array = list_all_npm_packages()
|
||||
#print(packages_array)
|
|
@ -0,0 +1,30 @@
|
|||
import subprocess
|
||||
|
||||
def list_all_pypi_packages():
|
||||
try:
|
||||
# Run the 'pip freeze' command and capture its output
|
||||
result = subprocess.run(['pip3', 'freeze', '--all'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
||||
|
||||
if result.returncode == 0:
|
||||
# Split the captured output into lines to get package names
|
||||
package_lines = result.stdout.split('\n')
|
||||
|
||||
# Initialize an empty list to store package names
|
||||
package_names = []
|
||||
|
||||
# Append package names to the list
|
||||
for package_line in package_lines:
|
||||
package_name = package_line.split('==')[0] # Extract the package name
|
||||
if package_name:
|
||||
package_names.append(package_name)
|
||||
|
||||
return package_names # Return the list of package names
|
||||
|
||||
else:
|
||||
print("Error:", result.stderr)
|
||||
|
||||
except Exception as e:
|
||||
print("An error occurred:", e)
|
||||
|
||||
# packages_array = list_all_pypi_packages()
|
||||
# print(packages_array)
|
|
@ -0,0 +1 @@
|
|||
colorama==0.4.4
|
Loading…
Reference in New Issue