{"id":434,"date":"2018-02-01T16:19:16","date_gmt":"2018-02-01T14:19:16","guid":{"rendered":"http:\/\/oguzkartal.net\/blog\/?p=434"},"modified":"2021-10-31T16:05:13","modified_gmt":"2021-10-31T13:05:13","slug":"meltdown-zafiyeti-ve-istismar-edilmesi","status":"publish","type":"post","link":"https:\/\/www.oguzkartal.net\/blog\/index.php\/2018\/02\/01\/meltdown-zafiyeti-ve-istismar-edilmesi\/","title":{"rendered":"Meltdown Zafiyeti ve \u0130stismar Edilmesi"},"content":{"rendered":"<p>Bu yaz\u0131mda Meltdown g\u00fcvenlik zafiyetinin ne oldu\u011funu, nas\u0131l exploit edildi\u011fini ve geli\u015ftirdi\u011fim bir proof of concept ile nas\u0131l i\u015fletim sisteminde gizli kalmas\u0131 gereken bilgilerin \u00e7al\u0131nabilece\u011fini detayl\u0131 olarak anlatmaya ve g\u00f6stermeye \u00e7al\u0131\u015faca\u011f\u0131m. \u00d6ncesinde bu konunun \u00e7\u0131k\u0131\u015f\u0131 ve yank\u0131lar\u0131 \u00fczerine birka\u00e7 \u015fey s\u00f6yleyerek ba\u015flayay\u0131m.<\/p>\n<p>Malum, bili\u015fim ve teknoloji d\u00fcnyas\u0131 yakla\u015f\u0131k son 3-4 hafta i\u00e7erisinde b\u00fcy\u00fck etki yaratan bir dizi donan\u0131msal g\u00fcvenlik zafiyeti ile kar\u015f\u0131 kar\u015f\u0131ya kald\u0131 ve g\u00fcndemi bu konuyla me\u015fgul oldu. Tabi bu bitmi\u015f de\u011fil, halen de me\u015fgul olmaya devam ediyor ve bir m\u00fcddet daha edecek gibi g\u00f6r\u00fcn\u00fcyor. Bunun olas\u0131 bir\u00e7ok sebebi var.<\/p>\n<ol>\n<li>Konu hakk\u0131nda \u00e7ok fazla belirsizlik mevcut. Bu da \u00f6zellikle son kullan\u0131c\u0131 kesimini kayg\u0131land\u0131ran bir durum.<\/li>\n<li>G\u00fcvenlik zafiyeti donan\u0131msal yani bizzat i\u015flemci mimarisinin kendisinden kaynakl\u0131 oldu\u011fundan basit bir yaz\u0131l\u0131msal d\u00fczeltme ile \u00e7\u00f6z\u00fclemeyecek durumda.<\/li>\n<li>Zafiyetin \u00e7\u00f6z\u00fcm\u00fc hakk\u0131nda net bir yol haritas\u0131 yok ve bunun net \u00e7\u00f6z\u00fcm\u00fc i\u00e7in k\u0131sa vade i\u00e7erisinde bir zaman verilemiyor.<\/li>\n<li>\u0130\u015fletim sistemi tarafl\u0131 yaz\u0131l\u0131msal \u00f6nlemlerin i\u015flemci performans\u0131na muhtemel negatif etkisi. (En b\u00fcy\u00fck sebebi de san\u0131r\u0131m budur)<\/li>\n<li>\u0130\u015flemcilere mikrokod g\u00fcncellemesinin nas\u0131l ve ne \u015fekilde son kullan\u0131c\u0131ya ula\u015ft\u0131r\u0131laca\u011f\u0131 konusu muallak. Her vendor kendince bir yakla\u015f\u0131m sergiliyor. Bu da yine son kullan\u0131c\u0131n\u0131n akl\u0131n\u0131 kar\u0131\u015ft\u0131ran bir ba\u015fka unsur.<\/li>\n<\/ol>\n<p>B\u00fcy\u00fck server farm\u2019a sahip \u015firketler ve k\u00fc\u00e7\u00fck, orta yahut b\u00fcy\u00fck \u00f6l\u00e7ekteki kurumlar\u0131n sistem y\u00f6neticileri durumun ciddiyetinin fark\u0131nda iken, son kullan\u0131c\u0131 i\u00e7in g\u00fcvenlik a\u00e7\u0131\u011f\u0131n\u0131n ciddiyetinden \u00e7ok a\u00e7\u0131\u011f\u0131 gideren g\u00fcncellemelerin sistem performans\u0131na olumsuz etkileri daha \u00f6ncelikli oldu. Bunun sebebi de hem meltdown hem de spectre olarak isimlendirilen g\u00fcvenlik zafiyetinin ciddiyetine var\u0131lamam\u0131\u015f olmas\u0131. Ve g\u00f6rd\u00fc\u011f\u00fcm kadar\u0131yla bu konuda T\u00fcrk\u00e7e yap\u0131lm\u0131\u015f bir analiz, a\u00e7\u0131klama neredeyse yok gibi. Bu sebeple bu g\u00fcvenlik zafiyetleri hakk\u0131nda hem fazla derine inmeden normal kullan\u0131c\u0131lar i\u00e7in hem de daha detayl\u0131 teknik analiz ile geli\u015ftiriciler ve sistem y\u00f6neticileri i\u00e7in bir referans kaynak olu\u015fturmas\u0131n\u0131 umdu\u011fum bir yaz\u0131 yazmay\u0131 ama\u00e7lad\u0131m. Meltdown\u2019\u0131n detayl\u0131 teknik analizine ve nas\u0131l exploit edilebilece\u011fine ge\u00e7meden \u00f6nce genel olarak bilgi vermek istiyorum.<\/p>\n<h4><span style=\"font-weight: bold; color: #ff0000;\">Spectre ve Meltdown\u2019\u0131n Temelini Olu\u015fturan Fakt\u00f6rler<\/span><\/h4>\n<p>Her ne kadar bu iki g\u00fcvenlik zafiyeti bir anda ke\u015ffedilmi\u015f ve ortaya \u00e7\u0131kar\u0131lm\u0131\u015f gibi g\u00f6r\u00fcnse de esasen bu ikisinin ortaya \u00e7\u0131kmas\u0131n\u0131 sa\u011flayan temeller olduk\u00e7a eskiye dayanmaktad\u0131r. Spectre ve Meltdown bu ge\u00e7mi\u015ften gelen birikimlerin s\u00fcrekli bir ad\u0131m ileri ta\u015f\u0131narak geldi\u011fi nokta olarak d\u00fc\u015f\u00fcnmek daha do\u011fru olur. Modern say\u0131labilecek bu ara\u015ft\u0131rmalar 9-10 y\u0131l \u00f6ncesine gidebildi\u011fi gibi bu t\u00fcr sald\u0131r\u0131lar\u0131n teorileri ve deneysel \u00e7al\u0131\u015fmalar\u0131 30 y\u0131ldan fazla s\u00fcredir yap\u0131l\u0131yor. Ve \u00e7e\u015fitli y\u00f6ntemleri, yakla\u015f\u0131mlar\u0131 ve \u00e7ok farkl\u0131 uygulama alanlar\u0131 mevcuttur. Her ne kadar bu kadar \u00e7e\u015fitlilik olsa da bu y\u00f6ntemlerin geneline <strong>side channel attack<\/strong> denilmektedir. Peki side channel attack nedir?<\/p>\n<p><strong><u>Side Channel Attack<\/u><\/strong> bir sistemin d\u0131\u015f d\u00fcnyaya yans\u0131tt\u0131\u011f\u0131 \u00f6l\u00e7\u00fclebilir fiziksel davran\u0131\u015flar\u0131ndan bilgi \u00e7\u0131karmay\u0131 ama\u00e7layan y\u00f6ntemleri kar\u015f\u0131layan bir terimdir. Bu sistem sadece bilgisayar olmak zorunda de\u011fildir, bir radyo vericisi olabilir, uydu al\u0131c\u0131s\u0131 olabilir, gsm \u015febeke vericileri olabilir. Dijital veya mekanik bir sistem de olabilir. G\u00f6r\u00fcld\u00fc\u011f\u00fc gibi oluk\u00e7a geni\u015f bir alan\u0131 kapsayan ve kar\u015f\u0131layan bir kavramd\u0131r. \u00c7al\u0131\u015fan bir sistemin etrafa yayd\u0131\u011f\u0131 manyetik dalga frekans\u0131, g\u00fcr\u00fclt\u00fc seviyesi, sistemin harcad\u0131\u011f\u0131 elektrik g\u00fc\u00e7 fark\u0131, yahut sistemin normal ak\u0131\u015f\u0131 i\u00e7inde kabul edilen bir girdiye verdi\u011fi \u00e7\u0131kt\u0131 s\u00fcresi gibi fakt\u00f6rlerin \u00f6l\u00e7\u00fclmesi ve buradan bilgi \u00e7\u0131kar\u0131m\u0131 side channel attack\u2019\u0131n konusu dahiline girer. Side channel attack kavram\u0131 birden \u00e7ok alt kavram yahut y\u00f6ntem bar\u0131nd\u0131r\u0131r. \u00d6rne\u011fin bir yere vurarak mors alfabesi ile bir kelime kodlayan birini, vuru\u015f seslerini dinleyerek metnin ne oldu\u011funu anlamas\u0131 olay\u0131 side channel attack\u2019a bir \u00f6rnek olabilir. <u>Cache attack<\/u> ve <u>Timing attack<\/u> bu alt y\u00f6ntemlerden ikisidir.\u00a0 Meltdown ve spectre bu iki t\u00fcr\u00fcn birle\u015fimi ile exploit edilir.<\/p>\n<p><strong><u>Caching (\u00d6nbellekleme)<\/u><\/strong> mekanizmas\u0131 hem g\u00fcvenlik \u00fczerine ara\u015ft\u0131rma yapan ara\u015ft\u0131rmac\u0131lar hem de k\u00f6t\u00fc niyetli hacker\u2019lar\u0131n hedefinde olmu\u015f bir \u00f6zel bellek b\u00f6lgesidir. Peki neden?<\/p>\n<p>Cache (\u00d6nbellek) ad\u0131 verilen bellek b\u00f6lgeleri ana bellek \u00fczerindeki verinin ge\u00e7ici olarak\u00a0 daha h\u0131zl\u0131 eri\u015fim i\u00e7in sakland\u0131\u011f\u0131 \u00f6zel b\u00f6lgelerdir. Ve buray\u0131 hedef yapan \u015fey ise ana bellekteki herhangi bir verinin burada \u00f6nbelleklenebilece\u011fidir. Normalde anabelle\u011fe eri\u015fim i\u015flemci taraf\u0131ndan y\u00f6netilen bir dizi eri\u015fim kontrollerinden ge\u00e7tikten sonra ba\u015far\u0131l\u0131 olmaktad\u0131r. Ancak bir verinin cache \u00fczerine i\u015flemci taraf\u0131ndan y\u00fcklenmesi, anabelle\u011fe eri\u015fimden\u00a0 ba\u011f\u0131ms\u0131z olarak o veriye eri\u015fen bir kod var oldu\u011fu m\u00fcddet\u00e7e\u00a0 her zaman ger\u00e7ekle\u015febilir. Normalde kullan\u0131c\u0131 seviyesinde eri\u015fime kapal\u0131 bellek b\u00f6lgesindeki bir veri cache \u00fczerinde saklan\u0131yor olabilir.<\/p>\n<p>Cacheleme (\u00d6nbellekleme) i\u015flemcinin, dolay\u0131s\u0131yla \u00e7al\u0131\u015fan program\u0131n h\u0131z\u0131n\u0131 etkileyen bir dizi \u00f6zelli\u011fin ger\u00e7ekle\u015fmesi i\u00e7in kullan\u0131lmaktad\u0131r. \u00c7\u00fcnk\u00fc cache bellekler ana belleklerden \u00e7ok daha h\u0131zl\u0131d\u0131r. Misal her seferinde komutlar\u0131 bellekten \u00e7ekmek yerine \u00f6nce \u00f6nbelle\u011fe alma, yahut s\u0131k kullan\u0131lan bir veriyi yine her defas\u0131ndan ana bellekten almak yerine cache \u00fczerine almak gibi i\u015flem performans\u0131n\u0131 artt\u0131rmaya y\u00f6nelik ama\u00e7larla kullan\u0131l\u0131rlar. Yahut multicore i\u015flemcilerde \u00e7ekirdekler aras\u0131nda \u00f6nbelleklenmi\u015f veririnin senkronlanmas\u0131 gerekti\u011finde yine bir payla\u015f\u0131ml\u0131 \u00f6nbellek kullan\u0131labilir. Bu ihtiya\u00e7larla i\u015flemci mimarilerine \u00e7e\u015fitli adetlerde ve bellirli bir hiyerar\u015fiye g\u00f6re \u00f6nbellekler eklenmi\u015ftir. Bu adet ve hiyerar\u015fi i\u015flemci mimarisine g\u00f6re de\u011fi\u015fkenlik g\u00f6sterir.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_5.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Screenshot_5\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_5_thumb.png\" alt=\"Screenshot_5\" width=\"644\" height=\"320\" border=\"0\" \/><\/a><\/p>\n<p>\u00d6rnekteki i\u015flemci \u00e7ip\u2019i Intel\u2019in Sandy Bridge mimarisine ait 4 \u00e7ekirdekli bir i\u015flemcisine ait. G\u00f6r\u00fcld\u00fc\u011f\u00fc gibi her \u00e7ekirdek i\u00e7in i\u00e7sel 2 seviye cache bir adet de payla\u015f\u0131ml\u0131 di\u011fer iki seviyeye g\u00f6re daha b\u00fcy\u00fck boyutlu (hem kaplad\u0131\u011f\u0131 yer hem de tuttu\u011fu veri boyutu bak\u0131m\u0131ndan) mevcut. Her i\u015flemci mimarisi farkl\u0131l\u0131k g\u00f6sterse de genel yakla\u015f\u0131m 3 seviyeli cache\u2019e sahip olmas\u0131 ve 3. seviye cache\u2019in payla\u015f\u0131ml\u0131 olmas\u0131d\u0131r.<\/p>\n<p>Cache bellek b\u00f6lgeleri ana bellekten h\u0131zl\u0131 olduklar\u0131ndan ana belle\u011fe eri\u015fim ile cache belle\u011fe eri\u015fim aras\u0131nda eri\u015fim zaman\u0131 (latency) fark\u0131 vard\u0131r.<u> Side channel tan\u0131m\u0131nda hat\u0131rlayaca\u011f\u0131n\u0131z \u00fczere bu fark da gayet \u00f6l\u00e7\u00fclebilir bir fakt\u00f6r oldu\u011fundan Side channel attack i\u00e7in uygun bir zemin olu\u015fturur<\/u>. Bu cache bellekten bilgi s\u0131zd\u0131rmakta kullan\u0131labilir. Ancak tek ba\u015f\u0131na yeterli olamaz. \u015eimdilik cache ile ilgili bu kadar bilgi kafi. Zira konumuz i\u015flemcilerin caching mekanizmas\u0131 de\u011fil.<\/p>\n<p>Cache mekanizmas\u0131n\u0131n sistemi istismardaki konumu ve \u00f6nemini \u00f6\u011frendik. Art\u0131k bu k\u0131sm\u0131 exploit edebilmek i\u00e7in bilmemiz gereken 2 unsur daha var.<\/p>\n<ol>\n<li>Cache \u00fczerine eri\u015fimlerin cached \u2013 ve non-cached latencylerini \u00f6l\u00e7ebilme yetisi<\/li>\n<li>S\u0131zd\u0131rmak istedi\u011fimiz bellek adresindeki veriyi cache \u00fczerine al\u0131nmas\u0131na sistemi zorlayabilme yetisi<\/li>\n<\/ol>\n<p>Elbette bu g\u00fcvenlik zafiyetleri exploit edilebildi\u011fine g\u00f6re bu iki yetiye de sald\u0131r\u0131 yapanlar sahiptirler. Latency \u00f6l\u00e7\u00fcm\u00fc bizi bilgi s\u0131zd\u0131rmada verinin nereden geldi\u011fini anlamam\u0131za yard\u0131mc\u0131 olacakt\u0131r. Bu side channel attack\u2019\u0131n timing (zamanlama) ile ilgili olan k\u0131sm\u0131d\u0131r. E\u011fer zamanlamay\u0131 do\u011fru tespit edemezsek sald\u0131r\u0131 ba\u015far\u0131s\u0131z olacakt\u0131r. Latency \u00f6l\u00e7\u00fcm\u00fcnde \u00e7\u0131kar\u0131lacak sonu\u00e7 \u015fudur; e\u011fer eri\u015fmek istedi\u011fimiz veri uzun bir latency ile geliyorsa bu verinin anabellekten geldi\u011fini, daha k\u0131sa s\u00fcrede geliyorsa bu verinin cache \u00fczerinden geldi\u011fini anlamam\u0131z\u0131 sa\u011flar. Bu i\u015flem ise exploiti uygulamakta iken verinin cache miss (\u0131ska)\u00a0 yahut cache hit (isabet) durumunda olup olmad\u0131\u011f\u0131n\u0131 bize g\u00f6sterir. Buradan \u00e7\u0131karabiliriz ki i\u015flemciyi buna s\u00fcreklilik i\u00e7erisinde zorlarken ald\u0131\u011f\u0131m\u0131z bir cache hit verinin \u00f6nbelle\u011fe al\u0131nd\u0131\u011f\u0131n\u0131 bilmemize yarayacakt\u0131r.<\/p>\n<p>Bellek eri\u015fim latency\u2019si (gecikme) nas\u0131l \u00f6l\u00e7\u00fcl\u00fcr?<\/p>\n<p>Intel x86 ve AMD64 (Intel x86-64) mimarisi komut seti bunu ger\u00e7ekle\u015ftirecek \u00f6zel komutlar sa\u011flamaktad\u0131r. Bu i\u015flem s\u00f6zel olarak s\u0131ras\u0131yla \u015f\u00f6yle yap\u0131l\u0131r.<\/p>\n<p>Cache Hit latency \u00f6l\u00e7\u00fcm\u00fc;<\/p>\n<ol>\n<li>Bellek adresine ait cache line (hat)\u2019\u0131 s\u0131f\u0131rlan\u0131r.<\/li>\n<li>timestamp counter okunur. (Ba\u015flang\u0131c zaman\u0131)<\/li>\n<li>Belle\u011fe eri\u015filir<\/li>\n<li>timestamp counter tekrar okunur (Biti\u015f zaman\u0131)<\/li>\n<li>Biti\u015f zaman\u0131 ile ba\u015flang\u0131\u00e7 zaman\u0131 fark\u0131 bir de\u011fi\u015fkene eklenir.<\/li>\n<li>Belirlenen n. iterasyona gelene kadar 2. ad\u0131mdan itibaren i\u015flemler tekrarlan\u0131r<\/li>\n<li>n. iterasyon bittikten sonra timestamp counter farklar\u0131 toplam\u0131 n iterasyon adedine b\u00f6l\u00fcnerek ortalamas\u0131 al\u0131n\u0131r.<\/li>\n<\/ol>\n<p>Cache miss latency \u00f6l\u00e7\u00fcm\u00fc yukar\u0131dakine benzer ancak 6. ad\u0131mdan sonra 2. ad\u0131ma atlamak yerine 1. ad\u0131ma atlanarak i\u015flem tekrar edilir. \u00c7\u00fcnk\u00fc verinin cache\u2019den at\u0131l\u0131p tekrar ana bellekten eri\u015filmeye zorlanmas\u0131 gerekir. Cache\u2019de olmayan veri de bizim cache miss durumunda olmam\u0131z\u0131 sa\u011flayacakt\u0131r. Belirlenen bir n adet iterasyon yap\u0131lmas\u0131n\u0131n sebebi ise i\u015flemcinin veriyi \u00e7ok s\u0131k eri\u015fim oldu\u011funa karar verdi\u011finde cache \u00fczerine almas\u0131d\u0131r. Biz yeteri kadar iterasyon yaparak, ilk iterasyonlarda olmasa bile ilerleyen iterasyonlarda garanti alt\u0131na almak istiyoruz.<\/p>\n<p>Bu iki de\u011ferden ortalama bir cache miss e\u015fik de\u011feri hesaplan\u0131r. Bundan sonra exploiti uygularken bu e\u015fik (threshold) de\u011feri baz al\u0131n\u0131r.\u00a0 E\u011fer eri\u015fimlerimiz bu cache miss threshold\u2019u alt\u0131nda kal\u0131rsa veriyi cache\u2019lenmi\u015f kabul edilir. Bu bilginin meltdown zafiyetini nas\u0131l istismarda kullan\u0131laca\u011f\u0131n\u0131 ilerleyen a\u015famada detayland\u0131raca\u011f\u0131m.<\/p>\n<p>Latency \u00f6l\u00e7\u00fcm\u00fcn\u00fc yapabilmek i\u00e7in <strong>clflush<\/strong> ve <strong>rdtsc<\/strong> ad\u0131nda iki makine komutu kullan\u0131l\u0131r.<\/p>\n<p><strong>clflush<\/strong> komutu verilen bellek adresine denk d\u00fc\u015fen cache line\u2019\u0131 s\u0131f\u0131rlamaktad\u0131r. Ve en b\u00fcy\u00fck avantaj\u0131 da bu komut privileged (ayr\u0131cal\u0131kl\u0131) bir komut de\u011fildir. Hen user hem de kernel mod\u2019da istisnas\u0131z \u00e7al\u0131\u015fabilir. Meltdown zafiyetinin ve elbette Spectre\u2019in kilit unsurlar\u0131ndan biridir.<\/p>\n<p><strong>rdtsc<\/strong> komutu ise instruction (komut) \u00e7al\u0131\u015fma s\u00fcrelerini \u00f6l\u00e7ebilecek hassasiyette 64 bit uzunlu\u011funda bir zaman sayac\u0131 vermektedir. \u0130\u015flemci her bir clock cycle\u2019da (Saat vuru\u015fu) i\u00e7sel sayac\u0131 artt\u0131r\u0131r. Komutlar bu saya\u00e7 \u00f6l\u00e7\u00fcm\u00fc aras\u0131na konularak aradaki fark\u0131n hesaplanmas\u0131yla \u00e7al\u0131\u015fan komutun ne kadar cpu cycle harcad\u0131\u011f\u0131 \u00f6l\u00e7\u00fclebilir.<\/p>\n<p><strong><u>Out Of Order Execution (D\u00fczensiz Komut \u0130\u015fletme)<\/u><\/strong><\/p>\n<p>Meltdown g\u00fcvenlik zafiyetini ortaya \u00e7\u0131karan tek ba\u015f\u0131na olmasa da en b\u00fcy\u00fck sorun i\u015flemcilerin out-of-order execution \u00f6zellikleri. Out of order execution (k\u0131saca OOE diyece\u011fim) de i\u015flem performans\u0131n\u0131 artt\u0131rmak i\u00e7in uzun zamand\u0131r i\u015flemcilerde olan bir \u00f6zellik. Bunun bir benzeri de Speculative Execution denilen program ak\u0131\u015f\u0131ndaki dallanmalar\u0131n (Jump) y\u00f6n\u00fcn\u00fc\u00a0 tahmin ederek \u00e7al\u0131\u015ft\u0131rmaya dayal\u0131 bir \u00f6zellik. Bu \u00f6zelli\u011fi Spectre incelemesinde detayland\u0131rmak daha do\u011fru olur. O y\u00fczden \u00fczerinde fazla durmadan OOE konusunu biraz daha detayland\u0131rmak istiyorum.<\/p>\n<p>OOE (Out Of Order Execution) birbirine ba\u011f\u0131ml\u0131l\u0131klar\u0131 olmayan komutlar\u0131n s\u0131ras\u0131n\u0131 beklemek yerine zamandan kazanmak i\u00e7in paralel olarak farkl\u0131 bir pipeline\u2019a al\u0131narak paralel \u00e7al\u0131\u015ft\u0131r\u0131lmas\u0131n\u0131 sa\u011flayan bir \u00f6zelliktir ve her modern i\u015flemcide bu \u00f6zellik mevcuttur.<\/p>\n<p>Basit\u00e7e bir \u00f6rnek;<\/p>\n<pre class=\"lang:c decode:true\">x = array[array[i]];\ny = array[j]<\/pre>\n<p>yukar\u0131daki \u00f6rnek kodun 2. sat\u0131r\u0131 out-of-order olarak \u00e7al\u0131\u015ft\u0131r\u0131labilir. \u00c7\u00fcnk\u00fc 2. sat\u0131r\u0131n kendinden \u00f6nceki sat\u0131rdaki komutlar\u0131n sonucuna ba\u011f\u0131ml\u0131l\u0131\u011f\u0131 yoktur.<\/p>\n<p>Ancak, out of order \u00e7al\u0131\u015ft\u0131r\u0131lan komutlar\u0131n etkileri, kendinden \u00f6nceki komutlar\u0131n ba\u015far\u0131l\u0131 olarak tamamlan\u0131p pipeline\u2019dan \u00e7\u0131kar\u0131lmad\u0131klar\u0131 s\u00fcrece i\u015flemci genel ve durum yazma\u00e7lar\u0131na yans\u0131t\u0131lmaz. T\u00fcm OOE i\u015flemleri i\u015flemcinin i\u00e7sel (internal), yani d\u0131\u015far\u0131ya kapal\u0131 biriminde ger\u00e7ekle\u015ftirilir. E\u011fer OOE dahilindeki komutlar kendinden \u00f6nceki komutlarda, program ak\u0131\u015f\u0131n\u0131n kendisinin mant\u0131ksal olarak \u00e7al\u0131\u015fmamas\u0131n\u0131 sa\u011flayacak bir duruma neden olursa (\u00d6rne\u011fin bir exception) o i\u015flemin sonu\u00e7lar\u0131 ve etki etti\u011fi flagler ge\u00e7ersiz say\u0131l\u0131rlar.<\/p>\n<p>\u00d6rne\u011fin;<\/p>\n<pre class=\"lang:asm decode:true \">MOV RAX, 1000\nIMUL RAX, 2<\/pre>\n<p>komutu OOE dahilinde \u00e7al\u0131\u015ft\u0131r\u0131ld\u0131\u011f\u0131nda i\u015flem sonucunun 2000 olaca\u011f\u0131 hesaplanm\u0131\u015f durumdad\u0131r ancak RAX yazmac\u0131na bu de\u011ferler kendinden \u00f6nceki komutlar ba\u015far\u0131l\u0131 olmad\u0131klar\u0131 s\u00fcrece yaz\u0131lmaz.<\/p>\n<p>Ancak bu duruma ra\u011fmen OOE sonucunda istenmeyen bir yan etki g\u00f6zlemlenmi\u015ftir. Bu yan etki de \u015fudur; OOE dahilinde i\u00e7sel olarak i\u015fletilen komutlar ve sonu\u00e7lar\u0131 ignore edilmi\u015f olsa (yoksay\u0131lsa) dahi eri\u015fti\u011fi bellek cache \u00fczerinde kalmaya devam etmektedir. Bu mimarinin tasar\u0131m\u0131nda yatan, istismar edilebilece\u011fi d\u00fc\u015f\u00fcn\u00fclmemi\u015f bir durumdur. Zira cache edilmi\u015f bir veriyi tekrar flush etmenin bir anlam\u0131 yoktur. Tam aksine flush i\u015flemi ek operasyonlara neden olacakt\u0131r. Bu normalde d\u0131\u015far\u0131dan g\u00f6zlemlenmemesi gereken bir i\u015fleyi\u015fin d\u0131\u015f d\u00fcnyaya yans\u0131mas\u0131 olarak kalmaktad\u0131r. Yukar\u0131da anlat\u0131lan unsurlar bir araya getirildi\u011finde bir side channel attack i\u00e7in g\u00fczel bir zemin haz\u0131rlamaktad\u0131r. OOE \u00f6zelli\u011finin meltdown\u2019\u0131 exploit etmekte nas\u0131l kullan\u0131laca\u011f\u0131, yaz\u0131n\u0131n ilerleyen k\u0131sm\u0131nda detayland\u0131raca\u011f\u0131m. \u015eimdilik OOE\u2019un ne oldu\u011funu ne t\u00fcr yan etkilere sebep oldu\u011funu g\u00f6rd\u00fck.<\/p>\n<p><strong><u>Virtual Memory (Sanal Bellek)<\/u><\/strong><\/p>\n<p>Sanal bellek mekanizmas\u0131 i\u015fletim sistemlerinin en temel ve en gerekli mekanizmalar\u0131ndan biridir. Bu kavram\u0131n ge\u00e7mi\u015fi 1950\u2019li y\u0131llara kadar dayanmaktad\u0131r. Modern say\u0131labilecek anlamda ise sanal bellek konsepti 1970\u2019li y\u0131llara kadar uzanmaktad\u0131r. Sanal bellek, fiziksel belle\u011fi hem daha etkin, hem de \u00e7ok i\u015flemli (process) ve \u00e7ok kullan\u0131c\u0131l\u0131 sistemlerde her i\u015flemi birbirinden g\u00fcvenli \u015fekilde izole etmek amac\u0131yla uygulanm\u0131\u015f bir mekanizmad\u0131r. Page\u2019lere b\u00f6l\u00fcnm\u00fc\u015f fiziksel ve da\u011f\u0131n\u0131k bellek bloklar\u0131n\u0131 tek bir bellek \u00f6be\u011fi olarak tutabilirler. Bu sayede kullan\u0131c\u0131 programlar\u0131n\u0131n fiziksel belle\u011fi do\u011frusal olarak kullanmas\u0131na imkan tan\u0131r. Sanal bellek mekanizmas\u0131 kendi ba\u015f\u0131na olduk\u00e7a detayl\u0131 bir kavram o y\u00fczden bizi ilgilendiren \u00f6l\u00e7\u00fcde bahsedece\u011fim.<\/p>\n<p>Prosesler aras\u0131nda bellek izolasyonu yapabilmek i\u00e7in sanal bellek kullan\u0131l\u0131yor demi\u015ftik. Bunu sa\u011flamak i\u00e7in i\u015flemcilerde Page Table denilen sanal belle\u011fi fiziksel belle\u011fe d\u00f6n\u00fc\u015ft\u00fcrmekte kullan\u0131lan bir tablo bulunmaktad\u0131r. \u0130\u015fletim sistemi her proses (i\u015flem) ba\u015f\u0131na bir page table y\u00f6netir ve prosesler aras\u0131nda ge\u00e7i\u015fte bu page table \u00e7al\u0131\u015facak prosesin page table\u2019\u0131 ile de\u011fi\u015ftirilir. x86 mimarisinde bu i\u015f i\u00e7in \u00f6zel olarak kullan\u0131lan <strong>CR3<\/strong> yazmac\u0131 bu page table\u2019\u0131n adresini tutmaktad\u0131r. Her process\u2019in page table\u2019\u0131 fiziksel bellekte farkl\u0131 b\u00f6lgeleri i\u015faret etti\u011finden, A prosesi de, B prosesi de 0xAEAA1000 adresini kulland\u0131\u011f\u0131n\u0131 zannedebilir. Ancak her proses ayn\u0131 adrese eri\u015fmeye \u00e7al\u0131\u015ft\u0131\u011f\u0131nda farkl\u0131 veriler g\u00f6receklerdir. \u00c7\u00fcnk\u00fc page table sayesinde i\u015flemci o sanal adresi ger\u00e7ekte verisinin bulundu\u011fu fiziksel belle\u011fe d\u00f6n\u00fc\u015ft\u00fcr\u00fcp eri\u015fecektir.<\/p>\n<p>\u0130\u015fletim sistemi her proses i\u00e7in page table\u2019\u0131 y\u00f6netirken Kernel Mode \u2013 User Mode aras\u0131 gidip gelmelerde Kernel bellek alan\u0131 ile Process\u2019in bellek alan\u0131n\u0131 ayn\u0131 adres uzay\u0131 i\u00e7erisindedir. Bunun pek \u00e7ok avantaj\u0131 var.<\/p>\n<ol>\n<li>\u0130\u015fletim sistemi sistem \u00e7a\u011fr\u0131lar\u0131n\u0131 h\u0131zl\u0131 bir \u015fekilde kabul edebilmektedir. \u015euan i\u015fletim sistemlerinin meltdown i\u00e7in \u00e7\u0131kard\u0131\u011f\u0131 g\u00fcncellemelerin performans d\u00fc\u015f\u00fc\u015f\u00fcne sebep olan k\u0131sm\u0131 da bununla ilintilidir. Ona ilerde de\u011finece\u011fim.<\/li>\n<li>User mode\u2019da yani kullan\u0131c\u0131 seviyesinde bir prosess aktif olarak \u00e7al\u0131\u015fmaktayken bir Interrupt meydana geldi\u011finde yine herhangi bir adres alan\u0131 de\u011fi\u015fimine u\u011framadan \u0130\u015fletim sistemi interrupt (kesme) handling i\u015flerini yapabilmektedir.<\/li>\n<\/ol>\n<p>Ayn\u0131 adres alan\u0131 i\u00e7erisinde olmalar\u0131 elbette user mode taraf\u0131ndan kernel mode belle\u011fini okuma yazma yetkisi vermez. Her ne kadar da ayn\u0131 adres uzay\u0131 i\u00e7erisinde olsalar da Page Protection sayesinde kimin nereye, ne \u015fartlarda eri\u015fece\u011fi belirlenebilir. Her page\u2019in kendine \u00f6zel bir eri\u015fim kontrol Bit\u2019leri mevcuttur. Supervisor olarak i\u015faretlenmi\u015f page\u2019lerin User Mode&#8217;dan (yani ring 3) eri\u015fimi engellenir. Bu yakla\u015f\u0131m klasik User Mode, Kernel Mode izolasyonunda kullan\u0131lmaktad\u0131r.<\/p>\n<h2><span style=\"font-weight: bold; color: #ff0000;\">Meltdown<\/span><\/h2>\n<p>Bu noktaya gelene kadar meltdown zafiyetine sebebiyet veren ve istismar edilmesine olanak sa\u011flayan fakt\u00f6rleri tek tek inceledik. Art\u0131k bu noktadan sonra tam olarak meltdown\u2019\u0131 a\u00e7\u0131klamaya ba\u015flayabiliriz.<\/p>\n<p>Biraz evvel sanal bellek mekanizmas\u0131ndaki yakla\u015f\u0131m\u0131n Kernel mode adres alan\u0131n\u0131n User mode taraf\u0131nda da g\u00f6r\u00fcn\u00fcr oldu\u011funu g\u00f6rd\u00fck. Kernel adres alan\u0131, user mode taraf\u0131nda ge\u00e7erli oldu\u011funa g\u00f6re bir sanal adresin fiziksel adresini hesaplad\u0131\u011f\u0131m\u0131zda tam olarak almak istedi\u011fimiz veriyi oradan alabiliriz demektir bu. Ancak <strong>Page Protection<\/strong> sayesinde user mode\u2019dan bu b\u00f6lgeye gelen eri\u015fim isteklerinin i\u015flemci taraf\u0131ndan Genel koruma hatas\u0131 ile (General Protection Fault) engellendi\u011fini de biliyoruz.<\/p>\n<p>Ancak hat\u0131rlarsan\u0131z i\u015flemcilerin baz\u0131 ba\u011f\u0131ml\u0131l\u0131\u011f\u0131 olmayan komutlar\u0131 Out Of Order dahilinde \u00e7al\u0131\u015ft\u0131rabildi\u011fini biliyoruz. Meltdown\u2019\u0131n alt\u0131nda yatan fikir bir kernel mode adresine s\u00fcrekli olarak eri\u015fmeye \u00e7al\u0131\u015fan bir kodumuz olsa ve hemen bu kernel adresine eri\u015fim denemesi yapan kodun pe\u015fi s\u0131ra o out of order \u015fekilde \u00e7al\u0131\u015fabilecek bir kod yerle\u015ftirsek sonu\u00e7 ne olur? sorusudur. Ne yaz\u0131k ki mikroi\u015flemcilerin mimarilerinin geli\u015ftiricilere a\u00e7\u0131k olmayan ve normal yaz\u0131l\u0131mlar \u00fczerinde yahut firmware\u2019lerde oldu\u011fu gibi rahat\u00e7a reverse engineering (Tersine m\u00fchendislik) yapabilme \u015fans\u0131 yoktur. Biraz evvel bahsetti\u011fim sorunun cevab\u0131n\u0131n ne oldu\u011fu ancak Side channel attack denemelerinin \u00f6l\u00e7\u00fcmleri ile ula\u015f\u0131labilir ve \u00fczerinde olduk\u00e7a \u00e7al\u0131\u015f\u0131lmas\u0131 gereken olduk\u00e7a hassas bir i\u015ftir.<\/p>\n<p>Ancak \u015fu rahatl\u0131kla bilinebilir bir ger\u00e7ektir. User mode\u2019da bir kodun kernel b\u00f6lgesine eri\u015fimi az evvel bahsetti\u011fim genel koruma hatas\u0131 ile sonland\u0131r\u0131lacakt\u0131r. Bunun User Level\u2019daki kar\u015f\u0131l\u0131\u011f\u0131 bildi\u011fimiz Exception\u2019a sebebiyet vermesi durumudur. Bu noktada soru \u015fu hale gelecektir.<\/p>\n<p>Bir kod kernel mode\u2019a ait bir adrese eri\u015fim sa\u011flamak istedi\u011finde olu\u015fan Exception\u2019dan sonra kalan komutlar ger\u00e7ekten Out Of Order kapsam\u0131nda i\u015fletilebilir mi? Yan\u0131t gayet tabi evet. \u00c7\u00fcnk\u00fc i\u015flemci mimarisi buna olanacak verecek \u015fekilde dizayn edilmi\u015ftir.<\/p>\n<p>A\u015fa\u011f\u0131da basite indirgenmi\u015f meltdown ile ilintili bir \u00f6rnek diyagram g\u00f6r\u00fcyorsunuz.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/ooe.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"ooe\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/ooe_thumb.png\" alt=\"ooe\" width=\"551\" height=\"417\" border=\"0\" \/><\/a><\/p>\n<p>Diyagramda belirlenen bir kernel adresinden 1 byte okunmak isteniyor. Ve i\u015flem sonucundan d\u00f6nen 1 bytel\u0131k de\u011fer KONTROL_DIZISI ad\u0131ndaki 256 byte\u2019dan olu\u015fan bir dizinin o de\u011fere denk d\u00fc\u015fen index\u2019indeki de\u011fere eri\u015fmek istiyor. S\u00f6z gelimi e\u011fer kernel adresinden okunan byte de\u011feri 14 ise, bu kontrol dizisinin 14. indexine eri\u015fmek demek. Yani x = KONTROL_DIZISI[14]<\/p>\n<p>Peki kontrol dizisinin neden 256 byte uzunlu\u011funda oldu\u011funa dair bir fikriniz var m\u0131? Yoksa ileride tam olarak nedenini detayl\u0131 olarak a\u00e7\u0131klayaca\u011f\u0131m. Normal olarak programc\u0131n\u0131n beklentisi b\u00f6yle bir durumda illegal olarak bir adresten 1 byte veri okunmas\u0131 sonras\u0131 Exception ile program ak\u0131\u015f\u0131n\u0131n kesilmesi olur. Ve hatal\u0131 eri\u015fim kodundan sonraki komutlar\u0131n bu sebepten asla \u00e7al\u0131\u015ft\u0131r\u0131lmayaca\u011f\u0131n\u0131 bekler. E\u011fer programda bir exception handling mekanizmas\u0131 yok ise, illegal eri\u015fim denemesi yapan program i\u015fletim sistemi taraf\u0131ndan sonland\u0131r\u0131lacakt\u0131r. \u00d6ncelikle istismar eden program\u0131n ba\u015far\u0131yla \u00e7al\u0131\u015fmaya devam edebilmesi bu durumun engellenmesini gerektirir.<\/p>\n<p>Meltdown\u2019\u0131 ba\u015far\u0131yla exploit edebilmek i\u00e7in \u00f6ncelikle bu durumdan kurtulmak gerekir. Bunun i\u00e7in bir ka\u00e7 se\u00e7ene\u011fimiz var.<\/p>\n<p>1-) <em><strong>Signal Handler<\/strong><\/em><br \/>\nUnix tabanl\u0131 i\u015fletim sistemlerinin standart ak\u0131\u015f kontrol mekanizmas\u0131 signal mekanizmas\u0131d\u0131r. Ancak POSIX gere\u011fi, POSIX uyumlu olma iddias\u0131nda olan t\u00fcm i\u015fletim sistemleri destekler. Windows i\u015fletim sistemi de signal mekanizmas\u0131n\u0131 destekler. Bu y\u00f6ntemde istismara ba\u015flamadan \u00f6nce SIGSEGV sinyali register edilir. SIGSEGV sinyali ge\u00e7ersiz bellek eri\u015fimlerinde program\u0131 sonland\u0131rmadan \u00f6nce program\u0131n hatay\u0131 tol\u00f6re etmesi i\u00e7in kullan\u0131lan bir signal t\u00fcr\u00fcd\u00fcr. Ancak bizim exception\u2019dan ka\u00e7\u0131n\u0131p kald\u0131\u011f\u0131m\u0131z yerden devam edebilmemiz gerekir. Bu sebepten setjmp, longjmp ikilisi kullan\u0131l\u0131r. setjmp \u00e7a\u011fr\u0131ld\u0131\u011f\u0131 nokta o anki t\u00fcm i\u015flemci durumunu bir buffer\u2019a (Buna jump buffer denilir) kaydeder. O anki yazma\u00e7 durumlar\u0131, flag, stack bilgisi vs. Yani \u00e7a\u011fr\u0131ld\u0131\u011f\u0131 o an\u0131n binary d\u00fczlemde foto\u011fraf\u0131n\u0131 \u00e7eker.\u00a0 longjmp ise program\u0131 kay\u0131t edilen o bilgilerin durumuna geri d\u00f6nd\u00fcr\u00fcr. B\u00f6ylece herhangi bir konumdan program tekrar eski i\u015fleyi\u015fine d\u00f6nebilir. Ancak herhangi bir stack corruption (Y\u0131\u011f\u0131n bozulmas\u0131) durumunda bu d\u00f6n\u00fc\u015f\u00fcn bir anlam\u0131 olmaz.<\/p>\n<ol>\n<li>SIGSEGV sinyalini register et. signal(SIGSEGV, signal_handler_fonksiyonu);<\/li>\n<li>Exploit kodu \u00e7al\u0131\u015fmadan \u00f6nce setjmp ile o an\u0131n durumunu yakala. setjmp(jmpBuf);<\/li>\n<li>signal_handler_fonksiyonu i\u00e7erisine longjmp(jmpBuf) ile exception\u2019dan en son duruma geri d\u00f6n.<\/li>\n<\/ol>\n<p>2-) <strong><em>Windows Exception Handler<\/em><\/strong><br \/>\nWindows i\u015fletim sisteminin native exception handling mekanizmas\u0131. Her ne kadar Windows POSIX gere\u011fi signal i\u015flemlerini de desteklese portability kayg\u0131s\u0131 g\u00fcd\u00fclm\u00fcyorsa en iyi yol kendi native exception handler\u2019ini kullanmak. Bunu Windows\u2019ta 2 \u015fekilde yapma \u015fans\u0131n\u0131z var.<\/p>\n<ul>\n<li>Compiler destekli Exception Handler<\/li>\n<li>Windows Vectored Exception Handler<\/li>\n<\/ul>\n<p>Compiler destekli SEH Microsoft\u2019un programlama diline C\/C++ ekledi\u011fi bildi\u011fimiz try catch, __try, __except kontrol bloklar\u0131yla kullan\u0131labilen \u015feklidir. Ben program ak\u0131\u015f\u0131na \u00e7ok fazla kar\u0131\u015fmamas\u0131 i\u00e7in ve exploit\u2019e ekstra SEH rutin komutlar\u0131 ekledi\u011fi i\u00e7in kullanmad\u0131m.<\/p>\n<p>Di\u011fer se\u00e7enek Vectored Exception Handler, exception handle etmenin en temiz ve h\u0131zl\u0131 yolu. Bu sistem t\u0131pk\u0131 signal mekanizmas\u0131na benzer \u00e7al\u0131\u015f\u0131r. \u00d6nce bir handler register edilir, bir exception olu\u015ftu\u011funda program ak\u0131\u015f\u0131 register etti\u011fimiz exception handler\u2019a y\u00f6nlendirilir. Oradan exception context\u2019i ayarlayarak istedi\u011fimiz noktadan program ak\u0131\u015f\u0131na devam etmemiz sa\u011flan\u0131r. Uygulad\u0131\u011f\u0131m meltdown implementasyonunda varsay\u0131lan olarak VEH kullan\u0131lmaktad\u0131r.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_7.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Screenshot_7\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_7_thumb.png\" alt=\"Screenshot_7\" width=\"571\" height=\"82\" border=\"0\" \/><\/a><\/p>\n<p>Ba\u015flang\u0131\u00e7ta bir defa <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms679274(v=vs.85).aspx\" target=\"_blank\" rel=\"noopener\">AddVectoredExceptionHandler<\/a> API\u2019i ile kendi handler\u2019\u0131m\u0131z\u0131 register ederiz. vectored_handler exception\u2019lar\u0131n yakalan\u0131p y\u00f6nlendirildi\u011fi fonksiyondur. \u0130\u00e7eri\u011fi signal handler i\u00e7eri\u011fi kadar k\u0131sa de\u011fil. \u00c7\u00fcnk\u00fc bu exception handler t\u00fcm exception t\u00fcrlerini y\u00f6nlendirdi\u011fi i\u00e7in bize \u00e7ok fazla bilgi sa\u011flar ve buna g\u00f6re y\u00f6nlendirmemiz gerekebilir.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_8.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Screenshot_8\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_8_thumb.png\" alt=\"Screenshot_8\" width=\"745\" height=\"458\" border=\"0\" \/><\/a><br \/>\nYukar\u0131da geli\u015ftirdi\u011fim exploit\u2019in exception handler rutinini g\u00f6r\u00fcyorsunuz. \u00c7al\u0131\u015fan exploit kodunun bulundu\u011fu noktadan \u00f6nce bir defal\u0131k return adresini bulup saklad\u0131ktan sonra sonraki exception\u2019larda h\u0131zl\u0131 olmas\u0131 i\u00e7in do\u011frudan o adrese Instruction Pointer\u2019i y\u00f6nlendiriyor ve Windows\u2019a o noktadan i\u015fleyi\u015fe devam etmesini belirtiyor. Instruction pointer ve context mimariye g\u00f6re farkl\u0131l\u0131k g\u00f6sterdi\u011finden x86 ile x86-64 (AMD64) i\u00e7in k\u0131smen farkl\u0131l\u0131k g\u00f6sterecek \u015fekilde yaz\u0131lmalar\u0131 gerekiyor. Bu noktadan sonra olu\u015fan exceptionlar h\u0131zl\u0131ca exploit\u2019in ola\u011fan ak\u0131\u015f\u0131na y\u00f6nlendirilmektedir.<\/p>\n<p>3-)<strong><em> Intel TSX (Transactional Synchronization Extensions)<\/em><\/strong><br \/>\nIntel\u2019in Haswell mimarisi ile birlikte kullan\u0131ma sundu\u011fu bu \u00f6zellik sayesinde donan\u0131msal olarak exception\u2019lar\u0131 suppress (bask\u0131lama) etme \u015fans\u0131 mevcut. Bu \u00f6zellik s\u0131n\u0131rlar\u0131 belirlenen bir dizi komutun transactional \u00e7al\u0131\u015ft\u0131r\u0131lmas\u0131n\u0131 sa\u011flar. Yani di\u011fer transacted operasyonlar gibi ba\u015flang\u0131c\u0131 ve biti\u015fi belirlenen bir \u00f6bek i\u015flemin t\u00fcm ad\u0131mlar\u0131n\u0131n ba\u015far\u0131l\u0131 \u015fekilde tamamlanmas\u0131n\u0131 aksi halde o ana kadar uygulanan i\u015flemlerin sisteme yans\u0131t\u0131lmamas\u0131n\u0131 (rollback), ba\u015far\u0131l\u0131ysa\u00a0 yans\u0131t\u0131lmas\u0131n\u0131 (commit) sa\u011flamaktad\u0131r. Exception suppression bu \u00f6zelli\u011fin bize getirdi\u011fi bir yan etkidir. Transaction dahilinde olu\u015fan bir hatal\u0131 durum exception\u2019a sebebiyet vermeden transaction sonlanacakt\u0131r. TSX sistemi i\u015flemcilerde y\u00fcksek performans getirmesi i\u00e7in dizayn edilmi\u015ftir. Meltdown\u2019\u0131n exploit edilmesinde ise sald\u0131r\u0131ya yapt\u0131\u011f\u0131 katk\u0131 gereksiz yere exception dispatch i\u015fleminin araya girmemesi sayesinde exploit kodunun \u00e7ok daha seri ve h\u0131zl\u0131 \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flar. Bu da exploit\u2019in ba\u015far\u0131m\u0131n\u0131 ve h\u0131z\u0131n\u0131 artt\u0131r\u0131r. B\u00f6ylece di\u011ferlerine g\u00f6re daha yava\u015f olan bellek i\u00e7eri\u011fini s\u0131zd\u0131rma i\u015flemi g\u00f6rece daha h\u0131zl\u0131 ger\u00e7ekle\u015fmektedir.<\/p>\n<p>TSX ile yap\u0131lmas\u0131 gereken ise di\u011fer exception handling\u2019e g\u00f6re kolay. TSX transaction ba\u015flang\u0131\u00e7 ve biti\u015fi i\u00e7in iki adet \u00f6zel komut sa\u011flamaktad\u0131r. xbegin ve xend. xbegin transaction\u2019\u0131n ba\u015flad\u0131\u011f\u0131n\u0131, xend ise transaction\u2019\u0131n sonland\u0131\u011f\u0131n\u0131 belirtir. <strong>xbegin<\/strong> ve <strong>xend<\/strong> aras\u0131nda kalan komutlar transacted i\u015flenmektedir. Yap\u0131lmas\u0131 gereken meltdown\u2019\u0131 exploit eden kodu transacted hale getirmekten ibarettir.<\/p>\n<p>Ancak k\u00f6t\u00fc yan\u0131 TSX\u2019in sadece destekleyen i\u015flemcilerde \u00e7al\u0131\u015f\u0131yor olmas\u0131d\u0131r. Ancak Meltdown\u2019\u0131 exploit ederken dinamik olarak i\u015flemcinin TSX deste\u011fi olup olmad\u0131\u011f\u0131 kontrol edilerek \u00e7al\u0131\u015fma zaman\u0131 tercih edilebilir. \u0130\u015flemcinin TSX deste\u011fi olup olmad\u0131\u011f\u0131n\u0131 anlamak i\u00e7in <strong>cpuid<\/strong> komutunun 7 numaral\u0131 ve 0 numaral\u0131 alt fonksiyonunu \u00e7a\u011f\u0131r\u0131p ebx yazmac\u0131n\u0131n 11. bitinin durumunu kontrol etmek gereklidir. E\u011fer bit set durumda ise TSX mevcuttur. A\u015fa\u011f\u0131da i\u015flemcinin TSX deste\u011fi olup olmad\u0131\u011f\u0131n\u0131 kontrol eden prosed\u00fcr\u2019\u00fcn x86 assembly komutlar\u0131.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_9.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Screenshot_9\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_9_thumb.png\" alt=\"Screenshot_9\" width=\"232\" height=\"338\" border=\"0\" \/><\/a><\/p>\n<p>E\u011fer kullan\u0131lan compiler cpuid komutu i\u00e7in intrinsic hali varsa, C dili kullan\u0131larak da bu kontrol yap\u0131labilir. \u00d6rne\u011fin Microsoft Visual C++ compiler bu tip intrinsic fonksiyonlar\u0131 sa\u011flamaktad\u0131r.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_10.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Screenshot_10\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_10_thumb.png\" alt=\"Screenshot_10\" width=\"383\" height=\"472\" border=\"0\" \/><\/a><\/p>\n<p>Ayn\u0131 i\u015fi yapan TSX kontrol\u00fcn\u00fc bu sayede C dili ile de yazmak m\u00fcmk\u00fcnd\u00fcr. TSX alt\u0131nda meltdown\u2019\u0131 exploit eden kodu transacted hale getirebiliriz. Visual C++ compiler TSX komutlar\u0131 i\u00e7in de intrinsic fonksiyonlar\u0131 sa\u011flamaktad\u0131r. Bu sayede<\/p>\n<p>_xbegin();<br \/>\nMELTDOWN_EXPLOIT;<br \/>\n_xend();<\/p>\n<p>\u015feklinde exploit eden kodu \u00e7al\u0131\u015ft\u0131rarak olu\u015facak exception\u2019lar\u0131 bask\u0131layabiliriz.\u00a0 Daha \u00f6ncede bahsetti\u011fim gibi TSX kullanarak yap\u0131lan exception suppression Meltdown\u2019\u0131n exploit edilmesi ba\u015far\u0131m\u0131n\u0131 olduk\u00e7a art\u0131rmaktad\u0131r. Bu veri s\u0131zd\u0131rma h\u0131z\u0131n\u0131 da olumlu y\u00f6nde etkileyen bir i\u015flemdir.<\/p>\n<p>Meltdown\u2019\u0131 exploit etmek i\u00e7in Windows platformuna port etti\u011fim mini k\u00fct\u00fcphane yukar\u0131da bahsetti\u011fim 3 exception suppression yakla\u015f\u0131m\u0131n\u0131 da desteklemektedir.<\/p>\n<p>Yukar\u0131da verilen \u00f6rne\u011fe tekrar d\u00f6nelim;<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/meltdown_ex.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"meltdown_ex\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/meltdown_ex_thumb.png\" alt=\"meltdown_ex\" width=\"225\" height=\"212\" border=\"0\" \/><\/a><\/p>\n<p>Demi\u015ftik ki bir kernel b\u00f6lgesine ait bir adresten 1 byte veri okumaya \u00e7al\u0131\u015fan MOV AL, [RCX] komutu \u00e7al\u0131\u015fmaya ba\u015flad\u0131\u011f\u0131nda i\u015fletim sistemi illegal bir i\u015flem yapt\u0131\u011f\u0131m\u0131z\u0131 anlayarak exception olu\u015fturacakt\u0131. Exception\u2019\u0131n prosese g\u00f6nderilmesi, program ak\u0131\u015f\u0131n\u0131n kernel mode\u2019a dallanmas\u0131 demektir. Exception\u2019\u0131n prosese dispatch edilmesi esnas\u0131nda OOE dahilinde i\u015fletilecek olas\u0131 komutlar\u0131n bu ba\u011flamda yorumlanmas\u0131 anlam\u0131na gelmektedir. Meltdown\u2019\u0131 ba\u015far\u0131yla exploit edebilmek i\u00e7in belirli maksimum adette bu i\u015flemi etmemiz gerekir. \u00c7\u00fcnk\u00fc eri\u015fim yapan komutun pipeline\u2019dan at\u0131lmas\u0131 ile komutlar\u0131n Out-of-order \u00e7al\u0131\u015ft\u0131r\u0131lmas\u0131 aras\u0131nda bir race condition durumu s\u00f6z konusu olabilir. (Race condition ile ilgili daha fazla detayl\u0131 bilgi almak isterseniz <a href=\"http:\/\/oguzkartal.net\/blog\/index.php\/2015\/11\/18\/concurrent-eszamanli-programlama-ve-race-condition-tehlikesi\/\" target=\"_blank\" rel=\"noopener\">Race Condition<\/a> yaz\u0131m\u0131 okuyabilirsiniz) Yeteri kadar tekrarda \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131m\u0131zda i\u015flemcinin istedi\u011fimiz kodu Out-of-order olarak i\u015fletmesini sa\u011flam\u0131\u015f oluruz. Bunu sa\u011flamak i\u00e7in de tekrar say\u0131s\u0131 kadar iterasyon yapan bir d\u00f6ng\u00fc i\u00e7inde i\u015flemciye OOE bask\u0131s\u0131 olu\u015fturmaya \u00e7al\u0131\u015f\u0131r\u0131z.<\/p>\n<p><strong><u>Meltdown ile Veri S\u0131zd\u0131rma \u0130\u015flemi<\/u><\/strong><\/p>\n<p>Yaz\u0131m\u0131n ba\u015flar\u0131nda Out of order execution konusundan bahsederken bu i\u015flemin bir tak\u0131m d\u0131\u015far\u0131dan g\u00f6zlenebilen yan etkileri oldu\u011fundan bahsetmi\u015ftim. Bu yan etkilerden bir tanesi de komutlar ne kadar i\u00e7sel olarak \u00e7al\u0131\u015ft\u0131r\u0131lsa da bir bellek eri\u015fimi oldu\u011funda hedef adresten al\u0131nan verinin cache\u2019lendi\u011fini ve i\u015flem sonunda ignore edilecek olsa bile cachle\u2019lenen verinin hala cache bellek \u00fczerinde kald\u0131\u011f\u0131 idi.<\/p>\n<p>Peki meltdown bu durumu kullanarak nas\u0131l veri s\u0131zd\u0131rmay\u0131 ba\u015far\u0131yor. Bu biraz dolayl\u0131 olarak yap\u0131l\u0131yor. Esasen tam olarak bir seferde tam ve do\u011fru olarak veriyi okumak diye bir durum s\u00f6z konusu de\u011fil. \u015eimdi yukar\u0131da g\u00f6sterdi\u011fim cache\u2019i exploit eden \u00f6rne\u011fe bakal\u0131m.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/meltdown_ex-1.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"meltdown_ex\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/meltdown_ex_thumb-1.png\" alt=\"meltdown_ex\" width=\"225\" height=\"212\" border=\"0\" \/><\/a><\/p>\n<p>Daha \u00f6nce KONTROL_DIZISI isimli 256 byte uzunlu\u011funda bir dizinin varl\u0131\u011f\u0131ndan bahsetmi\u015f ve bu dizinin neden 256 byte oldu\u011funu sormu\u015ftum. Cevab\u0131n\u0131 \u015fimdi alaca\u011f\u0131z. Yukar\u0131daki \u00f6rne\u011fin son 2 komutunu ad\u0131m ad\u0131m inceleyelim. Tabi bu istedi\u011fimiz \u015fekilde Out-of-order olarak \u00e7al\u0131\u015facaklar.<\/p>\n<p>RCX yazmac\u0131n\u0131n g\u00f6sterdi\u011fi adresteki 1 bytel\u0131k verinin 41 oldu\u011funu d\u00fc\u015f\u00fcnelim. Bu durumda;<\/p>\n<p>MOV AL, [RCX] komutu i\u00e7sel olarak AL yazmac\u0131na 41 de\u011ferini y\u00fckleyecektir. Out of order execution paralel olarak bu komutu i\u00e7sel olarak \u00e7al\u0131\u015ft\u0131rd\u0131. Ancak biz AL yazmac\u0131nda bu de\u011feri g\u00f6rm\u00fcyoruz \u00e7\u00fcnk\u00fc i\u015flemci geneline hen\u00fcz yans\u0131t\u0131lmad\u0131. Bu i\u015flemden sonra i\u015flemci di\u011fer komutu \u00e7al\u0131\u015ft\u0131racakt\u0131r.<\/p>\n<p>MOV RDX, [RDX + AL]<\/p>\n<p>Peki burada yap\u0131lan \u015fey tam olarak neyi ama\u00e7lar. RDX bildi\u011finiz gibi bizim KONTROL_DIZISI isimli 256 byte uzunlu\u011funda bir dizimize i\u015faret ediyordu. AL ise her ne kadar g\u00f6r\u00fcn\u00fcr olmasa da kernel mode adresinden okunan de\u011feri tutmaktad\u0131r. Bu durumda yap\u0131lan i\u015f KONTROL_DIZISI isimli dizinin okunan de\u011ferine denk d\u00fc\u015fen index\u2019ine bir eri\u015fim yapmaktad\u0131r. Varsay\u0131m\u0131m\u0131zda AL yazmac\u0131 41 de\u011ferini tutuyordu. Bu eri\u015fim bir ba\u015fka ifadeyle<\/p>\n<p>x = KONTROL_DIZISI[41]<\/p>\n<p>anlam\u0131na gelir. Peki bu bizim ne i\u015fimize yarar? Nas\u0131l ki eri\u015fim yetkimizin olmad\u0131\u011f\u0131 belle\u011fe yap\u0131lan eri\u015fimlerde OOE dahilinde \u00e7al\u0131\u015ft\u0131r\u0131lan komutlar adresten veri okurken cache mekanizmas\u0131 aktif olarak \u00e7al\u0131\u015fabiliyorsa, kontrol\u00fcm\u00fczde olan bellek b\u00f6lgeleri\u00a0 i\u00e7in de ayn\u0131 durum s\u00f6z konusu olabilir. E\u011fer okumak istedi\u011fimiz adresten ba\u015far\u0131l\u0131 olarak 1 byte s\u0131zd\u0131rabilirsek kontrol\u00fcm\u00fczde olan dizinin indexi okunan veri olacakt\u0131r. Bu da ikincil bir dizi eri\u015fimi anlam\u0131na gelir. \u0130kincil dizi eri\u015fimi kontrol dizimize ait bellek b\u00f6lgesine eri\u015fimdir. Hemen sonras\u0131nda bizim kontrol\u00fcm\u00fczde olan dizinin her bir eleman\u0131na denk d\u00fc\u015fen adresin latency de\u011ferlerini okuyabilirsek OOE dahilinde al\u0131nan verinin ne oldu\u011funu bulabiliriz. Ancak bu tek ba\u015f\u0131na yeterli de\u011fildir. \u00c7\u00fcnk\u00fc kontrol\u00fcm\u00fczde olan belle\u011fin cache \u00fczerindeki durumundan emin olmam\u0131z gerekir.<\/p>\n<p>Bunu garantilemek i\u00e7in i\u015fleme ba\u015flamadan \u00f6nce kontrol\u00fcm\u00fczde olan diziye ait cachle line\u2019\u0131 flush etmemiz gerekir. Ve her okuma denemesi sonras\u0131nda bunu yinelememiz gerekir. Side channel attack\u2019ta cache \u00fczerine yap\u0131lan sald\u0131r\u0131larda birka\u00e7 teknik kullan\u0131l\u0131r. Bunlardan FLUSH+RELOAD, FLUSH+FLUSH, PRIME+PROBE gibi birka\u00e7 yakla\u015f\u0131m s\u00f6z konusudur. Meltdown\u2019\u0131 exploit ederken tercih edilen en uygun yakla\u015f\u0131m FLUSH+RELOAD yakla\u015f\u0131m\u0131d\u0131r.<\/p>\n<p>FLUSH+RELOAD tekni\u011fi cache sald\u0131r\u0131lar\u0131nda belle\u011fin cache \u00fczerinden tamamen silinmesini (flush) sa\u011flay\u0131p ard\u0131ndan, bellekten eri\u015fim talebinde bulunarak verinin bellekten tekrar y\u00fcklenmesini (reload) tetiklemeyi ama\u00e7lar. Bu sayede verinin cache \u00fczerindeki durumu hakk\u0131nda \u00e7\u0131kar\u0131m yap\u0131labilir. Flush i\u015flemi yaz\u0131n\u0131n ba\u015flar\u0131ndaki Caching k\u0131sm\u0131nda anlat\u0131lan <strong>clflush<\/strong> makine komutu ile yap\u0131lmaktad\u0131r. Eri\u015fim i\u015flemi i\u00e7inse herhangi bir \u015fekilde bellekten okuma yapmay\u0131 ama\u00e7layan herhangi bir kod ile ger\u00e7ekle\u015ftirilebilir.<\/p>\n<p>Bahsetti\u011fim durumu basit bir diyagram dizisi ile g\u00f6stermeye \u00e7al\u0131\u015fay\u0131m.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/exp_diag1.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"exp_diag1\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/exp_diag1_thumb.png\" alt=\"exp_diag1\" width=\"537\" height=\"389\" border=\"0\" \/><\/a><\/p>\n<p>\u00d6ncelikle kontrol dizisine flush uygulanarak cache\u2019den at\u0131lmas\u0131 sa\u011flan\u0131yor.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/exp_diag2.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"exp_diag2\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/exp_diag2_thumb.png\" alt=\"exp_diag2\" width=\"537\" height=\"389\" border=\"0\" \/><\/a><\/p>\n<p>Out of order execution vas\u0131tas\u0131yla s\u0131zd\u0131r\u0131lan byte kontrol dizimizin indexi olarak kullan\u0131p diziye bir eri\u015fim ger\u00e7ekle\u015fiyor. Bu da o index\u2019e denk d\u00fc\u015fen verinin cache\u2019e at\u0131lmas\u0131na sebep oluyor.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/exp_diag3.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"exp_diag3\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/exp_diag3_thumb.png\" alt=\"exp_diag3\" width=\"537\" height=\"389\" border=\"0\" \/><\/a><\/p>\n<p>Kontrol dizisinden indexler okunarak latency de\u011ferleri \u00f6l\u00e7\u00fcl\u00fcyor. Cachlenen 41. index cachelendi\u011fi i\u00e7in cache\u2019den getiriliyor. Bu i\u015flemin latency de\u011feri de haliyle d\u00fc\u015f\u00fck oluyor. Cachelenmemi\u015f index ise do\u011frudan ana bellekten okunuyor. Anabellek eri\u015fimi cache belle\u011fe eri\u015fimden yava\u015f oldu\u011fundan latency de\u011feri daha b\u00fcy\u00fck oluyor. B\u00f6ylelikle latency de\u011ferine bakarak s\u0131zd\u0131r\u0131lan verinin 41 de\u011feri oldu\u011funu anl\u0131yoruz.<\/p>\n<p>Ger\u00e7ek anlamda meltdown zafiyetini istismar edebilmemiz i\u00e7in birka\u00e7 ekleme yapmam\u0131z gereklidir. x86 mimarisinde bellek y\u00f6netimi Page ad\u0131 verilen birimler \u00fczerinden yap\u0131l\u0131r. Bellek byte byte y\u00f6netilmek yerine i\u015flemcinin destekledi\u011fi boyutta page\u2019lere b\u00f6l\u00fcn\u00fcr. Sistem seviyesinde en k\u00fc\u00e7\u00fck bellek \u00f6be\u011fi belirlenen boyuttaki page\u2019lerdir. Bellek \u00fczerindeki eri\u015fim kontrolleri ve bir\u00e7ok \u00f6zel ayar Page\u2019ler \u00fczerine yaz\u0131l\u0131r. Bu sayede donan\u0131msal olarak eri\u015fim kontrol\u00fcne imkan sa\u011flan\u0131r. x86 mimarisinde varsay\u0131lan page boyutu 4 Kilobyte\u2019d\u0131r. Ba\u015fka bir deyi\u015fle 4096 byte\u2019dan meydana gelir. Bu sebeple mant\u0131ksal \u00f6rnekte belirtilen kontrol dizisi Page Aligned (Hizal\u0131) olmal\u0131d\u0131r. (Yukar\u0131daki \u00f6rne\u011fimiz page aligned de\u011fil) Page size ile s\u0131n\u0131rland\u0131r\u0131lmas\u0131n\u0131n sebebi, prefetcher\u2019in ayn\u0131 page s\u0131n\u0131rlar\u0131nda kalarak ayn\u0131 page \u00fczerinde cache operasyonuna sebebiyet vermesidir. \u00d6rnekte verdi\u011fimiz 256 byte\u2019dan olu\u015fan kontrol dizisi (CHAR KONTROL_DIZISI[256]) ayn\u0131 page dahilinde olcakt\u0131r. Bu y\u00fczden \u00f6ncelikli olarak kontrol dizimizi page aligned (hizal\u0131) tahsis etmemiz gerekir. Bu da bize en a\u015fa\u011f\u0131 1 Megabyte\u2019l\u0131k bir bellek tahsisat\u0131 gerektir. Bu bellek ihtiyac\u0131n\u0131 da stack b\u00f6lgesi yerine dinamik olarak heap \u00fczerinden yapmam\u0131z uygundur.<\/p>\n<p>Bu noktadan itibaren ger\u00e7ek meltdown kodu \u00fczerinde inceleme yapabiliriz. Meltdown\u2019\u0131 yukar\u0131da anlat\u0131lan gerek\u00e7eler g\u00f6zetilerek diledi\u011finiz bi\u00e7imde istismar eden kodu yazabilirsiniz ancak ben Meltdown zafiyetinin tespitinde \u00f6nemli bir yere sahip Graz \u00dcniversitesi, Institute for Applied Information Processing and Communications (k\u0131saca IAIK)\u2019\u0131n Unix sistemlerde \u00e7al\u0131\u015facak \u015fekilde geli\u015ftirdi\u011fi libkdump k\u00fct\u00fcphanesini Windows sistemler i\u00e7in port ettim. (libkdump_win) Port ederken windows i\u00e7in anlam ifade etmeyen kod bloklar\u0131n\u0131 \u00e7\u0131kararak, daha efektif \u00e7al\u0131\u015fmas\u0131 i\u00e7in baz\u0131 geli\u015ftirmeler uygulad\u0131m. Bu sayede windows alt\u0131nda etkili \u015fekilde kullan\u0131labilecek bir k\u00fct\u00fcphane ortaya \u00e7\u0131km\u0131\u015f oldu. Projenin Unix tabanl\u0131 sistemler i\u00e7in implementasyonuna <a title=\"https:\/\/github.com\/IAIK\/meltdown\/tree\/master\/libkdump\" href=\"https:\/\/github.com\/IAIK\/meltdown\/tree\/master\/libkdump\">https:\/\/github.com\/IAIK\/meltdown\/tree\/master\/libkdump<\/a> adresinden ula\u015fabilirsiniz. Bunu tercih etmemin sebebi libkdump\u2019\u0131n bir k\u00fct\u00fcphane olarak geli\u015ftirilmesi, dinamik olarak opsiyonlar alabilmesi oldu. Daha da\u011f\u0131n\u0131k bir implementasyon yerine bunu Windows ortam\u0131na ta\u015f\u0131mak farkl\u0131 konfig\u00fcrasyonlar \u00fczerinde \u00e7al\u0131\u015fmay\u0131 daha kolayla\u015ft\u0131rd\u0131. Port edilen libkdump_win k\u00fct\u00fcphanesini k\u0131sa s\u00fcre sonra kendi github sayfamda (<a title=\"https:\/\/github.com\/0ffffffffh\" href=\"https:\/\/github.com\/0ffffffffh\">https:\/\/github.com\/0ffffffffh<\/a>) payla\u015faca\u011f\u0131m.<\/p>\n<p>Meltdown i\u00e7in \u00f6ncelikle bir kontrol dizisi olu\u015fturmak gerekti\u011finden ve bunun page aligned olarak yap\u0131lmas\u0131 gerekti\u011finden bahsetmi\u015ftik.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_14.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Screenshot_14\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_14_thumb.png\" alt=\"Screenshot_14\" width=\"485\" height=\"267\" border=\"0\" \/><\/a><\/p>\n<p>Yukar\u0131da kontrol dizimiz i\u00e7in Page aligned bellek tahsisat\u0131 yap\u0131lmaktad\u0131r. 256 elemanl\u0131k her dizi i\u00e7in 1 page (4096 byte) uzunlu\u011funda (256 * 4096) byte kadar bellek gerek. 300 adet page tahsisat\u0131 yap\u0131ld\u0131\u011f\u0131 g\u00f6r\u00fclebilir. Bunun sebebi sonraki sat\u0131rda yap\u0131lacak olan bellek adresinin Page hizal\u0131 hale getirilmek istenmesi. Bunun i\u00e7in fazladan yeteri kadar bellek ay\u0131rmak durumunday\u0131z. Sonraki sat\u0131rda ise al\u0131nan bellek adresi page aligned hale getirilmektedir. Yap\u0131lan bitwise operasyonu bellek adresini kendisine en yak\u0131n Page size kat\u0131na \u00e7evirmektedir. Ba\u015fka bir ifadeyle bu (_mem \u2013 (_mem % 4096) \u015feklinde de yaz\u0131labilir. Bitwise i\u015flemler \u00e7ok daha h\u0131zl\u0131 yap\u0131ld\u0131klar\u0131ndan tercih sebebidir. Bu i\u015flem bellek adresinin esas olarak ayr\u0131lan bellek adresinin gerisine d\u00fc\u015fmesine sebebiyet verir. Bunu \u00f6nlemek i\u00e7in bu i\u015flem sonras\u0131 bellek adresi \u00fczerine 2 adet page size (0x1000 (4096) * 2) kadar ekleme yap\u0131larak bellek b\u00f6lgesi kullan\u0131ma uygun hale getirilir. Ard\u0131ndan bellek alan\u0131 s\u0131f\u0131rlan\u0131r. 290 adet page\u2019in s\u0131f\u0131rlanmas\u0131n\u0131n sebebi page aligned adres ile orijinal tahsis edilen bellek b\u00f6lgesi aras\u0131ndaki gereksiz bellek \u00f6be\u011fidir. Bu fark ise minimum 290 page kadard\u0131r. Bu y\u00fczden 290 page kadar b\u00f6lgeyi haz\u0131rlamam\u0131z yeterlidir.<\/p>\n<p>Kald\u0131 ki efektif olarak kullanaca\u011f\u0131m\u0131z alan sadece 256 page\u2019lik bellek b\u00f6l\u00fcm\u00fcd\u00fcr. Sonraki sat\u0131rda ise her bir dizi eleman\u0131na denk d\u00fc\u015fen page blo\u011fu cache \u00fczerinden at\u0131larak meltdown istismar\u0131 i\u00e7in haz\u0131r hale getirilmektedir. Bu i\u015flem sonras\u0131 elimizde 256 eleman i\u00e7in 256 page uzunlu\u011funda cache \u00fczerinden flush edildi\u011fi garanti alt\u0131na al\u0131nm\u0131\u015f kontrol dizimiz kullan\u0131ma haz\u0131r olur.<\/p>\n<p>Sonraki ad\u0131m \u00fczerinde \u00e7al\u0131\u015ft\u0131\u011f\u0131m\u0131z i\u015flemcinin cache edilmi\u015f ve cache edilmemi\u015f bellek eri\u015fim latency de\u011ferlerini tespit etmek.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_15.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Screenshot_15\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_15_thumb.png\" alt=\"Screenshot_15\" width=\"634\" height=\"551\" border=\"0\" \/><\/a><\/p>\n<p>Yaz\u0131n\u0131n Caching (\u00d6nbellekleme) k\u0131sm\u0131nda bu cache\u2019e y\u00f6nelik bir side channel sald\u0131r\u0131s\u0131nda latency\u2019nin \u00f6neminden, ne ama\u00e7la kullan\u0131laca\u011f\u0131ndan ve nas\u0131l tespit edilece\u011finden bahsetmi\u015ftim. Yukar\u0131daki kod blo\u011fu latency hesaplanmas\u0131 s\u0131ras\u0131nda anlat\u0131lan ad\u0131mlar\u0131n meltdown\u2019\u0131 istismar eden k\u00fct\u00fcphanenin latency hesab\u0131n\u0131 yapan k\u0131sm\u0131. Kod olduk\u00e7a a\u00e7\u0131k. \u00d6ncelikle tan\u0131mlad\u0131\u011f\u0131m\u0131z bir tampon bellek \u00fczerinde belirli iterasyonda s\u00fcrekli eri\u015ferek eri\u015fim s\u00fcresini bir de\u011fi\u015fken \u00fczerinde tuttuk. Bu iterasyon dahilinde tampon belle\u011fimize ait i\u00e7eri\u011fe \u00e7ok s\u0131k eri\u015fim yap\u0131ld\u0131\u011f\u0131ndan mimari gere\u011fi cache\u2019e al\u0131nacakt\u0131r. Bu noktadan sonraki her eri\u015fimlerimiz cache\u2019den gelece\u011fi i\u00e7in ilerleyen iterasyonlarda latency de\u011feri olduk\u00e7a d\u00fc\u015fecektir.\u00a0 Hemen sonras\u0131nda bu kez FLUSH+RELOAD tekni\u011fi uygulanarak verinin cache yerine ana bellekten getirilme s\u00fcresi yine bir de\u011fi\u015fkene eklenir. Bu i\u015flem i\u00e7in yine ayn\u0131 \u015fekilde bir iterasyon dahilinde yap\u0131l\u0131r. Toplam sonu\u00e7 de\u011fi\u015fkeni iterasyon say\u0131s\u0131na b\u00f6l\u00fcnerek ortalama bir latency de\u011feri hesaplan\u0131r. Bu i\u015flem sonucunda \u00fczerinde \u00e7al\u0131\u015ft\u0131\u011f\u0131m\u0131z i\u015flemcinin ne kadar latency de\u011ferinde cache miss, ne kadar latency de\u011ferinde cache hit oldu\u011funu bulmu\u015f oluruz. Bu iki de\u011fer kullan\u0131larak da ortalama bir cache miss threshold (e\u015fik) de\u011feri hesaplan\u0131r. Bu e\u015fik de\u011feri alt\u0131nda kalan latencyler cache hit olarak de\u011ferlendirilir.<\/p>\n<p>T\u00fcm bu i\u015flemlerden sonra bellekten veri s\u0131zd\u0131rmaya \u015fartlar haz\u0131r. Tabi \u00f6ncesinde ilgili exception suppress metodunu se\u00e7mi\u015f olmak ve ilgili ayarlamalar\u0131 yapmak gerek. Bunun nas\u0131l yap\u0131laca\u011f\u0131n\u0131 exception handling mekanizmalar\u0131n\u0131n anlat\u0131ld\u0131\u011f\u0131 k\u0131s\u0131mda detayland\u0131rm\u0131\u015ft\u0131m. O y\u00fczden tekrar a\u00e7\u0131klamaya gerek g\u00f6rm\u00fcyorum.<\/p>\n<p>Meltdown ile kernel b\u00f6lgesinden veri s\u0131zd\u0131rman\u0131n yollar\u0131n\u0131 teorik olarak g\u00f6rd\u00fckten sonra bu i\u015fi ger\u00e7ekle\u015ftiren fonksiyona g\u00f6z atal\u0131m.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_16.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Screenshot_16\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_16_thumb.png\" alt=\"Screenshot_16\" width=\"425\" height=\"433\" border=\"0\" \/><\/a><\/p>\n<p>Veri s\u0131zd\u0131rma i\u015fleminin teorisinden bahsederken i\u015flemin ba\u015far\u0131ya ula\u015fmas\u0131 i\u00e7in belirli bir adette iterasyon yap\u0131p i\u015flemciyi Out of order execution\u2019a zorlam\u0131z gerekti\u011fi ve nedenlerini biliyoruz. Veri s\u0131zd\u0131rmay\u0131 ama\u00e7layan fonksiyonumuz \u00f6nceden ayarlanan bir tekrar deneme adedi kadar d\u00f6ng\u00fc i\u00e7erisinde veri s\u0131zd\u0131rmay\u0131 ama\u00e7layan kodu \u00e7al\u0131\u015ft\u0131rmaktad\u0131r. MELTDOWN makrosu ise dinamik olarak se\u00e7ilebilen i\u015flemci h\u0131z\u0131 ve t\u00fcr\u00fcne g\u00f6re farkl\u0131l\u0131k g\u00f6steren s\u0131zd\u0131rma kodunu \u00e7al\u0131\u015ft\u0131r\u0131r.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_17.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Screenshot_17\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_17_thumb.png\" alt=\"Screenshot_17\" width=\"516\" height=\"237\" border=\"0\" \/><\/a><\/p>\n<p>MELTDOWN makrosu ise dinamik olarak tercih edilen meltdown istismar kodunu \u00e7a\u011f\u0131r\u0131r. Hepsi ayn\u0131 olmakla beraber k\u00fc\u00e7\u00fck farkl\u0131l\u0131klar i\u00e7eren istismar komutlar\u0131 vard\u0131r. ilk meltdown saat h\u0131z\u0131 y\u00fcksek i\u015flemcilerde (Yeni nesil i\u015flemciler \u00f6zellikle) kullan\u0131lmas\u0131 daha iyi sonu\u00e7 verir, y\u00fcksek saat h\u0131z\u0131nda \u00e7al\u0131\u015fmas\u0131 demek OOE \u015fans\u0131n\u0131 art\u0131rmak i\u00e7in araya ek geciktirici ge\u00e7ersiz komut koyulmas\u0131n\u0131 gerekli k\u0131lar. Di\u011feri versiyon ise standart olarak tercih edilebilecek bir t\u00fcrd\u00fcr. Tek fark\u0131 arada geciktirme ama\u00e7l\u0131 ek komut bulundurmaz. Son versiyon ise saat h\u0131z\u0131 d\u00fc\u015f\u00fck, yava\u015f i\u015flemcilerde tercih edilir. Saat h\u0131z\u0131 d\u00fc\u015f\u00fck oldu\u011fundan istismar kodunun yal\u0131n \u015fekilde \u00e7al\u0131\u015fmas\u0131 yeterli olacakt\u0131r.<\/p>\n<p>Orijinal IAIK implementasyonu derleme zaman\u0131 se\u00e7me \u015fans\u0131 vermekteydi, libkdump_win portunda bu dinamik olarak tercih edilebilir, atak ba\u015far\u0131m\u0131na g\u00f6re runtime (\u00e7al\u0131\u015fma zaman\u0131) de\u011fi\u015ftirilebilir. libkdump_win portu varsay\u0131lan olarak meltdown varyasyonunu kullanmaktad\u0131r.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_19.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Screenshot_19\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_19_thumb.png\" alt=\"Screenshot_19\" width=\"588\" height=\"443\" border=\"0\" \/><\/a><\/p>\n<p>Ne yaz\u0131k ki Microsoft Visual C++ derleyicisi 64 bit binary\u2019ler i\u00e7in inline assembly deste\u011fi sunmamaktad\u0131r. Bu sebepten meltdown istismar kodunu MASM (Microsoft Assembler)\u2019de derlenmek \u00fczere ayr\u0131 bir ASM dosyas\u0131 \u00fczerine yazmak gerekti. \u0130stismar kodu her ne kadar da C dilinde de yaz\u0131labilecek olsa da meltdown\u2019\u0131n ba\u015far\u0131m\u0131 i\u00e7in tercih edilmemelidir. \u00c7\u00fcnk\u00fc derleyici kodun e\u015fleni\u011fi assembly kodunu beklenenden farkl\u0131 \u015fekilde optimize edebilir. Optimizasyon kapal\u0131 olsa dahi tam olarak bekledi\u011fimiz kodu olu\u015fturmayabillir. O y\u00fczden istismar kodu assembly dilinde yaz\u0131lm\u0131\u015ft\u0131r.<\/p>\n<p>\u0130stismar kodu, yaz\u0131n\u0131n ortalar\u0131nda verilen \u00f6rnek kodla olduk\u00e7a benzer ancak elbette ayn\u0131 de\u011fil. Nedenini belirtmi\u015ftim. Kontrol dizimizin page aligned tahsis edildi\u011fini hat\u0131rlam\u0131\u015f olmal\u0131s\u0131n\u0131z. Page aligned diziye eri\u015fmek i\u00e7in indeximizin de ilgili page\u2019e denk d\u00fc\u015fecek \u015fekilde hesaplanmas\u0131 gerekir. shl rax, 12 komutu rax yazmac\u0131ndaki de\u011feri 12 bit sola \u00f6telemektedir. Bir veriyi 12 bit sola \u00f6telemek 4096 ile \u00e7arpmak ile ayn\u0131d\u0131r. Dedi\u011fim gibi bitsel operasyonlar her zaman daha h\u0131zl\u0131 oldu\u011fu i\u00e7in tercih edilmektedirler. index 4096 yani bir page boyutu ile \u00e7arp\u0131ld\u0131\u011f\u0131nda page aligned kontrol dizimizin tam olarak gerekli olan yerini i\u015faret edecektir. Tekrar veri s\u0131zd\u0131rma kodumuzu hat\u0131rlayal\u0131m.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_16-1.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Screenshot_16\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_16_thumb-1.png\" alt=\"Screenshot_16\" width=\"425\" height=\"433\" border=\"0\" \/><\/a><\/p>\n<p>Meltdown istismar kodu \u00e7al\u0131\u015fmaya ba\u015flad\u0131\u011f\u0131nda sisteme kaydetti\u011fimiz exception handler devreye girecek ve Exception handling k\u0131sm\u0131nda anlat\u0131lan \u015fekilde program\u0131n ak\u0131\u015f\u0131n\u0131 flush_load k\u0131sm\u0131na b\u0131rakacak ve bu sayede exploit prosesi herhangi bir zarar g\u00f6rmeden ak\u0131\u015f\u0131na devam edecektir.<\/p>\n<p>\u0130stismar kodu ak\u0131\u015f\u0131n\u0131 tekrar normal beklenen ak\u0131\u015fa devretti\u011finde art\u0131k kontrol dizimizi kontrol etmenin vakti gelmi\u015f demektir. Bu kontrol i\u015flemi de bildi\u011finiz \u00fczere latency kontrol\u00fcnden ibarettir. D\u00f6ng\u00fc aralar\u0131ndaki Sleep \u00e7a\u011fr\u0131lar\u0131 i\u015fletim sisteminin thread scheduler\u2019\u0131n\u0131 kernel mode\u2019a ge\u00e7erek s\u00fcrekli olarak aktif tutmaktad\u0131r. Windows\u2019ta Sleep( 0) \u00e7a\u011fr\u0131s\u0131 \u00f6zel bir amaca hizmet eder. E\u011fer bekleme s\u00fcresi 0 ise thread scheduler (i\u015fpar\u00e7ac\u0131\u011f\u0131 zamanlay\u0131c\u0131) \u00e7al\u0131\u015fmaya haz\u0131r durumdaki bir ba\u015fka thread\u2019i aktif hale getirir. Bu i\u015flem flush ve reload aras\u0131nda bizim i\u00e7in yeterli miktar bekleme zaman\u0131 tan\u0131r. Linux i\u015fletim sisteminde ayn\u0131 sonucu <strong>sched_yield<\/strong> fonksiyonu ile alabiliriz.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_18.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Screenshot_18\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_18_thumb.png\" alt=\"Screenshot_18\" width=\"478\" height=\"343\" border=\"0\" \/><\/a><\/p>\n<p>veri s\u0131zd\u0131ran fonksiyonumuz kontrol\u00fcm\u00fczdeki belle\u011fin cache durumunu kontrol etmek i\u00e7in flush_load\u2019 fonksiyonunu \u00e7a\u011f\u0131r\u0131yordu. Bu fonksiyon daha \u00f6nce bahsetti\u011fimiz gibi kontrol dizimizin belirli index\u2019indeki page\u2019in cache miss veya cache hit durumunu kontrol etmektedir. G\u00f6r\u00fcld\u00fc\u011f\u00fc gibi \u00f6nce timestamp sayac\u0131 okunuyor, ard\u0131ndan ilgili belle\u011fe bir DWORD uzunlu\u011funda okuma yap\u0131l\u0131yor. Ard\u0131ndan tekrar timestamp sayac\u0131 okunarak latency belirleniyor. Sonras\u0131nda bir sonraki i\u015flemde cache line\u2019\u0131n bo\u015falt\u0131ld\u0131\u011f\u0131ndan emin olmak i\u00e7in flush komutu \u00e7al\u0131\u015ft\u0131r\u0131l\u0131yor.\u00a0 Verinin cache\u2019den mi yoksa ana bellekten gelip gelmedi\u011fini anlamak i\u00e7in bir cache miss e\u015fik de\u011ferine ihtiyac\u0131m\u0131z oldu\u011funu ve nas\u0131l tespit edece\u011fimizi biliyoruz. Bu noktada latency de\u011ferimizi bu e\u015fik de\u011feri ile kar\u015f\u0131la\u015ft\u0131r\u0131p, e\u011fer e\u015fik de\u011ferinin alt\u0131nda ise cache hit\u2019i yakalad\u0131\u011f\u0131m\u0131z\u0131 anl\u0131yoruz.\u00a0 Bu demektir ki veri ba\u015far\u0131yla cache \u00fczerine y\u00fcklenmi\u015f. Bu kond\u00fcsyonu yakalad\u0131\u011f\u0131m\u0131zda o anki d\u00f6ng\u00fc indexini s\u0131zd\u0131r\u0131lan veri olarak al\u0131yoruz.<\/p>\n<p>Peki buradan al\u0131nan verinin do\u011frulu\u011fundan ne kadar emin olabiliriz?<\/p>\n<p>Tek seferde s\u0131zd\u0131r\u0131lan verinin ger\u00e7ekte bellekte saklanan veri oldu\u011funu varsaymak yerine bunu belli say\u0131da birka\u00e7 tekrar ve bir kabul e\u015fi\u011fi kullanmak verinin do\u011frulu\u011fu i\u00e7in zorunlu olmasa da gerekli bir i\u015flemler dizisidir. Bu gereklilik i\u015flemcinin mimarisi, h\u0131z\u0131, y\u00fck alt\u0131nda olma durumuna g\u00f6re de\u011fi\u015fkenlik g\u00f6sterebilir. Bunun optimal de\u011ferini bulmak yine sald\u0131r\u0131y\u0131 uygulayana kalm\u0131\u015ft\u0131r.<\/p>\n<p>Neyse ki libkdump_win bu kontrol ve kabul e\u015fiklerini parametre olarak alabilmektedir.<\/p>\n<p>Verinin do\u011fruluk oran\u0131n\u0131 y\u00fckseltmek i\u00e7in yukar\u0131da bahsi ge\u00e7en veri s\u0131zd\u0131rma i\u015flemini birka\u00e7 defa tekrar etmek do\u011fruluk oran\u0131n\u0131 y\u00fckseltebilir. Her tekrardan d\u00f6nen muhtemel veri bir dizi \u00fczerine e\u015flenir (mapped). Ard\u0131ndan bu e\u015fle\u015ftirme frekans\u0131na bak\u0131larak verinin y\u00fcksek do\u011fruluk oran\u0131nda al\u0131nmas\u0131 ama\u00e7lan\u0131r.<\/p>\n<p>Belirlenmesi gereken fakt\u00f6rler<\/p>\n<ol>\n<li>S\u0131zd\u0131rma tekrar adeti<\/li>\n<li>S\u0131zd\u0131r\u0131lan veri olarak kabul etme e\u015fi\u011fi<\/li>\n<\/ol>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/validation.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"validation\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/validation_thumb.png\" alt=\"validation\" width=\"623\" height=\"677\" border=\"0\" \/><\/a><\/p>\n<p>Do\u011fruluk oran\u0131n\u0131 y\u00fckseltmek i\u00e7in t\u0131pk\u0131 kontrol dizimize benzer s\u0131zd\u0131r\u0131lan verinin frekans\u0131n\u0131 tutmak i\u00e7in 256 byte\u2019l\u0131k dizi kullan\u0131r\u0131z. 1 byte\u2019l\u0131k s\u0131zd\u0131r\u0131lan her veri i\u00e7in verinin kar\u015f\u0131l\u0131k geldi\u011fi index\u2019i birer defa art\u0131rarak tekrar adedi sonunda benzer verinin ne kadar s\u0131kl\u0131kta al\u0131nd\u0131\u011f\u0131n\u0131 belirleyebiliriz. Bu bizim s\u0131zd\u0131r\u0131lan byte\u2019\u0131n do\u011fruluk oran\u0131n\u0131 y\u00fckseltecektir. accept_after parametresi ise bunu bizim dinamik olarak belirlememizi sa\u011flar.<\/p>\n<p>Di\u011fer bir do\u011fruluk kontrol\u00fc s\u0131zan verinin de\u011feriyle ilintilidir. Meltdown istismar\u0131 s\u0131ras\u0131nda istenmeyen yan etkiler sebebiyle \u00e7ok ince bir \u00e7izgide seyreden cache miss e\u015fi\u011finden \u00f6t\u00fcr\u00fc yanl\u0131\u015f de\u011ferlendirme yapabilmemiz a\u00e7\u0131kt\u0131r. \u0130lk do\u011frulamaya ek olarak okunan verinin maksimum de\u011feri bizim bekledi\u011fimiz de\u011fer olmas\u0131 olas\u0131d\u0131r. \u00c7\u00fcnk\u00fc cache hit olas\u0131l\u0131\u011f\u0131 cache miss olas\u0131l\u0131\u011f\u0131ndan daha d\u00fc\u015f\u00fckt\u00fcr. Al\u0131nabilecek maksimum de\u011ferdeki bir cache hit s\u0131zd\u0131r\u0131lan verinin do\u011fruluk oran\u0131n\u0131 daha yukar\u0131 \u00e7ekecektir.<\/p>\n<h2><span style=\"font-weight: bold; color: #ff0000;\">Demo<\/span><\/h2>\n<p style=\"text-align: center;\"><strong>YASAL FERAGAT:<\/strong><br \/>\n<em>A\u015fa\u011f\u0131da de\u011finilen ve detayland\u0131ran teknik ve y\u00f6ntemler bilgilendirme ve e\u011fitim amac\u0131yla yaz\u0131lm\u0131\u015ft\u0131r. Bu bilgilerin k\u00f6t\u00fc niyetli, zararl\u0131 faaliyetlerde kullan\u0131lmas\u0131ndan \u00f6t\u00fcr\u00fc yazar hi\u00e7bir sorumluluk kabul etmez.<\/em><\/p>\n<p style=\"text-align: left;\">Bu b\u00f6l\u00fcmde meltdown\u2019\u0131 Windows \u00fczerinde nas\u0131l exploit edilebilece\u011fine dair birka\u00e7 demo yay\u0131nlayaca\u011f\u0131m. Bu i\u015flem i\u00e7in iki farkl\u0131 exploit arac\u0131 geli\u015ftirdim. Birinci demo genel anlamda meltdown\u2019\u0131n Windows i\u015fletim sistemi \u00fczerinde exploit edilebilece\u011fini g\u00f6steren bir \u00f6rnek, di\u011feri ise d\u0131\u015far\u0131dan herhangi bir statik girdi almadan ASLR\u2019\u0131 bypass ederek kernel alan\u0131ndan process\u2019lere ait \u00f6nemli bilgilerin s\u0131zd\u0131r\u0131labilece\u011fini g\u00f6sterir nitelikte bir exploit olacak.<\/p>\n<p>Bu demolar\u0131n do\u011frulu\u011fundan emin olmak i\u00e7in verinin okundu\u011fu adresin ger\u00e7ekte tuttu\u011fu i\u00e7eri\u011fi g\u00f6rebilmemiz gerekli. Kernel bellek alan\u0131ndan bilgi s\u0131zd\u0131rmaya \u00e7al\u0131\u015ft\u0131\u011f\u0131m\u0131zdan bunu yapabilmemizin tek yolu bir kernel debugger ile ilgili bellek alanlar\u0131n\u0131 incelemek olacakt\u0131r.\u00a0 Bu sebeple bu i\u015f i\u00e7in kernel debugger olarak WinDbg kullanaca\u011f\u0131m.<\/p>\n<p>\u0130lk demomuzda d\u0131\u015far\u0131dan verdi\u011fimiz bir kernel adres ve uzunlu\u011funu alarak \u00e7al\u0131\u015ft\u0131rarak bize belle\u011fin okunmak istenen uzunlu\u011fu kadar\u0131n\u0131n d\u00f6k\u00fcm\u00fcn\u00fc verecek. \u00d6ncelikle bellek adresinin tespiti i\u00e7in WinDbg ile bir lokal kernel debugging session a\u00e7t\u0131ktan sonra rastele ancak ge\u00e7erli bir bellek b\u00f6lgesindeki device driver\u2019lara ait IRP listesini taratal\u0131m<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_58.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Screenshot_58\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_58_thumb.png\" alt=\"Screenshot_58\" width=\"856\" height=\"515\" border=\"0\" \/><\/a><\/p>\n<p>!irpfind komutu ile rastgele belirledi\u011fim bir adres aral\u0131\u011f\u0131ndaki device driver IRP\u2019leri bulduktan sonra ilk s\u0131radakini se\u00e7tim. \u0130kinci k\u0131rm\u0131z\u0131 dikd\u00f6rtgen i\u00e7erisindeki adres IRP yap\u0131s\u0131n\u0131 tutan adres. \u015eimdi i\u00e7eri\u011finin byte olarak d\u00f6k\u00fcm\u00fcn\u00fc g\u00f6relim.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_59.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Screenshot_59\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_59_thumb.png\" alt=\"Screenshot_59\" width=\"800\" height=\"442\" border=\"0\" \/><\/a><\/p>\n<p>db ffffc90f65eef910 komutu ile IRP\u2019ye ait bellek d\u00f6k\u00fcm\u00fcn\u00fc ald\u0131k. IRP tutan adresimiz ffffc90f65eef910. !irp ffffc90f65eef910 komutu ile ger\u00e7ekten bu adresin bir IRP\u2019ye i\u015faret etti\u011fini kontrol ettik.<\/p>\n<p>\u015eimdi geli\u015ftirmi\u015f oldu\u011fum meltdown Proof of concept program\u0131na ffffc90f65eef910 adresinden 40 byte kadar s\u0131zd\u0131rmas\u0131n\u0131 isteyelim.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_60.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Screenshot_60\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_60_thumb.png\" alt=\"Screenshot_60\" width=\"718\" height=\"571\" border=\"0\" \/><\/a><\/p>\n<p>S\u0131zd\u0131r\u0131lan veriyi kernel debugger\u2019dan ald\u0131\u011f\u0131m\u0131z \u00e7\u0131kt\u0131 ile kar\u015f\u0131la\u015ft\u0131rd\u0131\u011f\u0131m\u0131zda ayn\u0131 oldu\u011funu g\u00f6r\u00fcyoruz. Yani ba\u015far\u0131yla meltdown\u2019\u0131 exploit ederek kernel b\u00f6lgesinden veri okumay\u0131 ba\u015fard\u0131k. Peki bu zafiyet ne kadar etkili kullan\u0131labilir?<\/p>\n<p>\u015eimdi bunu g\u00f6sterebilmek i\u00e7in ger\u00e7ek anlamda bir exploit geli\u015ftirmeye \u00e7al\u0131\u015fal\u0131m. \u00d6rne\u011fin meltdown kullan\u0131larak Windows Kernel\u2019dan proseslere ait d\u0131\u015far\u0131dan g\u00f6r\u00fclmemesi gereken \u00f6nemli verileri alabilir miyiz? Ben bu amaca y\u00f6nelik bir exploit geli\u015ftirmeye \u00e7al\u0131\u015ft\u0131m. Burada ama\u00e7 herhangi bir statik adres gerektirmeden \u00e7al\u0131\u015fmaya ba\u015flad\u0131\u011f\u0131nda kernel yap\u0131lar\u0131na ait verilere ula\u015fabilmek.<\/p>\n<p>Windows NT tabanl\u0131 i\u015fletim sistemlerinde yarat\u0131lan processler <span class=\"lang:c highlight:0 decode:true crayon-inline\">PsActiveProcessHead<\/span>\u00a0 ad\u0131nda bir listede tutulmaktad\u0131r. <span class=\"lang:c highlight:0 decode:true crayon-inline\">PsActiveProcessHead<\/span>\u00a0 bir <span class=\"lang:c highlight:0 decode:true crayon-inline\">LIST_ENTRY<\/span>\u00a0 yap\u0131s\u0131na i\u015faret eden veri yap\u0131s\u0131n\u0131 tutmaktad\u0131r. Windows NT\u2019de <span class=\"lang:c highlight:0 decode:true crayon-inline\">LIST_ENTRY<\/span>\u00a0 s\u0131k\u00e7a kullan\u0131lan \u00f6nemli bir veri yap\u0131s\u0131d\u0131r. Bir t\u00fcr ba\u011fl\u0131 liste (Linked list) implementasyonudur.<\/p>\n<p><a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/windows\/hardware\/ff554296(v=vs.85).aspx\">LIST_ENTRY<\/a>\u00a0 yap\u0131s\u0131 a\u015fa\u011f\u0131daki gibidir.<\/p>\n<pre class=\"striped:false marking:false ranges:false nums:false nums-toggle:false wrap:false wrap-toggle:false decode-attributes:false lang:default highlight:0 decode:true \">lkd&gt; dt _LIST_ENTRY\nnt!_LIST_ENTRY\n   +0x000 Flink            : Ptr64 _LIST_ENTRY\n   +0x008 Blink            : Ptr64 _LIST_ENTRY\n<\/pre>\n<p>LIST_ENTRY hem linkedlist header&#8217;i hem de list entry olacak \u015fekilde tasarlanm\u0131\u015ft\u0131r. Flink e\u011fer header olarak kullan\u0131l\u0131yorsa ilk eleman\u0131, bir entry ise kendinden sonraki eleman\u0131 i\u015faret eder. Blink ise header olarak kullan\u0131l\u0131yorsa son eleman\u0131, bir entry olarak kullan\u0131l\u0131yorsa kendinden \u00f6nceki eleman\u0131 i\u015faret eder.<\/p>\n<p><span class=\"lang:c highlight:0 decode:true crayon-inline\">PsActiveProcessHead<\/span> kernel image taraf\u0131ndan export edilmemi\u015ftir. Bu y\u00fczden kernel&#8217;da hangi adreste y\u00fckl\u00fc oldu\u011funu export table&#8217;dan \u00f6\u011frenemeyiz. Bilinse dahi Windows i\u015fletim sisteminde uzunca bir s\u00fcredir var olan ASLR (Address Space Layout Randomization) PC&#8217;nin her boot edi\u015finde adresini rastsal bir yere y\u00fckleyecektir. Meltdown&#8217;\u0131 exploit etmeden evvel \u00f6nce <span class=\"lang:c highlight:0 decode:true crayon-inline\">PsActiveProcessHead<\/span> yap\u0131s\u0131n\u0131n yerini bulup, ASLR&#8217;\u0131 bypass etmemiz gerekir.<\/p>\n<p><span class=\"lang:c highlight:0 decode:true crayon-inline \">PsActiveProcessHead<\/span>\u00a0 listesinin yerini buraya yak\u0131n export edilmi\u015f bir yap\u0131n\u0131n yerini bularak dolayl\u0131 olarak hesaplayabiliriz. Global de\u011fi\u015fkenler ayn\u0131 b\u00f6lgede ard\u0131\u015f\u0131k olarak dururlar. Bunun tespiti i\u00e7in WinDbg&#8217;yi kullanabiliriz.<\/p>\n<pre class=\"decode-attributes:false lang:default highlight:0 decode:true\">lkd&gt; ln PsActiveProcessHead<\/pre>\n<p>bu komut ile PsActiveProcessHead debug sembol ad\u0131na yak\u0131n adreslerdeki sembol adlar\u0131n\u0131 bulabiliriz. Bu komutu uygulad\u0131\u011f\u0131m\u0131zda<\/p>\n<pre class=\"striped:false ranges:false nums:false nums-toggle:false decode-attributes:false lang:default highlight:0 decode:true\">lkd&gt; ln PsActiveProcessHead\nBrowse module\nSet bu breakpoint\n\n(fffff801`271e59a0)   nt!PsActiveProcessHead   | \n(fffff801`271e59b0)   nt!PsReaperListHead\nExact matches:\n<\/pre>\n<p>Kendisine yak\u0131n PsReaperListHead var. ntoskrnl.exe imaj\u0131n\u0131n export tablosuna bakt\u0131\u011f\u0131m\u0131zda PsReaperListHead&#8217;i g\u00f6remiyoruz. Demek ki bu da export edilmi\u015f bir sembol de\u011fil. O halde biraz gerisine bakal\u0131m.<\/p>\n<pre class=\"striped:false ranges:false nums:false nums-toggle:false decode-attributes:false lang:default highlight:0 decode:true\">lkd&gt; ln PsActiveProcessHead - 0x5\nBrowse module\nSet bu breakpoint\n\n(fffff801`271e5998)   nt!PsSiloContextPagedType+0x3   |  \n(fffff801`271e59a0)   nt!PsActiveProcessHead<\/pre>\n<p>\u00f6ncesinde PsSiloContextPagedType sembol\u00fcn\u00fc bulduk. Bu defa bakt\u0131\u011f\u0131m\u0131zda bu sembol\u00fcn export edildi\u011fini g\u00f6r\u00fcyoruz.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_67.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-444\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_67.png\" alt=\"\" width=\"582\" height=\"193\" srcset=\"https:\/\/www.oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_67.png 582w, https:\/\/www.oguzkartal.net\/blog\/wp-content\/uploads\/2018\/01\/Screenshot_67-300x99.png 300w\" sizes=\"auto, (max-width: 582px) 100vw, 582px\" \/><\/a><\/p>\n<pre class=\"striped:false ranges:false nums:false lang:default highlight:0 decode:true\">lkd&gt; ? PsActiveProcessHead - PsSiloContextPagedType\nEvaluate expression: 8 = 00000000`00000008\n<\/pre>\n<p>Aralar\u0131nda sadece 8 byte var. Bu i\u015fimizi g\u00f6r\u00fcr. PsSiloContextPagedType&#8217;\u0131 export table&#8217;dan bulup 8 byte \u00f6teledi\u011fimizde PsActiveProcessHead&#8217;i bulmu\u015f olaca\u011f\u0131z. Ancak a\u015f\u0131lmas\u0131 gereken \u00f6nemli bir problem daha var ki o da ASLR.<\/p>\n<p>ASLR her boot sonras\u0131 imajlar\u0131 dolay\u0131s\u0131 ile veri yap\u0131lar\u0131n\u0131 farkl\u0131 adreslere y\u00fcklemektedir. \u015eansl\u0131y\u0131z ki export tablosundan edindi\u011fimiz veri bize bu konuda ASLR&#8217;\u0131 kolayca bypass etme imkan\u0131 tan\u0131maktad\u0131r.<\/p>\n<p>\u00d6ncelikle referans sembol\u00fcn kernel imaj\u0131ndaki ofset de\u011ferini bulmam\u0131z gerekir. Bunun en k\u0131sa yolu, \u00f6nce ntoskrnl.exe imaj\u0131n\u0131 kendi processimize y\u00fcklemek, ard\u0131ndan referans sembol\u00fcn\u00fcn adresini GetProcAddress API fonksiyonu ile alarak ofset de\u011ferini hesaplayabiliriz.<\/p>\n<pre class=\"lang:c decode:true\">VOID *sym;\nLONG64 offset;\nHMODULE ntos = NULL;\n\nntos = LoadLibraryA(\"ntoskrnl.exe\");\nsym = GetProcAddress(ntos, \"PsSiloContextPagedType\");\noffset = (LONG64) ((ULONG64)sym - (ULONG64)ntos);<\/pre>\n<p>\u0130ki sembol\u00fcn aralar\u0131nda 8 byte oldu\u011funu bildi\u011fimizden PsActiveProcessHead kernel imaj\u0131ndaki ofsetini<\/p>\n<p><span class=\"lang:c decode:true crayon-inline\">ULONG64 PsActiveProcessHeadOffset = offset + 8;<\/span><\/p>\n<p>olarak hesaplar\u0131z. B\u00f6ylece ilk ad\u0131m\u0131 hallettik. Ancak bize PsActiveProcessHead sembol\u00fcn\u00fcn ger\u00e7ekte hangi adrese y\u00fckl\u00fc oldu\u011fu bilgisi gerekli. E\u011fer kernel imaj\u0131n\u0131n nereye y\u00fcklendi\u011fini bilirsek, biraz \u00f6nceki bilgiyi kullanarak PsActiveProcessHead sembol\u00fcn\u00fcn kernel&#8217;da hangi adrese y\u00fcklendi\u011fini bulabiliriz. Bu i\u015flem ile otomatik olarak ASLR&#8217;\u0131 da bypass etmi\u015f oluyoruz. B\u00f6ylece boot sonras\u0131 dahi bu i\u015flemleri uygulayarak her defas\u0131nda ger\u00e7ek adresi bulabilece\u011fiz.<\/p>\n<p>Kernel imaj\u0131n\u0131n sistemde nerede y\u00fckl\u00fc oldu\u011funu bulmak i\u00e7in\u00a0<span class=\"lang:default highlight:0 decode:true crayon-inline\">NtQuerySystemInformation<\/span>\u00a0 API fonksiyonunda yararlanaca\u011f\u0131z. Bu API i\u015fletim sistemi ile ilgili pek \u00e7ok sistem seviyesi bilgiyi alabilmemizi sa\u011flar. Ancak sa\u011flad\u0131\u011f\u0131 bilgi t\u00fcrlerinin k\u0131s\u0131tl\u0131 bir b\u00f6l\u00fcm\u00fc d\u00f6k\u00fcmante edilmi\u015ftir. \u0130stedi\u011fimiz bilgiler ise d\u00f6k\u00fcmante edilmemi\u015f bilgi s\u0131n\u0131f\u0131na girmektedir.\u00a0 Ancak tersine m\u00fchendislik (reverse engineering) ile bu bilgi s\u0131n\u0131flar\u0131na dair veri al\u0131nabilir. SystemModuleInformation information class kullanarak sistemde y\u00fckl\u00fc t\u00fcm mod\u00fcller hakk\u0131nda bilgi alabiliriz. Buna kernel imaj\u0131 da dahil.\u00a0<span class=\"lang:default highlight:0 decode:true crayon-inline \">NtQuerySystemInformation<\/span>\u00a0 ve sistem bilgi s\u0131n\u0131flar\u0131yla ilgi detayl\u0131 bilgi https:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms724509(v=vs.85).aspx adresinden al\u0131nabilir. Bize gerekli olan information class tan\u0131m\u0131 a\u015fa\u011f\u0131daki gibidir.<\/p>\n<pre class=\"ranges:false nums:false nums-toggle:false lang:c decode:true \">typedef enum _SYSTEM_INFORMATION_CLASS\n{\n\tSystemModuleInformation = 0x000B\n}SYSTEM_INFORMATION_CLASS;\n\ntypedef struct _SYSTEM_MODULE_INFORMATION_ITEM\n{\n\tLPVOID Reserved[2];\n\tLPVOID ImageBaseAddress; \n\tULONG ImageSize; \n\tULONG Flags; \n\tUSHORT Index;\n\tUSHORT Rank; \n\tUSHORT LoadCount; \n\tUSHORT NameOffset;\n\tUCHAR Name[256]; \n}*PSYSTEM_MODULE_INFORMATION_ITEM,SYSTEM_MODULE_INFORMATION_ITEM;\n\ntypedef struct _SYSTEM_MODULE_INFORMATION\n{\n\tULONG Count;\n\tSYSTEM_MODULE_INFORMATION_ITEM Modules[1];\n}*PSYSTEM_MODULE_INFORMATION, SYSTEM_MODULE_INFORMATION;<\/pre>\n<p>NtQuerySystemInformation API ile yukar\u0131da tan\u0131mlad\u0131\u011f\u0131m\u0131z information class bilgilerini kullanarak kernel imaj\u0131n\u0131n base adresini bulaca\u011f\u0131z. Yukar\u0131da tan\u0131ml\u0131 yap\u0131daki ImageBaseAddress alan\u0131 bizim istedi\u011fimiz bilgiyi tutacakt\u0131r. Sistem imaj\u0131 olup olmad\u0131\u011f\u0131n\u0131 ise Name alan\u0131n\u0131n ntoskrnl.exe i\u00e7erip i\u00e7ermedi\u011fini kontrol ederek bulaca\u011f\u0131z. Bu bilgiler \u0131\u015f\u0131\u011f\u0131nda kodumuz a\u015fa\u011f\u0131daki gibi olacak.<\/p>\n<pre class=\"ranges:false nums:false nums-toggle:false lang:c decode:true\">typedef NTSTATUS (WINAPI *pNtQuerySystemInformation)(\n    _In_      SYSTEM_INFORMATION_CLASS SystemInformationClass,\n    _Inout_   PVOID                    SystemInformation,\n    _In_      ULONG                    SystemInformationLength,\n    _Out_opt_ PULONG                   ReturnLength\n);\n\npNtQuerySystemInformation _NtQuerySystemInformation = NULL;\n\n\n\nPSYSTEM_MODULE_INFORMATION sysModInfo=NULL;\nPSYSTEM_MODULE_INFORMATION_ITEM pModule = NULL;\nULONG_PTR ntOsKrnl;\nULONG modLen=0;\nHMODULE ntdll = NULL;\nDWORD ret;\n\nntdll = LoadLibraryA(\"ntdll.dll\");\n\n_NtQuerySystemInformation = (pNtQuerySystemInformation)GetProcAddress(\n                                          ntdll,\"NtQuerySystemInformation\");\n\nsysModInfo = malloc(sizeof(SYSTEM_MODULE_INFORMATION));\n\nret = _NtQuerySystemInformation(\n                       SystemModuleInformation, sysModInfo, \n                       sizeof(SYSTEM_MODULE_INFORMATION), &amp;modLen\n      );\n\nif (ret)\n{\n    free(sysModInfo);\n    sysModInfo = (PSYSTEM_MODULE_INFORMATION)malloc(modLen);\n    memset(sysModInfo, 0, modLen);\n}\n\nret = _NtQuerySystemInformation(\n                       SystemModuleInformation, sysModInfo, modLen, &amp;modLen\n       );\n\nif (ret)\n{\n    return;\n}\n\npModule = (PSYSTEM_MODULE_INFORMATION_ITEM)sysModInfo-&gt;Modules;\n\nfor (int i = 0;i &lt; sysModInfo-&gt;Count;i++)\n{\n    if (strstr(pModule-&gt;Name, \"ntoskrnl.exe\") != 0)\n    {\n        ntOsKrnl = (ULONG_PTR)pModule-&gt;ImageBaseAddress;\n        break;\n    }\n    pModule++;\n}\n\n<\/pre>\n<p>Yukar\u0131daki kod vas\u0131tas\u0131yla art\u0131k NT Kernel imaj\u0131n\u0131n base adresinin neresi oldu\u011funu biliyoruz. ntOsKrnl de\u011fi\u015fkeni bu bilgiyi saklamaktad\u0131r. PsActiveProcessHead yap\u0131s\u0131n\u0131n kernel imaj\u0131nda hangi offsette oldu\u011funu \u00f6\u011frenebildik. \u00c7al\u0131\u015fan sistemde kernel imaj\u0131n\u0131n nereye y\u00fcklendi\u011fini de bulabildi\u011fimize g\u00f6re PsActiveProcessHead yap\u0131s\u0131n\u0131n ger\u00e7ekte nerede oldu\u011funu bulmam\u0131z basit bir toplama i\u015flemine bakacakt\u0131r. \u00d6nceki bilgileri hat\u0131rlarsak;<\/p>\n<pre class=\"lang:c decode:true\">\/\/Daha \u00f6nceki referans sembol\u00fcn ofsetini bulan kodumuz\nVOID *sym;\nLONG64 offset;\nHMODULE ntos = NULL;\nntos = LoadLibraryA(\"ntoskrnl.exe\");\nsym = GetProcAddress(ntos, \"PsSiloContextPagedType\");\noffset = (LONG64) ((ULONG64)sym - (ULONG64)ntos);\n\nULONG64 PsActiveProcessHeadOffset = offset + 8;\n\n\/*\nReferans sembol ofseti bilgisini kullanarak ger\u00e7ek kernel adresini\nhesapl\u0131yoruz\n*\/\nULONG64 PsActiveProcessHead = ntOsKrnl + PsActiveProcessHeadOffset;<\/pre>\n<p>Hedefledi\u011fimiz veri yap\u0131s\u0131n\u0131n tam olarak yerini bulduk. Meltdown&#8217;\u0131 PsActiveProcessHead de\u011fi\u015fkeninde tutulan adrese bir LIST_ENTRY boyutu kadar uygulad\u0131\u011f\u0131m\u0131zda elimizde process list&#8217;in header bilgisi ge\u00e7mi\u015f olacak. LIST_ENTRY yap\u0131s\u0131n\u0131n \u00f6zelliklerini hat\u0131rlarsan\u0131z bu yap\u0131dan okunan de\u011ferin FLink alan\u0131 bize ilk process&#8217;i i\u015faret edecektir. Peki bu listeden process verisi nas\u0131l okunur ve tutulan process yap\u0131s\u0131 nas\u0131ld\u0131r? \u00d6ncelikle bunu bilmemiz gerekli.<\/p>\n<p>LIST_ENTRY bir veri yap\u0131s\u0131n\u0131, o yap\u0131n\u0131n i\u00e7erisinde bir referans noktas\u0131 olu\u015fturarak tutmaktad\u0131r. Yani bir listede tutulmak istenen veri yap\u0131s\u0131 ayn\u0131 zamanda ba\u011fl\u0131 listedeki bir sonraki d\u00fc\u011f\u00fcm\u00fc i\u00e7ermektedir.\u00a0 \u00d6rne\u011fin;<\/p>\n<pre class=\"striped:false ranges:false nums:false nums-toggle:false lang:default highlight:0 decode:true\">typedef struct\n{\n\tDWORD x;\n\tDWORD y;\n\tLIST_ENTRY link;\n}VERIYAPISI;<\/pre>\n<p>Linked list d\u00fc\u011f\u00fcm olarak yukar\u0131da link ad\u0131 verilmi\u015f b\u00f6lgelere i\u015faret eder. Bir LIST_ENTRY&#8217;den bir veri yap\u0131s\u0131 okunmak istendi\u011finde link ad\u0131ndaki d\u00fc\u011f\u00fcm\u00fcn adresi kullan\u0131larak veri yap\u0131s\u0131n\u0131n adresi hesaplan\u0131r. Bu i\u015flem de \u00f6rne\u011fimizden gidersek VERIYAPISI i\u00e7erisindeki link&#8217;in adresinden, link alan\u0131n\u0131n VERIYAPISI i\u00e7erisindeki ofseti \u00e7\u0131kar\u0131larak bulunur. Bu i\u015f i\u00e7in <span class=\"lang:default highlight:0 decode:true crayon-inline \">CONTAINING_RECORD<\/span>\u00a0 ad\u0131nda bir makro kullan\u0131lmaktad\u0131r. LIST_ENTRY ile bu temel bilgiyi edindikten sonra process veri yap\u0131s\u0131n\u0131n da \u00f6rne\u011fimize benzer bir entry bar\u0131nd\u0131rmas\u0131 gerekti\u011fini d\u00fc\u015f\u00fcnm\u00fc\u015f olabilirsiniz ki bu do\u011fru.<\/p>\n<p>Windows NT&#8217;de process&#8217;ler <span class=\"lang:default highlight:0 decode:true crayon-inline \">EPROCESS <\/span>\u00a0ad\u0131nda \u00f6zel bir veri yap\u0131s\u0131nda tutulmaktad\u0131r. Yarat\u0131lan b\u00fct\u00fcn processlerin t\u00fcm bilgileri bu veri yap\u0131s\u0131nda saklan\u0131r. Olduk\u00e7a uzun bir veri yap\u0131s\u0131d\u0131r \u00e7\u00fcnk\u00fc dedi\u011fim gibi process&#8217;e ait tutulmas\u0131 gereken \u00e7ok fazla \u00f6zellik mevcuttur. Ancak ben sadece Meltdown exploit&#8217;imiz i\u00e7in bize gerekli olan alanlar \u00fczerinde duraca\u011f\u0131m. Birincisi ve \u00f6nemlisi tuttu\u011fu LIST_ENTRY alan\u0131, ikincisi process ad\u0131, di\u011feri de process&#8217;in eri\u015fim haklar\u0131n\u0131n belirlendi\u011fi access token yahut security token olsun.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/02\/Screenshot_3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-456\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/02\/Screenshot_3.png\" alt=\"\" width=\"565\" height=\"218\" srcset=\"https:\/\/www.oguzkartal.net\/blog\/wp-content\/uploads\/2018\/02\/Screenshot_3.png 565w, https:\/\/www.oguzkartal.net\/blog\/wp-content\/uploads\/2018\/02\/Screenshot_3-300x116.png 300w\" sizes=\"auto, (max-width: 565px) 100vw, 565px\" \/><\/a><br \/>\nWinDbg&#8217;de <span class=\"lang:default highlight:0 decode:true crayon-inline \">EPROCESS<\/span>\u00a0&#8216;e ait bize laz\u0131m olan alanlar\u0131n bilgisinin d\u00f6k\u00fcm\u00fcn\u00fc yukar\u0131daki komut ile ald\u0131k. G\u00f6r\u00fcld\u00fc\u011f\u00fc gibi ActiveProcessLinks&#8217;in bir LIST_ENTRY t\u00fcr\u00fcnde oldu\u011fu g\u00f6r\u00fcl\u00fcyor. Yani bu alan <span class=\"lang:default highlight:0 decode:true crayon-inline \">PsActiveProcessHead <\/span>\u00a0listesine ba\u011flan\u0131rken kullan\u0131l\u0131yor. Di\u011feri almaya \u00e7al\u0131\u015ft\u0131\u011f\u0131m\u0131z Access token, Sonuncusu 15 karakter dizisinden olu\u015fan process ad\u0131. Sembol adlar\u0131n\u0131n solunda ise bu alanlar\u0131n <span class=\"lang:default highlight:0 decode:true crayon-inline \">EPROCESS <\/span>\u00a0yap\u0131s\u0131n\u0131n hangi ofsetinde oldu\u011fu bilgisi mevcuttur. Bu bilgi Windows process listesinin Meltdown ile d\u00f6k\u00fcm\u00fcn\u00fc al\u0131rken laz\u0131m olacak.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/02\/Screenshot_4.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-458\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/02\/Screenshot_4.png\" alt=\"\" width=\"693\" height=\"406\" srcset=\"https:\/\/www.oguzkartal.net\/blog\/wp-content\/uploads\/2018\/02\/Screenshot_4.png 693w, https:\/\/www.oguzkartal.net\/blog\/wp-content\/uploads\/2018\/02\/Screenshot_4-300x176.png 300w\" sizes=\"auto, (max-width: 693px) 100vw, 693px\" \/><\/a><\/p>\n<p>Yukar\u0131daki assembly komut dizisi bilgisayar\u0131m\u0131n \u015fuan \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131 <span class=\"lang:default highlight:0 decode:true crayon-inline \">Windows 10 S\u00fcr\u00fcm 1709 Build 16299.64<\/span>\u00a0&#8216;e ait ntoskrnl.exe imaj\u0131n\u0131n disassembly d\u00f6k\u00fcm\u00fc. Process olu\u015fturduktan sonra i\u015fletim sisteminin yarat\u0131lan process&#8217;i Process list&#8217;e yani <span class=\"lang:default highlight:0 decode:true crayon-inline \">PsActiveProcessHead<\/span>\u00a0 yap\u0131s\u0131na ekleyen rutinin (<span class=\"lang:default highlight:0 decode:true crayon-inline \">PspInsertProcess<\/span>\u00a0) bir k\u0131sm\u0131n\u0131 g\u00f6r\u00fcyorsunuz. Sar\u0131 ile se\u00e7ili ofset alan\u0131n\u0131 bir \u00f6nceki EPROCESS d\u00f6k\u00fcm\u00fcndeki ile ayn\u0131 <span class=\"lang:default highlight:0 decode:true crayon-inline \">0x2e8<\/span>\u00a0. Bakt\u0131\u011f\u0131m\u0131z nokta tam olarak process&#8217;in PsActiveProcessHead listesine eklendi\u011fi yer. Yani edindi\u011fimiz bilgiler tutarl\u0131 ve bekledi\u011fimiz gibi.<\/p>\n<p>Bu demektir ki biz <span class=\"lang:default highlight:0 decode:true crayon-inline \">PsActiveListHead<\/span>\u00a0&#8216;in FLink alan\u0131n\u0131n tuttu\u011fu adresten <span class=\"lang:default highlight:0 decode:true crayon-inline\">0x2e8<\/span> byte kadar \u00e7\u0131kar\u0131rsak, tam olarak <span class=\"lang:default highlight:0 decode:true crayon-inline\">EPROCESS<\/span> veri yap\u0131s\u0131n\u0131n adresini bulmu\u015f oluruz.<\/p>\n<pre class=\"lang:default decode:true\">read_kernel_memory(PsActiveProcessHead, &amp;pmem, sizeof(LIST_ENTRY));\nULONG64 eprocess = ((PLIST_ENTRY)pmem)-&gt;Flink - 0x2e8;<\/pre>\n<p>EPROCESS&#8217;in yerini bulduktan sonra dosya ad\u0131 ve access token&#8217;in yerini de bu sayede rahatl\u0131kla bulabiliriz. WinDbg ile ald\u0131\u011f\u0131m\u0131z EPROCES d\u00f6k\u00fcm\u00fcnden g\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi token alan\u0131n\u0131n ofseti <span class=\"lang:default highlight:0 decode:true crayon-inline \">0x358<\/span>\u00a0, dosya ad\u0131 alan\u0131n\u0131n ofseti <span class=\"lang:default highlight:0 decode:true crayon-inline \">0x450<\/span>\u00a0 idi. Dosya ad\u0131n\u0131 tutan ImageFileName&#8217;in 15 karakter dizisi oldu\u011funu biliyoruz. 15 byte okumak yeterli. Peki token&#8217;in alan\u0131n\u0131n boyutu ne kadar. Onu da \u00f6\u011frenmek kolay. token alan\u0131n i\u015faret etti\u011fi tip <span class=\"lang:default highlight:0 decode:true crayon-inline \">EX_FAST_REF<\/span>\u00a0. Bu veri tipi Windows NT&#8217;de genel ama\u00e7l\u0131 kullan\u0131labilen bir referans veri tipidir. \u00d6zelli\u011fine bakt\u0131\u011f\u0131m\u0131zda<\/p>\n<pre class=\"striped:false lang:default highlight:0 decode:true\">lkd&gt; dt _EX_FAST_REF\nnt!_EX_FAST_REF\n   +0x000 Object           : Ptr64 Void\n   +0x000 RefCnt           : Pos 0, 4 Bits\n   +0x000 Value            : Uint8B\n<\/pre>\n<p>esasen bir union tipi oldu\u011funu g\u00f6r\u00fcyoruz. 64 bit Windows&#8217;ta 64 bit (8 byte) uzunlu\u011funa bir veri tipi. Bu veri i\u00e7in de 8 byte okumam\u0131z yeterli.<\/p>\n<pre class=\"lang:c decode:true \">libk_print(lt_info, \"_EPROCESS : %p\\n\", eprocess);\nlibk_print(lt_info, \"reading security token\\n\");\n\nread_kernel_memory(eprocess + 0x358, &amp;pmem, sizeof(ULONG64));\nmemcpy(&amp;token, pmem, sizeof(ULONG64));\n\nfree(pmem);\n\nlibk_print(lt_info, \"reading process image name\\n\");\nread_kernel_memory(eprocess + 0x450, &amp;pmem, sizeof(ImageName)-1);\nmemcpy(ImageName, pmem, sizeof(ImageName)-1);\n\nfree(pmem);<\/pre>\n<p>Yukar\u0131da bu bilgileri kullanarak sistem process&#8217;inin yerini bulduktan sonra ona ait access token ve imaj dosya ad\u0131n\u0131 okumakta kulland\u0131\u011f\u0131m kod par\u00e7as\u0131n\u0131 g\u00f6r\u00fcyorsunuz. O noktadan sonra birka\u00e7 sadece birka\u00e7 ofset ekleyerek t\u00fcm istedi\u011fimiz bilgiyi kernel&#8217;dan s\u0131zd\u0131rabilmekteyiz.<\/p>\n<p>A\u015fa\u011f\u0131da bu bilgiler \u0131\u015f\u0131\u011f\u0131nda yazd\u0131\u011f\u0131m exploit&#8217;in verdi\u011fi sonucu g\u00f6rmektesiniz.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/02\/Capture2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-461\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/02\/Capture2.png\" alt=\"\" width=\"839\" height=\"561\" srcset=\"https:\/\/www.oguzkartal.net\/blog\/wp-content\/uploads\/2018\/02\/Capture2.png 839w, https:\/\/www.oguzkartal.net\/blog\/wp-content\/uploads\/2018\/02\/Capture2-300x201.png 300w, https:\/\/www.oguzkartal.net\/blog\/wp-content\/uploads\/2018\/02\/Capture2-768x514.png 768w\" sizes=\"auto, (max-width: 839px) 100vw, 839px\" \/><\/a><\/p>\n<p>Demo exploitimde proses listesinin en ba\u015f\u0131ndaki elemana ait se\u00e7ti\u011fimiz bilgilere ait verileri s\u0131zd\u0131rmay\u0131 ba\u015fard\u0131m. Proses list&#8217;de ilk entry her zaman sistem prosesi olacakt\u0131r. \u00c7\u00fcnk\u00fc sistem ba\u015flat\u0131ld\u0131\u011f\u0131nda ilk olarak sistem process&#8217;i olu\u015fturulmaktad\u0131r. Peki bu bilgiler ne kadar tutarl\u0131? Kontrol etmek i\u00e7in yine Kernel debugger&#8217;a ba\u011flan\u0131p ger\u00e7ek durumu g\u00f6relim.<\/p>\n<p><a href=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/02\/Capture.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-462\" src=\"http:\/\/oguzkartal.net\/blog\/wp-content\/uploads\/2018\/02\/Capture.png\" alt=\"\" width=\"577\" height=\"477\" srcset=\"https:\/\/www.oguzkartal.net\/blog\/wp-content\/uploads\/2018\/02\/Capture.png 577w, https:\/\/www.oguzkartal.net\/blog\/wp-content\/uploads\/2018\/02\/Capture-300x248.png 300w\" sizes=\"auto, (max-width: 577px) 100vw, 577px\" \/><\/a><\/p>\n<p>Yukar\u0131daki WinDbg komutlar\u0131na ait d\u00f6k\u00fcm exploiti ba\u015far\u0131yla ger\u00e7ekle\u015ftirerek istedi\u011fimiz bilgileri ald\u0131\u011f\u0131m\u0131z\u0131 do\u011frulamaktad\u0131r. Sar\u0131 ile i\u015faretlenmi\u015f b\u00f6lgeler \u00fczerinde \u00e7al\u0131\u015ft\u0131\u011f\u0131m\u0131z adres ve verileri g\u00f6stermektedir. Sonu\u00e7lar exploit&#8217;in bize s\u0131zd\u0131rd\u0131\u011f\u0131 verilerle tutarl\u0131 oldu\u011funu g\u00f6sterdi.<\/p>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc gibi Meltdown zafiyeti performans kayg\u0131s\u0131yla g\u00fcndem me\u015fgul etmekten \u00e7ok daha \u00f6te ve ciddiyetle \u00fczerinde durulmas\u0131 gereken bir sorun durumunda. Biraz evvel g\u00f6stermi\u015f oldu\u011fum \u00f6rnek exploit&#8217;te sistemin kritik veri yap\u0131lar\u0131ndan ASLR&#8217;\u0131 atlatarak veri s\u0131zd\u0131rabilece\u011fini g\u00f6rm\u00fc\u015f olduk. Elbette bu zafiyetleri k\u00f6t\u00fc ama\u00e7larla istismar etmek isteyenler bunu \u00e7ok daha ileri g\u00f6t\u00fcrerek, \u00e7ok daha \u00f6nemli verileri \u00e7almaya \u00e7al\u0131\u015facaklard\u0131r. Bu veriler aras\u0131nda encryption key (\u015eifreleme anahtar\u0131), Parolalar\u0131n\u0131z, Online al\u0131\u015fveri\u015flerde girdi\u011finiz kredi kart\u0131 bilgileriniz, Kimlik bilgileriniz gibi sadece klasik bilgisayar zararl\u0131 yaz\u0131l\u0131mlar\u0131n\u0131n verebilece\u011fi zararlardan \u00e7ok daha fazlas\u0131na u\u011framan\u0131za sebep olacak bilgiler yer almaktad\u0131r. Bu sebepten g\u00fcnl\u00fck olarak kulland\u0131\u011f\u0131n\u0131z, ve pek \u00e7ok online i\u015flemi yapt\u0131\u011f\u0131n\u0131z cihazlar\u0131 g\u00fcncel tutmak her\u015feye ra\u011fmen olduk\u00e7a \u00f6nem arz eder.<\/p>\n<p>Peki i\u015fletim sistemleri Meltdown&#8217;\u0131 nas\u0131l yamad\u0131lar ve yamalar neden performans\u0131 k\u00f6t\u00fc etkiliyor?<\/p>\n<p>Yaz\u0131n\u0131n Meltdown&#8217;a sebebiyet veren fakt\u00f6rlerlerin say\u0131ld\u0131\u011f\u0131 k\u0131s\u0131mda bu fakt\u00f6rlerden birinin Sanal bellek mekanizmas\u0131n\u0131n birtak\u0131m gerek\u00e7elerle kernel bellek alan\u0131n\u0131n user mode taraf\u0131ndan g\u00f6r\u00fcn\u00fcr oldu\u011funu anlatm\u0131\u015ft\u0131m. O k\u0131s\u0131mdaki bilgileri tekrar hat\u0131rlad\u0131\u011f\u0131m\u0131zda, i\u015fletim sistemlerinin bu problemi User ve Kernel mode adres uzay\u0131n\u0131 birbirinden tamamen izole ederek \u00e7\u00f6zd\u00fc\u011f\u00fcn\u00fc bilmek bu durumu anlamay\u0131 daha kolayla\u015ft\u0131racakt\u0131r. Daha \u00f6nce bahsetti\u011fim gibi User mode processler nas\u0131l birbirinden page table de\u011fi\u015fimi ile izole ediliyorsa bu problem de kernel ve user adres uzay\u0131n\u0131n birbirinden tamamen izole edilmesiyle \u00e7\u00f6z\u00fclmeye \u00e7al\u0131\u015f\u0131lm\u0131\u015ft\u0131r. Bu \u015fu demektir;<\/p>\n<p>Sadece processlerin i\u015flemci \u00fczerinde zamanlanaca\u011f\u0131 durumlarda switch edilen page table, bundan b\u00f6yle her Kernel mode&#8217;a yap\u0131lacak sistem \u00e7a\u011fr\u0131lar\u0131nda da yap\u0131lmas\u0131n\u0131n gerekli olmas\u0131 demektir. Maalesef bu page table&#8217;in her sistem \u00e7a\u011fr\u0131s\u0131nda de\u011fi\u015fimi i\u015flemci a\u00e7\u0131s\u0131ndan olduk\u00e7a maliyetli (costly) bir i\u015flemdir. Kernel mode&#8217;a ge\u00e7i\u015f i\u015fleminin maliyeti \u00fczerine binen bu Page table switch maliyetinin sistem performans\u0131n\u0131 olumsuz etkileyece\u011fi a\u00e7\u0131kt\u0131r. Yahut i\u015flemci User mode bir process&#8217;i \u00e7al\u0131\u015ft\u0131rmaktayken olu\u015facak bir Interrupt&#8217;\u0131n ge\u00e7erli bir \u015fekilde handle edilmesi de buna ba\u011fl\u0131d\u0131r.<\/p>\n<p>Bu durumda e\u011fer \u00e7ok fazla sistem \u00e7a\u011fr\u0131s\u0131 yapacak bir i\u015f yapm\u0131yorsan\u0131z, \u00e7ok fazla interrupt meydana getirecek y\u00fckte bir i\u015f yapm\u0131yorsan\u0131z (Server&#8217;larda network kartlar\u0131 \u00f6rne\u011fin) son kullan\u0131c\u0131 olarak bu yamalar \u00e7ok fazla g\u00f6z korkutan bir seviyede performans kayb\u0131na neden olmayacakt\u0131r. \u00d6zellikle yeni nesil i\u015flemcilerde bu fark b\u00fcy\u00fck olas\u0131l\u0131kla hissedilmeyecektir.<\/p>\n<p>Bu ara\u015ft\u0131rmalar i\u015flemci mimarilerinin de tasarlan\u0131rken t\u0131pk\u0131 yaz\u0131l\u0131mlar gibi istismar durumlar\u0131na kar\u015f\u0131n daha dikkatle incelenmesi gerekti\u011fini g\u00f6stermi\u015ftir. Asl\u0131nda problem yaratan k\u0131s\u0131m mimarinin hatal\u0131 tasarlanmas\u0131 de\u011fil, tasar\u0131m\u0131 gere\u011fi k\u00f6t\u00fcye kullan\u0131ma zemin haz\u0131rlam\u0131\u015f olmas\u0131d\u0131r. Elbette bu k\u00f6t\u00fcye kullan\u0131m\u0131 engellemek i\u00e7in ek bir tak\u0131m \u00f6nlemler gereklidir ve bu ek \u00f6nlemler yahut tasar\u0131mda gidilecek de\u011fi\u015fikliklerin performansa az da olsa ekstra y\u00fck bindirmesi olas\u0131d\u0131r.<\/p>\n<p>\u015eimdilik bu kadar. Spectre i\u00e7in de bir\u015feyler yazmak isterim ancak bunun ne zaman olaca\u011f\u0131n\u0131 kestiremiyorum. Dayand\u0131klar\u0131 temel k\u00fc\u00e7\u00fck farklarla benzer oldu\u011fundan Spectre i\u00e7in kilit noktalara de\u011finilebilir. Umar\u0131m bilgilendirici olmu\u015ftur, konuyla ilgili merak ettiklerinizi yorum k\u0131sm\u0131n\u0131 kullanarak sorabilirsiniz. Elimden geldi\u011fince h\u0131zl\u0131 bir \u015fekilde cevapland\u0131rmaya \u00e7al\u0131\u015f\u0131r\u0131m.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Bu yaz\u0131mda Meltdown g\u00fcvenlik zafiyetinin ne oldu\u011funu, nas\u0131l exploit edildi\u011fini ve geli\u015ftirdi\u011fim bir proof of concept ile nas\u0131l i\u015fletim sisteminde gizli kalmas\u0131 gereken bilgilerin \u00e7al\u0131nabilece\u011fini detayl\u0131 olarak anlatmaya ve g\u00f6stermeye \u00e7al\u0131\u015faca\u011f\u0131m. \u00d6ncesinde bu konunun \u00e7\u0131k\u0131\u015f\u0131 ve yank\u0131lar\u0131 \u00fczerine birka\u00e7 \u015fey s\u00f6yleyerek ba\u015flayay\u0131m. Malum, bili\u015fim ve teknoloji d\u00fcnyas\u0131 yakla\u015f\u0131k son 3-4 hafta i\u00e7erisinde b\u00fcy\u00fck etki yaratan&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"twitterCardType":"","cardImageID":0,"cardImage":"","cardTitle":"","cardDesc":"","cardImageAlt":"","cardPlayer":"","cardPlayerWidth":0,"cardPlayerHeight":0,"cardPlayerStream":"","cardPlayerCodec":"","footnotes":""},"categories":[88,34,64,49],"tags":[94,90,91,89,92,93],"class_list":["post-434","post","type-post","status-publish","format-standard","hentry","category-hardware","category-oses","category-programming","category-security","tag-exploitation","tag-infosec","tag-intel","tag-meltdown","tag-security","tag-side-channel-attack"],"_links":{"self":[{"href":"https:\/\/www.oguzkartal.net\/blog\/index.php\/wp-json\/wp\/v2\/posts\/434","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.oguzkartal.net\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.oguzkartal.net\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.oguzkartal.net\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.oguzkartal.net\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=434"}],"version-history":[{"count":29,"href":"https:\/\/www.oguzkartal.net\/blog\/index.php\/wp-json\/wp\/v2\/posts\/434\/revisions"}],"predecessor-version":[{"id":680,"href":"https:\/\/www.oguzkartal.net\/blog\/index.php\/wp-json\/wp\/v2\/posts\/434\/revisions\/680"}],"wp:attachment":[{"href":"https:\/\/www.oguzkartal.net\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=434"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.oguzkartal.net\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=434"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.oguzkartal.net\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=434"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}