안경잡이개발자

728x90
반응형

  이 문제 또한 웹 해킹 유형의 문제입니다.

 

 

  문제 풀이를 시작하니 해당 페이지의 기능을 담당하는 PHP 소스코드를 보여주는 버튼이 등장합니다. [get source] 버튼을 눌러서 소스코드를 확인할 수 있습니다.

 

 

  소스코드를 확인합니다. 먼저 mysql_real_escape_string() 함수는 SQL Injection을 방어하기 위한 기본적인 함수입니다. trim() 함수는 사용자가 입력한 문자열에서 앞뒤 공백문자를 제거해주는 역할을 수행합니다.

 

  다시 말해 적절한 ID와 PW를 입력하여 로그인을 하면 플래그(Flag) 값이 나올 것 같습니다. 그렇다면 어떠한 아이디와 비밀번호를 입력해야 문제를 풀 수 있을까요? 이 문제는 문제 제목에서부터 볼 수 있듯이 필터링(Filtering)과 관련한 문제로 이해할 수 있습니다.

 

 

  이 문제는 SQL Injection 문제가 아닙니다. 페이지의 소스코드를 보면 다음과 같이 데이터베이스에 기록되어 있는 아이디 및 비밀번호 정보가 포함되어 있습니다. 따라서 SQL Injection 문제는 아니고, 인증에서의 필터링(Filtering) 우회 문제라고 할 수 있습니다.

 

  이 문제는 PHP는 문자열 비교에 있어서 대소문자를 구별하지만, MySQL은 기본적으로 대소문자를 구별하지 않는다는 점을 이용하면 풀 수 있습니다. (이는 MySQL을 이용하는 개발자들이 자주 간과하는 특징이기도 합니다.) 다시 말해 파라미터 $id 값의 문자열에 대문자를 끼워서 입력하면 문제를 풀 수 있습니다.

 

  예를 들어 아이디(ID) 값으로 GUEST라고 넣게 되면, 데이터베이스에 존재하는 guest라는 회원 정보 검색에 성공하기 때문에 GUEST라는 데이터를 얻습니다. 그렇기 때문에 필터링을 우회하여 블록(Block) 처리 된 사용자로 로그인을 할 수 있게 되는 것입니다.

 

 

  따라서 다음과 같이 아이디(ID)에 하나 이상의 대문자를 끼워서 ID 및 PW를 입력하면 문제가 풀립니다.

 

 

  다음과 같이 Password(Flag) 값이 등장합니다.

 

 

※ MySQL 대소문자 구별에 대하여 ※

 

  MySQL 온라인 컴파일러를 이용하면, 대소문자 구별을 정말 안 하는지 확인할 수 있습니다.

 

  https://paiza.io/en/projects/new?language=mysql

 

  위 사이트에 접속하여 다음과 같은 소스코드를 입력하여 실행해보세요.

 

create table Test(id integer, title varchar(100));
insert into Test(id, title) values(1, "Hello");
select * from Test where title = 'HELLO';

 

  실행 결과 정상적으로 데이터를 조회합니다.

 

 

728x90
반응형