Vulnerability: SQL Injection
์ฟผ๋ฆฌ๋ฌธ์ ๊ตฌ์กฐ๋ฅผ ํ์ ํ๊ณ , SQL Injection์ ์ด์ฉํ์ฌ ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ์กฐํ(์ถ๋ ฅ)ํด๋ณด๋ ๊ฒ์ ๋ชฉ์ ์ผ๋ก ํ๋ค.
DVWA SQL Injection ์ค์ต
์ค์ต ํ๊ฒฝ
- Windows Docker๋ฅผ ์ด์ฉํ DVWA
- Windows ํ๊ฒฝ์ Burp Suite
Security Level: Low
Low ๋ ๋ฒจ์ ๊ฒฝ์ฐ, User ID์ ํด๋นํ๋ ํ๋ผ๋ฏธํฐ๋ฅผ ์ง์ ์ ๋ ฅํ๋ ๊ฒ์ด ๊ฐ๋ฅํ๋ค.
์์ User ID์๋ 1~5์ ์ซ์์ ๋ํ ๊ฐ์ด ์กด์ฌํ๋ค. ๊ฐ๊ฐ์ ์ ๋ ฅ์ ๋ํ ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ๋ค.
์์ ๊ฒฐ๊ณผ ๊ฐ์ ์ ๋ฆฌํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
ID: 1 - First name: admin / Surname: admin
ID: 2 - First name: Gordon / Surname: Brown
ID: 3 - First name: Hack / Surname: Me
ID: 4 - First name: Pablo / Surname: Picasso
ID: 5 - First name: Bob / Surname: Smith
Query ์์
์ ๋ ฅ ํ๋ผ๋ฏธํฐ(parameter)๋ user ID ์ด๊ณ , ๊ทธ์ ํด๋นํ๋ First name๊ณผ Sun name์ ๋ฐํํด์ฃผ๊ณ ์๋ค.
SELECT First_name, Sun_name FROM ~~~ WHERE UserID = '_____' ;
์ค์ Query
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
์ฟผ๋ฆฌ ์์ผ๋ก user_id์ ํด๋นํ๋ ํ๋ผ๋ฏธํฐ๋ '___' ์ฌ์ด์ ๋ค์ด๊ฐ ๊ฒ์ด๊ธฐ ๋๋ฌธ์, user_id' or ์ฐธ์ธ ๊ฐ์ ๋์ ํ๋ ๊ฒฝ์ฐ, ํญ์ ์ฐธ์ธ ๊ฐ์ด ๋๊ธฐ ๋๋ฌธ์ ๋ชจ๋ user ์ ๋ณด๋ฅผ ์ป์ ์ ์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ๊ณ ์ด๋ฅผ ํ์ธํด๋ณธ๋ค.
1' or 1=1 # / 1' or '1'='1
(๊ฐ๋ฅํ๋ฉด ์ฃผ์์ ์ฌ์ฉํ์ง ์๋ ๊ฒ์ด ์ข๋ค.)
์์ ๊ฐ์ด 1~5์ ์ ์ฒด ๋ฐ์ดํฐ๊ฐ ์กฐํ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
WHERE id = '____' ; ๊ณผ ๊ฐ์ Query ์ ๋น์นธ์ 1' or '1'='1๋ฅผ ์ ๋ ฅํ๋ ๊ฒฝ์ฐ ๋ค์๊ณผ ๊ฐ๋ค.
WHERE id = '1' or '1'='1';
์์ ๊ฐ์ ๊ฒฝ์ฐ WHERE ์กฐ๊ฑด์ด ํญ์ ์ฐธ์ด ๋๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ์ฌ์ฉ์์ ์ ๋ณด๊ฐ ์ถ๋ ฅ๋๋ ๊ฒ์ด๋ค.
์๊ฐํด๋ณผ ์
ํ๋์ ๊ฐ์ ์ ๋ ฅํ์ฌ์, ์ ์ฒด ๋ฐ์ดํฐ๊ฐ ์กฐํ๋๋ ๊ฒ์ ์ด๋ฏธ SQL Injection์ด ๊ฐ๋ฅํ๋ค๋ ์ฆ๋น์ด ๋๋ค.
์ฌ์ฉ์์ ์ ๋ ฅ ๊ฐ์ด ์ ๋ฌ๋๋ ๊ฒฝ๋ก๋ ์น ๋ธ๋ผ์ฐ์ (Web Browser) -> ์น ์ ํ๋ฆฌ์ผ์ด์ (Web Application) -> DB ์๋ฒ(SQL Parser, SQL ๋ถ์๊ธฐ)๋ก ์ถ์ ์ด ๊ฐ๋ฅํ ๊ฒ์ด๋ค.
๊ณต๊ฒฉ์๊ฐ ์ฝ์ ํ SQL ๊ตฌ๋ฌธ์ด ํด์๋์๋ค๋ฉด SQL Parser์์ or ์ฐ์ฐ์์, ์ฃผ์(#) ๋ฐ์๋ฅผ ์ฒ๋ฆฌํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ SQL Injection ์ทจ์ฝ์ ์ด ์๋ค๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ข ๋ ์์ธํ ํ์ธ์ ์ํด์๋ and ์ฐ์ฐ์๋ฅผ ์ด์ฉํ์ฌ ์ฐธ(true) / ๊ฑฐ์ง(false) ๊ฐ์ ๊ฐ๊ฐ ํ์ธํด๋ณผ ์ ์๋ค.
1' or 1=1 # (์ ์ฒด ๋ฐ์ดํฐ ์กฐํ)
1' or 1=2 # (1 ๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ)
1' and 1=1 # (1๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ)
1 ' and 1=2 # (๊ฒฐ๊ณผ ์์)
๊ณผ ๊ฐ์ด or / and ์ฐ์ฐ์์ ๋ํ ์ฐธ/๊ฑฐ์ง ๊ฐ์ ์ํ์ฌ ์ถ๋ ฅ ๊ฐ์ ๋ณํ๊ฐ ์๋ ๊ฒ์ ๊ด์ฐฐํ ์ ์๋ค.
Security Level: Medium
Medium ๋ ๋ฒจ์ ๊ฒฝ์ฐ, ๋ค์๊ณผ ๊ฐ์ด ์ฝค๋ณด ๋ฐ์ค(Combo Box)์ 1~5์ ๊ฐ์ด ์กด์ฌํ๋ค.
์์ ์ฝค๋ณด ๋ฐ์ค ๋ถ๋ถ์ ๋ค์๊ณผ ๊ฐ์ด ์ด๋ฃจ์ด์ ธ ์๋ค.
ํด๋น ์ฝค๋ณด ๋ฐ์ค์ ๊ฒฝ์ฐ, ์ฌ์ฉ์๋ ์ง์ ๊ฐ์ ์ ๋ ฅํ ์ ์๊ณ , ๋ชฉ๋ก์ ์กด์ฌํ๋ 1~5์ ๋ํด์๋ง ๊ฐ์ ์ ํํ ์ ์๋ค.
ํ์ง๋ง Burp Suite๋ก ํ์ธํด๋ณด๋ฉด ํด๋น ๊ฐ์ ๋ํ ํ๋ผ๋ฏธํฐ ๊ฐ์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ๋ณ์กฐํ์ฌ ๋ค๋ฅธ ๊ฐ์ ์ฝ์ ํ ์ ์๋ค.
id=1~5&Submit=Submit
์์ ๊ฐ์ด ๊ธฐ๋ณธ์ ์ผ๋ก๋ id ํ๋ผ๋ฏธํฐ์ ์ฝค๋ณด๋ฐ์ค์ ์กด์ฌํ๋ 1~5๊ฐ ์ ๋ ฅ๋์ง๋ง, ์ด๊ฒ์ ๋ณ์กฐํ์ฌ ์์ฒญํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
id=1+or+1=1# / id=1+or+1=1
(๊ฐ๋ฅํ๋ฉด ์ฃผ์์ ์ฌ์ฉํ์ง ์๋ ๊ฒ์ด ์ข๋ค.)
์์ ๊ฐ์ด id ํ๋ผ๋ฏธํฐ๋ฅผ ๋ณ์กฐํ์ฌ ์์ฒญํ๋ ๊ฒฝ์ฐ ๋ชจ๋ user ์ ๋ณด๊ฐ ์ถ๋ ฅ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ค์ ์ฟผ๋ฆฌ๋ฅผ ์ดํด๋ณด๋ฉด ์์ ๊ฐ์๋ฐ, mysqli_real_escape_string์ ์ด์ฉํ์ฌ NUL (ASCII 0), \n, \r, \, ', ", CTRL+Z. ์ ๊ฐ์ ๊ฐ์ ๋ง๋๋ค. ์ฝค๋ณด ๋ฐ์ค๋ก ๊ฐ์ ๋ฐ๊ณ ์๊ธฐ ๋๋ฌธ์ ํด๋น ๊ฐ์ ์ซ์ ๊ฐ์ผ๋ก ๋ฐ์์ง๊ธฐ ๋๋ฌธ์ ' ์ " ๋ฑ์ ๋ง๋ ์ญํ ์ ํ๋ ๊ฒ์ผ๋ก ๋ณด์ฌ์ง๋ค. ํ์ง๋ง ์์ ๊ฐ์ด ๋ฐ์ดํฐ๋ฅผ ์ ์ฒด ์กฐํํ๋ ๋ฐ์๋ ๋ฌธ์ ๊ฐ ์์๋ค.
Security Level: High
High ๋ ๋ฒจ์ ๊ฒฝ์ฐ, ํ์ ์ฐฝ์ ํตํด ์ ๋ ฅ์ ๋ฐ๋๋ค.
here to change your ID. ๋ฅผ ๋๋ฅด๋ฉด ๋ค์๊ณผ ๊ฐ์ ํ์ ์ฐฝ์ด ๋์จ๋ค.
// Get input
$id = $_SESSION[ 'id' ];
// Check database
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
SQL๋ฌธ์์ ์ฌ์ฉํ id ๊ฐ์ ์๋ฒ์ ์ธ์ (session)์ผ๋ก๋ถํฐ ์ฝ์ด์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์จ์ ํ๊ฒ ์์ ํ ๋ฐฉ๋ฒ์ด๋ผ๊ณ ํ ์ ์๋ค. ์ค์ง์ ์ผ๋ก ์ฌ์ฉ์๊ฐ ์๋ฒ์ ์ ์ฅ๋ ์ธ์ ๋ด์ ๊ฐ์ ์กฐ์ํ ๋ฐฉ๋ฒ์ด ์๊ธฐ ๋๋ฌธ์ด๋ค.
ํ์ง๋ง ํด๋น ๋ฌธ์ ์ ๊ฒฝ์ฐ ์๋ฒ์ ์ธ์ ์ ์ ์ฅ๋๋ ๊ฐ์ ์ฌ์ฉ์๊ฐ ๋ณ๊ฒฝํ ์ ์๋ ์๋์ ๊ฐ์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ๊ณตํ๋ค.
์ด๊ฒ์ ๋นํ์ค์ ์ธ ์ํฉ์ ๊ฐ์ ํ ๊ฒ์ผ๋ก ๋ณด์๋ ๋ฌด๋ฐฉํ๋ค๊ณ ํ ์ ์๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ธ์ ์ ์๋ฒ๊ฐ ์๋์ผ๋ก ๋ง๋๋ ๊ฒ์ผ๋ก, ๋ก๊ทธ์ธ์ ํ๋ ๊ณผ์ ์์ ๊ฒ์ฆ๋ ๊ฐ(ID, ๊ถํ)์ ์ ์ฅํ๋ค. ์ด๋ฌํ ๊ฐ์ ์๋ฒ์ ์ ์ฅ๋๋ ๊ฐ์ผ๋ก์ ์ฌ์ฉ์๊ฐ ๊ด์ฌํ ์ ์๋ ๊ฒฝ์ฐ๋ ๊ฑฐ์ ์๋ค๊ณ ๋ณผ ์ ์๋ค.
์์ ์ ๋ ฅ ์ฐฝ์ ๋ํ์ฌ ์ดํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
ํด๋น ์ ๋ ฅ์ฐฝ์ ํตํด ์ ๋ ฅํ๋ฉด ํด๋น ์ ๋ ฅ๊ฐ์ด ์ ๋ ฅ์ฐฝ์ ๋ํ๋๊ณ , ํด๋น ๊ฐ์ด ์ ๋ฌ๋๋ค.
์ฐ์ ์ด์ ๋ ๋ฒจ์์ ์๋ํด๋ดค๋ ๊ฐ์ ์ ๋ ฅํด๋ณธ๋ค.
1' or '1'='1
์์ ๊ฐ์ด ์ ๋ ฅํ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด, ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค.
์ด์ ์ ๋ ๋ฒจ๊ณผ ์ฟผ๋ฆฌ๋ฌธ์ด ๊ฐ๋ค๊ณ ๊ฐ์ ํ๋ค๋ฉด, ์ ์ฒด ๋ฐ์ดํฐ๊ฐ ์กฐํ๋์ด์ผ ํ๋ค. ํ์ง๋ง High ๋ ๋ฒจ์ ๊ฒฝ์ฐ, ํ ์ค๋ง ์ถ๋ ฅ๋์๋ค. ๊ทธ๋ ๋ค๋ฉด ์ด๊ฒ์ ๋ฐํ๋๋ ํ ์๋ฅผ ์ ํํ๋ค๊ณ ๋ณผ ์ ์๋ค.
MySQL ์์ LIMIT์ ์ด์ฉํ ํ์์ ์ ํ์ ๋ค์๊ณผ ๊ฐ์ ์ฟผ๋ฆฌ๋ฅผ ๊ฐ์ง๋ค.
mysql> SELECT ์ด๋ช FROM ํ ์ด๋ธ๋ช WHERE ์กฐ๊ฑด์ ORDER BY ์ด๋ช LIMIT ํจ์;
๊ทธ๋ ๋ค๋ฉด ์์ ๊ฒฝ์ฐ, ORDER BY ๊ตฌ๋ฌธ์ ์๋ค๊ณ ์๊ฐํ ์ ์์ผ๋, ์กฐ๊ฑด์์ธ WHERE ๊ตฌ๋ฌธ ๋ค์ LIMIT ํจ์๊ฐ ๋ถ์ด ์๋ค๊ณ ์๊ฐํ ์ ์๋ค. ๊ทธ๋ ๋ค๋ฉด ์ฃผ์์ ์ด์ฉํ๋ฉด ์ฐํ๊ฐ ๊ฐ๋ฅํ๋ค๊ณ ๋ณผ ์ ์๋ค.
์ฌ๊ธฐ์ ์ฃผ์์ # ๋๋ -- ๋ฅผ ์ด์ฉํ ์ ์๋ค. ( -- ์ ๊ฒฝ์ฐ -- ๋ค์ ๊ณต๋ฐฑ์ด ํ์นธ ์ ์ฉ๋์ด์ผ ์ฃผ์์ผ๋ก ์ธ์ํ๋ค.)
๊ทธ๋ ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ ๊ฐ์ ์ ๋ ฅํด๋ณผ ์ ์๋ค.
1' or 1=1 # / 1' or 1=1 --
(1=1 ์ ์ ๋ ฅํ๊ฑฐ๋ '1'='1'์ ์ ๋ ฅํด์ or ๋ค์ ๊ฐ์ ์ฐธ์ด๊ธฐ๋ง ํ๋ฉด๋๋ค.)
์์ ๊ฐ์ด ์ ๋ ฅํด์ค ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ๋ค.
์์ ๊ฐ์ด ์ ์ฒด ๋ฐ์ดํฐ๊ฐ ์กฐํ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค. ์ด๋ฅผ Burp ํตํด ํ์ธํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
์ค์ ์ฟผ๋ฆฌ ๋ถ๋ถ์ ์ดํด๋ณด๋ฉด ์์ ๊ฐ์ด LIMIT 1์ ์ด์ฉํ์ฌ, ํ ์ค๋ง ์ถ๋ ฅํด์ฃผ๊ณ ์๋ ๊ฒ์ ํ์ธํ ์ ์์๋ค.
Security Level: Impossible
Impossible ๋ ๋ฒจ์ ๊ฒฝ์ฐ ๋ค์๊ณผ ๊ฐ์ด Low ๋ ๋ฒจ๊ณผ ๊ฐ์ด ์ ๋ ฅ ๊ฐ์ ์ง์ ์ ๋ ฅํ ์ ์๋ค. ํ์ง๋ง ์ซ์ ๊ฐ๋ง ๋ฐ๋๋ก ์กฐ์น๋์ด ์๊ณ , ๊ธฐ์กด์ Medium ์ ๋ณด์ ์กฐ์น์ ๋๋ถ์ด Prepared State๋ฅผ ์ด์ฉํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์๋ฒฝํ ๋ณด์ ์กฐ์น๋ฅผ ์ทจํ๊ณ ์๋ค๊ณ ๋ณผ ์ ์๋ค.
์์ ๊ฐ์ด ์ ๋ ฅ๋๋ ํ๋ผ๋ฏธํฐ์ ๋ํ์ฌ ์ซ์์ธ์ง ํ์ธํ๊ณ , ๊ฒฐ๊ณผ ๊ฐ์ ๋ํ์ฌ๋, ํ์ค์ ๊ฒฐ๊ณผ๋ง์ด ๋์ค๋์ง ํ์ธํ๊ณ ์๋ค.
์ง๋ฌธ ํ์, ์์ ๋ฐ ๋ณด์์ ๋ํ ์ง์ ํ์