
1. 從一次真實的內部安全演練說起上個月我們團隊進行了一次內部紅藍對抗演練。我作為藍隊成員負責防守幾臺關鍵的Linux應用服務器。演練開始沒多久監控告警就響了——有一臺測試機的SSH登錄日志出現了異常。我立刻登錄上去排查在/var/log/auth.log里看到了大量來自內網未知IP的失敗嘗試。這顯然是紅隊在嘗試橫向移動。我當時的第一個念頭不是去封IP而是立刻檢查這臺服務器上有沒有“遺留”的敏感文件。因為經驗告訴我攻擊者一旦通過某種方式比如利用一個脆弱的Web應用拿到了一個低權限的shell他們的首要目標絕不是立刻提權而是翻箱倒柜尋找能讓他們通往其他系統的“鑰匙”——也就是各種配置文件、腳本、備份文件里明文存儲的賬號密碼。果然我在一個用于部署的deploy.sh腳本里發現了硬編碼的數據庫密碼在一個~/.bash_history文件里看到了帶-p參數的mysql命令記錄甚至在一個臨時日志文件里找到了某次調試時打印出的完整連接字符串。如果紅隊成員先我一步找到這些他們就能輕松登錄數據庫竊取數據甚至以此為跳板攻擊網絡中的其他機器。這次經歷再次印證了一個老生常談卻又極易忽視的真理在Linux系統上敏感信息的泄露往往不是由于高深的技術漏洞而是源于運維中的不良習慣和疏忽。無論是內網滲透測試中的攻擊方還是日常運維中的防守方掌握一套系統性的敏感文件查找方法都至關重要。對于安全研究人員和運維工程師而言在Linux環境下定位潛在的賬號密碼泄露點是一項基礎且核心的技能。這不僅僅是“找密碼”更是理解應用程序行為、梳理配置脈絡、進行安全審計的過程。本文將從實戰角度出發拋開那些華而不實的自動化工具依賴深入講解如何基于Linux系統本身的特點用手工結合命令的方式高效、精準地完成這項任務。我們會從常見存儲位置、針對性搜索命令、歷史痕跡分析、到內存與進程中的密碼抓取形成一個完整的排查鏈路。無論你是想加固自己的服務器還是在授權范圍內進行安全評估這些方法都能提供直接的幫助。2. 理解敏感信息的常見藏身之處在開始“翻找”之前我們必須先知道去哪里找。Linux系統中的密碼和密鑰并不會像Windows的LSA Secrets那樣有一個統一的保險庫。它們往往分散在以下幾個地方其存在通常都有合理的業務原因但也因此成為安全隱患。2.1 配置文件密碼的重災區這是最直接、最普遍的存儲位置。許多應用程序為了自動化運行會將連接憑證寫入配置文件。用戶級配置在用戶家目錄下以點號.開頭的隱藏文件是首要目標。例如~/.ssh/包含id_rsa私鑰、known_hosts曾連接過的主機密鑰有時甚至會有config文件里明文寫有連接密碼雖然不推薦。~/.aws/credentials和config文件可能包含AWS的訪問密鑰和密鑰。~/.docker/config.json可能包含容器倉庫的登錄憑證。~/.git-credentialsGit的憑據緩存文件。~/.bashrc,~/.bash_profile,~/.zshrc等這些shell初始化文件里有時會為了方便而直接導出環境變量如export DB_PASSWORD123456這是極其危險的做法。~/.mysql_history,~/.psql_history等數據庫客戶端的命令歷史如果執行過帶密碼的連接命令就會被記錄在此。系統級與應用級配置位于/etc目錄下或應用安裝目錄中。/etc目錄這是核心區域。像/etc/passwd和/etc/shadow需root權限存儲著系統用戶哈希但我們的目標更多是應用配置。例如/etc/mysql/my.cnf或/etc/mysql/debian.cnf中可能有數據庫密碼舊的FTP服務器配置/etc/vsftpd.confWeb應用的配置文件如/etc/apache2/sites-available/下的某些conf文件可能包含數據庫連接信息。應用目錄例如一個Web應用根目錄下的config.php、application.yml、.env文件。特別是.env文件在框架如Laravel、Django中常用它本意是隔離環境變量但若權限設置不當或誤提交到代碼庫就會導致密碼泄露。查找命令如find /var/www -name *.env -o -name *config*.php -o -name application*.yml 2/dev/null。注意直接搜索/etc下的所有文件包含“password”字符串可能會返回大量結果其中很多是注釋或示例。更有效的方法是結合對服務如mysql,postgresql,redis的了解定位其標準配置文件路徑。2.2 腳本文件自動化背后的隱患Shell腳本、Python腳本、SQL腳本等是自動化運維的利器也常常是密碼的“陳列館”。為了在腳本中直接連接數據庫、調用API或遠程執行命令開發者常常圖省事將密碼以明文形式寫在腳本里。部署腳本(deploy.sh,update.sh)可能包含SCP、SSH、Ansible或數據庫的明文密碼。備份腳本(backup.sh)為了自動備份數據庫到遠程常出現mysqldump -u root -ppassword這樣的命令。定時任務腳本(cron job)在/etc/cron.*/目錄下或用戶crontab -l列出的任務中調用的腳本需要仔細檢查。查找技巧使用grep時不要只搜索password還要搜索pwd、pass、secret、key、token等常見變量名并且使用-r進行遞歸-i進行忽略大小寫。例如grep -r -i pass\|pwd\|secret /opt/scripts/ 2/dev/null。2.3 日志文件被遺忘的泄露現場日志的本意是記錄但常常記錄了不該記錄的東西。應用程序在調試或報錯時可能會將完整的連接字符串、請求參數包括密碼打印到日志中。Web服務器日志/var/log/apache2/access.log或/var/log/nginx/access.log中如果采用GET方式傳遞密碼極其錯誤會在URL中明文顯示。錯誤日志(error.log)中也可能包含配置信息或堆棧跟蹤里的敏感數據。應用日志在/var/log/下或應用自定義目錄中如/var/log/tomcat/、/home/app/logs/。查找最近修改過的、較大的日志文件。命令歷史之前提到的.bash_history是最典型的例子。但要注意如果用戶設置了HISTCONTROLignorespace并在命令前加空格該命令就不會被記錄。此外還可以檢查~/.sh_history,~/.zsh_history等。2.4 內存與進程運行時密碼的提取這是進階技術通常需要root權限。有些密碼永遠不會落盤只存在于進程的內存空間里。例如一個啟動了的MySQL服務進程其內存中必然持有連接數據庫的密碼或哈希一個通過ssh-agent緩存的私鑰密碼也存在于內存中。進程命令行參數使用ps auxfww或ps -ef命令查看進程啟動時的完整命令行。有時密碼會通過-p參數直接傳遞。例如一個過時的mysqld啟動命令/usr/sbin/mysqld --usermysql --passwordMySuperSecretPass。進程內存轉儲使用gdbGNU調試器或/proc/$PID/mem接口可以附加到進程并嘗試從其內存空間中搜索字符串。這是一個更復雜、對系統有侵入性的操作必須在授權范圍內謹慎進行。一個相對簡單的命令是使用strings工具處理進程的內存映射strings /proc/$PID/mem | grep -i pass。但更常見和專業的做法是使用像gcore生成核心轉儲文件然后用strings分析。3. 手工排查構建你的搜索命令組合拳了解了目標在哪下一步就是組織有效的搜索。完全依賴單一自動化腳本可能會遺漏上下文或產生大量誤報。手工排查的核心思路是由面到點層層遞進。3.1 初始偵察快速定位可疑文件首先獲得一個shell后無論什么權限先對環境有個整體了解。當前用戶與權限idwhoamisudo -l查看當前用戶能以root身份運行哪些命令這本身可能就是個突破口。系統信息uname -acat /etc/*-release了解系統版本。運行的服務netstat -tulpn或ss -tulpn查看開放端口和對應進程這能告訴你系統上跑了什么服務MySQL? Redis? PostgreSQL?從而明確重點搜索方向。查找有特殊權限或最近修改的文件find / -perm -4000 -type f 2/dev/null查找SUID文件提權可能。find / -perm -2000 -type f 2/dev/null查找SGID文件。find / -type f -mtime -7 2/dev/null查找最近7天內修改過的文件。攻擊者上傳的工具或修改的配置可能在其中。find / -type f -name “*.bak” -o -name “*.old” -o -name “*.temp” 2/dev/null。備份文件、舊配置文件往往包含原始的、未加密的密碼。3.2 核心搜索基于內容的精準挖掘這是最關鍵的步驟。我們將使用find、grep、awk等命令的組合。基礎關鍵字搜索從根目錄開始搜索包含常見密碼關鍵詞的文件。注意這會比較慢且可能觸發大量權限錯誤所以我們將錯誤輸出重定向到/dev/null。# 搜索包含password, pass, pwd等關鍵詞的文件并顯示匹配行的前后幾行內容 grep -r -n -i -B2 -A2 passw\|pwd\|secret\|key\|token /etc /home /opt /var 2/dev/null | head -100-B2 -A2參數可以顯示匹配行前后各2行的內容這對于理解密碼的上下文比如是哪個變量、在哪個配置文件里非常有幫助。針對特定格式的搜索密碼有時會以特定格式出現。連接字符串搜索mysql://postgresql://jdbc:://user:pass。grep -r ://[^:]*:[^]* /home /opt 2/dev/nullBase64編碼看起來像亂碼的長字符串可能是編碼后的密碼。可以搜索結尾的字符串或者用grep -E匹配Base64字符集。grep -r -E ([A-Za-z0-9/]{4})*([A-Za-z0-9/]{3}|[A-Za-z0-9/]{2})? /path/to/search 2/dev/null | head -20JSON或YAML格式搜索password:password:。grep -r -i \password\\s*: /path/to/search 2/dev/null檢查歷史與內存命令歷史立即查看當前shell的歷史以及所有可讀用戶的.bash_history。history # 當前shell歷史 cat ~/.bash_history for user in $(ls /home); do echo History for $user ; cat /home/$user/.bash_history 2/dev/null | tail -50; done進程信息ps auxfww | grep -E “(mysql|redis|postgres|ssh)” # 查看相關進程的命令行 # 如果有root權限可以嘗試從進程內存中搜索字符串 # 例如找到MySQL的PID PID$(pgrep mysqld) if [ ! -z $PID ]; then strings /proc/$PID/environ | grep -i pass fi3.3 權限提升與深度搜索如果當前用戶權限較低很多文件無法讀取。那么搜索的第一步可能變成了權限提升。利用找到的數據庫密碼嘗試登錄數據庫也許能在數據庫里找到其他系統的密碼例如某些應用將配置存在數據庫里。或者利用找到的SSH私鑰嘗試連接其他服務器。這就是所謂的“橫向移動”。在獲得更高權限尤其是root后搜索范圍將豁然開朗讀取所有用戶的家目錄grep -r -i “pass” /home/* 2/dev/null。檢查/etc/shadow雖然密碼是哈希值但弱密碼可以通過哈希碰撞或彩虹表破解。可以使用unshadow工具結合john或hashcat進行破解測試僅限授權測試。檢查內存中的敏感信息使用/proc文件系統或工具如linpeas、LinEnum這些是自動化腳本但原理是手工命令的集合進行更全面的信息收集。4. 從攻擊者視角看防御如何讓你的密碼“隱身”了解了攻擊者如何尋找密碼我們就能更好地進行防御。這不僅僅是安全人員的職責更是每一位系統管理員和開發者的必修課。4.1 配置管理杜絕明文存儲使用配置管理工具與密鑰庫將密碼、API密鑰等敏感信息從配置文件中徹底移除。使用如HashiCorp Vault、AWS Secrets Manager、Azure Key Vault等密鑰管理服務。在應用啟動時從這些服務動態拉取憑據。環境變量對于簡單場景可以使用環境變量。但要注意環境變量在ps命令中可能被看到通過/proc/$PID/environ且可能在日志中泄露。確保不將敏感信息打印到日志。配置文件權限如果必須使用配置文件將其權限設置為僅所有者可讀chmod 600 config.properties。并確保其所屬用戶和組正確。4.2 開發與運維規范代碼審查將“硬編碼密碼/密鑰”作為代碼審查的高危項。使用預提交鉤子pre-commit hook掃描代碼中是否含有密碼模式。清理歷史記錄定期清理或妥善管理命令歷史。對于包含敏感信息的命令可以在其前面加空格如果HISTCONTROL設置了ignorespace或者直接unset HISTFILE再執行命令但更好的做法是根本不在命令行中直接輸入密碼。最小權限原則運行服務的賬戶如mysqlwww-data不應該有讀取其他用戶家目錄或無關配置文件的權限。通過嚴格的用戶和文件權限控制即使某個服務被攻破也能將影響范圍限制在最小。4.3 日志與監控日志脫敏確保應用程序和中間件的日志配置中啟用了脫敏功能避免將密碼、令牌、身份證號等敏感信息寫入日志。文件完整性監控使用工具如AIDE、Tripwire或Osquery監控關鍵配置文件如/etc/passwd/etc/shadow Web應用配置文件的變更并在發生未授權修改時告警。進程監控監控異常進程的創建特別是那些嘗試讀取/etc/shadow或大量掃描文件系統的進程。5. 實戰案例一次完整的內部排查模擬假設我們作為內部安全員接到通知某臺Web服務器(192.168.1.10)可能因一個過時的Web框架版本存在漏洞而被初步入侵。我們需要登錄該服務器檢查是否存在敏感信息泄露并評估風險。步驟1初始連接與環境評估通過SSH使用已有賬號登錄。首先檢查當前權限(id)發現是普通用戶webadmin。運行sudo -l發現該用戶被允許以root身份運行/usr/bin/systemctl restart apache2這是一個有價值的點但暫時用不上。先看看系統跑著什么ss -tulpn顯示有80Apache、3306MySQL、22SSH端口開放。步驟2針對性搜索Web相關配置既然有Apache和MySQL重點搜索相關配置和代碼。# 查找網站根目錄通常Apache默認在/var/www/html find /var/www -type f -name “*.php” -o -name “*.env” -o -name “config*.php” -o -name “*.yml” -o -name “*.yaml” 2/dev/null | head -20發現路徑/var/www/html/wordpress/wp-config.php。這是WordPress的配置文件經典的存在數據庫密碼的地方。cat /var/www/html/wordpress/wp-config.php | grep -A2 -B2 “DB_PASSWORD”果然找到了define(DB_PASSWORD, Wpss123456);。步驟3利用找到的密碼進行橫向試探嘗試用這個密碼連接本機的MySQL。mysql -u wordpressuser -pWpss123456 -h 127.0.0.1成功登錄。在MySQL中可以查看是否有其他數據庫或表存儲了更多信息。執行show databases;發現除了wordpress庫還有一個app_config庫。進入該庫發現一張表service_credentials里面竟然明文存儲了訪問內網另一臺Redis緩存服務器(192.168.1.20)和一臺文件服務器(192.168.1.30)的密碼。步驟4擴大搜索范圍退出MySQL。現在有了新的目標。同時繼續在本地搜索。# 檢查webadmin用戶的歷史和文件 cat ~/.bash_history ls -la ~/.ssh/ cat ~/.ssh/config 2/dev/null # 搜索備份腳本 find / -type f -name “*.sh” -exec grep -l “pass\|pwd” {} \; 2/dev/null在/opt/scripts/backup_db.sh中發現使用了mysqldump -u root -pRootDBPass!#的命令。這又是一個高權限的數據庫密碼。步驟5評估與報告至此我們發現了至少三處嚴重的明文密碼泄露WordPress配置文件中的數據庫密碼已導致可訪問app_config庫。app_config庫中存儲的其他內網服務密碼導致內網橫向移動風險劇增。備份腳本中的MySQL root密碼導致數據庫完全失控。根本原因開發人員將生產數據庫密碼硬編碼在配置文件中另一個應用將多個服務的憑證以明文形式存在業務數據庫里運維人員在腳本中直接使用root密碼。防御措施完全缺失。建議立即更改所有涉及的服務密碼。將WordPress的wp-config.php文件權限設置為640所有者設為root組設為Web服務器用戶。廢除備份腳本中的明文密碼改用mysql_config_editor設置登錄路徑或從安全存儲中獲取。徹底改造app_config庫移除明文密碼引入統一的密鑰管理服務。對所有服務器進行一輪類似的敏感信息掃描。通過這個模擬案例你可以看到一次簡單的查找如何像剝洋蔥一樣層層深入地揭示出整個系統中脆弱的安全實踐。它遠不止是執行幾條grep命令而是一個結合了系統知識、應用理解、邏輯推理和持續驗證的過程。無論是攻擊還是防御對這套流程的熟練掌握都價值連城。