Bu mesajda, Kanadalı Foulab’in izlediği yolu adım adım toparlayıp, aynı yöntemi başka TP-Link modellerine de uygulayabilmemiz için bir özet paylaşıyorum.

getBackNRestoreK Fonksiyonu Ne Yapıyor?


Libcmm içindeki kritik fonksiyon:

C++:
void getBackNRestoreK(byte *key)
{
byte bVar1;
int iVar2;
char *hex_;
byte xor[8];
byte dm_in[16];
char hex[16];
IGD_DEV_INFO_OBJ devInfo;

```
xor[4] = 0xf9;
xor[5] = 0x3e;
xor[6] = 0x2d;
xor[7] = 0xcf;
xor[0] = 0x74;
xor[1] = 0x8d;
xor[2] = 0xa5;
xor[3] = 0x0b;

memset(hex, 0, 16);
memcpy(dm_in, dm_in_getBackNRestoreK, 0xe);

// int dm_getObj(uint oid, ushort *in_buf, uint size, void *out_buf)
iVar2 = dm_getObj(2, dm_in, 0x988, &devInfo);

if (iVar2 == 0) {
    memcpy(key, xor, 8);
    hex_ = hex;
    snprintf(hex_, 0x10, "%08x", devInfo.bnr_key);

    do {
        bVar1 = *hex_;
        hex_ = (char *)((byte *)hex_ + 1);
        *key = bVar1 ^ *key;
        key = key + 1;
    } while (hex_ != hex + 8);
} else {
    cdbg_printf(8, "getBackNRestoreK", 0x136, "Get dev info for BNR key failed");
}
```

}

Bu fonksiyonun yaptığı özetle şu:
  • 8 baytlık sabit bir “base key” dizisi tanımlıyor:
Kod:
xor = [0x74, 0x8d, 0xa5, 0x0b, 0xf9, 0x3e, 0x2d, 0xcf]
  • dm_getObj(2, ...) çağrısıyla OID 2 için bir IGD_DEV_INFO_OBJ dolduruyor.
  • IGD_DEV_INFO_OBJ içindeki 32-bit bir alanı (bnr_key) alıyor.
  • bnr_key değerini "%08x" formatıyla ASCII hex string’e çeviriyor (8 karakter).
  • Bu 8 karakteri, xor[] dizisindeki 8 baytla teker teker XOR’layarak final DES anahtarını üretiyor.
Yani:

Kod:
final_key[i] = xor[i] ^ ascii_hex_bnr_key[i]

OID 2 → IGD_DEV_INFO ve XML Tarafı


OID string tablosundan:

Kod:
00199564  ->  "IGD_DEV_INFO"

Yani OID 2, IGD_DEV_INFO ile eşleşiyor. Rootfs içindeki XML şemada da bunu görüyoruz:

XML:
 <DeviceInfo t=o r=P s=IGD_DEV_INFO_OBJ>
...
<X_TP_ProductID t=u r=R d=0x4aa13401 nw=1 h=1 />
... </DeviceInfo>

Foulab’ın “bnr_key muhtemelen X_TP_ProductID” demesinin sebebi bu.
IGD_DEV_INFO struct’ındaki bnr_key alanı, XML’deki X_TP_ProductID ile çok mantıklı şekilde örtüşüyor.

Dolayısıyla:

Kod:
devInfo.bnr_key = 0x4aa13401;

Yanlış Yol: 0x4aa13401’i Doğrudan Key Sanmak


İlk bakışta insanın aklına şu gelebiliyor:

DES key = 0x4aa13401 veya bunun RAM’deki raw baytları.

Ama fonksiyon bunu böyle kullanmıyor. Mantık şöyle:
  • 0x4aa13401 → "%08x" → "4aa13401" (8 karakterlik ASCII string)
  • Bu string’in her karakteri, xor[] içindeki ilgili bayt ile XOR’lanıyor.
  • Sonuç: 8 baytlık DES anahtarı.
Yani asıl DES key, base xor key + bnr_key’in ASCII hex gösterimi karışımı.

VC220-G3u İçin Hesabı Adım Adım Yapalım


Base XOR Key


Kod:
xor = [0x74, 0x8d, 0xa5, 0x0b, 0xf9, 0x3e, 0x2d, 0xcf]

bnr_key → ASCII


Kod:
bnr_key = 0x4aa13401
"%08x" → "4aa13401"

Karakterlerin hex değerleri:

Kod:
'4' = 0x34
'a' = 0x61
'a' = 0x61
'1' = 0x31
'3' = 0x33
'4' = 0x34
'0' = 0x30
'1' = 0x31

XOR İşlemi


Her byte için:

Kod:
1. 0x74 ^ 0x34 = 0x40
2. 0x8d ^ 0x61 = 0xec
3. 0xa5 ^ 0x61 = 0xc4
4. 0x0b ^ 0x31 = 0x3a
5. 0xf9 ^ 0x33 = 0xca
6. 0x3e ^ 0x34 = 0x0a
7. 0x2d ^ 0x30 = 0x1d
8. 0xcf ^ 0x31 = 0xfe

Sonuçta elde edilen DES key:

Python:
'vc220-g3u': b'\x40\xec\xc4\x3a\xca\x0a\x1d\xfe'

Bu, Foulab’in paylaştığı anahtarla bire bir aynı.

Geri test de yapabiliyoruz:

Kod:
final_key[i] ^ xor[i] = ascii("4aa13401")[i]

Bu işlemi tersten yaptığınızda "4aa13401" string’ini geri alıyoruz, yani gerçekten bnr_key = 0x4aa13401.

“Sadece libcmm + rootfs ile” Nasıl Bulunuyor?

Genel yöntem (başka TP-Link modelleri için de aynısı):
  1. Libcmm içinde "getBackNRestoreK" string’ini veya fonksiyon referansını bul.
  2. Fonksiyonun içinde:
    • 8 baytlık sabit bir diziyi tespit et (base xor key).
    • dm_getObj(2, ...) çağrısını bul, son parametre IGD_DEV_INFO_OBJ pointer’ı.
    • IGD_DEV_INFO_OBJ içinde bnr_key alanının offset’ini çıkart.
  3. Rootfs’teki TR-098/TR-181 XML şemalarında IGD_DEV_INFO_OBJ tanımına bak:
    • X_TP_ProductID, X_TP_HardwareID, vs. alanları incele.
    • Genelde d=0xXXXXXXXX şeklinde default ürün ID’si duruyor.
  4. Bu değeri al:
    • bnr_key = 0xXXXXXXXX
    • "%08x" → 8 karakterlik ASCII hex string.
  5. Base xor key ile bu 8 karakteri XOR’la → final DES key’i elde et.
Hiç config.bin, runtime debug veya seri konsolda ekstra sihir gerekmiyor.
Sadece:

libcmm.so + rootfs (XML şema)

yeterli.

Python Script’te Kullanım


Bu mantığa göre script’e eklenmiş hali:

Python:
KEYS = {
'default': b'\x47\x8D\xA5\x0B\xF9\xE3\xD2\xCF',
'xz005-g6-un-v1': b'\x45\xEE\x92\x32\xCF\x5B\x1D\xFE',
'vc220-g3u': b'\x40\xec\xc4\x3a\xca\x0a\x1d\xfe',
}

Artık bu key’in nereden geldiği, nasıl üretildiği ve başka modellere nasıl aynısını uygulayabileceğini öğrenmiş olduk.

Techolay olarak bu işlem için Foulab'e C$100 bağış yaptık.
 
Config'i sorunsuz şifrelediğimizde modemde artık istediğiniz ayarı değiştirebileceksiniz.

Aynısı TurkNet'in GigaFiber routerına gelir mi? ZTE Zxhn H3601p V9. DNS PPoE falan her şey kilitli. Sizin kırdığınız ZTE modemlerle aynı arayüz. Config dosyasının indirildiği alanı gizlemişler Config alamayalım diye. Bu cihazı sansuronline ve Türk Telekom da veriyor müşterilerine göz atabilir misiniz?
 
Son düzenleyen: Moderatör: