문제

Admin is Mine

50

admin 계정으로 로그인하자!

현재 우리의 계정은 다음과 같다. [ID/PW] : doldol / dol1234

 


SQL Injection을 테스트하기 위해 ID = doldol' #  PW=dol1234로 요청을 보내보니 아래와 같은 결과를 볼 수 있었다.

 

보낸 #이후의 값이 없다.

 

예상으로는 #* 와같은 정규식으로 SQL 보내기 전 replace를 한다면 발생 할 수 있을 것 같다.

그렇다면 or는 동작할가?

 

일단 전송하는 단에서는 replace가 안되는 것으로 보인다.

 

그렇다면 doldol' or '1'='1로 전송을 보내보자 

실행되는 쿼리는 id='doldol' or '1'='1' and pw='dol1234'로 예상된다.

 

실패하는 것을보니 다른 방법으로 SQL Injection을 막는것 같다.

 

history를 찾아보자 

 

찾다보니 login.js 라는 파일을 찾았다.

응답 값으로부터 resultData가 'ok'라면 로그인 성공이라고 한다. 

응닶으로 오는 값을 ok로 바꿔보자

Action > Do intercept > response to this request

클릭해주고 forward를 누르면 해당 리퀘스트에 대한 response를 인터셉트 할 수 있다.

 

요청이 fail로 들어왔다. 이를 ok로 변조하여 전달해보

 

 

 

정답을 찾을 수 있었다.

문제

PIN CODE Bypass

50

핵미사일 시스템 접근 권한을 획득했다! 발사만 남았다! 가자!!!

 

step1.php
step2.php

 

아무 입력을 넣으면 step2.php?admin_pass=123 로 이동 하며 "비밀번호가 일치히 않습니다." 라고 나온다.

 

그런데 첫 페이지가 step1.php, step2.php이다. 그렇다면 다음 페이지는 step3.php로 직접 이동 하면 될 것 같다.

 

step3.php

발사 버튼을 누르면 정답이 나온다.

문제

Get Admin

50

admin 계정으로 접속하자!

현재 우리의 계정은 다음과 같다. [ID/PW] : doldol / dol1234


SQL Injection Test

ID를 알고있으니 SQL Injection이가능한지 테스트 해보자

로그인 쿼리는 ID = '' and PW ='' 라고 한다면

  • id='doldol' #' : SQL Injection이 가능하고 #이 제거되지 않는다면 가능
  • id='doldol' or '1'='1' and pw='dol1234' :  and 연산이 우선되기에 해당 구문은 
    id='doldol' or ('1'='1' and pw = 'dol1234')와 같다 즉 pw가 틀려도 id가 일치하면 된다.
  • id='doldol' || '1'='1' && pw='dol1234' :
    만약  쿼리에 들어가기전에 and, or가 모두 삭제된다면?
  • id='doldol' -- 주석은 #뿐만 아니라 -- 도 있다고한다 

모두실패하는 것을 보니 SQL Injection은 불가능해 보인다.

 


쿠키 분석

로그인 성공 시 html과 쿠키 세션등 데이터를 확인해보자

 

loginUser라는 항목이 doldol로 보인다. admin으로 수정후 새로고침 해보자

 

 

로그인 여부를 쿠키의 아이디를 사용하여 체크하는 로직인듯 하다.

 

 

요약 및 힌트

데이터의 조회 결과가 몇건이건 한건만 보여지기에 든 생각으로 데이터를 모두 가지고오더라도 php 소스에서 첫 데이터만 화면에 표시하는 듯 하다. 그렇기 때문에 limit을 사용하여 데이터의 결과 순서를 변경했다.

 

만약 데이터들이 몇만건씩 있다면 limit 부분을 python으로 전송하여 데이터를 조회하는것도 좋은 방법일 듯 하다

 

참고로 SQL Injection1의 풀이는 6주차 정리에 있다.


문제 풀이

 

 

normaltic을 넣었을 때랑 1=1을 넣엇을 때 값이 같다.

'한개만 입력을 넣으니 동작을 하지 않는다. 

아무런 데이터를 넣어도 1개의 row는 존재하며 normaltic을 입력시 info에 데이터가 출력된다

 

예상되는 Back-End의 로직은 2가지

1. 테이블에서 id로 info만 조회하고 level, rank Point는 모두 화면에서 마스킹 고정

즉 테이블은 4개의 정보를 가지고 있는 것 처럼보이지만 실제로는 info 하나의 컬럼만 조회하고 있는 듯?

 

2. select '입력받은 id값', '****', '****', (select info from table where id = '입력받은 id값') from dual

 

1번 케이스가 더 의심간다...

일단 order by로 선행 select의 컬럼이 몇개 존재하는지 확인하보자

normaltic' order by 1 #

 

order by 7에서 데이터 조회가 안되므로 선행 컬럼은 총 6개

 

이제 어느 컬럼이 화면에 표기되는지 union으로 잡아보자

 

normaltic' union select 1,2,3,4,5,6 from dual #

 

어라 union을 해도 아래 데이터가 붙어나오진 않는다....

 

db에서 가지고 온 데이터를 화면에서 뿌릴때 인덱스(배열의 인덱스) 0번만 가져오는거 같다... 그렇다면  없는 데이터를 union으로 넘긴다면 내가 넘긴 데이터를 조회 할 수 있을 것이다.

빙고 배열의 가장 처음데이터가 내가 넣은 데이터다.

info는 6번째 컬럼에 있다는 걸 알았다.

 

이제 DB, Table, COLUMN을 찾아보자

123' union select 1,2,3,4,5,database() from dual #

 

 

이제 테이블 찾기가 노가다일것 같다.... limit 1,1 , limit 2,1 이런식으로 찾아도 되고...

생각해보니 테이블생성일시에 대한 컬럼이 있을 것 같다.

 

create_time이 있다.

기본 mysql테이블보다 늦게 생성되었을 태니 역순 정렬하면 될듯 하다

union과 order by를 같이 쓰려면 서브쿼리로 써야한다.... 서브쿼리는 쓸 수 없으니 count로 총 테이블의 개수를 찾고 limit으로 거꾸로 찾아가보자

 

123' union select 1,2,3,4,5, count(TABLE_NAME) from information_schema.TABLES  #

총 64개의 테이블이 있다.

limit 60, 1부터 늘려가보자

 

123' union select 1,2,3,4,5, TABLE_NAME from information_schema.TABLES  limit 60, 1#

유효해보이는 테이블을 찾았다. 컬럼명들을 찾아보자

 

 123' union select 1,2,3,4,5, COLUMN_NAME from information_schema.COLUMNS where TABLE_SCHEMA = 'sqli_5'and TABLE_NAME = 'flag_honey' #

 

flag_honey 테이블에서 flag 컬럼을 가져오자

 

 

이 테이블이 아닌가보다 count결과 1개의 데이터만 존재하기 때문이다.

 

다른 테이블을 찾아보니 secret이라는 이름의 테이블이 존재한다. 컬럼을 찾아보자

여기도 플래그라는 컬럼이 존재한다.

 

 

총 데이터가 몇개 존재할까?

2개

그렇다면 2번째 데이터에는 정답이 있지 않을까?

 

 

빙고!

 


 

+ Recent posts