文章

nginx-deny绕过

参考链接:

1.nginx deny限制路径绕过 - 先知社区 (aliyun.com)

2.(Research) Exploiting HTTP Parsers Inconsistencies (hashnode.dev)

周末打byteCTF的时候遇到一题,访问目标路由后发现回显403,扫描目录也没有扫出什么来,无思路,遂放弃。今天看WP说是解析差异,正好来学学。

NGINX的配置文件

Nginx 是一个高性能的 HTTP 服务器和反向代理服务器,配置文件一般是位于 /etc/nginx/nginx.conf,当然也可以根据用户的环境有所变化

基本的配置文件分为:

全局配置:定义 Nginx 的主进程行为,例如 worker 进程数量、日志配置等。
事件块:定义 Nginx 如何处理连接,比如并发连接数的限制。
http块:配置与 HTTP 服务相关的所有内容,可以包含多个服务器的配置。
sever块:定义一个虚拟主机的配置,通常用于处理特定域名或 IP 的请求。
location块:定义 URL 路径的匹配规则和对应的资源处理方式。

部分指令介绍:

root指令:
在ngnix配置文件中,root指令用于指定网站的根目录。可以分为全局根目录和局部根目录

server {
    listen 80;
    server_name example.com;

    # 全局根目录
    root /var/www/html;

    location / {
        # 继续使用全局根目录
        index index.html;
    }

    location /static/ {
        # 为 /static/ 指定不同的根目录
        root /var/www/static;
        # 访问 http://example.com/static/file.js 将查找 /var/www/static/static/file.js
    }
}

在这个例子中:
访问 http://example.com/ 时,Nginx 会从 /var/www/html/index.html 加载首页。
访问 http://example.com/static/file.js 时,Nginx 会从 /var/www/static/static/file.js 加载文件。注意这里 root 的行为是拼接路径,因此 /static/ 会被保留并与指定的 root 路径结合。
alias: 
用于将匹配的请求路径替换为服务器上的指定目录,而不是像 root 指令那样将请求路径与指定目录拼接。

server {
    listen 80;
    server_name example.com;

    location /images/ {
        alias /data/pictures/;
    }
}

当用户访问 http://example.com/images/cat.png 时,Nginx 会将 /images/ 替换为 /data/pictures/。
最终,Nginx 会去服务器上的 /data/pictures/cat.png 文件路径查找并返回给客户端。

deny all

deny all; 指令用于禁止对特定路径的所有访问。它意味着 Nginx 会拒绝任何用户对匹配该 location 的 URL 进行访问,不论用户来自哪个 IP 地址或是使用哪种方式访问。返回一个 403 Forbidden 状态码,表示访问被禁止。

location = /admin {
    deny all;
}

路径规范化

Nginx的路径规范化指的是在处理请求的URL之前,将请求的URL转换和标准化为一致且规范的格式的过程。涉及到从URL路径中删除冗余或者不必要的元素,例如额外的斜杠、点段、处理路径遍历和 URL 编码字符等

不同的语言都有类似于trim的函数,用于删除字符串两端的空白字符(例如空格、制表符、换行符等)。同时不同的语言删除的东西不经相同,ngnix使用C语言编写的,并不能覆盖所有的字符串。如果使用不同语言的函数解析 HTTP 消息,则可能会发生 HTTP Desync 攻击

利用Node.js绕过ACL

配置如下:

location = /admin {
    deny all;
}

location = /admin/ {
    deny all;
}

app.get('/admin', (req, res) => {
    return res.send('ADMIN');
});

16进制输入a0,即可以绕过deny检测

  • 首先,Nginx 收到 HTTP 请求,对路径名进行路径归一化;

  • 由于 Nginx 将字符作为路径名的一部分,因此不会触发 URI 的 ACL 规则。因此,Nginx 会将 HTTP 消息转发到后端;

  • 当 Node.js 服务器收到 URI 时,将删除该字符,从而成功检索端点。

演示视频: 点击这里

Nginx 版本

Node.js Bypass Characters

1.22.0

\xA0

1.21.6

\xA0

1.20.2

\xA0, ,\x09\x0C

1.18.0

\xA0, ,\x09\x0C

1.16.1

\xA0, ,\x09\x0C

利用Flask绕过

Nginx 版本

Flask Bypass 角色

1.22.0

\x85,\xA0

1.21.6

\x85,\xA0

1.20.2

\x85, , , , , , ,\xA0\x1F\x1E\x1D\x1C\x0C\x0B

1.18.0

\x85, , , , , , ,\xA0\x1F\x1E\x1D\x1C\x0C\x0B

1.16.1

\x85, , , , , , ,\xA0\x1F\x1E\x1D\x1C\x0C\x0B

利用spring boot来绕过

Nginx 版本

Spring Boot 旁路字符

1.22.0

;

1.21.6

;

1.20.2

\x09,;

1.18.0

\x09,;

1.16.1

\x09,;

其他利用姿势详见参考文章2

防御

将loaction的规则改为:

location ~* ^/admin {
    deny all;
}
采用正则表达式,~*代表不区分大小写,^/admin表示匹配所有/admin开头的字符串
不过坏处就是/AdminPanel, /ADMIN/login这些URL都会匹配到这个规则。

License:  CC BY 4.0