TIK.LAT şeysini analiz edelim

Anonim6

Yeni üye
29 Şub 2012
0
5
merhaba arkadaşlar, gelin bu konuda TIK.LAT şeysini analiz edelim. başlamadan evvel temel mimariyi, invaryant olarak nitelendirebileceğimiz konumları bilmekte fayda var. ayrık iki TIK.LAT adreslemesindeki kaynak satırlarının kıyası vasıtasıyla dosyanın değişen ve değişmeyen bileşenlerini tespit edebiliriz. dosyalarımızı temin edelim.
Kod:
$ wget -P ./tiklat/ -i tiklat.txt --adjust-extension

ardından,
Kod:
$ comm --nocheck-order -3 ./tiklat/*.html

vasıtasıyla dosyaların kıyasını yüzeysel olarak yapmamızla birlikte dikkatimizi tüm sabitlerin yanında değişkenlik gösteren bir kod bloğu çeker,
Kod:
eval(function (p, a, c, k, e, d) {
    e = function (c) {
        return c.toString(36)
    };
    if (!''.replace(/^/, String)) {
        while (c--) {
            d[c.toString(a)] = k[c] || c.toString(a)
        }
        k = [function (e) {
                return d[e]
            }
        ];
        e = function () {
            return '\\w+'
        };
        c = 1
    };
    while (c--) {
        if (k[c]) {
            p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c])
        }
    }
    return p
}
    ('$("0.3").8("<0 1=\\"6\\"><0 1=\\"5\\"><a 4=\\"2://7.h.9/f/g/e-d/\\">b c !</a></0></0>");', 18, 18, 'div|class|https|wait|href|btn|skip|www|html|org||REKLAMI|ATLA|0020|pep|dev|peps|python'.split('|'), 0, {}))

eh, fonksiyonun mimarisinden de anlaşılabileceği üzere burada çözümlememiz gereken esas TIK.LAT şeysi bu; bize yönlendirilecek sayfayı verecek olan zımbırtı. kısaca fonksiyonumuz şu yapıda,
Kod:
eval(function (p, a, c, k, e, d) {
	[...]
}([...]))

arka plandan çektiği argümanları ECMAScript-262 nimetinden yararlanıp ifade içerisinde tanıladığı fonksiyona paslıyor, ardından dönüt değerini eval([...])'e tabi tutuyor. argümanların ne halta yaradığını, ne gibi işlemlerden geçirildiklerini şekillendirmek işin arka plana bakmak şart, şey, her ne kadar her halt patates gibi ortada olsa da (...).
Kod:
e = function (c) {
	return c.toString(36)
};

(c) => c.toString(36) olarak tanılı e([...]) nesnesi aldığı argümanı 36 tabanında bir string ifadeye dönüştürüyor. yanlış anlaşılmasın, kafa karışıklığı oluşturmak maksadıyla(!) ana fonksiyonun argüman isimlerini yerel fonksiyonların argümanlarıyla aynı bırakıyor. peki bu fonksiyona sahiden* ihtiyacımız var mı - birazdan anlayacağız.
Kod:
if (!''.replace(/^/, String)) {
	while (c--) {
		d[c.toString(a)] = k[c] || c.toString(a)
	}
	k = [function (e) {
			return d[e]
		}
	];
	e = function () {
		return '\\w+'
	};
	c = 1
};

bu kod bloğunda odaklanmamız gereken unsur kontrol şartı olan !''.replace(/^/, String) boolean ifadesi. eğer ki bu true ise koş paşam diyor kısaca, hangi şartlarda bu değeri çevirdiği ise ilgilenmemiz gereken kısım. ''.replace(/^/, String) kısmı, String.prototype.replace([...]) fonksiyonunun tanılı olmasının ardından satırın başına tekabül eden kısmı (regex, /^/) String([...]) native fonksiyonuna postalıyor. haliyle !''.replace(/^/, String) ifadesini !String("") := true olarak baştan yazabiliriz. sonuç? kontrol segmentinin JavaScript'in immutable nesne huyundan ötürü String fonksiyonun üstüne yazılıp yazılmadığını teyit etmekten başka bir halta yaradığı yok, zaten her türlü geçiriyor; kırpalım. gözüme çarpan ikinci bir husus, zaten tam geçirgen olan bu bloğun bir kısmında e = function () {[...]} biçiminde tekrardan bir tanımlamanın gerçekleştiği. zaten kodun başında tanımlanmışı varken üstüne yazmamızla beraberinde ilk satır da işlevini yitiriyor. o da kırpılabilir. elimizdeki hali şimdilik bu,
Kod:
while (c--) {
	d[c.toString(a)] = k[c] || c.toString(a)
}
k = [function (e) {
		return d[e]
	}
];
e = function () {
	return '\\w+'
};
[COLOR="Red"]c = 1[/COLOR]

while ([COLOR="red"]c--[/COLOR]) {
	if (k[c]) {
		p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c])
	}
}
return p

c=1 ve hemen ardından gelen while(c--){[...]} bizi bir sadeleştirmeye daha sürüklüyor. while içerisindeki dec(c) sebebiyle kontrol şartı yalnız tek bir kere (bool)1 olacağından, ardından da c değişkeninin numerik değeri 0'a eşitleneceğinden ötürü aslında tek bir iterasyon adımımız var, ve artık c bir değişkenden öte sabit kıvamına geliyor. bunun yanı sıra, d[c.toString(a)] = k[c] || c.toString(a) satırı da lüzumsuz bir kod barındırıyor gibi. argümanımız olan k[] arka planda hazırlanan bir string ifadenin '[...]|[...]|...'.split('|') satırı vasıtasıyla '|' karakterinden bölünmesi sonucu oluşturuluyor. ilginç olan şudur ki ne olduğu pek aleni olmayan argümanlarımızdan çifte numerik değerlerimiz (a, c) k[].length'e eşitler. haliyle, while(c--); zaten [k[].length, 0] aralığında iterasyonu sağladığından ötürü k[c] değeri hep var olacak, "|| c.toString(a)" ile ayrı bir koşul tanımlamak lüzumsuz. son olarak if (k[c]) {} içerisindeki (bool)k[c] kontrol şartı da ulaştığımız c:=0 sonucundan ötürü k[0]'ın varlığını teyit ediyor - [function (e) {return d[e]}][0]. görünen o ki zaten var, bu kontrol de saydam. ah ah, birkaç tane daha var da nefesim tükendi. kodumuzun son hali şudur,
Kod:
eval(function (p, a, c, k, e, d) {
	while (c--) {
		d[c.toString(a)] = k[c]
	}
	return p.replace(new RegExp('\\b\\w+\\b', 'g'), function (n) { return d[n] })
}(str, k[].length, k[].length, k[], _, {})
)

ha gayret, odaklanmamızı gerektirecek tek bir nokta kaldı; o da d{} sözlüğünün key:val (=c.toString(a):k[c]) ikililerinin atama süreci. c-- ifadesinden ötürü 0<=c<=a=k[].length aralığında c değeri numerik olarak azalış göstermekte. ardından bu numerik değer, kendisinden hep büyük olan bir k[].length tabanında string'e çevrilmekte. JavaScript'in bu süreçteki davranışı nedir? cevabı V8 Engine bizzat versin.

src/builtins/builtins-bigint.cc
Kod:
Object BigIntToStringImpl(Handle<Object> receiver, Handle<Object> radix,
						  Isolate* isolate, const char* builtin_name) {
	[...]
	int radix_number = 10;
	if (!radix->IsUndefined(isolate)) {
		[...]
		radix_number = static_cast<int>(radix_double);
	}
	[...]
	RETURN_RESULT_OR_FAILURE(isolate, BigInt::ToString(isolate, x, radix_number));
}

src/objects/bigint.cc
Kod:
MaybeHandle<String> BigInt::ToString(Isolate* isolate, Handle<BigInt> bigint,
									 int radix, ShouldThrow should_throw) {
	[...]
	return MutableBigInt::ToStringGeneric(isolate, bigint, radix, should_throw);
}

vee nihayetinde, src/objects/bigint.cc içerisindeki MutableBigInt::ToStringGeneric([...]) fonksiyonunda barınan bir kod parçacığı ve referansı her şeyi özetliyor,
Kod:
static const char kConversionChars[] = "0123456789abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < chunk_chars; i++) {
	chars[pos++] = kConversionChars[chunk % radix];
	chunk /= radix;
}

yahu zaten bizim c.toString(k[].length) değerimize göre her türlü radix>(BigNum)c olduğundan kConversionChars[chunk % radix] işlemi kConversionChars[chunk] oluveriyor, "0123456789abcdefghijklmnopqrstuvwxyz"[c]. d[c.toString(a)] = k[c] satırımız aslında d["0123456789abcdefghijklmnopqrstuvwxyz"[c]] = k[c] imiş, yani d{} sözlük objemiz k[].length değerine göre değişkenlik gösteren {'0': k[0], '1': k[1],...,'a': k[10], 'b': k[11],...} formunda bir veri imiş. ardından bu mapping ışığında formatlanacak olan string ifadeye karşılıkları geçiriliyor. eh, artık algoritmayı çözdüğümüze göre bize direkt olarak URL adresini verecek olan fonksiyonu yazabiliriz. ihtiyacımız olan yalnızca k[] := "[...]|[...]|...".split('|') ve formatlanacak olan string ifade.
Kod:
import requests, re
print(
	re.search(r"a [a-z0-9]\=\\\\\"(.*?)\"", c := requests.get(input()).text)
		.group(1)
		.translate(
			str.maketrans({
				"0123456789abcdefghijklmnopqrstuvwxyz"[i]:j for i,j in enumerate(
					re.findall(r"\d+,\'(.*?)\'\.split", c)[2].split('|')
				)
			})
		)
)

deneyelim.
Kod:
$ echo $TIKLAT | python3.8 damn.py
[COLOR="red"][SANSÜR][/COLOR]/dev/peps/pep-0020/\\

analizimiz sonuçlandı. URL bırakırsam ileride belki TIK.LAT olarak bulabilirim diye sansürledim alan adını. diğer adres kısaltma servislerinin de aman aman farklı bir yanı yok. teşekkür ediyorum.
 

ALcatraz'

Kıdemli Üye
30 May 2013
4,338
4
İstanbul
Bir sorum olacaktı, ana fonksiyonun argüman isimlerini niye yerel fonksiyonların argümanlarıyla aynı bırakmışlar peki?

Kod:
e = function (c) {
	return c.toString(36)
};

Burada neyi amaçlamışlar ve niye böyle bir kafa karışıklığı yaratmak istemişler?
 

Osmangazi

Administrator
18 Mar 2017
48
49
"botların linkleri almasını engellemek için direk reklam sayfa geçişini engellemek içim js kodunu obfucate etmektelermiş." TIK.LAT ile görüşmemiz sonucunda bu şekilde dönüldü. Site yetkilileri ile yakınen görüşmekteyiz. Herhangi bir sorun yok.
 
Son düzenleme:
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.