문제파일은 첨부
(apmsetup 이용하여 서버를 열어서 거기에 집어넣고, db파일은 소스코드 보고 설정하셈. 따로 설명안함.)
일단 html 페이지를 열어보면
아래와 같은 페이지가 나온다. 원래 대회때는 get source를 누르면
login_check.php 소스 파일을 받을 수 있었따는데.. 나는 일단
첨부한 문제파일에 소스 파일이 담겨있었다.
로그인 창만 덩그러니 나와 있는 것을 보아 로그인 우회를 해야하는 문제라고 판단할 수 있다.
일단 소스를 보자.
php함수에 대해 잘 모르는 관계로 검색해서 좀 알아봤따.
---------------------------------------------------------------------------------------------------------------------------
* isset() : 변수가 셋팅 되어 있고, null이 아닌지 체크하는 함수. <-> unset()
* or die() : 좌측의 함수가 실패할 경우, 우측의 함수를 실행
* mysql_real_escape_string : mysql 쿼리에서 특수 문자열을 이스케이프하기 위해 사용.
인젝션 공격에 대비하기 위한 함수.
* $ps = hash("whirlpool",$ps, true);
->whirlpool 알고리즘을 이용하여 $ps 문자열을 이진데이터로 뽑아냄. ( true: 바이너리값, false: 핵사값)
* mysql_fetch_assoc : db에서 가져온 값을 배열변수에 대입하는 함수
---------------------------------------------------------------------------------------------------------------------------
소스 코드를 훑어보면 로그인 체크하는 코드이다. (이름에 나와있듯.)
근데 여기서 포인트는 특수 문자열을 사용할 수 없고, 비밀번호를 hash 함수를 이용해 암호화 시킨 후 저장하는 것이다.
로그인을 우회해야 하는데.. 특수 문자를 쓸 수 없다.
그렇다면 우리는 일단 = (equal) 연산자를 이용한 sql 인젝션으로 로그인 우회를 시도해야 함.
왜 equal을 쓰는지 이제 설명해주겠음.
일단 먼저 sql 쿼리문에서 equal 연산자의 사용에 대해 좀 알필요가 있다.
알다시피 '='는 같은지 틀린지 확인하는 연산자이다.
query문에서 equal을 이용한 sql injection 을 할 때
select * from table where $id=admin and $ps='string1'='string2'
이런식으로 집어넣는다. 왜그럴까?
My-SQL에서는 equal이 'string1'='string2' 같이 문자열을 비교할 때 정수형으로 형변환을 한다.
문자열과 숫자를 비교할 때 형 변환 에러가 일어나지 않는다는 말이다.
이때 문자열의 첫글자가 문자로 시작하거나 문자로만 이루어져 있다면 이 문자열은 정수형으로 0을 반환한다.
문자를 정수형으로 바꾸려니, 유효하지 않은 수라고 판단하고 0을 반환한다.
반대로 첫번째 배열문자가 0이 아닌 숫자이거나 배열이 숫자로 이루어져 있따면 1을 반환한다.
그래서 'abc'='cde' 는 결과적으로 TRUE를 반환한다. ( 0 = 0 은 참이니까 )
그럼 위 의 쿼리문 and 이후는 true가 된다.
비밀번호를 몰라도 우회가 가능하다는 것이다.
그리하여 My-SQL 에서는 블라인드 SQL Injection 취약점이 많이 사용된다.
sql에서 문자열을 비교할 때 정수형으로 변환을 하고, 문자는 정수가 아니니 0을 반환한다는 사실을 알고있어야한다.
그럼 이제 패스워드 쿼리문에 우리가 '=' 을 집어넣으면 우회를 할 수 있따는 사실을 알았다.
왜? select * from table where $id=admin and $ps=' string1'='string2 '
위의 빨간색 부분이 실제로 패스워드 파라미터에 대입되는 값이기 때문이다.
하지만 그냥 이렇게 풀리면 너무 쉽겠지.;;
우리는 암호가 해쉬함수로 인해 암호화 된 채로 저장된다는 사실을 망각해서는 안됨.
그니까 해쉬값으로 변환했을 때 '=' 문자가 나오도록 하면 (앞 뒤로는 어떤 값이 와도 다 0으로 반환되고 true가 됨)
로그인을 우회할 수 있을 거라는 추측이 가능하다.
그러기 위해 간단한 php 소스 코딩이 필요하다.
쉽게말해 그냥 brute foce 공격 한다고 생각하믄됨.
위에서 eregi 함수는 찾고자하는 문자열이 나올 때까지 찾는것이다.
i값을 출력시켜 패스워드 창에 집어넣으면 해쉬로 변하면서 '=' 문자가 낑겨 있는 쿼리문이 완성된다.
돌리니까, 364383 라는 값이 나온다.
이녀석이 이제 해쉬함수 돌리면 '=' 문자가 포함되어 있는 해쉬값 돌리기전의 원래 값이다.
admin에 364383을 입력하면, 답이 나온다.
원래 flag.txt파일에 답이 있는데, 내가 서버를 열어서 문제를 풀었기 때문에 flag파일은 없다.
(원래 문제에선 답이 적혀있음.)
'IT 그리고 정보보안 > Write-up' 카테고리의 다른 글
Codegate 2013 - Forensic(100) (0) | 2021.04.12 |
---|---|
Pwnable.kr - fd (0) | 2021.04.12 |
LOB Level 20 (xavius) (0) | 2021.04.12 |
LOB Level 19 (nightmare) (0) | 2021.04.12 |
LOB Level 18 (succubus) (0) | 2021.04.12 |