<?php
include "./welcome.php";
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)|admin/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\(\)|admin/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_cthulhu where id='{$_GET[id]}' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) solve("cthulhu");
highlight_file(__FILE__);
?>
ModSecurity는 WAF(웹방화벽)이다. 이를 우회하는 문제다.
https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/1181
위 링크에 접속하면 우회기법들이 있다. 이 문제엔 paranoia level 1 수준의 웹 방화벽이 설정되어 있어서 위 링크의 PL1 우회기법들을 봤는데 뭔진 잘 모르겠다. 문법이 이해가 안 간다. PL2 우회기법들 중에 하나를 골라서 테스트해 봤다.
- -1'<@=1 OR {a 1}=1 OR '
인데 조금 변형하니 통과했다.
답: ?id='<@ or 1%23
@variable는 session-specific user-defined variable의 변수선언에 사용된다고 한다. 자세한 건 아래 링크에 예시까지 잘 나와있다.
https://stackoverflow.com/questions/1009954/mysql-variable-vs-variable-whats-the-difference
MySQL에서 테스트해보면 select @;은 NULL을 반환한다. 마찬가지로 select ''<@;도 NULL을 반환한다.
우선 DB가 MySQL의 경우에 <@를 libinjection에서 처리를 잘 못한다고 한다. 다른 DB에서는 해당 공격이 잘 안 먹힌다고 한다.
참고로 libinjection이란 SQL Injection을 탐지하는 C 기반의 오픈소스 라이브러리다.
https://portswigger.net/daily-swig/libinjections-sql-injection-defenses-cracked
위 링크에서 말하길 ModSecurity는 detectSQLi 연산자를 통해 libinjection을 사용한다고 한다. detectSQLi 연산자는 SQL Injection 데이터가 감지되면 참을 반환한다고 한다.