인프런 커뮤니티 질문&답변

김소연님의 프로필 이미지
김소연

작성한 질문수

모의해킹 실무자가 알려주는, SQL Injection 공격 기법과 시큐어 코딩 : PART 1

[실습4-1] 환경 분석 실습

mysql 연결연산자 질문드립니다.

작성

·

305

·

수정됨

1

안녕하세요.

이전에 강사님이 써주신 답변을 통해,

mysql에서의 공백은 사실 공식적으로는 연결 연산자는 아니며 구문을 구분해주는 역할을 하는 것이라고 참고하였습니다.

 

[실습4-1] 환경 분석 실습에서 위와 같이 %2b를 통해,

MSSQL의 연결 연산자인 +를 테스트해보았는데 결과가 잘 출력됩니다.

-> 실행 페이로드 : ?idx=13+and+'test'='te'%2b'st'

이런 경우 연결 연산자로 판단하는 관점에서는 mysql과 MSSQL을 혼동할 여지가 있는 것 같은데,

True로 쿼리가 실행되는 이유가 궁금합니다.

항상 좋은 강의 감사합니다.

답변 2

1

크리핵티브님의 프로필 이미지
크리핵티브
지식공유자

안녕하세요.

이부분을 설명할까 고민하다가 넣지 않고 스스로 풀? 과제처럼 생각하긴 했었습니다.ㅎㅎ

 

mysql에서는 다른 dbms와는 다른 성향을 가지고 있습니다.

'test'='te'+'st' 구문을 해석해보면,

mysql에서는 +는 연결 연산자가 아닌 산술 연산자 입니다.

따라서, 'te'+'st'에서 산술연산을 위해 'te'와 'st'는 숫자로 형 변환을 하려고하고 하지만

'te'와 'st' 형변환을 할 수 없기 때문에 0이 반환됩니다.('0', '1' ... 이런 문자는 형변환이 됨)

결국 0+0이 되어 결과는 0입니다.

그러면 , 'test'=0 이런 구문이 완성되는데, 여기서도 비교 연산자에서 피연산자1은 문자형, 피연산자2는 숫자형이기 때문에 우선순위가 높은 숫자형 기준으로 피연산자1은 형변환이 발생됩니다.(이부분은 규칙 같은거)

그러나 'test' 또한 형변환 실패를 하게 되여 0이 반환되어 결국 0=0 이기 때문에 참이되는 기이한(?) 결과가 반환 됩니다.

따라서 mysql에서 실습한 것이 결과가 참이 되었던 것입니다.

 

그러면 질문하신 mysql과 mssql을 어떻게 구분하냐? 이부분은

mssql은 'test'='te' 'st' 이렇게 요청하면 에러가 발생됩니다.

그러나 mysql은 정상 결과가 반환됩니다.

따라서 +를 통한 결과가 잘나왔다면, 공백을 통해 식별하는 방법도 있습니다.

또 다른 방법으론 len 함수를 이용하는 것 입니다.

idx=100+and+len('test')=4

이렇게 요청을 했는데 참 결과가 나오면 mssql, 나오지 않으면 mysql이 됩니다.

이유는 len 함수는 mssql 함수이기 때문입니다.

 

 

김소연님의 프로필 이미지
김소연
질문자

강사님 안녕하세요~ 허억 이런 히스토리가 있었군요.
설명을 하지 않으신 큰 뜻에 감명(?)받고 갑니다.

DBMS의 특성또한 잘 알아야 성공적인 SQLI 공격을 수행할 수 있다고 하셨던 점이 이번 답변에서 크게 와닿았습니다. MySQL과 MSSQL의 함수 사용 등이 달라서 또다른 구분이 가능하다는 것을 질문 당시에 시야가 좁아져서 잊어버렸습니다. ^^;;

'+' 등의 산술연산자에서 숫자가 문자열보다 우선순위가 높아 int로 형변환하는 것으로 이해하였고, 답변주신 내용을 토대로 '10'과 같이 숫자로 구성된 문자열이 아니면 형변환이 되지 않아 0으로 처리된다는 점도 알게 되었습니다.

초반에는 환경설정 부분이 잘 되지 않아 최신 버전(PHP 7, MariaDB 10)를 사용해야만 했어서,

제공해주신 게시판 함수 일부를 해당 버전 문법으로 디버깅해보며 바꿔서 실습을 하고 있어 아주 애정을 가지고 있는 강의인데 이렇게 답변주시니 더욱 기쁩니다~!

앞으로도 열심히 시간투자해서 제가 도출한 진단결과에 확신을 가져보고 싶어요! 감사합니다!

0

안녕하세요, 인프런 AI 인턴입니다.
전달해주신 내용을 바탕으로 질문에 답변 드리겠습니다.

HTTP 요청 예시를 보면 MySQL 데이터베이스에서 %2b (URL 인코딩된 ‘+’ 기호)를 이용해 연결 연산자처럼 사용한 것으로 보입니다. 일반적으로 MySQL에서는 문자열 연결을 위해 CONCAT() 함수를 사용하거나, 경우에 따라 || 연산자가 사용됩니다. + 연산자는 MySQL에서는 기본적으로 정수 연산에 사용되는 연산자입니다.

하지만, 예시에서 주어진 쿼리가 해당 MySQL 환경에서 잘 실행되었다고 하신 것을 보면, 소급적으로 서버 측에서 어느 정도의 처리가 이루어진 것으로 추정됩니다. 예를 들어, URL 인코딩을 디코딩한 + 기호가 문자열 연결을 위해 내부적으로 해석되었거나, 웹 애플리케이션 측에서 추가적인 쿼리 해석을 거치는 등의 상황이 있을 수 있습니다.

정확한 상황을 알기 위해서는 서버 측의 코드나 데이터베이스 쿼리 처리 로직을 확인해볼 필요가 있습니다. 또한, + 기호를 사용한 쿼리가 실제로 어떻게 실행되었는지, 실제 쿼리 로그를 보거나 테스트 환경에서 같은 쿼리를 실험해보는 것도 정확한 원인 분석에 도움이 될 것입니다.

보다 자세한 정보는 Spring Data JPA의 공식 문서의 ‘Using Advanced LIKE Expressions’ 섹션을 참조하시어, SQL Injection의 안전한 예방책을 마련하는 것이 중요합니다.

참조 URL: Spring Data JPA Reference Documentation

MySQL과 관련된 추가적인 정보가 필요하시다면 관련 문서를 참고하시거나, 질문이 있으시다면 언제든 질문해주세요.

김소연님의 프로필 이미지
김소연

작성한 질문수

질문하기