오랜만에 ctf를 풀어보는것같다..
문제를 한번 살펴보자
제목부터 SQL INJECTION이라 적혀있다!
우리가 지난번에 알아본 구문을 넣어보자( ' or 1=1--)
no hack??
이렇게 쉽게 풀리지는 않을거라 생각했지만 진짜 안풀린다..
일단 소스코드를 분석해보자
if($_GET['no']){
$db = dbconnect();
if(preg_match("/ |\/|\(|\)|\||&|select|from|0x/i",$_GET['no'])) exit("no hack");
$result = mysqli_fetch_array(mysqli_query($db,"select id from chall18 where id='guest' and no=$_GET[no]")); // admin's no = 2
if($result['id']=="guest") echo "hi guest";
if($result['id']=="admin"){
solve(18);
echo "hi admin!";
소스코드 분석
if($_GET['no']){
$db = dbconnect();
- 만약 GET['no'] 값이 들어온다면
- db와 연결 하고
if(preg_match("/ |\/|\(|\)|\||&|select|from|0x/i",$_GET['no'])) exit("no hack");
- 공백, /, \, (, ), |, &, select, fro, 0x(16진수) 가 있는지 검사하고 있으면 no hack을 출력한다(아마 여기서 막힌듯?)
| : or 을 의미 ex) "/abc|abcd/" -> abc 또는 abcd가 존재하는지 검사
/(특수문자) : /를 검사하고싶은데 이는 preg_match에 사용되는 구문이므로 / 를 사용해 뒤에 나온 특수문자를 검사함(/, ' 등등)
( ) : ex) hel(lo) -> hel과 hello를 검사한다는 뜻
/i : 대소문자를 구분하지 않겠다는 뜻
$result = mysqli_fetch_array(mysqli_query($db,"select id from chall18 where id='guest' and no=$_GET[no]")); // admin's no = 2
- 만약 id 가 guest이고 no 가 $_GET[no]라면 chall18로 부터 id 열을 가져옴(admin은 no 값이 2라고 말해줌)
if($result['id']=="guest") echo "hi guest";
if($result['id']=="admin"){
solve(18);
echo "hi admin!";
- 만약 result 가 guest라면 hi guest를 출력.
- result 가 admin이라면 문제가 해결됨
admin 이 2라길래 뭔소리지 싶어서 2를 적어보았는데 아무일도 안일어난다..
1을 적으면 어떻게 되지 싶어 적어보니
어라?
hi guest라고 나온다(아마 guest의 no값은 1인듯?).
그러면 우리의 목표는 no 값을 2로 만드는것이다.
https://webhacking.kr/challenge/web-32/index.php?no=1
참고로 ulr에서 no를 발견할 수 있음
여기서 조건은 위에 나온 특수문자를 사용하면 안되며, 16진수도 사용하지 않는것이다.
어떻게 풀지 생각하던중 지난번에 알아본 퍼센트 문자열이 생각이 났다.
https://j4zzch0rd.tistory.com/8
일단 우리의 공격방식은 SQL INJECTION 인데 특수문자들을 넣으면 preg_match에 걸리게된다.
그래서 no = 0 or no = 2 를 삽입해 no값을 2로 만들어주고싶은데
이때 공백이 필터링에 걸리게 된다..
이를 해결하기위해서 탭키를 퍼센트 문자열로 바꿔 공백 대신에 적어주면( 0%09or%09no=2 )
??
왜 안되는거지..
이유를 찾기위해 url을 보는데 "no=0%2509or%2509no%3D2" 이런 값이 적혀져있었다.
이때 안 사실은 저 칸에 입력하면 한번 인코딩해 url에 넣기 때문에 숫자가 다른것이다.
그래서 url에 직접 입력하면 문제가 해결된다.
문제 해결 :)
+
왜 1을 입력하면 guest가 나오지만 2를 입력하면 admin이 나오지 않을까?
이 질문에 답하려면 쿼리문을 다시 살펴보아야한다.
select id from chall18 where id='guest' and no=$_GET[no]
이 문구에서 id = guest인것이 보이는가?
이 쿼리문이 작동하려면 id에 맞는 no 값을 넣어야한다.
guest의 no 값은 1이므로(우연히 찾음) 1을 넣으면 hi guest가 나오지만 2를 넣으면 안나오는 이유도 그것 때문이다.
그래서 id값을 admin으로 바꿔도 풀리긴 한다.
오랜만에 적으니 조금 힘드네요..ㅎ
그래도 다시 열심히 적어보겠습니다.
"용기란 자기 자신을 굳게 믿는 것이다. 그러나 아무도 그것을 가르쳐주지는 않는다." - 엘 코르도베스
'Webhacking.kr' 카테고리의 다른 글
[Webhacking.kr] Challenge 24 (1) | 2024.11.19 |
---|---|
[Webhacking.kr] Challenge 10 (1) | 2024.11.17 |
[Webhacking.kr] Challenge 39 (0) | 2024.10.11 |
[Webhacking.kr] Challenge 12 (0) | 2024.10.10 |
[Webhacking.kr] Challenge 26 (0) | 2024.10.08 |