มีวิธีใดบ้างที่จะแยกสตริงออกและฉีด SQL โดยไม่ต้องใช้เครื่องหมายคำพูดเดี่ยวใน oracle?


12

ฉันกำลังทดสอบแอปพลิเคชันที่ใช้ Oracle และพบรหัสต่อไปนี้

Query = "เลือกชื่อจากพนักงาน WHERE id = '" + PKID + "';

เช่นสตริงการสืบค้นมีเครื่องหมายคำพูดล้อมรอบค่า PKID ซึ่งได้มาจาก URL โดยตรง

เห็นได้ชัดว่านี่คือการฉีด SQL แบบคลาสสิกที่รอให้เกิดขึ้น ... ยกเว้นแอปพลิเคชันอยู่เบื้องหลัง CA SiteMinder ซึ่งบล็อก URL ใด ๆ ด้วยการเสนอราคาเดียว (ในรูปแบบใด ๆ ) จากการถูกส่งผ่านไปยังแอปพลิเคชัน

มีวิธีใดบ้างที่จะแยกออกจากสตริงและฉีด SQL โดยไม่ต้องใช้เครื่องหมายคำพูดเดี่ยว?

แก้ไข: ขออภัยฉันควรชัดเจนกว่า - ฉันเข้าใจว่าควรเขียนอย่างไร แต่ฉันต้องโน้มน้าวผู้คนว่าเป็นปัญหาที่เอาเปรียบ ในขณะนี้เพราะมันอยู่เบื้องหลัง siteminder ซึ่งบล็อกราคาเดียวดังนั้นมันจะเป็นการแก้ไขที่มีลำดับความสำคัญต่ำ


1
คุณเคยลองใช้ตัวแปรผูก?
JHFB

@JHFB พูดอะไร ตัวแปรที่มีผลผูกพันเป็นแนวปฏิบัติมาตรฐาน
ฟิลᵀᴹ

คำตอบ:


9

ใช่มันเป็นไปได้ที่จะทำการโจมตี SQL injection โดยไม่ต้องใส่เครื่องหมายคำพูดในพารามิเตอร์

วิธีการทำเช่นนี้คือการใช้ประโยชน์จากวิธีการประมวลผลตัวเลขและ / หรือวันที่ คุณสามารถระบุในระดับเซสชันว่ารูปแบบของวันที่หรือตัวเลขคืออะไร โดยจัดการสิ่งนี้คุณสามารถฉีดด้วยตัวละครใด ๆ

ตามค่าเริ่มต้นในสหราชอาณาจักรและสหรัฐอเมริกาจะใช้เครื่องหมายจุลภาคเพื่อระบุตัวคั่นหลักพันเป็นตัวเลขและหยุดเต็มสำหรับจุดทศนิยม คุณสามารถเปลี่ยนค่าเริ่มต้นเหล่านี้ได้โดยดำเนินการ:

alter session set nls_numeric_characters = 'PZ';

ซึ่งหมายความว่า "P" ตอนนี้เป็นจุดทศนิยมและ "Z" เป็นตัวคั่นหลักพัน ดังนั้น:

0P01

เป็นจำนวน 0.01 อย่างไรก็ตามถ้าคุณสร้างฟังก์ชั่น P01 การอ้างอิงวัตถุจะถูกหยิบขึ้นมาก่อนการแปลงตัวเลข สิ่งนี้ช่วยให้คุณสามารถใช้งานฟังก์ชั่นในฐานข้อมูลที่ให้คุณเพิ่มพลังดังนี้:

สร้างฟังก์ชัน "get by id" พื้นฐาน:

create procedure get_obj ( i in number ) as
begin
  execute immediate 'select object_name from all_objects where object_id = ' || i;
end;
/

สร้างฟังก์ชัน P01 ซึ่งทำสิ่งที่ไม่พึงประสงค์ (ในกรณีนี้เพียงแค่สร้างตาราง แต่คุณได้รับแนวคิด):

create function p01 return number as
  pragma autonomous_transaction;
begin
  execute immediate 'create table t (x integer)';
  return 1;
end;
/

และเรายินดีที่จะไป:

alter session set nls_numeric_characters = 'PZ';

SELECT * FROM t;

SQL Error: ORA-00942: table or view does not exist

exec get_obj(p01);

anonymous block completed

SELECT * FROM t;

no rows selected

ไม่มีคำพูดใด ๆ แต่เรายังคงสามารถใช้งานฟังก์ชัน "hidden" P01 และสร้างตารางได้t!

ขณะนี้อาจเป็นเรื่องยากที่จะทำในทางปฏิบัติ (และอาจต้องการความรู้ / ความช่วยเหลือภายใน) สิ่งนี้แสดงให้เห็นว่าคุณสามารถฉีด SQL โดยไม่ต้องมีเครื่องหมายคำพูด การเปลี่ยนแปลงnls_date_formatสามารถอนุญาตให้ทำสิ่งที่คล้ายกันได้

ผลการวิจัยเดิมสำหรับตัวเลขได้โดยเดวิดลิชฟิลด์และคุณสามารถอ่านกระดาษของเขาที่นี่ คุณสามารถค้นหาอภิปรายทอม Kyte ของวิธีการที่วันที่สามารถใช้ประโยชน์ได้ที่นี่


4

คุณอาจจะเกินประเภทข้อมูลที่คุณใช้ทำให้คำสั่งนั้นล้มเหลว แล้วสิ่งที่เกิดขึ้นหลังจากนั้นอาจถูกเรียกใช้

บางทีการส่งในรูปแบบอาร์เรย์ Unicode จะทำเคล็ดลับและนำคุณออกจากคำสั่งนั้นไปยังอีกชุดหนึ่ง

หากมีรูเปิดมันจะถูกละเมิด และการปิดกั้นสตริงทั้งหมดด้วยคำพูดเดียวไม่ใช่ความคิดที่ดีเพราะคนที่มีนามสกุล "O'Brian" ไม่สามารถเป็นลูกค้าของคุณได้


ฉันเดาว่าคุณหมายถึง "หลุม" และไม่ใช่ "ทั้งหมด"
ypercubeᵀᴹ

1

ลองใช้ตัวแปรผูก คุณสามารถประกาศเป็นตัวเลขและควรป้องกันการฉีด SQL ที่สร้างความเสียหาย

เพิ่มเติม: ตัวแปรผูกยังเพิ่มประสิทธิภาพและความสามารถในการปรับขนาดได้เนื่องจากแผนแบบสอบถามจะรวบรวมและจัดเก็บไว้เพื่อนำกลับมาใช้ใหม่ มีอย่างอื่นที่จะเพิ่มในอาร์กิวเมนต์ของคุณ :)


1
เขาไม่ได้ถามเกี่ยวกับวิธีที่จะป้องกันไม่ให้ฉีด แต่เกี่ยวกับวิธีการที่จะละเมิดมัน
Jeff

1
@jeff OP ยังถามถึงเหตุผลที่ไม่ใช้รหัสประเภทนี้ การไม่ใช้ตัวแปรผูกจะทำลายประสิทธิภาพดังนั้นนี่เป็นเหตุผลที่ดีที่จะใช้มัน
Vincent Malgrat

@Vincent Malgrat: "ไม่ใช้ตัวแปรผูกทำลายประสิทธิภาพ" ผิดมันเป็นความจริงที่การหลีกเลี่ยงการคอมไพล์ของคำสั่งสามารถทำได้โดยใช้ตัวแปรผูก นอกจากนี้สระว่ายน้ำที่ใช้ร่วมกันจะเต็มไปด้วยข้อความที่คล้ายกันมากมายหากคุณไม่ใช้ตัวแปรผูก อย่างไรก็ตามเครื่องมือเพิ่มประสิทธิภาพมีข้อมูลน้อยลงสำหรับการสร้างแผนหากมีการใช้ตัวแปรผูกแทนค่าที่แท้จริง มีสถานการณ์ที่ควรเลือกแผนการแตกต่างกันขึ้นอยู่กับค่าของตัวแปรผูก (หรือค่าตัวอักษร)
miracle173

@ miracle173 แน่นอนว่าจะมีข้อยกเว้น แต่ไม่ใช่สำหรับการค้นหาคีย์หลักตามที่กำหนดโดย OP ไม่เลย =)
Vincent Malgrat
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.