Privacy policy / Opium

Prince of Hell

სასწაული ფორუმი


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
ბლოგი რობლოქსის რევერსალი
#1
Information 
რობლოქსის ექსპლოიტინგის სცენა წარსდგება რამოდენიმე ჯგუფისგან, ყველაზე პოპულარული იწყება ექსტერნალიდან რომელიც უმეტესს შემთხვევაში შედგება ორი მთავარი კომპონენტისგან: IOCTL ანუ RING 0 დონეზე შემუშავებული დრაივერი რომელსაც შეუძლია დაამყაროს კომუნიკაცია UserMode აპლიკაციასთან. ეს ყოველივე გვაძლევს უფლებას რომ ჩვეულებრივი აპლიკაციიდან ვმართოთ რობლოქსის მეხსიერება მარტივად, მაგრამ ყველაფრისდა მიუხედავად ბევრი მნიშვნელოვანი დეტალი არის გასათვალისწინებელი რათა ჩვენი ექსპლოიტი იყოს უსაფრთხო.

ახლა განვიხილოთ ინტერნალი და მოდი დავიწყოთ იმითი რომ ამჯერად გაცილებით ძნელადაა საქმე რადგანაც ჩვენ არ შეგვიძლია მარტივად კერნელის გამოყენება რომ ვმართოთ რობლოქსის მეხსიერება, წაკითხვისთვის ან გადაწერისთვის. იმის გასაგებად თუ რა გვჭირდება რომ გავაკეთოთ ინტერნალ ექსპლოიტი მოდი ჯერ დავფიქრდეთ რას შვება თითონ Hyperion-ი, ჩვენ ვერ ავდგებით და უბრალოდ ვერ ჩავტვირთავთ ჩვენს DLL-ს რადგანაც Hyperion ანტი-ჩეთი კი არა ანტი-ტამპერია რაც გულისხმობს იმას რომ ის ამოწმებს ყველა DLL-ს, თრედსა თუ მოდულს რომელიც კავშირს ამყარებს რობლოქსის აპლიკაციასთან და ყველაზე დიდი კოზირი მათთვის ის არის რომ, Hyperion-ი აწყობილია სპეციალურად რობლოქსისთვის რაც გულისხმობს იმას რომ ყველაფერი გათვლილი აქვთ რა უნდა ჩაიტვირთოს და რა არა, მაგრამ როცა ჩვენ ვცდილობთ ჩვენი ექსპლოიტის ასე უბრალოდ გაშვებას რობლოქსის აპლიკაციაში ის ამოწმებს დაშვებული DLL-ების სიას და როცა არ ემთხვევა ის იწყებს თვით განადგურებას ანუ რობლოქსის გამორთვას. წეღან ვახსენე რომ Hyperion-ზე ის კოზირი უჭირავთ რომ სპეციალურადაა აწყობილი თქო მაგრამ ჩვენც გვიჭირავს ამ დროისთვის ისეთი კოზირი რომელსაც Hyperion ვერ აჯობებს, ანუ თავად Hyperion-ი არის UserMode ანტი-ტამპერი რაც ტოვებს მას ჩვენს დონეზე Ring 3-ში რაც ნიშნავს იმას რომ გვათანაბრებს და რადგანაც ზუსტად რომ USERMODE აპლიკაციაა, მას არ გააჩნია ბევრი რამის შესაძლებლობა და უწევს WIN32 API-ს გამოყენება რომ შეამოწმოს რას აქვს შეხება რობლოქსთან, ანუ ჩვენ შეგვიძლია გადავაწეროთ ერთერთ ფუნქციას რომ დააბრუნოს ის რაც ჩვენ გვსურს რომ გავცდეთ Hyperion-ის DLL-ის შემოწმების ფაზას. თავდაპირველად როცა roblox-internal გავაკეთე იმდროს WinVerifyTrust-ის დაწყებით ბიტებს ზედ გადავაწერდით და Hyperion ვეღარ შეძლებდა კავშირების შემოწმებას რაც გვაძლევდა უფლებას გაგვეშვა ჩვენი DLL უსაფრთხოდ.



რა განსხვავებაა ინტერნალსა და ექსტერნალს შორის? რომელი ჯობია?
ზოგადად GameHacking-ში თუ ხართ გარკვეული წესით კითხვას პასუხი უკვე გაცემული უნდა ქონდეს მაგრამ რადგანაც და ეს კითხვა რამოდენიმეჯერ დამისვეს, ბარემ აქ ავხსნი და თუ რამეა ჩავასწორებ ხოლმე. მგონი მივხვდით უკვე როგორ მუშაობს Hyperion-ი და ეშვება ექსტერნალი ან ინტერნალ ექსპლოიტები, მაგრამ ახლა მთავარ თემაზე გადავიდეთ, თვით ფუნქციონალზე. დავიწყებ იმით რომ თითოეულ სკრიპტს, პლუგინს, კონსოლს და ასე შემდეგ გააჩნიათ თავიანთი სამბრძანებლო დონე, მაგალითად ძველ იერარქიას ავიღებ რომ უკეთ დაგეხმაროთ გაგებაში, გლეხები რომელთაც უფლებები არ გააჩნიათ შეგიძლიათ შეადაროთ Identity 0-ს, საშუალო მაცხოვრებელთა წარმომადგენლები რომელთაც გააჩნიათ სახელიდან გამომდინარე საშუალო უფლებები, არც იქეთ და არც აქეთ, შეგიძლია შეადაროთ Identity 2-ს, როცა სკრიპტს/ლოკალსკრიპტს უშვებთ მათ ენიჭებათ ზუსტად ეს Identity/სამბრძანებლო დონე, შემდგომ მოდის აზნაურები რომლებიც უფრო მაღლა დგანან ვიდრე საშუალო დონის წარმომადგენელი ხალხი და გააჩნიათ მათზე მეტად ბევრი უფლება, შეგიძლიათ ეს შეადაროთ Identity 3-ს, ამ Identity-ს იყენებენ ექსტერნალის ექსპლოიტები რადგანაც მხოლოდ ამაზე არიან ლიმიტირებულები. რობლოქსში როცა ჩათში წერთ, მოძრაობთ და ნებისმიერ რამეს აკეთებთ ეს სკრიპტების დამსახურებაა რომელიც არ გიჩანთ რობლოქს სტუდიოში, მაგრამ თუ ოდესმე გამოგიყენებიათ Dex Explorer, მაგ შემთხვევაში დაინახავდით ხოლმე CoreGui-ს და ასე შემდეგ, ეგ ადგილები არის რობლოქსისთვის საჭირო სკრიპტები ფუნქციონალისთვის რომ შეგვეძლოს თამაში, ეგ ყველაფერი ეშვება Identity 3-ზე და აქვთ ბევრი უფლება ვიდრე Identity 2-ს, წესით უკვე უნდა მიხვედრილიყავით. ექსტერნალით განა რა უნდა ვქნათ ახლა, LuaU-ს მთავარ ძრავას ვერ შევეხებით რომ რამე ვუბრძანოთ, მაგრამ შეგვიძლია ავდგეთ და ვიპოვოთ ისეთი რობლოქსის Core სკრიპტი რომელსაც იმდენად დიდი ფუნქციონალი რაც შეცვლის თამაშს, მაგალითად VRNavigation-ის მოდულსკრიპტი რაც არ გამოიყენება VR Headset-ით ჩართვის გარეშე. ჩვენ ვწერთ Lua სკრიპტს რაზეც იქნება შემდგომ განსაკუთრებული ფუნქციები და ხიდი რომელიც დააკავშირებს რობლოქსის ექსპლოიტს და ამ ლუა სკრიპტს, როცა დავასრულებთ ავდგებით და Bytecode Conversion(*)-ს გამოყენებით გარდავქმნით Bytecode-ად და გადავაწერთ ზუსტად VRNavigation-ს რომელთანაც შეგვეძლება მოვახდინოთ კომუნიკაცია და გავუშვათ სკრიპტები.  მგონი უკვე მიხვდით როგორც მუშაობს ექსტერნალი ხომ, ვპოულობთ რობლოქსის Core/მთავარ სკრიპტს და უბრალოდ გადავაწერთ ჩვენს ლუა კოდს ზევიდან და გავუშვებთ მას, ნუ შემდგომ მოდის რამოდენიმე Identity და ნუ მოკლედ მოდი გადავიდეთ ახლა ინტერნალზე, ექსტერნალზე ჩვენ არ შეგვეძლო LuaU-ს ძრავასთან შეხება მაგრამ ინტერნალზე სრულიად განხსვავებულადაა საქმე, რადგანაც ჩვენი ექსპლოიტი/DLL პირდაპირ ხდება თამაშის ნაწილი და აქვს შეხება ნებისმიერ მეხსიერების ადრესთან, ანუ ჩვენ უნდა ვიპოვოთ DataModel(*) და ჩვენ შევძლებთ ამას გაცილებით მარტივად ვიდრე ექსტერნალზე, მარტივად რომ აგიხსნათ დათამოდელში არის ყველაფერი მოთავსებული, თუ ოდესმე რობლოქს სტუდიოში სკრიპტი დაგიწერიათ აუცილებლად დაწერდით game. ან game.workspace და ეს game არის ზუსტად დათამოდელი. დათამოდელის პოვნის შემდგომ ჩვენ უნდა ვიპოვოთ ScriptContext რომელსაც აბარია ყველა სკრიპტი რაც თამაშში არის და ჩვენ ამ ScriptContext-ს ვიყენებთ რომ ვიპოვოთ GlobalState რისი დახმარებითაც შეგვიძლია შემდგომ ვიპოვოთ Decrypted LuaState, ამის ბევრი ხერხი არსებობს მაგრამ GlobalState-თი Decrypted-ს ვიპოვით სადაც შეგვიძლია მარტივად გამოვიყენოთ და ისე შეიძლება Encrypted იყოს რომელსაც ესაჭიროება შემდგომ Decryption State-ს სწორად გამოსაყენებლად. როცა LuaState ვიპოვეთ ჩვენ ისევ უნდა გადავაქციოთ ლუას კოდი Bytecode-ად, მოვახდინოთ მისი კომპრესირება და rbx_luavmload ფუნქციის გამოყენებით LuaState-ში ჩავტვირთოთ ეს კომპრესირებული კოდი, გავზარდოთ პროტო, დავაყენოთ კონტექსტი და დავაყენოთ ყველაზე მაღალი Identity ანუ 8, შემდგომ გავუშვათ კოდი ნამდვილად ან task.defer-ის გამოყენებით ან task.spawn-ის გამოყენებით (მე პირადად defer მირჩევნია), შემდგომ LuaState-ს სტაკის პირველი წევრი ანუ ჩვენი კოდი გადავაგდოთ უკან და დაველოდოთ ახალ კომპრესირებულ ლუა კოდს გაშვებისთვის. ჩემი თვალსაზრისით რამდენადაც მარტივი არ უნდა ჩანდეს ინტერნალი ვიდრე ექსტერნალი, ექსტერნალი ბევრად მარტივია და ნაკლებად საჩალიჩო, მაგრამ რომ ამბობენ ახლა რობლოქსის ექსტერნალ ექსპლოიტები 99 UNC და ასე შემდეგ სრული სისულელეა, მსგავსი რამ შეუძლებელია რადგან ფუნქციები როგორიცაა hookfunction შესაძლებელია მხოლოდ ინტერნალზე და არა ექსტერნალზე, ეს კიდევ იმიტომ რომ ექსტერნალზე იმისდა მიუხედავად რომ შეიძლება უბრალოდ სკრიპტზე ზევიდან გადაწერა, ეგრე ფუნქციას ვერ შევეხებით, მაგრამ ინტერნალზე კი ჩვეულებრივ LuaState-დან მოვახერხებთ ყველაფერს, კონტსანტების ამოღებასაც და ასე შემდეგ. ექსტერნალი დამწყებებისთვის და სტრუქტურის ასე თუ ისე გასაგებად ცუდი არაა მაგრამ რეკომენდირებულია რომ დაიწყოთ ინტერნალით, რადგანაც ჯობია ამაზე დაკარგოთ დრო და ისწავლოთ ერთი ორი რამე ვიდრე ექსტერნალზე იხალოთ თავი.


Bytecode-ს ინსტრუქციები
მკითხველისთვის შეიძლება ეს ნაწილი გაუგებარი იყოს მაგრამ იმ ნაწილისთვის ვისაც აინტერესებს ლუაუს ბაიტკოდი ან ესაჭიროება ექსპლოიტის დაწერაში, შესანიშნავი კი არა შეიძლება ითქვას მნიშვნელოვანიც არის. მოდი დავიწყოთ იმით რომ თითოეულ ინსტრუქციას აქვს ოთხი პარამეტრი: opcode, A რეგისტრი, B რეგისტრი და C რეგისტრი. თითოეული მათგანი ერთი ბაიტის სიგრძისაა, რომელიც ქმნის ერთ signed integer-ს. ინსტრუქცია, რომელიც იყენებს სამივე რეგისტრს, არის iABC ტიპის. გარკვეული ინსტრუქციები აერთიანებს B რეგისტრს C რეგისტრთან, რათა შეიქმნას მოკლე (მთლიანი რიცხვი ორი ბაიტით), რომელსაც შეუძლია შეინახოს უფრო დიდი მნიშვნელობები, ეს ქმნის Bx (ბ გაფართოებულ) რეგისტრს. ინსტრუქცია, რომელიც იყენებს A და Bx რეგისტრებს, არის iABx ტიპის. (ინსტრუქცია, A, Bx) ზოგიერთ ინსტრუქციას აქვს ხელმოწერილი Bx რეგისტრი (ის შეიძლება შეიცავდეს უარყოფით მნიშვნელობებს). ისინი iAsBx ტიპისაა. (ინსტრუქცია, A, signed Bx) და არის ინსტრუქციები, რომლებიც უბრალოდ იყენებს A რეესტრს, ისინი iA ტიპის არიან (ინსტრუქცია, A) მაგრამ ეს იშვიათია.


ასევე ავღნიშნე opcodes, მაგრამ რა არის ის სინამდვილეში? opcodes არის ის, რაც ეუბნება ინტერპრეტერს რასაც ინსტრუქცია აკეთებს. თუ ინსტრუქციის opcode არის OP_ADD (iABC), მაშინ ის გვეუბნება ინტერპრეტერმა A რეესტრში ჩადოს B და C-ზე მდებარე მნიშვნელობების ჯამი. ლუას აქვს ზუსტად 37 ინსტრუქცია, რაც მცირეა, თუ შევადარებთ ლუას ინსტრუქციების კომპლექტს მაგ. x86-ის ინსტრუქციების ნაკრებისთვის (მინიშნება: საშუალოდ ~2000 ინსტრუქციაა. CPUები განსხვავდება, ამიტომ ყველას აქვს სხვადასხვა ინსტრუქციის ნაკრები, ამიტომ ინსტრუქციების რაოდენობა განსხვავდება CPU-ს ბრენდისა და არქიტექტურის მიხედვით.) იმის გამო, რომ ოპკოდი ინახება როგორც ერთი ბაიტი, შეიძლება იყოს მაქსიმუმ 255 ინსტრუქციები, თუ ლუას განვითარების გუნდს სურდა მეტი ინსტრუქციის დამატება, ეს რიცხვი მაშინ მათ უნდა გადაიყვანონ 64 ბიტიან მთელ რიცხვზე (8 ბაიტი). ესეც ნიშნავს, რომ მათ შეეძლებათ მეტი რეგისტრის დამატება, რაც შეიძლება ნიშნავდეს უფრო ეფექტურ VM-ს, მაგრამ ეს მხოლოდ ოცნებაა რომელიც არასოდეს ახდება.


ლუაუ, ფუნქციები და ბაიტკოდი
Lua Bytecode არის კომპილირებული ლუა სკრიპტები (ეს გამოგვადგება მომავალში ანუ ჩეთის დაწერაში), როდესაც აწარმოებთ ლუა სკრიპტს, ლუა ავტომატურად აგროვებს მას შუამავლ ფორმატში და ემსგავსება ბაიტკოდს ვირტუალურ მანქანაზე მიწოდებამდე. ეს "შუა მავალი ფორმატი" (რომელიც უბრალო პროტო სტრუქტურაა) შეიძლება სერიული იყოს და შემდგომ გადმოცემული როგორც ბაიტკოდათ, რომელიც შეიძლება იყოს შენახული როგორც ფაილი, შემდეგ თუ გსურთ ბაიტკოდის გაშვება უბრალოდ უნდა მიაწოდოთ ის luaU_undump, რომელიც გადააქცევს ბაიტკოდს ლუას შუამავალ ფორმატში (პროტოდ). პროტოს მიღების შემდეგ, შეგიძლიათ ჩასვათ ის ლუა ფუნქციაში (LClosure) შემდეგ დაგეგმეთ(Task Scheduler-ის გამოყენებით) რომ გაეშვას ის. ზემოთ ხსენებული შეგიძლია ააგოთ თქვენით და გაუშვათ ისე კოდი რობლოქსში მაგრამ, ჩვენ შეგვიძლია უბრალოდ ავაგოთ ბაიტკოდი და შემდგომ რობლოქსის ფუნქციის გამოყენებით გავაგზავნოთ ბაიტკოდი და გააქტიურდეს კომპაილერში ჩვენი გაგზავნილი ინფორმაცია (ამ ტექსტის პირველი ნაწილი LuaU-ს გზა არის, ბოლო ნაწილი კიდევ იგივე არის რაც წინად ავხსენი rbx_luavmload-ზე).


გავითვალისწინოთ რომ რობლოქსის რევერსი განსხვავდება ბევრი სხვა თამაშისგან, რადგანაც ამ სიტუაციაში თქვენ გესაჭიროებათ LuaU-ს სტრუქტურის შესწავლა და კარგად გაანალიზება, როგორ ასერიალიზებს კოდს რობლოქსი.


დათამოდელის მოპოვება
დათამოდელი წესით გასაგები უნდა იყოს რაც არის მაგრამ, თუ არ წაგიკითხავთ ან დაგავიწყდათ გაგახსენებთ რომ დათამოდელი არის ადგილი სადაც ყველაფერია რობლოქსთან კავშირში, ჩათვალეთ როგორც თავი ყველაფრის რასაც ხედავთ თქვენ თამაშისას, რობლოქს სტუდიოში ლუა სკრიპტის წერისას წააწყდებოდით "game.###"-ს და ზუსტად game არის დათამოდელი.


მოდი დავიწყებ TaskScheduler-იდან, ეს არის ერთერთი რობლოქსის მამოძრავებელი ნაწილი რომელიც აკონტროლებს გაშვებულ სკრიპტებს, თამაშის ფიზიკას და ასე შემდეგ. თუ F9 სთვის დაგიჭერიათ და რაღაცეები გიჩალიჩიათ დიდი ალბათობით TaskScheduler-ს შეხვდებოდით, ან თუნდაც რობლოქს სტუდიოში თუ იყავით მოწყენილი და რაღაც ღილაკებს აჭერდით მანდაც აღმოაჩენდით ამ TaskScheduler-ს, მაგრამ ამით დათამოდელი როგორ უნდა ვიპოვოთ? ჩვენდა საბედნიეროდ TaskScheduler-ში ერთერთი რობლოქსის ძრავის დავალებული ნაწილი არის WaitingHybridScriptsJob, რომელიც ზედამხედველობს ჰიბრიდულ Task Scheduler-ს. ჩვენ უნდა ჩამოვუაროთ ყველა დავალებას რომელიც არის TaskScheduler-ში და ვიპოვოთ ის, შემდგომ უნდა ვიპოვოთ ScriptContext-ი, ეს შეგვიძლია ReClass.NET ის გამოყენებით ან IDA-თი. ScriptContext-ი არის მოთავსებული თვითონ დათამოდელში, ანუ ჩვენ უნდა ავიღოთ მისი Parent/მშობელი და ასე მარტივად ვიპოვით დათამოდელს.

რობლოქსს აქვს ერთერთი ფუნქცია რომელიც უდგას თავში რაღაცეების წაშლას დათამოდელიდან, ჩვენ შეგვიძლია ეს გამოვიყენოთ დათამოდელის საპოვნელად, მაგრამ ასე უბრალოდ ვერ მოვძებნით მაგ ყველაფერს და ანუ ჩვენ გვესაჭიროება IDA-ს გამოყენება რომ მოვნახოთ ოფსეტი, თუ არ იცით როგორ უნდა ქნათ სამწუხაროდ ამ ყველაფერს ამ დოკუმენტში ვერ გასწავლით მაგრამ შეიძლება მომავალში ცალკე დოკუმენტი შევქმნა მაგისთვის.
Code:
LABEL_55:
    v30 = sub_7088C0(); // ამას ვეძებთ, საძებნელი სტრინგი: %s. Retrying... (%d)
    sub_70AEB0(v30, 1LL, &v9, 0xFFFFFFFFFLL);
sub_7088C0 ფუნქციაში გადახვალთ და უნდა მონახოთ შემდეგ ნაწილი სადაც ფუნქციას უბრუნდება რაღაც, ანუ return არის გამოყენებული და რომ ნახავთ რაც იქნება გვერძე მოცემული, მაგ. ("unk_0000000"), ამ ნულების მაგივრად რაც ეწერება იქნება თქვენი ოფსეტი. ოფსეტის მოპოვების შემდგომ არ ნიშნავს რომ ასე მარტივად ვიპოვეთ დათამოდელი, ანუ კი ვიპოვეთ მაგრამ ეს არის შენიღბული ვირტუალიზირებული ყალბი დათამოდელი საიდანაც უნდა ამოვიღოთ ნამდვილი დათამოდელი, თქვენით შეგიძლიათ ცადოთ და იპოვოთ ის ReClass.NET-ში ან ლოგიკურად გამოიტანოთ IDA-ში (მინიშნება: მოგიწევთ ორი ფოინტერის პოვნა).


კიდევ ერთი მეთოდი არის და ისევ TaskScheduler-ის გამოყენება მოგიწევთ მაგრამ ამჯერად თქვენ უნდა იპოვოთ RenderJob დავალება სადაც უნდა ეჩალიჩოთ და იპოვოთ შემდგომი ერთი ფოინთერი და მაგ ფოინთერში მეორე ფოინთერი რომელიც იქნება დათამოდელი.

როცა ამას ვწერ როგორც ვიცი ლოგების მეთოდი აღარ არსებობს, არადა ჩემს roblox-internal პროექტში ამ მეთოდს ვიყენებდი. ცნობისთვის TaskScheduler-ს გამოყენება შეგიძლიათ მხოლოდ ინტერნალზე და არა ექსტერნალზე.


Reply
Topic Options
Forum Jump:


Messages In This Thread
რობლოქსის რევერსალი - by zero - 03-05-2025, 02:41 AM



Users browsing this thread: 2 Guest(s)