[그림 1] 문제
[그림 2] auth를 누를 시 나타나는 창

auth 클릭 시 Access_Denied 문자열이 뜬다.

 

[그림 3] view-source 를 통해 코드 확인

php 코드를 분석해보자.

 

GET 요청과 함께 넘어온 val 인자값을 변수 $go에 저장한다.

$go에 들어온 값이 없다면 처음 페이지로 무조건 가게 되어있다.

그리고 preg_match 함수가 사용되는데, preg_match의 설명은 아래와 같다.

 

<preg_match> 패턴일치
첫 번째 인수 : 정규 표현식 작성
두 번째 인수 : 검색 대상 문자열
세 번째 인수 : 배열 변수 반환
→ 패턴 매치에서 매칭된 값을 배열로 저장
→ 반환값 : 매칭에 성공하면 1, 실패하면 0을 반환

/ 2 | - | \+ | from | _ | = | \\ s | \* | \/ /i

더보기

| (or)를 기준으로 살펴보면

숫자 2

기호 -

\+ ; 1개 이상의 \

from 문자열

기호 _

기호 =

\\s; 공백

\* ; 0개 이상의 \

기호 /

/i ; 대소문자 구별 x

 

여기에 해당되면 다 매칭이 되기 때문에 이를 사용하면 안된다.

 

$go 변수가 이 정규 표현식에 매칭되면 "Access Denied"가 뜨므로 매칭되지 않도록 해야한다.


이 단계를 넘기면 db로 연결되고 ( $db dbconnect(); )

$rand 변수에 1~5 사이의 수가 임의로 결정된다.( $rand=rand(1,5); )

 

$rand 변수의 값에 따라 밑의 조건문 중 하나가 무조건 실행이 된다. 

예를 들어 $rand == 1 이라면 실행되는 문장은 아래와 같다.

 

$result=mysqli_query($db,"select lv from chall7 where lv=($go)") or die("nice try!");

+) mysqli_query(연결객체, 쿼리) 함수는 mysqli_connect 를 통해 연결된 객체를 이용하여 MySQL 쿼리를 실행시키는 함수이다. 

1. chall7 테이블에서 lv가 $go변수값인 레코드의 lv를 보여주는 쿼리를 실행하거나

2. "nice try!"라는 문자열을 띄우면서 종료한다.

 

따라서, 해당 레코드가 없다면 die 되므로

쿼리의 결과가 있도록 $go 변수값을 잘 지정해줘야 한다.


+) mysqli_fetch_array() 함수는 쿼리문을 통해 가져온 결과의 레코드를 배열 형태로 받아오는 함수이다.

 

위 코드를 성공적으로 통과해왔다면

레코드를 배열 형태로 받아서 $data에 저장하게 된다.

 

$data[0] == 1 이면 'Access_Denied' 메시지를 띄우고

$data[0] == 2 이면 'Hello admin' 메시지를 띄운다.


결론적으로, data[0] == 2가 되어야 하고 그러러면 $result가 2라는 값을 가지도록 하면 된다.

 

chall7 테이블의 lv 컬럼에 어떤 형태의 값이 있는지 모르기 때문에

select lv from chall7 where lv=($go) 의 쿼리문을 통해 2라는 값을 가지도록 하려면

chall7 테이블의 lv 컬럼 값을 찾거나, lv 컬럼에 값을 넣어야 한다.

 

select lv from chall7 where lv=(0) union select 2#)

라고 먼저 넣어준다.

 

이렇게 되면 SELECT lv FROM chall7 WHERE lv =(0)

UNION

SELECT (2)

와 같은 쿼리문이 전달되는 것이다.

 

하지만 정규표현식에 숫자 2가 걸리므로

 

0)union(select(char(50)))%23

 

 

 

 

 

 

 

 

+ Recent posts