您现在的位置是:烟消火灭网 > 探索

有sql注入漏洞的网站

烟消火灭网2026-10-17 07:41:30【探索】3人已围观

简介去年秋天,我在一个本地论坛上闲逛,想找点二手相机镜头的信息。点进一个帖子,页面加载完,地址栏里赫然挂着个 id=128。职业习惯,我顺手在末尾加了个单引号,回车。屏幕上直接弹出一段 SQL 报错,连数

去年秋天,注入站我在一个本地论坛上闲逛,漏洞想找点二手相机镜头的注入站信息。点进一个帖子,漏洞页面加载完,注入站地址栏里赫然挂着个 id=128。漏洞职业习惯,注入站我顺手在末尾加了个单引号,漏洞回车。注入站屏幕上直接弹出一段 SQL 报错,漏洞连数据库表名都露出来了——wp_posts。注入站那一刻我就知道,漏洞这站点基本等于没穿衣服站在大街上。注入站

SQL 注入这东西,漏洞说穿了就是注入站网站太信任用户输入。开发者写代码时假设所有人都会老老实实填表单,结果有人往输入框里塞一段 SQL 语句,数据库就当真执行了。上面那个论坛,它把 URL 里的 id 参数直接拼进查询语句,连过滤都没做。我试了 id=128 and 1=1 页面正常,换成 and 1=2 就空了。布尔盲注,教科书级别的漏洞。

但真正让我停下来的是后面的事。我用 order by 一路试到第 12 列,确认字段数,然后 union select 把数据库版本、当前用户、库名全捞了出来。MySQL 5.7,用户是 root@localhost。权限高得离谱。再往下,information_schema 里翻出所有表名,用户表里躺着三千多条记录,密码字段是 MD5 哈希。我没继续,关掉页面,给论坛管理员发了封邮件。三天后漏洞修了,他没回我邮件。

这种事太常见了。很多中小型网站,尤其是外包做的或者用老 CMS 搭的,SQL 注入几乎是标配。原因不复杂:开发者觉得“没人会盯着我的站”,或者根本不知道预处理语句(Prepared Statement)能解决大部分问题。PHP 里 PDO 和 mysqli 都支持参数化查询,把用户输入当参数传,而不是拼进 SQL 字符串。可现实是,大量遗留代码还在用 mysql_query("SELECT * FROM users WHERE id=".$_GET['id']) 这种写法。这行代码放在今天,跟把家门钥匙插在锁上没区别。

我见过更离谱的。一个电商站点,搜索框输入 %' union select 1,2,3-- -,直接把所有商品价格显示成 1 块钱。还有一次,某政府服务网站,登录框用户名填 admin'--,密码随便写,直接进了后台。那个 -- 是 SQL 注释符,把后面的密码验证整段注释掉了。开发者大概以为密码检查是铁律,没想到有人能把整条语句拦腰截断。

自动化工具让这事门槛低到离谱。sqlmap 一条命令,剩下的事它全包了。跑个 sqlmap -u "http://target.com/page?id=1" --dbs,有漏洞的话,数据库列表几分钟就出来。脚本小子拿着工具到处扫,跟拿金属探测器在海滩上走一样。被扫到的站,轻则数据泄露,重则整个数据库被拖走。之前有个国内婚恋网站被脱库,几百万用户信息挂在暗网上卖,起因就是一个没过滤的 id 参数。

防御其实不复杂。参数化查询是第一道墙,把 SQL 语句的结构和用户输入的数据彻底分开。PHP 里用 PDO::prepare 加 bindParam,Java 里用 PreparedStatement,Python 里用 cursor.execute 带占位符。其次,数据库账号别用 root,给 Web 应用单独建个账号,只给必要的 SELECT、INSERT 权限。再狠一点,上 WAF,把 union、select、information_schema 这些关键词拦一拦。但说到底,代码层面的修复才是根本。WAF 只是创可贴,伤口还在。

我后来养成了一个习惯,看到 URL 里有数字参数就手痒。加个单引号,看报不报错。报错就说明有戏。这习惯不太礼貌,但能让我快速判断一个站点的安全水平。大部分时候没事,偶尔中奖。中奖那次,我通常只验证漏洞存在,不碰数据,然后想办法通知管理员。有些站有 security.txt,有些得去 WHOIS 里翻邮箱。回复率大概三成。剩下七成,要么没看到,要么不在乎。

写这些不是教人入侵。SQL 注入漏洞存在了二十多年,OWASP Top 10 里年年上榜,可它依然活着。因为写代码的人换了一茬又一茬,老问题跟着新项目走。每当我看到 id=1' 弹出一串数据库错误,就觉得这行代码背后,大概又是一个赶工期的深夜,和一个没来得及学的安全课。

很赞哦!(282)