if(isset($_POST['id']) && isset($_POST['ps'])){
<!-- |
문제 소스 코드 일부
guest와 blueh4g으로 로그인 하면 your account is blocked가 뜬다.
그 외의 계정으로 로그인해야지만 문제 key를 얻을 수 있는데 주석으로 문제 테이블의 계정을 적어두었다.
테이블 내 존재하는 계정은 guest와 blueh4g 테이블 내 존재하는 모든 계정이 block 되어있다.
없는 계정을 만들어야하는 문제일까? 아니면 guest, blueh4g로 로그인 하되 이를 우회하는 방법이 있는걸까?
고민을 꽤 많이 했었던 기억이 있다. 처음엔 어떻게든 escape해서 union 쿼리를 통해 이외의 계정을 만들어 보려했지만 escape_string에서 특수문자를 막아버린다.
mysql과 php에서 문자열을 처리하는 방식의 차이에서 문제가 발생한다.
평범하게 guest / guest 로 요청하여 로그인을 시도하면 mysql은 테이블 내에 있던 guest / guest를 반환할 것이고,
조건문에서 guest가 걸려 blocked를 출력한다.
여기서 자세히 봐야할 것은, 기껏 $row['id']를 받아왔는데, 조건문에서는 $id 값으로만 검증을 시도한다. 또한 문자열 검증도 preg_match등의 함수를 이용하지 않는다.
즉, db에서 guest나 blueh4g를 반환해도 내가 페이지에 요청한 파라미터 $id의 값만 guest와 blueh4g가 아니면 우회할 수 있다.
파라미터의 값이 'guest'와 'blueh4g'이 아니면서 mysql에서는 'guest'또는 'blueh4g'를 반환할 수 있는 요청 값을 고민해보자.
Guest/ guest로 요청할 시, 해당 검증을 우회할 수 있다. php는 기본적으로 문자의 대소문자를 구분하지만, mysql은 기본적으로 대소문자를 구분하지 못한다. php의 Guest와 guest는 다른 문자열이지만 mysql에서의 Guest와 guest는 같은 문자열로 인식한다.
이로 인해 mysql은 쿼리의 결과값으로 테이블 내에 있던 guest를 $row['id']에 반환하면서, php의 $id = "Guest"는 대소문자를 구분하여 if($id=='guest' || $id=='blueh4g') 검증을 우회할 수 있게 된다.
'wargame > wargame.kr' 카테고리의 다른 글
[wargame.kr] fly to the moon (0) | 2019.04.08 |
---|---|
[wargame.kr] WTF_CODE (0) | 2019.04.08 |
[wargame.kr] qr code puzzle (0) | 2019.04.08 |
[wargame.kr] flee button (0) | 2019.04.08 |
[wargame.kr] already_got (0) | 2019.04.08 |