day77 πŸŒ•

μž₯λ―ΈΒ·2022λ…„ 8μ›” 30일
0

였늘의 μ„±κ³Ό

λͺ©λ‘ 보기
77/129

λ°€λ¦° κ±° 처리!!!!!!!!


ν† ν”½ 1개 - SQL Injection

+) 22. 08. 31. μΆ”κ°€!!

SQL Injection κ³΅κ²©μ΄λž€, μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ DB에 쿼리λ₯Ό μš”μ²­ν•  μ‹œ μž…λ ₯된 λ°μ΄ν„°μ˜ μœ νš¨μ„± 검증을 ν•˜μ§€ μ•Šμ•„ DB 정보λ₯Ό μ—΄λžŒν•˜κ±°λ‚˜ μ‘°μž‘ν•  수 μžˆλŠ” λ³΄μ•ˆ 취약점을 λ…Έλ¦° 곡격을 λ§ν•œλ‹€.

SQL Injection은 일반적으둜 μ‚¬μš©μž 이름 / μ‚¬μš©μž ID와 같이 μ‚¬μš©μžμ—κ²Œ μž…λ ₯을 μš”μ²­ν•  λ•Œ λ°œμƒν•œλ‹€.

userId = getRequestString("userId");
sql = "SELECT * FROM Users WHERE userId = " + userId;

1 = 1을 기반으둜 ν•˜λŠ” SQL Injection은 항상 참이닀.
λ§Œμ•½ userId λ₯Ό 105 OR 1=1둜 μž…λ ₯ν•œλ‹€λ©΄ SQL문은 λ‹€μŒκ³Ό 같이 ν‘œμ‹œλ  것이닀.

SELECT * FROM Users WHERE userId = 105 OR 1=1;

μœ„μ˜ SQL문은 μœ νš¨ν•˜λ©°, OR 1=1이 항상 참이기 λ•Œλ¬Έμ— Users ν…Œμ΄λΈ”μ˜ λͺ¨λ“  rowsλ₯Ό λ°˜ν™˜ν•œλ‹€.
이 λ•Œ Users ν…Œμ΄λΈ”μ— 이름과 μ•”ν˜Έκ°€ ν¬ν•¨λ˜μ–΄ μžˆλ‹€λ©΄, λ°μ΄ν„°λ² μ΄μŠ€μ˜ λͺ¨λ“  μ‚¬μš©μž 이름과 μ•”ν˜Έμ— μ ‘κ·Όν•  수 μžˆμ„ 것이닀.

β€œβ€=””에 κΈ°λ°˜ν•œ SQL Injection은 항상 참이닀.
λ‹€μŒκ³Ό 같은 μ‚¬μš©μž 둜그인 μ˜ˆμ‹œκ°€ μžˆλ‹€.

Username: Jangmi
Password: myPass

uName = getRequestString("username");
uPass = getRequestString("userpassword");

sql = 'SELECT * FROM Users WHERE Name ="' + uName + '" AND Pass ="' + uPass + '"'

μœ„μ™€ 같은 SQL문을 μž…λ ₯ν•˜λ©΄ μ•„λž˜μ™€ 같은 SQL문이 μ™„μ„±λœλ‹€.

SELECT * FROM Users WHERE Name = β€œJangmi” AND Pass =β€œmyPass”

μ‚¬μš©μž 이름 λ˜λŠ” νŒ¨μŠ€μ›Œλ“œ ν…μŠ€νŠΈ μƒμžμ— β€œ OR β€œβ€=”을 μ‚½μž…ν•˜λ©΄ λ°μ΄ν„°λ² μ΄μŠ€μ˜ μ‚¬μš©μž 이름과 μ•”ν˜Έμ— μ ‘κ·Όν•  수 μžˆλ‹€.

μ„œλ²„λŠ” λ‹€μŒκ³Ό 같은 μœ νš¨ν•œ SQL문을 μƒμ„±ν•œλ‹€.

SELECT * FROM Users WHERE Name =”” or ””=”” AND Pass =”” or ””=””

μœ„μ˜ SQL문은 μœ νš¨ν•˜λ©°, OR β€œβ€=””가 항상 TRUE이기 λ•Œλ¬Έμ— Users ν…Œμ΄λΈ”μ˜ λͺ¨λ“  rowsλ₯Ό λ°˜ν™˜ν•œλ‹€.

Batched SQL Statements에 κΈ°λ°˜ν•œ SQL Injection
λŒ€λΆ€λΆ„μ˜ λ°μ΄ν„°λ² μ΄μŠ€λŠ” 일괄(batched) SQL문을 μ§€μ›ν•œλ‹€. 일괄 SQL문은 μ„Έλ―Έμ½œλ‘ μœΌλ‘œ κ΅¬λΆ„λœ λ‘˜ μ΄μƒμ˜ SQLλ¬Έ 그룹으둜 μ²˜λ¦¬λœλ‹€.

μ•„λž˜ SQL문은 Users ν…Œμ΄λΈ”μ˜ λͺ¨λ“  rowsλ₯Ό λ°˜ν™˜ν•œ λ‹€μŒ Suppliers ν…Œμ΄λΈ”μ„ μ‚­μ œν•œλ‹€.

SELECT * FROM Users; DROP TABLE Suppliers

μ˜ˆμ‹œ

txtUserId = getRequestString("userId");
sql = "SELECT * FROM Users WHERE userId = " + txtUserId;

μœ„ μ˜ˆμ‹œμ— λ‹€μŒκ³Ό 같은 ꡬ문을 λ„£λŠ”λ‹€λ©΄

User id: 105; DROP TABLE Suppliers

SQL문은 λ‹€μŒκ³Ό 같이 적용될 것이닀.

SELECT * FROM Users WHERE userId = 105; DROP TABLE Suppliers;


SQL InjectionμœΌλ‘œλΆ€ν„° μ›Ή μ‚¬μ΄νŠΈλ₯Ό λ³΄ν˜Έν•˜κΈ° μœ„ν•΄ SQL Parametersλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = @0";
db.Execute(txtSQL, txtUserId);
ASP.NET Razor Example

νŒŒλΌλ―Έν„°λŠ” SQLλ¬Έμ—μ„œ @ 마컀둜 ν‘œμ‹œλœλ‹€.
SQL 엔진은 각 νŒŒλΌλ―Έν„°κ°€ ν•΄λ‹Ή 열에 λŒ€ν•΄ μ˜¬λ°”λ₯Έμ§€ ν™•μΈν•˜κ³ , μ‹€ν–‰ν•  SQL의 일뢀가 μ•„λ‹Œ 문자 κ·ΈλŒ€λ‘œ μ²˜λ¦¬λ˜λŠ”μ§€ ν™•μΈν•œλ‹€.

κ·Έ μ™Έ λŒ€μ‘ λ°©μ•ˆ

  1. μž…λ ₯ 값에 λŒ€ν•œ 검증
    μ„œλ²„μ—μ„œ ν™”μ΄νŠΈλ¦¬μŠ€νŠΈ 기반으둜 κ²€μ¦ν•œλ‹€.

  2. Error Message λ…ΈμΆœ κΈˆμ§€
    κ³΅κ²©μžκ°€ SQL Injection을 μˆ˜ν–‰ν•˜κΈ° μœ„ν•΄μ„œλŠ” λ°μ΄ν„°λ² μ΄μŠ€ 정보(ν…Œμ΄λΈ”λͺ…, 컬럼λͺ… λ“±)κ°€ ν•„μš”ν•˜λ‹€. λ°μ΄ν„°λ² μ΄μŠ€ μ—λŸ¬ λ°œμƒ μ‹œ λ”°λ‘œ 처리λ₯Ό 해주지 μ•Šμ•˜λ‹€λ©΄ μ—λŸ¬κ°€ λ°œμƒν•œ 쿼리문과 ν•¨κ»˜ μ—λŸ¬μ— λŒ€ν•œ λ‚΄μš©μ„ λ°˜ν™˜ν•œλ‹€.
    이 λ•Œ ν…Œμ΄λΈ”λͺ… 및 컬럼λͺ…이 κ·ΈλŒ€λ‘œ λ…ΈμΆœλ  수 있기 λ•Œλ¬Έμ— 였λ₯˜ λ°œμƒ μ‹œ 였λ₯˜ νŽ˜μ΄μ§€λ₯Ό μ œμž‘ν•˜κ±°λ‚˜ λ©”μ‹œμ§€ λ°•μŠ€λ₯Ό λ„μš°λ„λ‘ ν•΄μ•Ό ν•œλ‹€.

  3. μ›Ή λ°©ν™”λ²½ μ‚¬μš©

    • μ†Œν”„νŠΈμ›¨μ–΄ ν˜•: μ„œλ²„ 내에 직접 μ„€μΉ˜ν•œλ‹€.
    • ν•˜λ“œμ›¨μ–΄ ν˜•: λ„€νŠΈμ›Œν¬ μƒμ—μ„œ μ„œλ²„ μ•žλ‹¨μ— 직접 ν•˜λ“œμ›¨μ–΄ μž₯λΉ„λ‘œ κ΅¬μ„±ν•œλ‹€.
    • ν”„λ‘μ‹œ ν˜•: DNS μ„œλ²„ μ£Όμ†Œλ₯Ό μ›Ή λ°©ν™”λ²½μœΌλ‘œ λ°”κΎΈκ³ , μ„œλ²„λ‘œ κ°€λŠ” νŠΈλž˜ν”½μ΄ μ›Ή 방화벽을 λ¨Όμ € κ±°μΉ˜λ„λ‘ ν•œλ‹€.

참고 자료

  1. w3schools, β€œSQLΒ Injection”, https://www.w3schools.com/sql/sql_injection.asp

  2. plura blog, β€œSQL Injection λŒ€μ‘ λ°©μ•ˆβ€, http://blog.plura.io/?p=6056

  3. NoirStar Space, β€œSQL Injection μ΄λž€? (SQL μ‚½μž… 곡격)”, https://noirstar.tistory.com/264

profile
김뉴비

0개의 λŒ“κΈ€

κ΄€λ ¨ μ±„μš© 정보