Webhacking.kr

[Webhacking.kr] Challenge 39

J4zzCh0rd 2024. 10. 11. 23:03

Challenge 39

 

문제에 접속하니 입력란과 소스코드를 보는 페이지가 있다.

 

일단 아무거나 입력해보자.

 

제출 버튼을 누르면

 

??

 

아무런 반응이 없다.

 

그러면 다음으로 소스코드를 한번 보자

 

 

필요한 부분만 가져와서 한줄씩 분석해보자.

 

$db = dbconnect();
  if($_POST['id']){
    $_POST['id'] = str_replace("\\","",$_POST['id']);
    $_POST['id'] = str_replace("'","''",$_POST['id']);
    $_POST['id'] = substr($_POST['id'],0,15);
    $result = mysqli_fetch_array(mysqli_query($db,"select 1 from member where length(id)<14 and id='{$_POST['id']}"));
    if($result[0] == 1){
      solve(39);
    }
  }

 

 

소스코드 분석


 

$db = dbconnect();

 

  • db 연결
if($_POST['id']){
  $_POST['id'] = str_replace("\\","",$_POST['id']);
  $_POST['id'] = str_replace("'","''",$_POST['id']);
  $_POST['id'] = substr($_POST['id'],0,15);

 

  • 만약 post로 받아온 id 값이 있으면
  • 그 값 중 \\ 를 없애고 ' 를 ''(작은 따옴표 두개)로 바꾼다
  • 또한 그 값을 0부터 15까지 문자열로 리턴한다.
$result = mysqli_fetch_array(mysqli_query($db,"select 1 from member where length(id)<14 and id='{$_POST['id']}"));

 

 

  • $db를 mysql로 연결해 쿼리 구문을 실행(첫번째 열에 있는 테이블 중 member 테이블을 검색, 단 id 길이가 14 이하고 id 가 post로 나온 id 이면 출력)

mysqli_query(연결객체,쿼리)

  • result set을 배열.
더보기

mysqli_fetch_array(result set) 예시 

 

DB------------------------------------------------------------- *

|     id    |   title   |   description   |           ~~~            |

|    30    |    Hi    |  My_name_is |           ~~~            |       

|    31    |    ~~   |         ~~~         |          ~~~            | 

|    ~~    |    ~~   |         ~~~         |          ~~~            |

*-----------------------------------------------------------------DB

 

mysqli_fetch_array(mysqli_query($db, "select * from topic where id = 30)) 을 실행한다면

 

==> Array( [0] => 30 [id] => 30   [1] => Hi  [title] => Hi  [2] => 1 [description] => My_name_is  [3] => ~~~)

//                 ㄴ자릿수  ㄴ콜롬명

가 나옴을 알 수 있다.

 

if($result[0] == 1){
      solve(39);
    }
  }

 

  • 만약 result[0] 이 1이면 문제 해결

 

이제 소스코드 분석은 끝났다.

 

한번 해결해보자.

 

아마 post 값은 위에서 입력하는 값이 출력되는것 같다.

 

그리고 특수한 문자를 바꾸는것으로 보아 sql injection을 방지하는것같다.

 

$result = mysqli_fetch_array(mysqli_query($db,"select 1 from member where length(id)<14 and id='{$_POST['id']}"));

 

그렇게 계속 코드를 보는 도중..

 

뭔가 이상함을 느꼈다.

 

먼저 분명히 15번째 까지 자른다고 했는데 코드를 보면 14 미만이라 적혀있고

 

id 뒷부분을 보면 작은따옴표 하나가 없다.

 

그러면 어떻게든 저 쿼리를 완성시키면 되는데

 

마지막에 '를 넣으면 분명히 ''로 바뀔것이다...

 

하지만 생각해보면 코드는 15번째까지 자르는데

 

''로 바뀌어도 상관이 없지 않을까 생각하였다.

 

12345678901234''  - 16번째로 가서 ' 잘림

 

 

그래서 admin         '를 입력해보니

 

 

문제 해결 :)

 

더보기

+ 왜 답에 공백이 들어가는가?

 

문제를 보면 문자는 14줄 미만이라고 했는데

 

만약 adminadminadmi'을 입력하게되면 14줄이므로(' 제외) 참이 아니게된다

            5        5         5

하지만 마지막 i를 공백으로 입력한다면

 

sql에서는 'admin' = 'admin ' 이라고 인식하기때문에

 

참이 된다!

 

 

 


사실 고백하자면 이번 문제가 너무 안풀려 정답을 보게되었다..

 

정답을 보니 내가 정말 쓸데없이 고민한것을 알 수 있었다.

 

실제로 위에 저 조건만 만족하면 답이 나오지만

 

sql injection 공격을 시도해보면서 시간만 날렸다..

 

다음 문제는 직접 풀릴때까지 풀어보겠다..

 

"내일을 실현하는 데 유일한 한계는 오늘의 의심이다." - 루즈벨트