Android & Java Tersine Mühendislik Önlemleri

Başlatan sem, 28 Temmuz 2012 - 17:25:27

« önceki - sonraki »

0 Üyeler ve 3 Ziyaretçi konuyu incelemekte.

sem

Java'da deneyimli arkadaşlar var mı acaba aramızda. Başlıktaki tersine mühendislik ile kastım .class dosyalarından kaynak kodun elde edilmesi aslında.

İnternette araştırdığımda açıkcası düzgün daha doğrusu somut bir örnek ya da anlatım göremedim. Anlayabildiğim kadarı ile genel kanı şu;

"Java her türlü ters işlem yapılabilir (decompile ). Önlem olarak kaynak koda ulaşmaya çalışan kişiyi engellemek için sınıf, method, değişken vs bunlara aynı isimleri verin, kodu çözecek kişinin kafası karışsın."

Diyelim ki bir istemci (client) uygulaması yazdık, belirli bir yere bağlanarak işlemler yapılıyor fakat kullanıcı adı ve şifre sabit.

public final static String userName = "username";
public final static String password = "password";

Class dosyasından gördüğüm kadarı ile bu bilgilere ulaşmak bir cat komutuna bakıyor.

yok mudur bunun Java'da bir önlemi*...


* Java derken kasdetmek istediğim örneğin uygulamanın bir kısmını C++ ile yazarak Java Byte Code olarak derlenmesini engelleme gibi çözümler değil de salt olarak  Java üzerindeki bir çözümden bahsediyorum. Var mıdır böyle bir yöntem bilen acaba?
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

Barış Can

Tersine mühendislik gün geçtikçe gelişen bir kavram, zamanında uğraşmıştım hatta bir video bile çekmiştim bir programı çözüp. Salt olarak hiçbir programlama dilinde koruma yöntemi bulabileceğinizi zannetmiyorum, çünkü yöntemde programın çıkış noktasından başlayıp içeri doğru süregelen bir çalışma var. Bu tür yöntemlerle bilgileri çekiyorlar.

Ben de merak ettim, araştıracağım fakat olduğunu pek zannetmiyorum. :)
» genelde hiçbir şey planladığım gibi gitmez.
» kişisel blog.

sem

Ben de araştırmaya devam ediyorum...

Kapalı kaynak severler için çok sıkıntılı bir durum olsa gerek. Yalnız sadece kapalı kaynak sorunu değil aslında yukarıda verdiğim örnekte de olduğu gibi aslında ciddi bir güvelik sorunu da var ortada.

Enteresan bir durum, bir şey bulabilirsem buradan aktararım.

Bulamazsam da konuyu güncel tutmaya çalışacağm artık yapacak bir şey yok sanırım.=)

".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

ct

Alıntı yapılan: sem0900 - 28 Temmuz 2012 - 17:25:27
Java'da deneyimli arkadaşlar var mı acaba aramızda. Başlıktaki tersine mühendislik ile kastım .class dosyalarından kaynak kodun elde edilmesi aslında.

İnternette araştırdığımda açıkcası düzgün daha doğrusu somut bir örnek ya da anlatım göremedim. Anlayabildiğim kadarı ile genel kanı şu;

"Java her türlü ters işlem yapılabilir (decompile ). Önlem olarak kaynak koda ulaşmaya çalışan kişiyi engellemek için sınıf, method, değişken vs bunlara aynı isimleri verin, kodu çözecek kişinin kafası karışsın."

Diyelim ki bir istemci (client) uygulaması yazdık, belirli bir yere bağlanarak işlemler yapılıyor fakat kullanıcı adı ve şifre sabit.

public final static String userName = "username";
public final static String password = "password";

Class dosyasından gördüğüm kadarı ile bu bilgilere ulaşmak bir cat komutuna bakıyor.

yok mudur bunun Java'da bir önlemi*...


* Java derken kasdetmek istediğim örneğin uygulamanın bir kısmını C++ ile yazarak Java Byte Code olarak derlenmesini engelleme gibi çözümler değil de salt olarak  Java üzerindeki bir çözümden bahsediyorum. Var mıdır böyle bir yöntem bilen acaba?

Bu şekilde bir

public final static String userName = "username";

Kullanımı olmuyor. get set methodları ile direkt ulaşımı engellenebilir. cat ile görmek de engelleniyor bu şekilde. Önemli verilerin olduğu değişkeni public yapmak da garip. Düzgün kullanımla bu tarz açıkların olmayacağını düşünüyorum. public kullanılmadığında da cat ile görülüyormuş şimdi denedim.

Bunun dışında c'de olduğu gibi debug etsek her şeyi görür müyüz bilmiyorum.

Şöyle bir şey var bir de

http://stackoverflow.com/questions/2842169/why-are-public-static-final-array-a-security-hole

sem

Sizin dediğiniz, nesne yönelimli programlamadaki kapsülleme olsa gerek.

Public, private, protected vs şeklinde kullanarak ara yüze açmayabilirsiniz değişkeni. Bu farklı bir durum.

Benim verdiğim örnek nesne saklama üzerine değil aslında ya da minimum yetki kuralına yönetlik bir şey değil. Derlenmiş dosya içerisinde değişkenlerin gözükmesinden bahsediyorum aslında. Örnek

private final String = "username";

şeklinde de olabilir.
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

kafkasyali

Konuyu tam olarak anlamış mıyım bilemiyorum :)

Java maalesef .net gibi kaynak kodları alenen ele geçirilebilecek en kolay platformlardan biri. Android uygulamalarını (*.apk) ya da java uygulamalarını (*.jar) herhangi bir arşivleme programı (7-zip idealdir) ile açıp, içinden bir çok kaynak (resim, müzik v.s.) çıkardığımı belirtmek isterim.

İngilizce olan bu bağlantıyı incelerseniz inşaallah somut bir kaç şey geçer elinize. http://www.thegeekstuff.com/2008/06/protect-your-java-code-from-reverse-engineering/

String saklamanın en güzel yolu kripto kullanmak gibi geliyor bana. Sha512 kullanılan bir şifrenin kırılması ortalama bir bilgisayar ile uzun yıllar sürebilir. Yazacağınız istemci programın ne olduğunu bilmiyorum. İki farklı yol kullanılabilir.

1-) Sunucu da sizin, istemci de

Programa girilecek değerler hash edilip sunucuya gönderilir. Sunucuda bulunan hash değeri ile eşleşiyorsa giriş sağlanır (forumlarda kullanılan üye girişi mantığı)


2-) İstemci sizin, sunucu başkasının

Kullanıcı kodu ve şifrenin hash karşılıkları uygulamada bulunsun. Kullanıcı kodu ve şifresi sisteme girildiğinde hash değerleri tutuyorsa sunucuya string değerler öyle gönderilsin. (Zaten sunucu bu gönderilen değerleri tekrar hash yapıp kontrol edecek :) )

Yapacağınız işle ilgili biraz daha açık bilgi vermeniz mümkün mü? 


http://wp.me/1pScW
sɹǝʇ nq ʞǝʇ ɹıq ؛ɐp ɐpunloʎ ʎǝsɹǝɥ ıʞuɐs

sem

Yapacağım şeylere bu konu üzerinden bir çok örnek verebilirim.

En basitinden gidelim, oturum açma. Bir kullanıcı vardır ve bir çok kişi aynı uygulamayı kullanarak farkında bile olmadan uygulama içerisine gömülmüş olan bu kullanıcı adı ve şifre ile giriş yapacak olsun. Şu anda sunucu da istemci de elimde. Örneğin oturum açacağım diyelim ve dediğiniz gibi hashlenmiş String türünde tutalım şifreyi ve sunucuya onu gönderelim.

Bu durumda hash bilgisi nano ile görülebiliyor olacak ve çok sık kullanılan bu yöntemi bilen ya da bilmese bile tahmin edebilecek herhangi birisi =) Böyle bir String'in şifre yerine kullanabileceğini anlayacaktır. Anlamasa bile en azından deneyecektir.

Bu durumda saldırgan olarak nitelendirebileceğimiz kötü niyetli arkadaşlar aynı şekilde sunucuya nano ile görmüş olduğu hash bilgisini yollayabilir?

Uygulamanın özel/yalıtılmış (private) alanına gömeyim diyorum ve uygulama içerisine yazmadan doğrudan diskten okuyayım diyeceğim ama bu durumda zaten kodlar gözüktüğü için bilginin diskten okunduğu da decompile işlemi sonucunda görülmüş olacak. Ki yalıltılmış alanlar da aslında o kadar da uygulamaya özel değil. Root yetkisi alabilen her uygulama ya da kullanıcı istediği uygulamanın istediği alanına girebilir.
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

kafkasyali

Alıntı yapılan: sem0900 - 30 Temmuz 2012 - 10:27:03
Bu durumda saldırgan olarak nitelendirebileceğimiz kötü niyetli arkadaşlar aynı şekilde sunucuya nano ile görmüş olduğu hash bilgisini yollayabilir?

Nano'nun ne olduğunu bilmiyorum. Bir çeşit debugger mı yoksa hash anahtarı etkeni mi? Bir dönem yazılım korsanlığı ile uğraştım ama hack deneyimim hiç olmadı. İnternetten biraz araştırdım nano'yu, pek bir şey anlamadım. Nano doğrudan hash anahtarını mı veriyor? Misal karma bir hash kullansam. Önce MD5, çıkan hash'i Sha512, çıkan hash'i Serpent yapsam bu nano en son hash'i mi veriyor?

Zaten gerçek hash bilgisini gören kötü niyetli şifreyi aramaz. Eskiden kullanılan çerez (cookie) yöntemi benzeri bir giriş yapabilir. Bu da inanılmaz bir açık demek!!!

Sistemde tuş kaydedici ya da buna benzer bir kötü yazılım varsa veya ağ trafiğini izleyebiliyorsa (snife) istediğiniz kadar şifreleme yapın. Bu şifre doğrudan salgırganın elinde olacaktır. Böylesi bir durumda kodlanan programın hangi dilde yazıldığı da önemini yitirir.


http://wp.me/1pScW
sɹǝʇ nq ʞǝʇ ɹıq ؛ɐp ɐpunloʎ ʎǝsɹǝɥ ıʞuɐs

sem

Nano ile Java .class dosyalarının içerisine bakabiliyorum. Nano uç birim tabanlı bir metin editörü. Yani Vim ile de görülebilir. Yani öyle dediğiniz gibi bir işlevi yok =) Tek işlevi dosyayı metin halinde açmak, ikilik (binary) dosyayı da açıp bakabiliyoruz Vim'de olduğu gibi. Mesela uçbirim geçmişinizi görmek için;

ctrl + alt + tab yaptıktan sonra (bu kısayol Ubuntu kullanıyorsanız geçerlidir)

nano ~/.bash_history


Yazmanız yeterli olacaktır. Daha sonra ctrl + x  ya da ctrl + z ile kapatabilirsiniz.




Mesaj tekrarı yüzünden mesajınız birleştirildi. Bu mesajın gönderim tarihi : 30 Temmuz 2012 - 11:56:12

Ek: Snife'dan korunmak için http isteklerini (request) SSL üzerinden yani https üzerinden gönderebilirsiniz.
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

rutku

Bu decompile olayını engellemenin tek yolu proje içerisindeki tüm değişken,sınıf,method isimlerinin anlamsız yazılmasıdır. Buda yetmiyor malesef okunabilir kod yazmayacaksınız. Buda çok olumsuz durum. Bunu yapan programlar mevcut. Tek güvence aslında patent dir.  Java, c#,python, ruby .... gibi platform bağımsızı dillerde decompile olayı çok fazladır. Bu aslında her dilde olur. Fakat c,c++,pascal,delphi gibi dillerde çok daha zordur. Çünkü assembly kodu vardır elinizde. Ayrıca çok uzun ve okuması zordur. Hatırlarsanız bir rus skype ın eski sürümünü decompile etmişti. Kaynak kodlarınıda açmıştı. Bu adam assembly kodunu okuyor sonrada c/c++ projesine çeviriyor. Bunu yapmak senelerini almış. Ama bir java,c# için aylarla sınırlı.

Bende bu yüzden c++ ı tercih ettim. İlerde bir ticari bir işim olursa sıkıntı yaşamak istemiyorum. Büyük firmalar bu konuları o kadar önemsemiyor. İş verimliliği açısından üst seviye diller daha mantıklı. Ayrıca satış rakamları fazla olduğundan zarar edecek durumları yok.
Hayallerini kodla ...

uKiriş
Mezgeldek

kafkasyali

Tamam şimdi anlaştık :)

Ama uygulamada kullandığınız hash fonksiyonu çözülürse? O zaman keygen bile yazılabilir. Kendi tezimi çürüttüm :D

En güzeli şu olurdu sanırım. Forum mantığı yani. İstemci sadece kullanıcı girişini ve şifresini sunucuya yollayacak. Sunucu onaylarsa giriş yapılacak ;) Kullanıcı işlemleri de sunucuda yapılacak. Kullanıcı açma, silme, yetki tanımları gibi. Yoksa java ters mühendislik için oldukça ideal bir yapı. Hani desek ki safi java değil, gömülü çalışan bir uygulama olsa koruma yöntemi çok. Fakat java neredeyse metin tabanlı bir dil :)


http://wp.me/1pScW
sɹǝʇ nq ʞǝʇ ɹıq ؛ɐp ɐpunloʎ ʎǝsɹǝɥ ıʞuɐs

sem

Olaya salt ticari ve kod kaygısı olarak bakmıyorum aslında. Bu benim bakışım, çalıştığım yer tabii ki böyle düşünmeyecektir en azından düşünmek zorunda değil. yalnız kodu almak kullanmak tabii olası bir durum fakat bir diğer yanda da gömülü hiç bir bilginin içeriye gömülememesi durumu var, kullanıcı adı ve şifre gibi.

Bu sadece bununla da sınırlı değil tabii. Akıl vermek gibi olmasın kötü niyetli  arkadaşlara da =) C2DM uygulaması yazıldığı zaman mail adresini gömülmesi zorunlu örneğin.

Enteresan bir durum. Skype da C++  ve QT ile yazılmıştı diye anımsıyorum.

Benim araştırdığım ve sizlerden gelen yanıtlardan anladığım kadarı ile ilk iletimde belirttiğim kodu karmaşıklaştırma dışında elle tutulur bir yöntem yok şu anda. Yine de çözüldü olarak işaretlemeyeceğim, konuyu gören bilir kişiler belki daha ileri seviye yorumlar yaparak bizleri aydınlatırlar ya da bir yolu varsa paylaşırlar. Aynı şekilde  ben de bir yol bulabilirsem buradan aktarırım.



İlginiz için teşekkür ederim arkadaşlar.
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

ct

http://stackoverflow.com/questions/1383551/hacker-proofing-a-jar-file

http://stackoverflow.com/questions/442862/how-can-i-protect-mysql-username-and-password-from-decompiling

Birincisinde jar dosyaları için koruma olmaz ama anlaşılması zorlaştırılabilinir denilmiş.  İkincisinde nasıl olduğunu anlamaya çalışıyorum o yüzden yorum yazamıyorum.

virs

İnsan için ancak çalıştığının karşılığı vardır. (Kur'an: Necm, 39)