Pharma hack (Google Cloaking Hack) nedir?

Pharma hack nedir?

Pharma hack bır çeşit SEO saldırısıdır. Asıl adı Google Cloaking Hack’dır. Sitenizi html çıktısını kullanıcıya göre manipüle etmek üzerine kuruludur. Pharma hack adını genellikle internette cinsel sağlık ürünleri veya besin takviyesi satan şirketlerin bu hack ile trafik kazanmaya çalışmasından almıştır. Yani bu hack sadece sitenizin arama motoru trafiğini kesmez. Tabi siz analitics yazılımlarda bir trafik kaybı görmezsiniz. Sadece bounce rate’iniz her gün yükselir ve dış trafiğiniz artar. Bu da pagerank’ınızı kaybetmeninizi sağlayabilir.

Büyük tehlike ise sitenizin sansürlenmesi. Türkiye’de son dönemde birçok sitenin/blogun sansürlerden dolayı engellendiğini görüyorsunuz. Bu filtreler genelde halka açık ortamlar, eğitim kurumları gibi alanlarda çok daha etkin. Yani zararsız bir siteye sahip olsanız bile bu hack ile MEB ve BTK’nın google indeksleri ile edindiği site bilgisi genelde cinsel sağlık ürünleri olacağı için muhtemelen siz o içeriğe sahip olmasanız bile okullar, internet cafe’ler gibi yerlerden otomatik olarak filtrelenmiş olacaksınız.

Nasıl oluyor?

Pharma hack sitenize doğrudan ziyaretle anlayamayacağınız bir saldırıdır. Siteniz doğrudan gelen ziyaretçilere normal çıktısını verir ve tarayıcıda doğrudan sitenize giren insanlar sitenizi görmeye devam ederler, böylece siz de anlamazsınız pharma hack altında olduğunuzu.

Ama arama motoru botları sitenizi taramaya çalıştığı zaman sitenizin hack kodu sitenizin sayfa başlığı, anahtar kelimeleri gibi meta etiketlerini değiştirip sayfa içeriğinde istedikleri anahtar kelimeleri de ekleyerek sitenizin çıktısını manipule eder. Böylece pagerank’ınızı kullanarak arama motorlarından gelen trafiğinizi çalarlar. Böylece sitenize ait tüm google indeksleri bir sonraki güncellemede o anahtar kelimeleri alır. Eğer siteniz yüksek page rankına sahipse o anahtar kelimelerde üst sıralarda çıkar ve kullanıcı linke tıkladıgı zaman sayfanızdaki ufak bir javascript kodu kullanıcıyı başka bir sunucuya yönlendirir. Arama motoru trafiğiniz yanlış içerikle sunulur ve kısaca arama motoru trafiğiniz başka bir siteye yönlendirilir.

Sitenizde pharma hack var mı?

Sitenizi sayfaları kontrol ederek pharma hack olup olmadığını anlayamazsınız. Birkaç yolu var;

1) Tarayıcınızın User Agent’ını GoogleBot olarak değiştirip sitenize girebilir, sayfalarınız öyle kontrol edebilirsiniz.

2) Google Webmaster Tools’a kayıt olup sitenizi ekleyip google botun sitenizi nasıl taradığını görebilirsiniz. Googlebot site sitenizin verdiği HTML çıktısını gösterecektir. Meta etiketlerinizi ve sayfa içeriğinizi kontrol edip fakrlı olup olmadığını görebilirsiniz.

Ne tür uygulamalarda yapıyorlar?

Benim gördüğüm örnekleri popüler php hostinglerde ya sunucu kontrolünü ele geçirdikten sonra tüm hesaplara ya da sadece sizin hesabınızı ele geçirdilerse sizin hesabınızda yapılan birkaç ufak php numarasıyla sayfalarınızı arama motoru botlarında farklı render etme üzerine kuruludur. Eğer bir wordpress bloguna veya joomla, drupal gibi bir CMS kullanıyorsanız muhtemel olarak tehlike altındasınız demektir çünkü ele geçirilmesi, gizlenmesi en kolay ve hackerların hedef kitlesidir.

Örnek bir pharma hack kodu göstermem gerekirse:

Bu kod wordpress bloglar için özellikle yazılmış bir pharma hack kodu. Genelde sitenizde her sayfada çalıştırılan bir dosyada yer alırlar. (bootstrap.php, common.php, db.php vs…)

PHP ile basit HTTP authentication

Authentication, yani kimlik dogrulama, daha anlasilir ifade ile bir sayfayi kullanicilara sinirlamak veya tek bir kullanici olan yoneticiye sinirlamak icin genelde birkac yontem izlenir, hangi web altyapisini yaziyor olursaniz olun bununla her calistiginiz projede karsilasabilirsiniz. Kullanicilar icin hazirlanmasi gereken authentication icin yapacak birsey yok, kayit, giris, cikis vs gibi seyleri yazmak zorundasiniz. Fakat yonetici gibi tek kullanici icin sinirlandirilmak istenen sayfalar icin en pratik cozum ve genelde tercih edilen cozum htaccess ile basic auth yapilmasidir, yani statik bir sifre ve belirli bir kullanici adi ile yapilan http authentication. Sunucu konfigurasyonunuza gore (belki cpanel gibi paneller yardimi ile) bir dizini veya bir sayfayi sinirlandirir ve bunun icin hic kod yazmadan halledebilirsiniz.

Ancak her zaman bu imkan elinizde olmayabilir (mesela sadece ftp erisimine sahip oldugunuz ve htaccess desteklemeyen bir hosting konfigurasyonu). Ya da authentication’u bir sekilde kodunuzda saklamak istiyor olabilirsiniz.

PHP’de sayfa header’lari ile tarayicidan authentication bilgisi isteyebiliyoruz. Bunu kullanarak http authentication yaptirabiliriz, bunun avantaji kullanici girisi icin herhangi bir arayuz yazmak zorunda kalmamamizdir. Tabi bir diger avantaji ise bu bilgi giris ekranlarini tarayicilar yonettigi icin sifre hatirlama, belki 1password gibi uygulamalar ile kimlikleri saklama gibi secenekler sunuyor ve kullaniciniz bu seceneklerden faydalanmak istiyor olabilir. Her zaman sayfa icindeki elementlerle bunu saglayamayabilirsiniz.

Son birkac projemde daha duzenli kullandigim bir kodu paylasacagim. Bu kodu tek bir dosyaya (mesela auth.php) yazip bu dosyayi tum uygulamamda include ediyorum en basta. Boylece eger birisi authenticate edilmeden ulasmaya calisirsa http auth ile karsilaniyor.

PHP’de diziler yerine nesnelerle çalışmaya alışmak

Javascript, jquery ile çok uğraşmaktan dizi kavramı php’de kullandığım birşey olarak kalmaya başladı. Yani jquery’de o her şeyi nesnel yazıyor, uğraştığınız şeylerin neredeyse tamamı DOM üzerinde bir nesne oluyor. PHP’de de genellikle yazdığınız bir sınıftan ürettiğiniz nesneler var. Onun dışında anlık yaptığınız bütün işleri dizilerle yapmaya alıştık.

Belki JSON ile back-end’de uğraşıyor olmak biraz daha nesnelerle çalışmayı zorluyor çünkü encode ettiğiniz veya decode ettiğiniz her şey nesnelere dönüşüyor.

Neyse, 2 satır kod ile diziler yerine anlık yaptığınız basit işleri nesneler üzerinde yapabileceğinizi gösterebilirim.

Nesne, dizi ve nesne şeklinde karışık kullanabilirsiniz.
Mesela son arabanın markasına;

şeklinde ulaşabilirsiniz.

Dinamik sitemap.xml oluşturmak

“Sitemap nedir? Önemi nedir?” diyenler şuradan (Vikipedi: Site haritası) başlasınlar.

Şimdi gelelim öneminden çok üretilmesine. Basit bir xml aslında. Fakat eğer sürekli güncellenen yapıda bir siteniz var ise bu xml’i periyodik olarak yenilemeniz gerekir. Tabi ki yüzlerce sayfası olan bir sitede (örneğin blog) bu linklerin envanterini bir xml’de tutmak oldukça zor olacaktır.

Çoğu web uygulamasında sayfaların içerikleri veritabanında tutulan bilgilerin listelenmesi ve detay sayfalarından oluşmaktadır. Yazılar, Arşiv sayfaları, Fotograf sayfaları, Forumlar, forum konularının bulunduğu sayfalar vs. Bu sayfaları listeleyen/gösteren php dosyaları olduğunu düşünürsek sitemap.xml’i oluşturacak kodun bu içerikleri sadece adresleyerek listelemesini yapacak bir kod olduğunu söyleyebiliriz.

Bu içerikleri listeleyerek sadece o içeriklere ait sayfaların URL’lerini oluşturan bir php dosyası düşünün. Basitçe örnekleyeceğim.
Mesela forum adında bir tablonuz var ve bu forum’un site haritası için sadece URL’leri gerekli ve bunu oluşturan ufak bir kod vermek gerekirse :

bu kod, forum konularının sayfalarını URL dizisi olarak oluşturur. Yani 156 nolu forum konusuna erişilecek URL http://mfyz.com/?/konu/156/ şeklindeyse bu URL’i veritabanının yapısına göre oluşturduğunuzu düşünün.

Şimdi sitenizin diğer bölümlerini de bu URL listenize ekleyin. Bu liste 50.000 URL’e kadar olabilir, çünkü sitemap.xml dosyalarında en fazla 50.000 url indeksleyebilirsiniz.

Bütün url listenizi oluşturduğunuzda aşağıdaki yapıda bir XML oluşturmak için gerekli ufak php kodunu vereceğim.
Önce örnek bir sitemap.xml dosyasına bakacak olursak:

Burada urlset nodu içinde url elementini ve loc, lastmod, changefreq, priority alt elementlerini görebilirsiniz. Şimdi basitçe elinizde olan sitedeki tüm sayfaları belirten URL dizisini dönüp bu XML’i oluşturabiliriz.

Eğer veritabanınınzda bu sayfaların oluşturulma tarihleri gibi bir bilgi saklıyorsanız XML’de bunu belirtmeniz iyi olacaktır. Bundan önemlisi changefreq ve priority’dir. changefreq belirttiğiniz url’deki sayfanızın değişme sıklığını arama motoruna söyler. Arama motoru da o değişiklik sürecine göre o sayfayı o periyodda tarayacaktır. Priority de o sayfanın sitenizdeki içerik etkisini ifade edebilir. Mesela forum sitenizin asıl içeriği olmayabilir, ya da fotograflar sitenizin içeriğine çok etkisi olabilir ve 0-1 arasında yüzdelik belirtir gibi öncelik belirtebilirsiniz.

Şimdi bir URL dizisini sitemap.xml dosyasına çevirecek php koduna bakarsak:

en son XML_Content değişkeninde sakladığınız içeriği

ile sitemap.xml dosyası olarak kaydedebilirsiniz. Bu işleri yaptırdığınız php dosyasını da sunucunuzun cron’una haftada veya ayda bir çalışacak şekilde ayarlarsanız site içeriğinizi düzenli olarak bu dosyada toplayabilirsiniz.

Siteye yeni bir içerik eklendiği zaman da bu betiğinizi tekrar çalıştırarak eklenen içeriği doğrudan sitemap.xml’inize ekleyebilirsiniz.

Google Webmaster Tools kullanarak bu sitemap.xml dosyanızı google botlarına düzenli kontrol etmesi için gönderebilir, google’ı pingleyerek bu dosyayı taramasını söyleyebilirsiniz. Arama motoru servislerini pinglemek ile ilgili konuyu başka bir yazıda anlatacağım.

PHP’de gelen isteğin Ajax çağrısı olup olmadığını tespit etmek

Her yerde ajax kullanımından geçilmez oldu. Ajax, hem kolaylıklarından hem de RIA’in (Rich Internet Applications) temeli olduğundan popülerliği gitgide artıyor. Karşımıza her yerde çıkıyor ve artık jquery gibi frameworkler sayesinde ajax çağrıları yapmak için tek satırda 5-10 karakterlik bir javascript kodu bile yeterli oluyor.

Bir php kodunda genelde çıktı verirken normal html etiketleri kullanıp tüm sayfayı tasarlıyoruz fakat genelde bu sayfalar bir verit yapısının görüntüleri (view) oluyor ve aynı çıktıyı javascript ile alıp basmak, hatta bazen ajax ile dışarıya bile vermek gerekebiliyor.

Artık az sonra bahsedeceğim method ile, dosyaları tasarlarken 2 türlü kullanımı için tasarlayacaksınız. Yani hem normal erişim ile hem de o sayfayı ajax ile kullanabilecek şekilde düşüneceksiniz. Burada ajax çağrısı olduğunu yakalamak için genel bir teknik olarak get methodu ile bir değişken gönderip onu izleyebilirsiniz. Mesela kayit.php?ajax=1

Bu, işin ilkel noktası. Ajax çağrısı olup olmadığını yakalamak için artık sunucu ortam değişkenleri arasında $_SERVER[“HTTP_X_REQUESTED_WITH”] değişkeni ile çağrı türünde değer xmlhttprequest ise yapan client’in kullandığı protokolu alabiliyorsunuz. Genellikle içindeki değer “xmlhttprequest” oluyor zaten. Yani bir çağrının ajax olup olmadığını bu şekilde kolayca kontrol edebilirsiniz.

Ufak şekilde örneklemek gerekirse:

Bu kodda isimleri liste çıktısı alırsınız. Eğer javascript ile bu veriye erişmek istersek ajax çağrısı ile bu sayfayı çağırabiliriz ama işlenmiş html kodundan o isimleri almak zor olur. Ya da sadece belirli bir kısmını almak isteyebiliriz. Bunun için basitçe:

Bu kod eğer normal istek yapılırsa

çıktısı; ajax ile istek yapıldığı zaman:

çıktısı verecektir.

Bu şekilde gelen çağrılardan ajax olanlarına sadece kisiler dizisini jsona çevirip sayfayı durduruyoruz. Javascript ile gelen json’u kolayca işleyebilirsiniz.

Burada json’a çevirip javascriptde işlemek zorunda değilsiniz. Ajax ile aldıktan sonra içeriği basmak istediğiniz yere uygun html kodu da üretebilirsiniz bu noktada.

PHP’de Pratikçe Sorgu Cümlesi Oluşturmak

Daha önce SQL injection ve MDB2 hakkında birşeyler yazmıştım.

Bu döküman birkaç konuda size yardımcı olacak, pratikleştirecek sorunlar :

  • Çok alan (4-5+) kullanırken sorgu cümlesi oluşturmak zor
  • Gözden kaçırıp alanları kontrol etmek bazen mümkün olmuyor.
  • Yukarıdaki 2 maddeyi yapmak için satırlarca duplicate kod yazmak gerekebiliyor

Kısaca 3-4 adımda kocaman bir sorgu cümlesini oluşturacağız. Genel olarak bu dökümandaki sorun insert ve update türü sorgularda çıkan kargaşayı kolaylaştıracaktır. Zira select sorguları hem çok veri içermiyor hem de özel cümleler olabiliyor.

Bu methodolojide doğal olarak bir otomatizasyon var. Bunun için verinin düzenli olması gerekiyor. Bu noktada genelde bir dizi içinde verilerin tutulduğunu düşünelim.

Verinin anahtarları veritabanındaki alan adları ile aynı olmalı. Zaten bu veri dizisini oluştururken gerekli sql injection kontrolleri yapılıp kolayca kurtulabilinir fakat her değerde bir ton fonksiyon çağırmaya gerek yok. Kısaca :

kullanımıyla tüm diziye mysql_real_escape_string() uygulayabiliriz.

Sonra zaten cümleyi oluşturmak için genel method olan sprintf ile alanları ve değerleri basacağız. Ancak işin güzelliği burada bu alanlar ve değerler kısımlarını bir sürü döngü ile çözmeyeceğiz.

Gördüğünüz gibi array_keys ve array_values ile hızlıca alanlar ve değerleri alıp implode ile aralarına virgül ve tırnak ekleyebiliriz. Burada dikkat edeceğimiz şey implode sadece değerlerin aralarına tırnak ve virgül ekleyecektir. En dışda kalan tırnakları sprintf içinde tanımlayacağız.

Sonuç olarak bu noktada $sql değişkeninde, değerler ve alanlar giydirilmiş, aşağıdaki gibi bir sql cümlesi elde etmiş olacağız.

Bu cümleyi de mysql_query($sql) ile çalıştırıp sonucu işlemede bitiyor olay.

PHP dosyanıza resim (dosya) gömmek

Böyle birşeye neden ihtiyaç duyarsınız?

En büyük nedeni, tek dosyadan oluşan bir script yazıyor olabilirsiniz (konuyla ilgili olarak PHP ile tek dosyadan oluşan proje üretmek dökümanını okuyabilirsiniz). Ya da yazdığınız projede kullandığınız ufacık ikonların bir sürü dosya şeklinde durmasını istemiyor olabilirsiniz. Başka bir tercih de dosyalarınızı bir veritabanında tutuyormuşcasına tek dosyada depolamak isteyebilirsiniz. Çok küçük boyutlu resimler için bahsettiğim konu daha yaygın kullanılır.

Yani yazdığınız betik kendi içindeki css kuralları ile şekillendirilmiş, ikonlarla da güçlendilirmişse ve ikonlar için ek dosyalar koymak istemiyorsanız bu yöntemi kullanabilirsiniz.

Teknik

Aslında yapılan iş oldukça basit. Öncelikle dosyalarımızı php dosyamızın içine nasıl gömeceğiz? PHP dosyalarımız ascii dosyalar, binary içeriği alabilmek ve saklayabilmek için base64 ile şifreleyeceğiz. Sonuçta ortaya çıkacak olan şey bir ascii şifre olacaktır. Dosya boyutuna göre bu şifrenin uzunluğu artacaktır. Unutmayın ki bu anlattığım yöntem tamamen ufak dosyaları gömmek içindir 100kb üzeri dosyaları php dosyanıza gömerseniz, ya da php dosyanızın boyutu megabyte’ları aştığı zaman işlenmesi zorlaşacaktır. Birkaç ufak dosya için kullandığınız sürece verimli olacaktır.

Dosyalarımız encode etmek için bir kod kullanacağız. Bu işlemi başka bir php dosyası oluşturarak yapın.

Bu kod resim.gif dosyasını ekrana ascii karakterlerle şifrelenmiş şekilde uzun bir metin şeklinde basacaktır. Bu metini kopyalayarak kullanacağız ve orjinal proje dosyamız şöyle olacak

Yukarıda gördüğünüz şey aslında çok uzun bir string. Yani o satırlar yan yana bitişik fakat ben bu dökümanda açıkca görülebilmesi için bu hale getirdim. Bu gördüğünüz string 258 byte’lık 16×16’lık bir ikonun base64 şifresidir. 258 byte’ın bu kadar sürdüğünü düşünürseniz 10-20kb’lık bir dosyanın ne kadar uzun süreceğini tahmin edebilirsiniz. Onun için büyük dosyalarınızı php dosyanıza gömmeyin.

Yukarıdaki şekilde tüm dosyalarınızı base64_encode’dan geçirip $dosyalar dizisine dosyanın adını taşıyan indiste yazın.
Unutmayın bu dizi proje dosyanızın en üstünde tanımlanmalı. Yani proje dosyanızın içinde her türlü işlemi yapıyor olabilirsiniz ama bu teknikteki kodlar dosyanın en üstünde durmalı.

Neyse, dosyalarınızı $dosyalar dizisine kendi adları indis olacak şekilde kaydettiniz. php dosyanızın boyutu kabardı farkındaysanız (kontrol ediniz). Şimdi bu tanımların ardına ufak bir kod ile işlemi bitireceğiz.

Eğer get methodu ile islem değişkeni dosya olarak gelmişse ve get methodu ile dosya değişkeninin içeriği bizim $dosyalar dizisinde indis olarak varsa $dosyalar dizisindeki o elemanın içeriğini base64_decode edip ekrana basıyoruz. Yoksa dosya bulunamadı hatası verip duruyoruz.

Nasıl kullanacaksınız?

Projenin devamındaki bir kısımda

şeklinde kullandığınızda dosyanız resim olarak görüntülenecektir. Aynı şeyi bir arşiv dosyası için de yapabilirsiniz.

gibi.

Dosya deposu

Yukarıdaki kodları ayrı bir dosya olarak kaydedip dosyalarınızı tek parça hale getirdiğiniz bir veritabanı gibi düşünebiliriz. Yani

Bu dosyaya goster.php, resimler.php veya indir.php diyebilirsiniz. Kullanırken yukarıda index.php olarak gösterdiğimiz yola dosyanızın adını yazın. Ayrıca islem=dosya parametresine de gerek kalmadı çünkü bu dosya zaten sadece bu işi yapıyor 🙂

Çok fazla işinize yarar mı bilmiyorum ama yine de bazı yerlerde kullanılan bir teknik olduğu için paylaşma gereği duydum. Umarım faydası dokunur.