游客发表
一个不起眼的含漏参数,可能让攻击者直接读取服务器上的含漏任意文件。?含漏page=../../../../etc/passwd,这种看起来像恶作剧的含漏输入,在CTF赛场上往往意味着整台服务器的含漏沦陷。
文件包含漏洞的含漏核心就一句话:开发者把用户输入直接拼进了文件路径。PHP里最常见的含漏include($_GET['page']),本意是含漏加载不同页面模板,结果成了攻击者的含漏后花园。本地文件包含(LFI)能读密码文件,含漏远程文件包含(RFI)更狠——直接执行你服务器上的含漏代码。
我记得某次线下赛,含漏主办方给了个博客系统。含漏所有文章都通过?含漏view=article1.html加载。我试着把参数改成../../../../etc/passwd,含漏页面空白。当时以为没戏,直到同行提醒我试试PHP封装协议。换成php://filter/convert.base64-encode/resource=index.php,源码哗啦啦地吐了出来。那一刻才明白,读文件不是目的,拿到源码才能找到下一个突破口。
CTF里最常见的利用姿势是伪协议。除了filter,data://能直接注入代码——前提是allow_url_include开启。有些题目会故意用include($_GET['file'].'.php')这种写法,看似限制了后缀,实际上用php://input加POST数据,或者用%00截断(仅限PHP 5.3以前),照样能绕过。现在的题目越来越狡猾,有时候需要配合日志注入或者临时文件竞争,把恶意代码写进服务器能读到的位置。
有次遇到个坑,过滤了../和php://。绕了半小时没进展,最后发现服务器跑着Nginx,访问日志路径是/var/log/nginx/access.log。User-Agent里塞了PHP代码,再用LFI包含日志文件,代码就执行了。这种思路比直接读flag有意思得多——你得理解服务器怎么运作,而不是背几个payload。
文件包含漏洞的根源在于信任了不该信任的输入。防御手段其实简单:白名单校验、禁用危险函数、关闭allow_url_include。但现实中总有人图省事,写个动态包含就完事。CTF赛题恰恰利用了这种懒惰,把常见的错误浓缩成一道题,逼着你去思考开发者为什么会写出这样的代码。
打CTF久了你会发现,文件包含往往不是终点。拿到源码后,里头可能藏着数据库密码,可能有不安全的反序列化点,甚至直接有后门。一个看似低危的读取漏洞,配合其他弱点就能串成完整的攻击链。这大概就是CTF最迷人的地方——每个漏洞都不是孤岛,它们像乐高积木,拼对了就能搭出意想不到的结果。
友情链接