最近ssrf神器Gopherus
更新了支援postgres
的攻擊。在ubuntu上搭建了環境試了一下發現效果還不錯。想了一下如果別人也想復現或者我想再次復現類似環境,還要重新搭建一遍。雖然搭建並不複雜,但還是想需要一鍵啓動的環境。於是就想到了docker。之前用過docker的基本命令和別人搭建的基礎映象,但還沒自己編寫過Dockerfile
,定製自己的映象。藉此機會學習一下Dockerfile的基本編寫。
首先新建一個資料夾postgres-ssrf
進入資料夾新建Dockerfile
編輯如下
## Dockerfile
FROM ubuntu # 拉取一個ubuntu基礎映象
ENV DEBIAN_FRONTEND=noninteractive # 不互動模式,防止在apt安裝一些軟體包是發生互動導致構建卡死。
RUN sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list # 更新軟體源增加構建速度
RUN apt-get clean
RUN apt-get update
RUN apt-get install apt-utils -y
RUN apt-get install php apache2 php-curl -y # 安裝php,apache,以及php-curl,這裏php-curl版本要和php版本一致
RUN echo "ServerName localhost:80" >> /etc/apache2/apache2.conf
RUN rm /var/www/html/index.html
ADD start.sh /start.sh
RUN chmod 755 /start.sh
ADD index.php /var/www/html/index.php
EXPOSE 80 # 開放80埠
CMD /start.sh # 映象入口
# start.sh
apachectl -D FOREGROUND
這裏的一個坑點就是CMD之前的使用RUN執行的命令只會在構建時執行,構建完成後就失效了。因此想要執行如
RUN service apache2 start
使得在映象啓動時啓動apache服務是行不通的。docker提供CMD
或ENTRYPOINT
來解決這一問題,使用CMD執行的命令會在容器啓動後自動執行。但apache服務使用CMD執行service apache2 start
還是無法啓動。需要使用
apachectl -D FOREGROUND
參考
How to start apache2 automatically in a ubuntu docker container?
ok,一個Dockerfile的大致結構就是如此。包括使用的基礎映象,容器內執行的命令,以及容器入口點。
更多編寫dockerfile請參考Dockerfile reference。
但我們發現在Dockerfile中我並沒有安裝postgres
服務。這也是我踩的一個大坑。開始時我嘗試在ubuntu內安裝postgres,並且進行設定,唯一重要的設定就是在pg_hba.conf
設定本地無需密碼進行登陸。(因爲Gopherus要求攻擊不能進行互動,至於爲什麼。抓包看一下postgres的認證流程就懂了,包括mysql的ssrf攻擊也是。)設定完成後需要插入一些測試數據。或者說是flag。如下
CREATE DATABASE "Flag";
WITH OWNER = "postgres"
ENCODING = 'UTF8';
\c Flag postgres;
CREATE TABLE flag (
flag text
);
INSERT INTO Flag (flag) values ('flag{abc569d9e7ac742b9bc8a8}');
但在構建的過程中會因爲postgres沒有啓動而無法匯入數據。因此只能想辦法使得在postgres容器啓動後匯入數據,還要先自動啓動postgres…,額有點麻煩。搜尋的過程中發現postgres官方映象在建立容器的時候自動匯入特定目錄的sql語句。那麼可以把web服務和db服務分開,db使用postgres官方映象。現在問題就是如何管理兩個映象。這就要引出docker-compose
。
在與Dockerfile同一目錄新建docker-compose.yml檔案,編輯如下
version: '2'
services:
webapp:
build:
context: .
dockerfile: Dockerfile # 此處會自動構建目錄下的Dockerfile並執行容器
depends_on: # 聲名依賴
- db
ports:
- "80:80" # 開放埠
db:
image: postgres:12 # 指定依賴的基礎映象
volumes: # 將當前的./initdb 對映到容器內/docker-entrypoint-initdb.d,根據文件這裏的sql檔案會被自動執行
- ./initdb/:/docker-entrypoint-initdb.d
environment:
POSTGRES_HOST_AUTH_METHOD: trust # 環境變數可在官方文件查閱,這裏代表無認證登陸
ports:
- "5432:5432"
使用yaml編寫邏輯已經很清晰了。docker-compose使用services來指定管理的多個映象,有依賴的容器docker-compose會構建網路保證容器間通訊。更多請參考Overview of Docker Compose
構建
經典兩條命令
docker-compose build
docker-compose up -d
測試一下