old-59

old-59

old-59

가입과 로그인을 할 수 있다.

view-source를 통해 페이지 소스 코드를 살펴보면

lv : {$result['lv']}"; if($result['lv'] == "admin"){ mysqli_query($db,"delete from chall59"); solve(59); } echo "view-source"; exit(); } } if($_POST['id'] && isset($_POST['phone'])){ $_POST['id'] = addslashes($_POST['id']); $_POST['phone'] = addslashes($_POST['phone']); if(strlen($_POST['phone'])>=20) exit("Access Denied"); if(preg_match("/admin/i",$_POST['id'])) exit("Access Denied"); if(preg_match("/admin|0x|#|hex|char|ascii|ord|select/i",$_POST['phone'])) exit("Access Denied"); mysqli_query($db,"insert into chall59 values('{$_POST['id']}',{$_POST['phone']},'guest')"); } ?>

id와 phone을 POST 방식으로 전달받아

insert into chall59 values('{$_POST['id']}',{$_POST['phone']},'guest') 쿼리를 수행한다.

그리고 lid와 lphone을 POST 방식으로 전달받아

select id,lv from chall59 where id='{$_POST['lid']}' and phone='{$_POST['lphone']}' 쿼리를 수행한 결과 중 lv가 admin이면 문제를 해결할 수 있다.

먼저, id는 woong, phone은 123으로 가입하고 로그인해보면

insert 문의 guest가 lv로 되는 것을 확인할 수 있다.

insert 문을 할 때 guest 대신 admin을 넣으면 된다.

가입할 때 입력하는 id와 phone은 "admin" 문자열을 필터링한다.

그리고 id에 woong2, phone에 123, 1)-- 를 입력하면(-- 뒤에 공백이 있어야 함)

insert into chall59 values('woong2', 123, 1)-- ,'guest') 되어 빨간 부분이 주석처리된다.

위와 같은 방법으로, guest를 admin으로 바꾸기만 하면 된다.

admin을 16진수나 2진수로 바꿔 입력할 수 있지만, 이 문제에서 "0x"를 필터링하기 때문에 사용할 수 없다.

그리고 admin을 2진수로 변환하면 길이가 길어진다. 이 문제에서 phone의 길이가 20보다 크거나 같으면

"Access Denied"를 출력하기 때문에 사용할 수 없다.

MySQL의 내장함수에는 reverse()가 있다.

reverse() 함수는 주어진 문자열을 반전시켜준다.

즉, reverse('nimda')은 admin을 뜻한다.

위 함수를 이용해

id에 woong3, phone에 123, reverse("nimda"))-- 를 하면 phone의 길이가 20보다 크기때문에"Access Denied"를 출력한다. phone의 길이를 더욱 줄여야 한다.

따라서, id를 사용해야 한다.

id도 "admin"을 필터링하기 때문에 id에 "nimda"를 입력하고, phone에 1,reverse(id))-- 로 가입한다.

lid는 "nimda", lphone에 1로 로그인하면 lv는 reverse(id)가 되어 "admin"을 출력하게 된다.

from http://woong971.tistory.com/260 by ccl(A) rewrite - 2021-12-28 16:26:55