From 3a367d2112069b0ee5f4c965d5c3aa02390e0c69 Mon Sep 17 00:00:00 2001 From: Carlos Polop Date: Sun, 11 Jul 2021 18:51:48 +0200 Subject: [PATCH] linpeas-ng --- build_lists/sensitive_files.yaml | 91 +++++++++++++++++++++------ linPEAS/builder/linpeas_base.sh | 30 ++++----- linPEAS/builder/src/fileRecord.py | 2 +- linPEAS/builder/src/linpeasBuilder.py | 18 +++++- linPEAS/builder/src/peasLoaded.py | 19 +++--- linPEAS/builder/src/yamlGlobals.py | 3 + 6 files changed, 120 insertions(+), 43 deletions(-) diff --git a/build_lists/sensitive_files.yaml b/build_lists/sensitive_files.yaml index 9e9a195..456ee95 100644 --- a/build_lists/sensitive_files.yaml +++ b/build_lists/sensitive_files.yaml @@ -93,6 +93,8 @@ defaults: exec: [] +variables_markup: "peass{VARIABLES}" + variables: - name: pwd_inside_history value: "7z|unzip|useradd|linenum|linpeas|mkpasswd|htpasswd|openssl|PASSW|passw|shadow|root|sudo|^su|pkexec|^ftp|mongo|psql|mysql|rdesktop|xfreerdp|^ssh|steghide|@" @@ -173,6 +175,16 @@ search: remove_path: "mysql/mysql" search_in: - common + + - name: "debian.cnf" + value: + bad_regex: "user.*|password.*" + type: f + only_bad_lines: True + search_in: + - common + + - name: PostgreSQL value: @@ -239,7 +251,7 @@ search: search_in: - common - - name: "000-default" + - name: "000-default.conf" value: bad_regex: "AuthType|AuthName|AuthUserFile|ServerName|ServerAlias" type: f @@ -438,7 +450,7 @@ search: search_in: - common - - name: Anaconda ks + - name: Anaconda ks value: config: auto_check: True @@ -516,7 +528,7 @@ search: search_in: - common - - name: Open VPN + - name: OpenVPN value: config: auto_check: True @@ -942,7 +954,7 @@ search: search_in: - common - - name: GMV_Auth + - name: GMV Auth value: config: auto_check: True @@ -1708,6 +1720,41 @@ search: search_in: - common + - name: Cacti + value: + config: + auto_check: True + + files: + - name: "cacti" + value: + files: + - name: "config.php" + value: + bad_regex: "database_pw.*|database_user.*|database_pass.*" + line_grep: '"database_pw|database_user|database_pass|database_type|database_default|detabase_hostname|database_port|database_ssl"' + + - name: "config.php.dist" + value: + bad_regex: "database_pw.*|database_user.*|database_pass.*" + line_grep: '"database_pw|database_user|database_pass|database_type|database_default|detabase_hostname|database_port|database_ssl"' + + - name: "installer.php" + value: + bad_regex: "database_pw.*|database_user.*|database_pass.*" + line_grep: '"database_pw|database_user|database_pass|database_type|database_default|detabase_hostname|database_port|database_ssl"' + + - name: "check_all_pages" + value: + bad_regex: "database_pw.*|database_user.*|database_pass.*" + line_grep: '"database_pw|database_user|database_pass|database_type|database_default|detabase_hostname|database_port|database_ssl"' + + + type: d + search_in: + - common + + - name: Interesting logs value: config: @@ -2020,13 +2067,6 @@ search: search_in: - common - - name: "security" - value: - just_list_file: True - type: f - search_in: - - common - - name: "security.sav" value: just_list_file: True @@ -2041,13 +2081,6 @@ search: search_in: - common - - name: "services.xml" - value: - just_list_file: True - type: f - search_in: - - common - - name: "setupinfo" value: just_list_file: True @@ -2174,6 +2207,28 @@ search: search_in: - common + - name: Other Windows Files + value: + config: + auto_check: True + disable: + - linpeas + + files: + - name: "security" + value: + just_list_file: True + type: f + search_in: + - common + + - name: "services.xml" + value: + just_list_file: True + type: f + search_in: + - common + # Final section - name: Database value: diff --git a/linPEAS/builder/linpeas_base.sh b/linPEAS/builder/linpeas_base.sh index 2c04c4a..6d4e469 100755 --- a/linPEAS/builder/linpeas_base.sh +++ b/linPEAS/builder/linpeas_base.sh @@ -1,6 +1,6 @@ #!/bin/sh -VERSION="v3.2.6" +VERSION="ng" ADVISORY="This script should be used for authorized penetration testing and/or educational purposes only. Any misuse of this software will not be the responsibility of the author or of any other collaborator. Use it at your own networks and/or with the network owner's permission." ########################################### @@ -211,7 +211,7 @@ print_banner(){ echo "" if [ !"$QUIET" ]; then print_banner; fi -printf ${BLUE}" $SCRIPTNAME $VERSION ${YELLOW}by carlospolop\n"$NC; +printf ${BLUE}" $SCRIPTNAME-$VERSION ${YELLOW}by carlospolop\n"$NC; echo "" printf ${YELLOW}"ADVISORY: "${BLUE}"$ADVISORY\n"$NC echo "" @@ -400,7 +400,7 @@ fi Groups="ImPoSSssSiBlEee"`groups "$USER" 2>/dev/null | cut -d ":" -f 2 | tr ' ' '|'` #This variables are dived in several different ones because NetBSD required it -pwd_inside_history="7z|unzip|useradd|linenum|linpeas|mkpasswd|htpasswd|openssl|PASSW|passw|shadow|root|sudo|^su|pkexec|^ftp|mongo|psql|mysql|rdesktop|xfreerdp|^ssh|steghide|@" +peass{VARIABLES} pwd_in_variables1="Dgpg.passphrase|Dsonar.login|Dsonar.projectKey|GITHUB_TOKEN|HB_CODESIGN_GPG_PASS|HB_CODESIGN_KEY_PASS|PUSHOVER_TOKEN|PUSHOVER_USER|VIRUSTOTAL_APIKEY|ACCESSKEY|ACCESSKEYID|ACCESS_KEY|ACCESS_KEY_ID|ACCESS_KEY_SECRET|ACCESS_SECRET|ACCESS_TOKEN|ACCOUNT_SID|ADMIN_EMAIL|ADZERK_API_KEY|ALGOLIA_ADMIN_KEY_1|ALGOLIA_ADMIN_KEY_2|ALGOLIA_ADMIN_KEY_MCM|ALGOLIA_API_KEY|ALGOLIA_API_KEY_MCM|ALGOLIA_API_KEY_SEARCH|ALGOLIA_APPLICATION_ID|ALGOLIA_APPLICATION_ID_1|ALGOLIA_APPLICATION_ID_2|ALGOLIA_APPLICATION_ID_MCM|ALGOLIA_APP_ID|ALGOLIA_APP_ID_MCM|ALGOLIA_SEARCH_API_KEY|ALGOLIA_SEARCH_KEY|ALGOLIA_SEARCH_KEY_1|ALIAS_NAME|ALIAS_PASS|ALICLOUD_ACCESS_KEY|ALICLOUD_SECRET_KEY|amazon_bucket_name|AMAZON_SECRET_ACCESS_KEY|ANDROID_DOCS_DEPLOY_TOKEN|android_sdk_license|android_sdk_preview_license|aos_key|aos_sec|APIARY_API_KEY|APIGW_ACCESS_TOKEN|API_KEY|API_KEY_MCM|API_KEY_SECRET|API_KEY_SID|API_SECRET|appClientSecret|APP_BUCKET_PERM|APP_NAME|APP_REPORT_TOKEN_KEY|APP_TOKEN|ARGOS_TOKEN|ARTIFACTORY_KEY|ARTIFACTS_AWS_ACCESS_KEY_ID|ARTIFACTS_AWS_SECRET_ACCESS_KEY|ARTIFACTS_BUCKET|ARTIFACTS_KEY|ARTIFACTS_SECRET|ASSISTANT_IAM_APIKEY|AURORA_STRING_URL|AUTH0_API_CLIENTID|AUTH0_API_CLIENTSECRET|AUTH0_AUDIENCE|AUTH0_CALLBACK_URL|AUTH0_CLIENT_ID" pwd_in_variables2="AUTH0_CLIENT_SECRET|AUTH0_CONNECTION|AUTH0_DOMAIN|AUTHOR_EMAIL_ADDR|AUTHOR_NPM_API_KEY|AUTH_TOKEN|AWS-ACCT-ID|AWS-KEY|AWS-SECRETS|AWS.config.accessKeyId|AWS.config.secretAccessKey|AWSACCESSKEYID|AWSCN_ACCESS_KEY_ID|AWSCN_SECRET_ACCESS_KEY|AWSSECRETKEY|AWS_ACCESS|AWS_ACCESS_KEY|AWS_ACCESS_KEY_ID|AWS_CF_DIST_ID|AWS_DEFAULT|AWS_DEFAULT_REGION|AWS_S3_BUCKET|AWS_SECRET|AWS_SECRET_ACCESS_KEY|AWS_SECRET_KEY|AWS_SES_ACCESS_KEY_ID|AWS_SES_SECRET_ACCESS_KEY|B2_ACCT_ID|B2_APP_KEY|B2_BUCKET|baseUrlTravis|bintrayKey|bintrayUser|BINTRAY_APIKEY|BINTRAY_API_KEY|BINTRAY_KEY|BINTRAY_TOKEN|BINTRAY_USER|BLUEMIX_ACCOUNT|BLUEMIX_API_KEY|BLUEMIX_AUTH|BLUEMIX_NAMESPACE|BLUEMIX_ORG|BLUEMIX_ORGANIZATION|BLUEMIX_PASS|BLUEMIX_PASS_PROD|BLUEMIX_SPACE|BLUEMIX_USER|BRACKETS_REPO_OAUTH_TOKEN|BROWSERSTACK_ACCESS_KEY|BROWSERSTACK_PROJECT_NAME|BROWSER_STACK_ACCESS_KEY|BUCKETEER_AWS_ACCESS_KEY_ID|BUCKETEER_AWS_SECRET_ACCESS_KEY|BUCKETEER_BUCKET_NAME|BUILT_BRANCH_DEPLOY_KEY|BUNDLESIZE_GITHUB_TOKEN|CACHE_S3_SECRET_KEY|CACHE_URL|CARGO_TOKEN|CATTLE_ACCESS_KEY|CATTLE_AGENT_INSTANCE_AUTH|CATTLE_SECRET_KEY|CC_TEST_REPORTER_ID|CC_TEST_REPOTER_ID|CENSYS_SECRET|CENSYS_UID|CERTIFICATE_OSX_P12|CF_ORGANIZATION|CF_PROXY_HOST|channelId|CHEVERNY_TOKEN|CHROME_CLIENT_ID" pwd_in_variables3="CHROME_CLIENT_SECRET|CHROME_EXTENSION_ID|CHROME_REFRESH_TOKEN|CI_DEPLOY_USER|CI_NAME|CI_PROJECT_NAMESPACE|CI_PROJECT_URL|CI_REGISTRY_USER|CI_SERVER_NAME|CI_USER_TOKEN|CLAIMR_DATABASE|CLAIMR_DB|CLAIMR_SUPERUSER|CLAIMR_TOKEN|CLIENT_ID|CLIENT_SECRET|CLI_E2E_CMA_TOKEN|CLI_E2E_ORG_ID|CLOUDAMQP_URL|CLOUDANT_APPLIANCE_DATABASE|CLOUDANT_ARCHIVED_DATABASE|CLOUDANT_AUDITED_DATABASE|CLOUDANT_DATABASE|CLOUDANT_ORDER_DATABASE|CLOUDANT_PARSED_DATABASE|CLOUDANT_PROCESSED_DATABASE|CLOUDANT_SERVICE_DATABASE|CLOUDFLARE_API_KEY|CLOUDFLARE_AUTH_EMAIL|CLOUDFLARE_AUTH_KEY|CLOUDFLARE_EMAIL|CLOUDFLARE_ZONE_ID|CLOUDINARY_URL|CLOUDINARY_URL_EU|CLOUDINARY_URL_STAGING|CLOUD_API_KEY|CLUSTER_NAME|CLU_REPO_URL|CLU_SSH_PRIVATE_KEY_BASE64|CN_ACCESS_KEY_ID|CN_SECRET_ACCESS_KEY|COCOAPODS_TRUNK_EMAIL|COCOAPODS_TRUNK_TOKEN|CODACY_PROJECT_TOKEN|CODECLIMATE_REPO_TOKEN|CODECOV_TOKEN|coding_token|CONEKTA_APIKEY|CONFIGURATION_PROFILE_SID|CONFIGURATION_PROFILE_SID_P2P|CONFIGURATION_PROFILE_SID_SFU|CONSUMERKEY|CONSUMER_KEY|CONTENTFUL_ACCESS_TOKEN|CONTENTFUL_CMA_TEST_TOKEN|CONTENTFUL_INTEGRATION_MANAGEMENT_TOKEN|CONTENTFUL_INTEGRATION_SOURCE_SPACE|CONTENTFUL_MANAGEMENT_API_ACCESS_TOKEN|CONTENTFUL_MANAGEMENT_API_ACCESS_TOKEN_NEW|CONTENTFUL_ORGANIZATION" @@ -1942,7 +1942,7 @@ if [ "`echo $CHECKS | grep SofI`" ]; then peass{Htpasswd} - peass{PHPCookies} + peass{PHP Sessions} peass{Wordpress} @@ -1967,13 +1967,13 @@ if [ "`echo $CHECKS | grep SofI`" ]; then fi echo "" - peass{Anaconda-ks} + peass{Anaconda ks} peass{VNC} peass{Ldap} - peass{Open_VPN} + peass{OpenVPN} #-- SI) ssh files print_2title "Searching ssl/ssh files" @@ -1982,7 +1982,7 @@ if [ "`echo $CHECKS | grep SofI`" ]; then hostsdenied="`ls /etc/hosts.denied 2>/dev/null`" hostsallow="`ls /etc/hosts.allow 2>/dev/null`" - peass{SSH_FILES} + peass{SSH} grep "PermitRootLogin \|ChallengeResponseAuthentication \|PasswordAuthentication \|UsePAM \|Port\|PermitEmptyPasswords\|PubkeyAuthentication\|ListenAddress\|ForwardAgent\|AllowAgentForwarding\|AuthorizedKeysFiles" /etc/ssh/sshd_config 2>/dev/null | grep -v "#" | sed -${E} "s,PermitRootLogin.*es|PermitEmptyPasswords.*es|ChallengeResponseAuthentication.*es|FordwardAgent.*es,${SED_RED}," @@ -2192,9 +2192,9 @@ if [ "`echo $CHECKS | grep SofI`" ]; then peass{Neo4j} - peass{Cloud_credentials} + peass{Cloud Credentials} - peass{Cloud-Init} + peass{Cloud Init} peass{CloudFlare} @@ -2210,7 +2210,7 @@ if [ "`echo $CHECKS | grep SofI`" ]; then peass{Filezilla} - peass{Backup_Manager} + peass{Backup Manager} ##-- SI) passwd files (splunk) print_2title "Searching uncommon passwd files (splunk)" @@ -2348,11 +2348,11 @@ if [ "`echo $CHECKS | grep SofI`" ]; then peass{EXTRA_SECTIONS} - peass{Interesting_logs} + peass{Interesting logs} - peass{Windows_Files} + peass{Windows Files} - peass{Other_Interesting_Files} + peass{Other Interesting Files} echo "" @@ -2445,7 +2445,7 @@ if [ "`echo $CHECKS | grep IntFiles`" ]; then true #Don't do nothing elif ! [ "$IAMROOT" ] && [ -O "$sname" ]; then echo "You own the SGID file: $sname" | sed -${E} "s,.*,${SED_RED}," - elif ! [ "$IAMROOT" ] &6 [ -w "$sname" ]; then #If write permision, win found (no check exploits) + elif ! [ "$IAMROOT" ] && [ -w "$sname" ]; then #If write permision, win found (no check exploits) echo "You can write SGID file: $sname" | sed -${E} "s,.*,${SED_RED_YELLOW}," else c="a" @@ -2677,7 +2677,7 @@ if [ "`echo $CHECKS | grep IntFiles`" ]; then lastWlogFolder="ImPOsSiBleeElastWlogFolder" logfind=`find / -type f -name "*.log" -o -name "*.log.*" 2>/dev/null | awk -F/ '{line_init=$0; if (!cont){ cont=0 }; $NF=""; act=$0; if (act == pre){(cont += 1)} else {cont=0}; if (cont < 3){ print line_init; }; if (cont == "3"){print "#)You_can_write_more_log_files_inside_last_directory"}; pre=act}' | head -n 100` printf "%s\n" "$logfind" | while read log; do - if ! [ "$IAMROOT" ] && [ -w "$log" ] || ! [ "$IAMROOT" ] && [ `echo "$log" | grep -E "$Wfolders"` ]; then #Only print info if something interesting found + if ! [ "$IAMROOT" ] && [ "$log" ] && [ -w "$log" ] || ! [ "$IAMROOT" ] && [ "`echo \"$log\" | grep -E \"$Wfolders\"`" ]; then #Only print info if something interesting found if [ "`echo \"$log\" | grep \"You_can_write_more_log_files_inside_last_directory\"`" ]; then printf $ITALIC"$log\n"$NC; elif ! [ "$IAMROOT" ] && [ -w "$log" ] && [ "`command -v logrotate 2>/dev/null`" ] && [ "`logrotate --version 2>&1 | grep -E ' 1| 2| 3.1'`" ]; then printf "Writable:$RED $log\n"$NC; #Check vuln version of logrotate is used and print red in that case elif ! [ "$IAMROOT" ] && [ -w "$log" ]; then echo "Writable: $log"; diff --git a/linPEAS/builder/src/fileRecord.py b/linPEAS/builder/src/fileRecord.py index 79b24ec..740c978 100644 --- a/linPEAS/builder/src/fileRecord.py +++ b/linPEAS/builder/src/fileRecord.py @@ -20,7 +20,7 @@ class FileRecord: self.regex = regex self.bad_regex = bad_regex self.check_extra_path = check_extra_path - self.files = [FileRecord(regex=regex,**fr) for regex,fr in files.items()] + self.files = [FileRecord(regex=fr["name"],**fr["value"]) for fr in files] self.good_regex = good_regex self.just_list_file = just_list_file self.line_grep = line_grep diff --git a/linPEAS/builder/src/linpeasBuilder.py b/linPEAS/builder/src/linpeasBuilder.py index 5c29afd..6d51952 100644 --- a/linPEAS/builder/src/linpeasBuilder.py +++ b/linPEAS/builder/src/linpeasBuilder.py @@ -15,7 +15,9 @@ from .yamlGlobals import ( FIND_LINE_MARKUP, STORAGE_LINE_MARKUP, STORAGE_LINE_EXTRA_MARKUP, - EXTRASECTIONS_MARKUP + EXTRASECTIONS_MARKUP, + PEAS_VARIABLES_MARKUP, + YAML_VARIABLES ) @@ -30,6 +32,9 @@ class LinpeasBuilder: self.linpeas_sh = file.read() def build(self): + variables = self.__generate_variables() + self.__replace_mark(PEAS_VARIABLES_MARKUP, variables, "") + find_calls = self.__generate_finds() self.__replace_mark(PEAS_FINDS_MARKUP, find_calls, " ") @@ -68,6 +73,15 @@ class LinpeasBuilder: def __get_peass_marks(self): return re.findall(r'peass\{[\w\-\._ ]*\}', self.linpeas_sh) + + def __generate_variables(self): + """Generate the variables from the yaml to set into linpeas bash script""" + variables_bash = "" + for var in YAML_VARIABLES: + variables_bash += f"{var['name']}=\"{var['value']}\"\n" + + return variables_bash + def __get_files_to_search(self): """Given a PEASLoaded and find the files that need to be searched on each root folder""" @@ -158,7 +172,7 @@ class LinpeasBuilder: for precord in self.ploaded.peasrecords: if precord.auto_check: - section = f' print_2title "Analizing {precord.name.replace("_"," ")} Files (limit 70)"\n' + section = f' print_2title "Analyzing {precord.name.replace("_"," ")} Files (limit 70)"\n' for exec_line in precord.exec: if exec_line: diff --git a/linPEAS/builder/src/peasLoaded.py b/linPEAS/builder/src/peasLoaded.py index 1eedd93..4ad3c26 100644 --- a/linPEAS/builder/src/peasLoaded.py +++ b/linPEAS/builder/src/peasLoaded.py @@ -6,21 +6,26 @@ class PEASLoaded: def __init__(self): to_search = YAML_LOADED["search"] self.peasrecords = [] - for name,peasrecord_json in to_search.items(): + for record in to_search: + record_value = record["value"] + if "linpeas" in str(record_value["config"].get("disable","")).lower(): + continue + filerecords = [] - for regex,fr in peasrecord_json["files"].items(): + for filerecord in record_value["files"]: filerecords.append( FileRecord( - regex=regex, - **fr + regex=filerecord["name"], + **filerecord["value"] ) ) - + + name = record["name"] self.peasrecords.append( PEASRecord( name=name, - auto_check=peasrecord_json["config"]["auto_check"], - exec=peasrecord_json["config"].get("exec", DEFAULTS["exec"]), + auto_check=record_value["config"]["auto_check"], + exec=record_value["config"].get("exec", DEFAULTS["exec"]), filerecords=filerecords ) ) \ No newline at end of file diff --git a/linPEAS/builder/src/yamlGlobals.py b/linPEAS/builder/src/yamlGlobals.py index 5485c3f..c778345 100644 --- a/linPEAS/builder/src/yamlGlobals.py +++ b/linPEAS/builder/src/yamlGlobals.py @@ -27,6 +27,9 @@ STORAGE_LINE_MARKUP = YAML_LOADED["storage_line_markup"] STORAGE_LINE_EXTRA_MARKUP = YAML_LOADED["storage_line_extra_markup"] STORAGE_TEMPLATE = YAML_LOADED["storage_template"] +PEAS_VARIABLES_MARKUP = YAML_LOADED["variables_markup"] +YAML_VARIABLES = YAML_LOADED["variables"] + INT_HIDDEN_FILES_MARKUP = YAML_LOADED["int_hidden_files_markup"] EXTRASECTIONS_MARKUP = YAML_LOADED["peas_extrasections_markup"]