본문 바로가기

웹/LOS

Lord of SQL Injection # orge

728x90
반응형
SMALL

query : select id from prob_orge where id='guest' and pw=''

 

쿼리문은 이렇게 나와있다.

pw를 찾으면 되는 문제인듯!

 

 

php코드이구...

코드를 일단 간단하게 분석해보쟈.

 

<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~"); 

 

 

<preg_match>

 

문자열을 검색한 뒤, 그 결과에 따라 값을 반환해 주는 함수

 

사용 형식

: preg_match(정규식 표현, 검색 대상 문자열, 매칭된 결과)

 

첫 번째 인수 : 정규식 표현 작성.

두 번째 인수 : 검색 대상 문자열.

세 번째 인수 : 배열 변수 반환. 패턴 매치에서 매칭된 값을 배열로 저장.

반환값 : 매칭에 성공하면 1, 실패하면 0이 반환

 

 

  if(preg_match('/or|and/i', $_GET[pw])) exit("HeHe"); 

// '/or|and/i' 이 문자들이 필터링되고 있다.

그러므로 적당한 문자로 대체를 해줘야 한다.

or -> ||

and -> &&


  $query = "select id from prob_orge where id='guest' and pw='{$_GET[pw]}'"
  echo "<hr>query : <strong>{$query}</strong><hr><br>"
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 

 

 

<mysqli_query>

 

: mysqli_connect 를 통해 연결된 객체를 이용하여 MySQL 쿼리를 실행시키는 함수

 

사용 형식

: mysqli_query([연결 객체], [쿼리]);

 

 

<mysqli_fetch_array>

 

: mysqli_query 를 통해 얻은 반환 셋(result set)에서 레코드를 1개씩 리턴해주는 함수

레코드를 1개씩 리턴해주는 것은 mysqli_fetch_row 나 mysqli_fetch_assoc 와 동일하지만 리턴하는 배열의 형태가 다른다.

순번을 키로 하는 일반 배열과 컬럼명을 키로 하는 연관배열 둘 모두 값으로 갖는 배열을 리턴

 

사용 형식

mysqli_fetch_array([result set]);

 

(* 참고로

mysqli_fetch_array : 일반배열 + 연관배열

mysqli_fetch_row : 일반배열

mysqli_fetch_assoc : 연관배열

을 각각 리턴한다.)

 

 

참고한 블로그

blog.naver.com/diceworld/220295811114

PHP MySQL 레코드 가져오기 (mysqli_fetch_array)

- PHP mysqli_fetch_array 란? mysqli_fetch_array 함수는 mysqli_query 를 통해 얻은 리절트 셋(result...

blog.naver.com

 

 

  if($result['id']) echo "<h2>Hello {$result[id]}</h2>"; 

// ?pw=null'||1=1%23 이 값을 입력해줬다.

(굳이 저 코드가 아니더라도 참인 조건을 성립하는, 논리상으로 맞는 코드를 써주면 된다.

or과 and를 필터링 해주어야 하는 것을 잊지 말자!)

 

 

 

그렇게 입력을 해주니 코드에서 나와 있듯이 

Hello {$result[id]}

이 문자열이 출력된다.

 

 

 

(참이 아니라 거짓인 조건을 충족하는 코드를 입력해주면, 아무것도 출력되지 않았다.)
   
  $_GET[pw] = addslashes($_GET[pw]); 
  $query = "select pw from prob_orge where id='admin' and pw='{$_GET[pw]}'"

(쿼리문2)

// 아까 위에 나왔던 쿼리문과 조금 다르다.

다시 복사해와서 확인해보쟈.

 

 $query = "select id from prob_orge where id='guest' and pw='{$_GET[pw]}'"

(쿼리문1)

 

쿼리문1은 id가 'guest'로 되어 있고, 쿼리문2는 id가 'admin'으로 되어 있는 것을 확인할 수 있다.

쿼리에 따라 서버에서 서로 다른 반응을 보이는 'Blind SQL Injection' 문제인 것을 추측해 볼 수 있다.

 

Blind SQL Injection 은 임의의 SQL 구문을 삽입하여 인가되지 않은 데이터를 열람할 수 있는 공격 기법이라는 점에서 일반적인 SQL Injection 과 유사하다.

 

SQL Injeciton 의 경우, 조작된 쿼리를 입력해 한번에 원하는 데이터를 얻는다.

그러나, Blind SQL Injection 은

쿼리 결과에 따른 서버의 참/거짓 반응을 참고하여 공격을 수행한다.

 


  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orge"); 

// 이게 문제 해결 조건이다.

입력한 pw와 저장되어 있는, 정해진 pw값이 같아야 문제가 해결된다.

 

  highlight_file(__FILE__); 
?>

 

 

이제 pw를 찾아보자.

이렇게 아까 위에서 입력해준 것과 비슷하게 써주쟈.

(참인 조건을 입력해주면 "Hello guest" 문자열을 출력한다는 성질을 이용한 방법!)

 

 

 

 

length() 함수를 이용해줬다.

이런 방식으로 찾으니 pw의 길이는 8이라는 것을 알게 되었다.

 

Blind SQL injection 공격법을 찾아보다가 ascii 함수와 substring을 이용한 공격 기법을 알게 되었다.

 

<substr>

: 문자열을 자를 때 사용하는 함수

 

사용 형식

: sbstr(자를 문자열, 자를 문자의 시작점, 자를 문자의 개수)

 

 

<ascii>

: 문자의 아스키 코드 값을 반환하는 함수

 

사용 형식

: ascii(아스키 코드로 반환할 문자)

 

 

-> 위의 두 함수를 이용해 공격을 할 수 있다.

 

ascii(substr(pw,1,1)

이렇게 써주면 pw 문자열을 자른 뒤에, 그 잘린 문자에 맞는 아스키 코드 값을 반환해 준다.

 

위에서부터 계속 이용해왔던 성질을 다시 이용해주자.

만약 참인 조건이 입력되면 "Hello guest" 라는 문자열이 출력될 것이다.

 

?pw=null'||ascii(substr(pw,1,1)<100%23

이런식으로 범위를 정해서 pw값을 하나하나 찾아주면 된다.

 

위에서 pw가 8자리라는 것을 찾아냈으므로, 조금 시간은 걸렸지만 계속 하다 보니 찾을 수 있었다.

생각보다 빨리 찾을 수 있다.

 

55(7)

98(b)

55(7)

53(5)

49(1)

97(a)

101(e)

99(c)

 

-> 7b751aec

 

 

 

이렇게 문제가 해결된다!

 

 

728x90
LIST

' > LOS' 카테고리의 다른 글

LOS # skeleton  (0) 2021.03.13
LOS # vampire  (0) 2021.03.13
Lord of SQL Injection # troll  (0) 2021.03.13
CTF_WEEK2_Lord of SQL Injection # darkelf  (0) 2021.02.05
CTF_WEEK2_Lord of SQL Injection # wolfman  (0) 2021.01.20