You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用mysqli_real_escape_string仍有SQL注入风险?能否绕过登录验证?

Can We Bypass This Login Function to Authenticate as a Specific User (e.g., Sam)?

Short answer: Yes—you can exploit a timing vulnerability in the password verification logic to guess the target user's password, and you can also simplify the query to match any domain for the user. Let's break this down step by step:

Why Your Initial SQL Injection Attempt Failed

Your try with domain = "' union (SELECT 1, 123456) # a" didn't work because mysqli_real_escape_string() escapes the single quote in your payload. The function turns ' into \', so the resulting SQL query becomes:

SELECT user_id, password FROM users WHERE username = 'Sam' AND domain LIKE '\' union (SELECT 1, 123456) # a'

This is looking for a domain that literally matches that escaped string (which doesn't exist), so your injection doesn't alter the query's logic like you intended. Regular single-quote-based SQL injection is blocked here.

The Critical Flaw: Timing Attack on Password Verification

The password check code is vulnerable to a timing attack, and this is your path to bypass. Here's why:

  • The code compares each character of the input password to the stored password one by one, with a usleep(100000) (0.1 second) delay between every check.
  • If your input's nth character is wrong, the loop stops right away, returning FALSE after ~0.1 * n seconds.
  • If the nth character is correct, it moves to the next character, adding another 0.1 seconds to the total response time.

How to Guess Sam's Password with This:

  1. Start with the first character: Try pwd = "A". If the response is fast (~0.1s), that character is wrong. Try pwd = "S"—if the response takes ~0.2s, that means the first character was correct, and the loop failed on the second character.
  2. Repeat for each position: For every character in the password, test all possible values (letters, numbers, symbols) and measure the response time. The character that triggers a longer delay is the correct one for that spot.
  3. Full match: Once you've guessed all characters correctly, the loop will run through every character without failing, and the function returns TRUE.

Bonus: Broaden the Domain Match with a Wildcard

Since mysqli_real_escape_string() doesn't escape LIKE wildcard characters (% and _), you can set domain = "%" to match any domain linked to Sam. This changes the query to:

SELECT user_id, password FROM users WHERE username = 'Sam' AND domain LIKE '%'

This will pull Sam's user record no matter what domain they're associated with (assuming Sam exists in the database). Combine this with the timing attack to authenticate as Sam easily.

Are There Other Bypass Methods?

  • Empty password bypass: No, the code checks empty($password) upfront, so an empty input gets rejected immediately.
  • Blind SQL injection via query timing: Unlikely—all timing differences come from the password check loop, not the SQL execution itself, so you can't leverage query delays to extract data that way.

内容的提问来源于stack exchange,提问作者keyblade95

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:51:45