보안 공부/해킹기법

SQL injection(SQL 인젝션 공격)

sh1256 2022. 1. 15. 15:55
728x90

SQL injection(SQL 인젝션 공격)

SQL, 컴퓨터 보안, 해킹 기법, 

 

 

SQL 인젝션 공격이란 무엇일까요?

나무위키에 따르면, 코드 인젝션의 한 기법으로 클라이언트의 입력값을 조작하여 서버의 데이터베이스를 공격할 수 있는 공격방식을 말합니다. 

출처: https://namu.wiki/w/SQL%20injection

 

이렇게 말로 풀어 쓰니 어려워 보입니다. 

예를 하나 들어서 설명해 보죠!! (생각보다 쉬우니 따라와 보세요!!)

 

흔하디 흔한 SQL 구문을 하나 가져왔습니다. 

select data from table1 where id='id입력값' and pw='pw입력값'

table1

자 이렇게 table1이 있고, table1과 연결되있는 웹사이트가 하나 있다고 해봅시다. 

웹사이트에 ID와 PW를 입력하면 data가 출력되는 거라고 가정해보죠!

 

 

 

 

 

만약에 id=guest로 로그인한다고 하면

이렇게 작동이 되는 겁니다. 

 

이 때 SQL 쿼리문은

select data from table1 where id='guest' and pw='guest1234'

가 되서 해당하는 data인 'hello'를 출력하게 되는겁니다. 

 

 

 

 

그런데 우리는 id가 admin에 해당하는 data를 얻고 싶습니다! (기밀문서!! 그거!!)

그러기 위해선 admin의 pw를 알아야 하는데 우리에겐 관련 정보가 1도 없다고 가정해 봅시다. 

그래도 우리에겐 SQL injection라는 돌파구가 있습니다. 

 

대표적인 SQL injection 방법은 바로 주석을 이용하는 것입니다. 

만약 id 칸에 admin'-- 을 입력하면 

select data from table1 where id='admin'--' and pw='guest1234'

이렇게 --뒤부터는 주석으로 인식되어 pw부분은 쿼리문에 사용되지 않게 됩니다. 

 

그러면 id='admin'인 부분의 data인 기밀문서를 볼 수 있게 되는 거죠!!

 

 

 

 

이 외에도 다른 id들의 data도 모두 볼 수 있는 방법이 있습니다. 

select data from table1 where id='admin' or '1'='1'--

select data from table1 where id='admin'or '1'='1'--' and pw='guest1234'

위의 방법을 사용하면, where문의 조건이 id='admin' 또는 1=1(무조건 참)으로 되어서 table1의 모든 data를 가져올 수 있습니다. 

 

 

 

위의 두 구문으로 인해 sql 인젝션에 대한 감이 오셨나요? 

 

 

 

그럼 다른 문제를 한번 봅시다. 

preg_match()라는 함수를 아나요?

preg_match()는 간단히 말해서 필터링을 해주는 함수입니다. 

 preg_match("/admin/u","$id")  --> id입력값에서 admin을 찾으면 1을 반환한다. 

위 필터는 sql injection 방지를 위해 자주 쓰이는 함수입니다. 

id가 admin인 경우를 원천 차단하는 거죠.

 

 

 

위 함수를 우회하는 것은 간단합니다. 

바로 admin 대신 ADMIN을 사용하는 거죠

SQL 에서는 대소문자를 구분하지 않기 때문에 admin이던 ADMIN이던 같은 값으로 받아들입니다.

 

 

그럼

preg_match("/admin/i","$id")  --> id입력값에서 admin(대소문자 상관X)을 찾으면 1을 반환한다. 

대소문자를 상관없게 만드는 /i를 추가해 봅시다.

이제 ADMIN 이건 AdMiN이건 통하지 않은거죠.

 

하지만 이것도 뚫을 방법이 있습니다. (쉬운 방법도 있지만 조금 어렵게 가볼께요)

select data from table1 where id=''/* and pw = '*/ or id = 'admin'

 

흠 감이 오시나요?

힌트를 드리자면 /* */은 각 별 사이의 글을 주석으로 처리합니다. 

 

 

select data from table1 where id=''/* and pw = '*/ or id = 'admin'

바로 이렇게 말이죠!!

이렇게 되면 id= 'admin'인 곳의 data를 가져 올 수 있습니다. 

 

 

 

앞서 소개한 sql 인젝션 말고도 다양한 방법들이 있습니다. 

참고 --> https://sh1256.tistory.com/23?category=989861

 

SQL내장함수 모음 --> https://blog.naver.com/foryunha/20139047181

 

 

이런 SQL 인젝션은 너무나도 잘 알려진 공격 기법이기 때문에

대부분의 서버에서는 SQL 인젝션에 대한 방어가 되어 있습니다.

 

 

섣불리 시도하다간 IP차단만 당하고 말테니, 공부 용도로만 사용해 주세요 ^-^