본문 바로가기

해킹 공격

[NOOBHACK] 사이트에서 SQL injection 해보기

전에는 내가 손수 집적 차린 사이트를 테러하는 짓을 해봤는데 이번에는 하다 못해 백엔드 코드 없이 로그인을 무시하는

방법을 알아 볼 것이다 하지만 그 전에 SQL과 DataBase 라는 것을 알 필요가 있는데

 

 

 

DataBase란

정말 단순하게 말해 웹 사이트가 가지고 있는 정보들의 집합 표 라고 생각하면 된다

 

우리가 단순히 생각 해 보면 롤에서 로그인을 할 때 내가 ID와 PW를 입력 했는데 롤에서는

이 ID와 PW를 보고 내가 누군지 기억하고 알면서 롤을 할 수 있게 해준다 그 ID와 PW를 보관 하고 관리 하는 곳이

DataBase이며 우리가 ID와 PW를 입력하면 DataBase에서 ID와 PW가 일치하는 데이터가 있는지 확인을 해 준다

 

그때 여기서 DataBase를 효율적으로 관리하게 해주는 언어가 SQL이라는 것이다

 

실제 예를 들어보자

이것은 실제 mySQL 이라는 DataBase에 실제 표다

우리가 ID와 PW를 입력하면

 

ID:admin

PW:yong0021

 

이라고 한다면 서버에서는 

ID와 PW가 일치하는 계정이 DataBase안에 있다면 로그인에 성공해 롤을 할 수 있는 것이라고 생각 하면 된다

이때 서버에서는 DataBase안에 ID와 PW가 일치하는 계정이 있는지 찾을 것이다 이 때 사용하는 SQL 구문은

 

SELECT * FROM members WHERE uid="admin" and pwd="yong0021"

 

이렇게 된다 하지만 여기는 NOOBHACK인 컨셉에 걸맞게 SQL를 처음 접하는 분들을 위해 하나하나 설명하자면

 

 

 

 

SELECT: 선택하다는 의미이다 가장 기본적인 SQL명령어으로서 가장 많이 사용 돼는 명령어 중 하나

 

*: 전부 선택한다는 의미다 만약 *대신에 

SELECT uid,pwd FROM members WHERE uid="admin" and pwd="yong0021"

이렇게 되어 있다면 이 구문을 실행 시켰을 때에는 uid와 pwd만 보일 것이고 나머지 정보들은 보여 주지 않을 것이다

 

FROM: Table를 지정하는 명령어 이다 참고로 Table이란 정보들의 집합 표를 Table이라 부른다 DataBase에선 Table이

계정 Table, 게시물 Table, 결제내역 Table 등 한 두개가 아니므로 Table를 구분할 필요가 있다 

사용 예시: SELECT * FROM 테이블명

 

members: 이 테이블의 이름이다 즉 우리가 위에 보고 있는 사진의 테이블 명이 members라는 것

 

WHERE: 조건문이다 쉽게 생각하면 파이썬의 if문으라 생각하면 된다

사용 예시: SELECT * FROM 테이블명 WHERE 조건문

 

이제 얼추 다 설명 한 것 같지만 

SELECT * FROM members WHERE uid="admin" and pwd="yong0021"

구문이 아직도 이해가 안 간다면 이 사진을 보면 편하다 

그럼 처음부터 보여주던가

 

이 구문을 실행 할 시에 아래에 WHERE 조건문에 알맞는 데이터만 나왔다 이 데이터가 없다면 로그인은 실패한 것

그 데이터는 사진 하단에 한 줄만 나타나 있다 (중복돼는 아이디와 비번이 없다는 것)

 

자 이제 SQL에 대해 얼추 알았으니 이제 SQL injection를 알 수 있다

그전에 사전적 의미의 injection이란 "주사하다"라는 의미지만 SQL injection은 SQL의 구문을 속여서 개발자의 의도와는

다른 구문을 실행 시키는 것이 SQL injection의 핵심이다

그리고 이 취약점은 워낙 유명해 아직도 실제 웹 사이트에서도 많이 발견돼고 있다

그리고 개발자 혈압도 많이 오를 것이다

 

먼저 기본적인 SQL injection를 배우기 전에 우리가 웹 사이트에서 회원가입을 할 때에

ID와 비밀번호에 따옴표(')나 큰 따옴표(")같은 문자를 못 쓴다 

 

왜 못 쓰는 걸까?

만약에 쓸 수 있다고 가정을 해보자

내가 롤을 하기 위해 아이디와 비밀번호를 입력 했다

 

ID: admin'

PW: yong0021"

 

그리고 이에 서버는 이 정보와 일치하는 계정을 찾기 위해 SQL를 실행 시킬려고 한다

SELECT * FROM members WHERE uid="아이디" and pwd="비밀번호"

 

SELECT * FROM members WHERE uid=" admin' " and pwd=" yong0021" "

 

 

서버에 오류가 난다 왜냐하면 아이디 admin' 자체에는 문제가 없지만 SQL구문에 대입 될 시에는

따옴표로 인해 문자열 끝의 기준을 헷갈려하여 결국 에러가 나는 것이다

파이썬을 하다 보면 print 함수에 따옴표를 실수로 하나 떠 써서 에러가 났었던 적이 있었다면 더욱 이해가 잘 갈 것이다

 

이제 이것으로 버그가 발견 되었다면 악의적으로 다른 구문으로 만들어 버릴 수 있다

 

SELECT * FROM members WHERE uid="아이디" and pwd="비밀번호"

 

SELECT * FROM members WHERE uid="admin" and pwd="" or "1"

 

진하게 표시한 것이 사용자가 입력한 ID와 PW이다

이것을 실행 하게 된다면 

 

 

이런 구문에 같은 계정이 나오면서 로그인을 성공할 수 있다

사실은 서버는 거짓말을 하지 않았다 정직하게 그 구문에 알맞게 데이터를 보여줬을 뿐이다

 

SELECT * FROM members WHERE uid="admin" and pwd="" or "1"

이 구문에서 ID는 중요하지 않고 PW를 봐야 할 것이다

 

입력값: "or "1

인데 그것이 그대로 구문에 대입이 된다면

양 옆에 따옴표가 더 붙고

 

... and pwd ="" or "1"

pwd에 or문이 추가 되어 둘 중 하나면 True면 pwd의 값은 True가 된다

하지만 or문에서는 이미 "1" 이라는 무조건 True일 수 밖에 없는 조건문이 더 붙혀져 결국

ID가 admin 뿐인 데이터를 가져와 보여 주게 된 것이다 

 

그럼 집적 해보자

 

 

편의상 패스워드의 필터링을 제거 했고

원래 비밀번호인 yong0021입력해야 로그인 됐던 서버도

 

이렇게 뚫리게 된다

하지만 이것은 보안이 안되었다는 가정 하에 가능한 해킹이지 왠만한 사이트는 다 막혔다

 

이렇게 SQL의 구문을 만족 시키기만 한다면 방금 보여준 예시와 달라도 어떤 패스워드에 값을 넣든 로그인이 가능하다

그렇다고 다른 인터넷 사이트에 괜히 따라해서 IP 차단 당하지 말자