본문 바로가기
개념 노트장

[SQL] mysql boolean 비교 시 동작 방식과 false injection

by jwcs 2024. 2. 23.
728x90

출처

https://mysqlcode.com/mysql-bool-boolean/

 

MySQL BOOL, BOOLEAN - A Complete Guide - MySQLCode

In this tutorial, we will learn the MySQL data type BOOL and BOOLEAN. We will also be learning how to implement boolean in the queries and some exceptions you

mysqlcode.com

https://marketsplash.com/tutorials/mysql/mysql-boolean/

 

Working With The MySQL Boolean Data Type

Delve into MySQL Boolean data types, a key aspect for developers. This article provides a practical approach to using Boolean in MySQL, including variable declaration, query optimization, and common mistakes to avoid.

marketsplash.com

https://cvk.posthaven.com/sql-injection-with-raw-md5-hashes

 

SQL injection with raw MD5 hashes (Leet More CTF 2010 injection 300)

The University of Florida Student Infosec Team competed in the Leet More CTF 2010 yesterday. It was a 24-hour challenge-based event sort of like DEFCON quals. Ian and I made the team some...

cvk.posthaven.com

위 사이트들에서는 훨씬 더 자세하고 많은 양의 내용을 다루고 있다. 필자는 제목에 해당하는 내용만 다루겠다.

 

mysql의 boolean 데이터 유형은 tiny int이다.

https://mysqlcode.com/mysql-bool-boolean/

비교시에 true는 1, false는 0으로 convert된다. 그럼 아래 4가지 상황을 가정해보자.

1. select * from user where true = 1;

2. select * from user where true = 11;

3. select * from user where true = '1';

4. select * from user where true = '11';

 

  • 1번째 상황이다. true와 숫자 1의 비교다.

워크벤치에서 실행해보았다

true는 1로 변환되기 때문에 true가 되어 값이 출력되는 것을 확인할 수 있다.

 

  • 2번째 상황이다. true와 11의 비교다.

2번째 상황

1과 11은 같은 값이 아니다. 따라서 false가 출력된다.

 

  • 3번째 상황이다. true와 문자 '1'의 비교다

3번째 상황

true는 1로 변환되고, 문자 '1' 역시 문자에서 숫자값으로 변환된다. 따라서 true가 되는 것이다

 

  • 4번째 상황이다. true와 문자 '11'의 비교이다.

4번째 상황

true와 문자 11이 각각 1과 11로 변환되어 false가 된 모습이다.

 

이를 통해 boolean값과 문자열이 숫자로 convert되어 comparison되는 것을 확인했다. 그러면 '11'과 같은 문자열이 아니라 'aa'와 같은 문자열은 어떻게 변환될까? 아래 4가지 상황을 더 살펴보자.

 

5. select * from user where false = 'aa';

6. select * from user where false = '1aa';

7. select * from user where false = '0aa';

8. select * from user where 'aa' = 0;

 

  • 5번째 상황이다. false와 문자열 'aa'의 비교다.

5번째 상황

false는 0으로, 'aa' 역시 0으로 변환되어 0 = 0 -> true가 된 모습이다.

 

  • 6번째 상황이다. false와 문자열 '1aa'의 비교다.

6번째 상황

false와 '1aa'의 비교다. 각각 0과 1로 변환되어 false가 됐다. 이로써 문자열이 숫자로 변환될 때는 맨 앞을 기준으로 바뀐다는 것을 알 수 있다. php의 느슨한 비교가 생각난다.

 

  • 7번째 상황이다. false와 '0aa'

7번째 상황

이 역시 각각 0과 0으로 변환되어 true가 된다.

 

  • 8번째 상황이다. 그럼 명시적으로 false라고 나타낸 것이 아닌 0과 문자열 'aa'의 비교는 어떻게 될까?

8번째 상황

'aa'가 0으로 변환되어 true가 된다.

 

 

false injection

그럼 false injection에 대해 간략히 알아보자.

select * from user where passwd = 'aaa' = 'bbb'

위의 sql문은 true가 되어 데이터를 출력해줄까? 혹은 false가 될까?

 

passwd = 'aaa'에서 'aaa'라는 값을 가진 레코드를 찾지 못했다. 따라서 false이다.

false = 'bbb'는 위에서 알아봤듯, 0과 0으로 convert되어 true가 될 것이다.

false inj 예시

 

or를 사용한 경우

이번엔 `or`로 inj하는 상황을 가정해보자. 

9. select * from user where passwd = 'aaa' or 'bbb'

10. select * from user where passwd = 'aaa' or '1bbb'

11. select * from user where passwd = 'aaa' or '2bbb'
  • 9번째 상황이다. passwd = 'aaa' or 'bbb'

9번째 상황

passwd= 'aaa'라는 레코드를 찾지 못하기 때문에 false

false or 'bbb'인데, string인 'bbb'는 0으로 cast된다.

https://cvk.posthaven.com/sql-injection-with-raw-md5-hashes

따라서 결과는 false이다.

 

  • 10번째 상황. passwd= 'aaa' or '1bbb'이다.

10번째 상황

앞선 상황으로 생각해보면 `false or 1`인 것을 알 수 있다. 따라서 true이다.

 

  • 11번재 상황이다. passwd='aaa' or '2bbb'이다.

11번째 상황

`false or 2`인 상황일 것이다. 오늘 공부한 내용으로 인해 0을 제외한 모든 숫자값이 true가 된다는 것을 잊지말자.

https://mysqlcode.com/mysql-bool-boolean/

 

728x90
반응형