
备考CISP-PTE刷到SQL注入第5讲“万能密码”这个专题时我第一反应是这不就是网上到处传的 or 11--吗实战靶场里真的试了一遍才发现越是最基础的登录框越容易翻车。很多人连payload都没发完整后端就已经把请求拦了更别提把“万能密码”从一句口诀理解成一套可迁移的注入思路。CISP-PTE的实操考试里登录框注入几乎是最常见的SQL注入出题形态而万能密码正是针对这种形态最直接的利用方式。这篇文章我会把原理、构造手法、考试环境实操流程、常见翻车点一次讲透。准备备考PTE的朋友可以照着走一遍刚接触SQL注入的初学者也能顺着逻辑把“登录框为什么能被绕过”这件事彻底搞明白。1. CISP-PTE把万能密码单列一讲的底气分值、考法与常见失分点1.1 为什么SQL注入系列里必须单独给万能密码留一讲CISP-PTE的实操考试由多个安全方向组成Web安全是绝对的重头SQL注入、XSS、文件上传、命令执行这些方向几乎轮换着出。其中SQL注入又是出现频率最高、分值占比最稳定的方向。而整套SQL注入的学习脉络通常是注入基础原理、联合查询注入、报错注入、盲注第五讲落到万能密码。前四讲的核心目标都是“把数据库里的数据掏出来”到了万能密码这一讲目标变了——它不掏数据它直接改认证逻辑。这个“改逻辑”的思路恰好是很多新手从“注入工具使用者”转向“注入思路理解者”的一道坎所以被单独拎出来讲非常合理。1.2 CISP-PTE中万能密码的三种常见考法我在练习和模拟环境里总结下来万能密码在PTE考试中一般以三种面目出现直接登录绕过靶场给出一个登录页面目标是进入后台找到flag文件或者管理入口。此时用户名框存在字符型注入用万能密码直接通过身份验证。带条件的认证绕过页面回显“密码错误”和“用户不存在”两种提示注入时需要结合报错信息判断是否存在用户枚举。比如先用admin闭合字符串制造语法错误再用万能密码做条件恒真绕过。代码审计后的利用考试平台直接给出源码片段要求你找到登录逻辑中的SQL注入点并构造万能密码完成绕过。这种题考的不是无脑打payload而是读代码的能力。这三种考法出现在考题中的频率都不低登录绕过类题目又是典型的“快速拿分或快速失分”项。很多人觉得万能密码简单随手提交admin or 11发现进不去就卡住了。原因多半不是payload不对而是没先搞清楚闭合方式、数据库类型和请求编码这些坑我后面会展开说。1.3 与“极域万能密码”这类系统口令的区别搜索“万能密码”时经常能看到一些电子教室软件、远控软件所谓的“万能密码/系统后门口令”这类属于厂商预设或历史遗留的固定口令跟SQL注入没有任何关系。CISP-PTE考的是“万能密码”则是利用SQL查询逻辑缺陷让认证条件恒真或直接截断后续判断。二者本质完全不同备考时别被关键字混淆。2. 万能密码的原理后端登录SQL到底在拼接什么2.1 一次典型登录验证的完整代码链路先把一条最经典的登录验证逻辑写出来以PHPMySQL为例$username $_POST[username]; $password $_POST[password]; $sql SELECT * FROM users WHERE username {$username} AND password {$password}; $result mysqli_query($conn, $sql); $row mysqli_fetch_array($result); if ($row) { echo 登录成功; } else { echo 用户名或密码错误; }这段代码的问题在于$username和$password被直接拼接进SQL语句。正常情况下用户输入admin和123456后端执行的是SELECT * FROM users WHERE username admin AND password 123456当用户名输入admin or 11 --密码随便填一个x时拼接后的完整SQL变成SELECT * FROM users WHERE username admin or 11 -- AND password x注意看--在MySQL里是注释符会把后面 AND password x这段全部注释掉。真正参与判断的只剩下SELECT * FROM users WHERE username admin or 11usernameadmin是假也没关系因为OR 11恒为真整个WHERE条件的结果就是TRUE查询返回了表中所有用户记录。程序用mysqli_fetch_array取结果集第一行发现存在数据于是判定登录成功。这就是万能密码最核心的机理。2.2 为什么是or而不是and我见过很多初学者把payload改成admin and 11然后一脸困惑地问“为什么不行”。道理其实很简单AND的作用是让多个条件同时成立才能通过11虽然恒真但它和原条件做交集原条件usernameadmin如果本身成立加不加恒真条件结果都一样如果原条件不成立比如用户名枚举不到加了恒真条件也白搭。而OR的本质是给整个认证条件开了一个逻辑后门只要有一个条件为真整体就为真。登录验证本来就是“用户名和密码都对才放行”现在变成了“用户名对或者11就放行”那跟大门敞开没什么区别。2.3 用门禁卡来理解这个逻辑缺陷可以把这个登录校验想象成小区门禁正常逻辑是“刷卡识别成功且业主名单匹配才开门”。万能密码干的事相当于在门禁逻辑里塞进一条“或者今天是星期天”之类的恒真条件让门禁系统无论刷什么卡都判定“条件满足”。你甚至不需要是业主只需要让逻辑判断走到那个恒真分支就行。SQL注入万能密码就是这种“往判断条件里塞后门”的手法。2.4 一个经常会问的问题SQL注入现在还存在吗备考时总有人问“现在还存在SQL注入漏洞吗”。坦率地说大型互联网系统的核心业务线基本都上了参数化查询和预编译直接拼接SQL的情况少了很多。但老系统、边缘业务系统、内部管理系统、部分外包建站项目的登录模块仍然能看到这种经典拼接代码。CISP-PTE考试模拟的就是这些真实存在过的脆弱认证场景万能密码因此一直没有过时它考的是对SQL语句拼接细节的理解深度而不只是背一句话。3. 构造手法与数据库差异MySQL、SQL Server、Oracle的万能密码长不一样3.1 万能密码的四种基础构造思路万能密码不是只有 or 11--这一句。做多了就会发现它背后是四套可复用的构造思路闭合引号注入型先去闭合SQL语句里原本的单引号再用OR引入恒真条件。典型如admin or 11 --、 or 11 or 11。这类payload对单引号闭合位置很敏感多一个少一个都可能导致语法错误。注释截断型利用注释符把密码判断部分直接去掉。典型如admin--、admin#。这类payload相当于告诉数据库“后面不用管了”只要用户名能匹配上任意一条记录就行。恒真恒假组合型在无法使用注释符的场景下用两个恒真条件包围原判断例如 or 11 or 11保证整个WHERE条件不会因为原判断失败而短路。联合查询替代型有些查询把结果集的第一行作为登录凭证此时可用 union select 1, admin, 2020-01-01--之类的手法定制结果集让程序取到我们预设的那一行。3.2 MySQL、SQL Server、Oracle的注释符差异是翻车重灾区同样的payload在MySQL里好用换到SQL Server环境可能直接报错。核心差异就在注释符和字符串处理上。下面这个表是根据我自己的测试经验整理的数据库类型注释符字符串拼接关键特征MySQL--后面必须有空格、#、/* */单引号字符串报错信息含near ... at lineSQL Server--、/* */单引号字符串拼接报错信息含Unclosed quotation markOracle--、/* */单引号字符串||拼接报错信息含ORA-00933等这里特别要记住一个细节MySQL的--注释符后面必须跟一个空格或控制字符否则会被当作普通字符串。所以写admin--在MySQL里不生效要写admin--或者admin--在URL里会被当成空格。而#注释符在URL传输中要编码成%23否则浏览器会把#后面当锚点处理请求根本发不完整。这些细节都是考场和真实靶场里最常见的翻车原因。3.3 ASP/ASPX环境下的万能密码变种搜索“aspx万能密码”的朋友应该是在老ASP/ASPX系统里遇到了登录框。ASP/ASPX配合SQL Server是老组合了经典Payload长这样用户名: or 11-- 密码: 任意字符或者利用SQL Server字符串拼接特性用户名: or 密码: or 11第二条payload的逻辑是让用户名判断成立密码判断11也成立两个条件同时通过。这种写法在老ASPX系统的实际利用中非常常见原理也是围绕“闭合引号恒真条件”这两个核心动作。3.4 如何快速判断目标数据库类型构造万能密码前优先判断数据库类型能少走很多弯路。最直接的思路有三个看URL后缀.php多为MySQL.asp/.aspx多为SQL Server.jsp多搭配Oracle或MySQL。看报错信息输入一个单引号触发表单报错MySQL会回显You have an error in your SQL syntaxSQL Server常见Unclosed quotation mark after the character stringOracle会给出ORA-开头的错误码。看响应头Server: Apache/2.2配X-Powered-By: PHP/5.6基本能指向PHPMySQLMicrosoft-IIS/7.5配X-AspNet-Version基本指向ASPXSQL Server。4. 从注入点探测到登录成功PTE考试环境的完整手工流程4.1 考试环境的真实访问方式CISP-PTE实操考试通常在考试平台内进行登录考试系统后每个题目会分配一个独立的靶机访问地址。考场网络是封闭的浏览器直接打开题目给的URL就能看到目标Web站点所有测试操作都在这个授权的靶机环境内完成。相比互联网渗透测试PTE环境的网络路径更干净——没有CDN、没有云WAF、基本没有复杂的反爬机制干扰项少更多是考查基本功。4.2 第一步确定请求方式、参数名和注入点打开登录页面后不要急着填payload。先用浏览器开发者工具切到Network面板提交一次正常的登录请求随便输个用户名和密码看清楚数据是GET还是POST提交参数名是username/password还是user/pass/email。这一步看似基础实际上决定你后续能不能把payload准确送到后端。比如用GET方式注入时payload里的#符号会被浏览器吃掉必须编码成%23而POST方式则不存在这个干扰用Burp Suite Repeater直接改包更顺手。4.3 第二步用单引号闭合探测SQL语句结构拿到请求包后先做一个最基础的探测在用户名框输入一个单引号密码随便填提交并观察响应。如果页面返回500、数据库语法报错说明单引号被拼进了SQL且破坏了原有语法这里十有八九存在字符型注入。如果页面只是提示“用户名或密码错误”则要再试试用户名框里填admin、admin、admin)这类带闭合符号的输入观察是否触发异常。有一种常见情况是页面毫无波澜——不管怎么输都是“用户名或密码错误”。这往往说明目标可能对单引号做了转义或者SQL语句对输入做了格式化处理后面我会在排错链路里细讲。4.4 第三步手工构造万能密码并绕过登录确认用户名框存在字符型注入后按数据库类型选择对应的万能密码。以PHPMySQL环境为例可以在Burp Suite Repeater里这样构造POST /login.php HTTP/1.1 Host: target usernameadmin or 11 -- passwordx如果页面能正常跳转到后台说明绕过成功。若提示语法错误把注释符改成#并做URL编码usernameadmin or 11%23passwordx需要注意payload里如果带有空格在GET请求里要编码为%20或在POST请求体里则通常可以直接保留空格但保守起见建议统一用Burp的URL编码功能处理一遍。4.5 第四步绕过之后做什么把登录状态拿到手只是第一步。PTE实操题通常在后台里藏了关键目标——可能是一个包含flag的文件、一个可执行命令的上传点、或者带有更高权限的管理接口。登录后优先浏览URL路由、查看页面源码里注释掉的隐蔽链接、检查管理功能是否有新的可操作入口。很多时候登录绕过题的最终得分点反而是后台的二次利用比如后台存在文件上传直接传一个WebShell拿到服务器控制权题目就彻底通关了。4.6 训练靶场怎么选想把这套流程练熟我推荐四个靶场各有侧重靶场特点适合场景SQLilabs从第1关到第20关逐步进阶覆盖字符型、数字型、盲注、堆叠注入系统刷SQL注入基础DVWA等级分明包含登录框等经典漏洞场景综合练习登录绕过Pikachu中文靶场界面友好SQL注入模块包含万能密码、搜索型注入快速上手CTFHub技能树按技能树组织含SQL注入独立目录竞赛向训练这四个靶场的SQL注入模块我都实测过SQLilabs最适合练闭合判断DVWA适合练完整攻击链Pikachu对新手最友好CTFHub适合追求规范解题方法的选手。备考CISP-PTE时把这几个靶场的登录注入场景刷两遍考试基本不会慌。5. 实测最容易翻车的4个场景与完整排错链路5.1 翻车现场还原一个完整的排错过程有次我在一个模拟PTE环境的PHP登录框上测试提交admin or 11 #结果怎么提交都提示“用户名或密码错误”。正常情况下这句payload在MySQL里应该直接绕过但实际就是不生效。我当时没有急着换payload而是按下面的链路逐步排查。第一步检查请求到达后端后的真实数据。在Burp Suite里开着Intercept把整个POST包拦下来发现#在URL里被浏览器转成了锚点请求体里usernameadmin or 11 #中的#根本没有被传输到后端。原因就是#在URI规范中是片段标识符浏览器会自动丢弃它。正确做法是把#编码成%23或者干脆改用--注意带空格作为注释符。第二步验证闭合方式是否匹配。将#编码后重新发送页面依旧没有绕过。这时候把payload改成admin or 11 也就是用单引号做闭合而非注释符页面开始出现数据库报错信息说明SQL语句接受到了payload但闭合位置不对。仔细数引号的数量后发现我的payload多了一个单引号导致SQL变成了usernameadmin or 11 AND ...语法层面就错了。调整为admin or 11 --之后登录成功。第三步确认数据库类型和注释符。后来我又在另一个SQL Server环境里用admin#去测试规则上不支持#自然无效。换用--注释或 or 11--后顺利绕过。第四步检查是否存在安全设备拦截。如果payload本身没毛病语法也对但仍被拦截就要考虑是否存在安全设备对or、--、select等关键字做了规则匹配。PTE考试环境一般不会特意加WAF但靶场训练时偶尔会遇到。绕过思路包括把or换成||部分数据库支持、关键字大小写混写、内联注释/*!50000or*/分隔关键字、用等号位置变化等。这些技巧了解即可不要一上来就全堆上。5.2 万能密码失败快速排查清单把所有踩过的坑整理成一张书签表放在手边随时查症状可能原因处理方式请求发出去无任何变化#被浏览器截断、payload未到后端用Burp Repeater发请求#编码为%23报SQL语法错误单引号闭合数量不对、注释符后少了空格数清楚引号数量MySQL的--后补空格页面提示乱码或500数据库类型判断错误用了对方不支持的注释符确认MySQL/SQLServer/Oracle切换注释符怎么打都是“密码错误”后端可能对单引号做了转义尝试双写单引号、宽字节绕过或寻找其他注入点输入单引号完全无报错参数可能来自POST但被过滤或存在安全设备换闭合方式看是否用了预编译/参数化查询登录成功但跳转404后台路径变化、存在权限控制查看Set-Cookie和302跳转目标补全后台URL5.3 关于“有没有可能不是SQL注入而是逻辑缺陷”还有一个很容易忽略的情况某些登录框根本不走SQL判断而是前端把用户名密码提交给一个接口接口里直接写死了管理员名和密码哈希。这种情况下万能密码当然不生效。区分方法很简单——输入单引号如果没有任何数据库报错且用户名枚举提示正常那可能是纯逻辑验证而非SQL查询。此时应该转向弱口令、接口枚举、验证码绕过等思路而不是在万能密码上死磕。6. 从万能密码延伸到认证绕过考场之外还能走多远6.1 把万能密码的思路迁移到其他认证场景万能密码的本质是“认证逻辑缺陷利用”这个思路可以迁移到很多场景。比如修改密码接口如果后端执行的是UPDATE users SET password新密码 WHERE usernameadmin and oldpassword旧密码注入点同样存在可以尝试在username处构造admin or 11 --来绕过旧密码校验。比如找回密码功能如果查询用户名的SQL存在拼接也能通过万能密码的方式控制流程。只要是“条件判断字符串拼接SQL”的地方都有这套手法的施展空间。6.2 结合联合查询把登录结果变成任意用户万能密码的进阶版本是“定制登录结果”。有些查询逻辑不是简单判断是否有返回行而是直接使用返回的第一行数据当作会话身份。此时可以用联合查询把结果集第一行替换成已知用户名 union select 1, victim_user, password --需要注意联合查询的字段数量必须与原查询一致否则SQL会报错。先用order by n从1开始递增猜列数再用union select填充对应字段。这一手在PTE实测中很常见能把“碰运气的万能密码”升级成“指哪打哪的任意用户登录”。6.3 防御层面怎么看这个问题写到这里必须补一句防守视角。万能密码能成立的根本原因是开发者把用户输入直接拼接进了SQL语句修复方案不是过滤or、--这些关键字而是使用参数化查询或预编译语句。还是以PHP为例正确写法是把SQL改成$stmt $conn-prepare(SELECT * FROM users WHERE username ? AND password ?);这样用户输入永远只是“数据”不会变成SQL结构的一部分再花哨的万能密码也无效。此外登录接口加防暴力破解、验证码校验、双因子认证都能显著降低这类风险。CISP-PTE考试考的是攻击和利用但理解了防御原理反而能帮你从更深的层面判断一个登录框“为什么能被打穿”。6.4 最后分享一个我自己的备考习惯刷题刷到最后我习惯把常用万能密码按数据库类型、注释符、闭合方式整理成一张速查卡考前十分钟翻一遍。真正到考场上看到登录框先判断数据库、再数引号、最后选payload整套流程行云流水。万能密码虽然只是一句话但“判断后端逻辑”这种习惯才是备考CISP-PTE最大的收获。希望这篇能帮你少踩几个坑考场里一把过。