Google-ის Project Zero-მ აღმოაჩინა, თუ როგორ უნდა გვერდის ავლით Samsung-ის Knox Hypervisor (დასწორდა იანვრის პატჩში)

Project Zero-ს უახლეს ბლოგ პოსტში გუნდმა აღმოაჩინა გზა Samsung-ის ბირთვის რეალურ დროში დაცვის გვერდის ავლით, სახელწოდებით Knox Hypervisor.

Google-ის Project Zero-ს გუნდმა გადაამოწმა მრავალი ექსპლოიტი, რომელიც საშუალებას აძლევს Samsung-ის ტელეფონებს, რომლებიც მუშაობენ სავარაუდოდ უსაფრთხო Samsung Knox უსაფრთხოების კომპლექტზე, თავდასხმა. ბლოგში აღნიშნულია, რომ ყველა დაუცველობა გადაეცა Samsung-ს, რომელმაც რეალურად გამოუშვა მათი გამოსწორებები იანვრის პროგრამული უზრუნველყოფის განახლებაში.


ფონი

როგორც Samsung Knox უსაფრთხოების პროგრამული უზრუნველყოფის კომპლექტის ნაწილი, რომელიც წარმოადგინა Samsung-მა, არის პროგრამული უზრუნველყოფის ნაწილი, რომელიც მდებარეობს Android აპლიკაციებსა და ბირთვს შორის, სახელწოდებით: ჰიპერვიზორი. ეს შეიძლება გამოყენებულ იქნას, როგორც დამატებითი ფენა Android მოწყობილობების შემდგომი უსაფრთხოებისთვის. Samsung Knox Hypervisor-ს ჰქვია "ბირთვის დაცვა რეალურ დროში”ან მოკლედ RKP, როგორც ამას ამ სტატიის დანარჩენში მივმართავ.

ბირთვი მდებარეობს RKP-ს ქვემოთ Android-ის პროგრამული უზრუნველყოფის დასტაში, ხოლო აპლიკაციები, რომლებიც მუშაობს მოწყობილობაზე, განთავსებულია ზედა. RKP-ის იდეა არის მოწყობილობის უსაფრთხოების დამატებითი ფენის უზრუნველყოფა, როგორც ყველა მოთხოვნა (მეხსიერება და სხვა რესურსები) ბირთვის აპლიკაციებმა ჯერ უნდა გაიარონ Knox, რომელიც ცდილობს დაადგინოს, აკეთებს თუ არა აპლიკაცია რაღაცას. არ უნდა. RKP ასევე უზრუნველყოფს უსაფრთხოებას გაურკვევლობის საშუალებით დამატებითი ფენით, რათა დამალოს მგრძნობიარე ინფორმაცია, რომელიც აპლიკაციამ შეიძლება გამოიყენოს მოწყობილობის კომპრომისისთვის.

ბლოგის პოსტი საკმაოდ ღრმად არის ჩაწერილი იმის შესახებ, თუ როგორ მუშაობს Android მეხსიერება, RKP და ზოგადად ოპერაციული სისტემები, ასე რომ, მე გავაერთიანე და გავამარტივე ის, რომ სწრაფი მიმოხილვა მიმეღო აღმოჩენის შესახებ. მოგიწოდებთ წაიკითხოთ სრული სტატია, თუ დრო გაქვთ, თუმცა, რადგან ის ძალიან საგანმანათლებლოა.


ექსპლოიტი #1:

KASLR ან ბირთვის მისამართის სივრცის განლაგების რანდომიზაცია არის მეხსიერებაში ბირთვის კოდის მდებარეობის შეცვლის პროცესი შემთხვევითი რაოდენობით ჩატვირთვისას. ყოველ ჯერზე, როდესაც მოწყობილობა ჩაიტვირთება, ბირთვი იტვირთება მისამართების სხვა სივრცეში (მეხსიერების ზონაში). იდეა მდგომარეობს იმაში, რომ გართულდეს იმის პოვნა, თუ სად მდებარეობს ბირთვის კოდი, რათა მასზე თავდასხმა მოხდეს, რადგან ყოველი ჩატვირთვის შემდეგ ბირთვის კოდი "ცვლის" შემთხვევითი რაოდენობით მეხსიერებაში. ეს ჟღერს დიდი ნაბიჯი, რათა თავიდან აიცილოს სავარაუდო თავდამსხმელები, მაგრამ ბოლო კვლევა აჩვენა, რომ თქვენ შეგიძლიათ რეალურად დაამარცხოთ ეს პროგრამული ხარვეზის ან დაუცველობის საჭიროების გარეშე, რადგან KASLR რეალურად ძალიან რთულია ადგილობრივი თავდამსხმელების წინააღმდეგ ძლიერი გზით განხორციელება.

RKP პროგრამული უზრუნველყოფის შემთხვევაში, KASLR-ის გვერდის ავლით შესაძლებლობა რეალურად უფრო მარტივია, ვიდრე ზემოთ ნახსენები კვლევა. ყველა ანდროიდის მოწყობილობის მეხსიერება მითითებულია მაჩვენებლებით და მოწყობილობების თავდასხმისგან დასაცავად, როდესაც ანდროიდის მოწყობილობები იბეჭდება ან გამოდის (იქნება ეკრანზე ან ჟურნალების ან გამართვის შესატანად), მაჩვენებლების მითითებები ანონიმურია, - შეუძლებელს ხდის იმის გარკვევას, თუ სად მიუთითებს მაჩვენებელი კითხვისას. გამომავალი.

იფიქრეთ მეხსიერების მაჩვენებლებზე, როგორიცაა ქუჩის ნიშანი, რომელიც მიუთითებს მდებარეობაზე და იფიქრეთ ანონიმიზაციაზე, როგორც მის დაბინდვაზე. ტელევიზიის მსგავსად, ანონიმიზაცია ხდება გადაღების შემდეგ, Android ასევე იყენებს ამ ანონიმიზაციას გამომავალი დროს და მხოლოდ იმ შემთხვევაში, თუ ანონიმიზაცია სწორად არის კონფიგურირებული, და ავტორი აცხადებს რომ ყველა მოწყობილობას, რომელსაც [მას] შეხვდა, სწორად აქვს კონფიგურირებული მაჩვენებლის ანონიმიზაცია. ეს შეიძლება ჟღერდეს, თითქოს ძალიან ძნელია გატეხვა, მაგრამ ყველაფერი რაც თქვენ უნდა გააკეთოთ, არის იპოვოთ ერთი მაჩვენებელი (იფიქრეთ ქუჩის ნიშანი), რომელიც არ იყო ანონიმური (ბუნდოვანი) ბირთვის შემქმნელის მიერ (ფრთხილად, ეს არ არის თქვენი საშუალო Android აპლიკაციის დეველოპერი), როდესაც მაჩვენებელი იწერება ჟურნალებში ან სხვა მდებარეობაზე, მაგ. ეკრანი ან ა ფაილი.

ასე რომ, თუ იპოვით მაჩვენებელს, რომელიც არ იყო ანონიმური, მაშინ შეგიძლიათ გამოთვალოთ ბირთვის შემთხვევითი მისამართის ცვლა, როგორც განსხვავება ამ ორს შორის. საინტერესოა, რომ ავტორმა ვერ იპოვა ექსპლუატირებადი მაჩვენებელი ბირთვში, მაგრამ იპოვა ის RPK-ში სადაც დეველოპერებს დაავიწყდათ მაჩვენებლის ანონიმიზაცია გამართვის (ლოგირების) გამოსავალში, რომელიც წარმოიშვა ბეჭდური შეცდომა. ანდროიდში მაჩვენებლების ანონიმიზაციისთვის თქვენ უნდა გამოიყენოთ სპეციალური კოდი და გამოდის, რომ RPK დეველოპერებმა შეცდომით გამოიყენეს მცირე ასო 'k' ნაცვლად ა დიდი "K". ამიტომ შედარებით მარტივი იყო ბირთვის კოდის შემთხვევითი ცვლის რაოდენობის გარკვევა და მასზე თავდასხმა.


ექსპლოიტი #2:

შემდეგი ექსპლოიტი ცოტა უფრო რთულია: Samsung Knox იცავს თქვენს მოწყობილობას მოწყობილობის მეხსიერებაში წესების ერთობლიობის გამოყენებით მავნე კოდის შესაჩერებლად. წესები ასეთია:

  1. ყველა გვერდი (კოდი მეხსიერებაში), გარდა ბირთვის კოდისა, მონიშნულია, როგორც "პრივილეგირებული არ შესრულდეს არასოდეს" (იგულისხმება, რომ აქ კოდი ვერასოდეს გაიშვება)
  2. ბირთვის მონაცემთა გვერდები (პროგრამის მიერ მეხსიერებაში გამოყენებული მონაცემები) არასოდეს აღინიშნება შესრულებად (ასე რომ აქ კოდი ვერასოდეს გაიშვება)
  3. ბირთვის კოდის გვერდები (კოდი მეხსიერებაში) არასოდეს არ არის მონიშნული ჩასაწერად (ასე რომ, არცერთ მავნე კოდს არ შეუძლია მისი შეცვლა)
  4. ბირთვის ყველა გვერდი მონიშნულია, როგორც მხოლოდ წაკითხვადი მე-2 ეტაპის თარგმნის ცხრილში (ცხრილი, რომელიც განთავსებულია აპლიკაციასა და ბირთვს შორის, რათა აპლიკაციებმა არ გაიგონ მეხსიერების რეალური მდებარეობების შესახებ)
  5. მეხსიერების თარგმანის ყველა ჩანაწერი მონიშნულია, როგორც მხოლოდ წაკითხვადი აპლიკაციებისთვის.

ჩვენ ყურადღებას გავამახვილებთ მე-3 წესზე, რადგან სწორედ აქ აღმოაჩინა ავტორმა პრობლემა ზემოთ მოცემული წესების შესრულებასთან დაკავშირებით. RPK ფაქტობრივად აღნიშნავს ბირთვის მეხსიერებას, როგორც მხოლოდ წაკითხვის საშუალებას, თუმცა KASL-ზე დაკვირვების შედეგად აღმოჩენილ იქნა ხვრელი, რამაც გამოიწვია კოდის ჩაწერა სავარაუდო "მხოლოდ წაკითხვის" განყოფილებაში. ჩატვირთვის დროს ბირთვის მდებარეობის დაბინდვის მიზნით, მეხსიერება ენიჭება ბირთვს, მაგრამ მეხსიერების ეს რაოდენობა გაცილებით დიდია ვიდრე ბირთვის ტექსტის სეგმენტი. მეხსიერების უფრო დიდი რაოდენობის გამოყოფით გაცილებით ართულებს ბირთვის ნამდვილი კოდის პოვნას, რომელიც შეიძლება იყოს სადმე, და როგორც ზემოთ ვნახეთ, ის შემთხვევით გადაადგილდება მოწყობილობის თითოეულ ჩატვირთვაზე.

_text და _etext მონიშნეთ დაცული დიაპაზონი

ავტორმა შეძლო დაედასტურებინა, რომ ბირთვის მიერ გამოყენებული მეხსიერება მართლაც იყო მონიშნული, როგორც "მხოლოდ წაკითხვადი", თუმცა მეხსიერების დანარჩენი დიდი რაოდენობა, რომელიც გამოიყენებოდა ბირთვის დასამალად. არა მონიშნულია როგორც "მხოლოდ წაკითხვა". ეს იმიტომ ხდება, რომ RKP იცავს რეგიონს, რომელიც შეიცავს ბირთვის ტექსტს KASLR სლაიდის გამოყენების შემდეგ.


ექსპლოიტი #3

მესამე ექსპლოიტის დროს ავტორს შეეძლო მეხსიერების სხვა არეზე წვდომა, რომელიც ასევე უნდა იყოს შეზღუდული მხოლოდ წაკითხვაზე. RKP იცავს მეხსიერებას და იყენებს ა ჰიპერვიზორის კონფიგურაციის რეგისტრაცია (HCR) ძირითადი ბირთვის ოპერაციების გასაკონტროლებლად. HCR-ის მიზანია დაუშვას ბირთვის მოქმედი და რეალური ოპერაციების წვდომა რეგისტრებში და დაბლოკოს მავნე შეტევები. ის ამას აკეთებს რეგისტრებში განხორციელებული ზარების შემოწმებით, რომლებიც მართავენ ვირტუალიზაციის ფუნქციებს. HCR კონფიგურირებულია იმისთვის, რომ დაბლოკოს კონკრეტული ოპერაციები, რომლებიც ნორმალურად განიხილება, რაც RKP-ს საშუალებას აძლევს აირჩიოს დაუშვას თუ არ დაუშვას მოთხოვნა.

ამ ექსპლუატში იყო HCR კონტროლი არ მოიცავს ორ რეესტრს რაც ძალიან მნიშვნელოვანი აღმოჩნდა. ავტორმა ღრმად ჩახედა ARM Reference სახელმძღვანელოში და აღმოაჩინა, რომ პირველმა რეესტრმა მას საშუალება მისცა ძირითადად გამორთო RKP აპლიკაციებისთვის. "სისტემის კონტროლის რეგისტრაცია EL1-ისთვის (SCTLR_EL1) უზრუნველყოფს უმაღლესი დონის კონტროლს სისტემაზე, მეხსიერების სისტემის ჩათვლითსრულყოფილ სამყაროში აპლიკაცია გამოიყენებდა მეხსიერებას, რომელიც იყო დატანილი RKP-ის მეშვეობით, რათა RKP-ს შეეძლო გაეკონტროლებინა რაზე წვდომა შეეძლო აპლიკაციას. თუმცა, ამ რეესტრის გამორთვამ დაუშვა RKP გამორთულია RKP-ის დაყენებამდე მოწყობილობის ეფექტურ დაბრუნებით, რაც იმას ნიშნავს, რომ მოწყობილობა ფიზიკურ მეხსიერებაში არის შედგენილი RKP-ის მიერ მოწოდებული დამატებითი უსაფრთხოების გარეშე. ეს თავის მხრივ ნიშნავდა, რომ ავტორს შეეძლო წაიკითხა და ჩაწერა მეხსიერებაში, რომელიც თავდაპირველად და სწორად იყო დაბლოკილი RKP პროგრამული უზრუნველყოფის მიერ.

მეორე რეესტრი, რომელიც გამოტოვებულია, უფრო დახვეწილი ეფექტი ჰქონდა, მაგრამ საბოლოო ჯამში ისეთივე დამღუპველი იყო უსაფრთხოებისთვის. The თარგმანის კონტროლის რეგისტრაცია EL1-ისთვის (TCR_EL1) რეგისტრაცია პირდაპირ კავშირშია მეხსიერების რაოდენობასთან, რომლითაც მუშაობს აპლიკაცია, რომელსაც ეწოდება გვერდი. RKP არის მყარი კოდირებული გვერდის ზომაზე 4 კბ, რადგან AARCH64 Linux-ის ბირთვები (როგორიცაა Android) იყენებენ თარგმანის ზომას 4KB. აღნიშნული რეგისტრი (TCR_EL1) ადგენს ARM ჩიპსეტებს იმ მეხსიერების ზომაზე, რომელიც უნდა დაბრუნდეს. თურმე ეს რეესტრი არ არის დაცული HCR-ის მიერ და, შესაბამისად, თავდამსხმელს შეუძლია შეცვალოს ის, როგორც ავტორმა შეცვალა გვერდის ზომა 64 კბ.

ეს ნიშნავს, რომ როდესაც მოთხოვნა შესრულებულია RKP-ის მიერ, მეხსიერების რეალური რაოდენობა ახლა არის 64 კბ ნაცვლად 4 კბ. მიზეზი ის არის, რომ ARM ჩიპსეტი კვლავ აკონტროლებს გვერდის ზომას და ის დაყენებულია 64 კბ-ზე ექსპლოიტის საშუალებით. ვინაიდან RKP იცავს მეხსიერებას ჩაწერისგან, როგორც ექსპლოიტის #2-ში ჩამოთვლილი წესების ნაწილი, მეხსიერება მაინც რეალურად დაცულია. მაგრამ აქ არის დაჭერა - რადგან RKP არის მყარი კოდირებული 4 კბ-მდე, ის არ იცვლება 64 კბ გვერდის ზომამდე, როდესაც რეესტრი განახლდა, ​​ამიტომ მხოლოდ პირველი 4 კბ მეხსიერებაა დაცული საშუალებას აძლევს თავდამსხმელს გააკეთოს რაც უნდა, დარჩენილი 60 კბ.


ექსპლოიტი #4

ავტორის მიერ ნაჩვენები ბოლო ექსპლოიტი არის მეხსიერების მითითება, სადაც არის RKP პროგრამული უზრუნველყოფა, ასე რომ, თავდამსხმელს შეუძლია შეტევა თავად RKP პროგრამაზე. ერთი ხრიკი ამ ტიპის შეტევის შესაჩერებლად, რომელსაც Linux-ის ბირთვებიც იყენებენ, არის თქვენი პროგრამის ამოღება ვირტუალური მეხსიერების მისამართების სივრციდან ისე, რომ ვერც ერთმა აპლიკაციამ არ შეძლოს მასზე თავდასხმა, რადგან მათ არ შეუძლიათ მასზე მითითება.

გახსოვდეთ, რომ მეხსიერება ეხება მაჩვენებლებს და ცხრილებს, რომლებიც ფიზიკურ მეხსიერებას ასახავს ვირტუალურ მეხსიერებას. ამ ტიპის თავდასხმისას ნორმალური თავდაცვის მიხედვით, RKP ხსნის თავის თავს ისე, რომ მასზე თავდასხმა არ შეიძლება. თუმცა, იქ, სადაც ბირთვი არ იძლევა ასეთ შესაძლებლობებს, RKP საშუალებას აძლევს მეხსიერების ნაწილის რუკაზე დაწერას და წაკითხვის/ჩაწერის მონიშვნას. ერთადერთი შემოწმება არის ის, რომ ეს არ არის თავად ძირითადი ბირთვი, რადგან RKP არ ამოწმებს, არის თუ არა ის მისამართები, რომელთა შედგენასაც ითხოვენ, არის თუ არა ის ტერიტორია, სადაც თავად RKP მდებარეობს მეხსიერებაში. ძირითადად, RKP საშუალებას აძლევს თავის ხელახლა დახატვას დაუბრუნდით მისამართების სივრცეს, რომელზედაც აპლიკაციებს შეუძლიათ წვდომა და როგორც გვერდითი გავლენა მეხსიერება ავტომატურად აღინიშნება, როგორც წაკითხვა/ჩაწერა ასე რომ, თავდამსხმელს ახლა შეუძლია გამოიყენოს მეხსიერება, როგორც უნდა.


დასკვნა

ზემოთ ჩამოთვლილი ოთხი ექსპლოიტის ერთ-ერთი ყველაზე დიდი პრობლემა არის ის, რომ ავტორი აღნიშნავს, თუ რამდენად რთული იქნება მათი შესრულება Android-ის საბაზო ბირთვში ფუნქციების ნაკლებობის გამო. ბედის ირონიით, უსაფრთხო RKP Hypervisor-მა უზრუნველყო ყველა ინსტრუმენტი, რომელიც საჭირო იყო თავდასხმების განსახორციელებლად. ის გვიჩვენებს, რომ ზოგჯერ კარგად განზრახული პროგრამული უზრუნველყოფა იწვევს უფრო მეტ პრობლემას, ვიდრე აგვარებს და ჩვენ გაგვიმართლა, რომ გვყავს ხალხი გალ ბენიამინის მსგავსად, რომელსაც სურს ხელი დაასხას და შეამოწმოს, რომ დოკუმენტაცია შეესაბამება რეალურ პროგრამულ უზრუნველყოფას აკეთებს.

მიუხედავად იმისა, რომ ეს ექსპლოიტები საშინლად გამოიყურება და Knox-ს ძალიან დაუცველად აქცევს, მინდა დავამშვიდო ყველა, რომ ეს საკითხები იყო დაფიქსირდა იანვრის განახლებაში Samsung-ისგან. გარდა ამისა, ეს ექსპლოიტები მოითხოვს ARM პროცესორების და პროგრამირების ძალიან ღრმა გაგებას, ამიტომ ამ ექსპლოიტების გამოყენებაში შესვლის ბარიერი ასტრონომიულად მაღალია.


წყარო: Project Zero