Priviahub | RevOne

Reverse kategorisindeki orta zorluktaki RevOne'a yakından bakalım. Elf formatındaki executeable dosyamızı indirip çalıştırıdığımızda kullanıcı adı ve parola istemekte eğer girdiler yanlış ise "Wrong username or password -_-" mesajı ile sonlanıyor . Binwalk aracı ile dosyanın entropisine ve içeriğine baktığımızda dosyada herhangi bir şifreleme vb. görülmemekte .
Ghidra ile dosyamızı açıyoruz ve main fonksiyonundan incelemeye başlıyoruz. Açtığımızda koşullar ve döngüler görmekteyiz.Kodu daha iyi anlamak için L kısayolu ile değişkenlerin isimlerini değiştiriyoruz.Aşşağıdaki gibi bir kod ortaya çıkardık .
  
undefined8 main(void)

{
  byte bVar1;
  bool bVar2;
  size_t username_length;
  byte *pbVar3;
  undefined *puVar4;
  basic_ostream *pbVar5;
  char *pcVar6;
  ulong index;
  undefined8 local_468;
  undefined8 local_460;
  basic_string<char,std::char_traits<char>,std::allocator<char>> local_458 [32];
  byte password [4];
  char parola_karakter_5;
  char parola_karakter_6;
  char parola_karakter_7;
  char parola_karakter_8;
  char parola_karakter_9;
  char parola_karakter_10;
  char parola_karakter_11;
  char parola_karakter_12;
  char parola_karakter_13;
  char parola_karakter_14;
  char parola_karakter_15;
  char username [518];
  allocator<char> local_32;
  undefined local_31;
  basic_string<char,std::char_traits<char>,std::allocator<char>> *local_30;
  ulong local_28;
  int i;
  char degisken_bir;
  
  banner();
  printf(" Enter your name\n > ");
  std::operator>>((basic_istream *)std::cin,username);
  printf(" Enter password\n > ");
  std::operator>>((basic_istream *)std::cin,(char *)password);
  i = 0;
  while( true ) {
    index = (ulong)i;
    username_length = strlen(username);
    if (username_length <= index) break;
    if (username[i] == '_') {
      degisken_bir = '\x01';
    }
    i = i + 1;
  }
  if (degisken_bir == '\x01') {
    username_length = strlen(username);
    if (6 < username_length) goto LAB_001013b9;
  }
  hatavar();
LAB_001013b9:
  username_length = strlen((char *)password);
  if (username_length < 0xf) {
    hatavar();
  }
.
.
.
LAB_001013b9: etiketine kadar olan kısımda kullanıcı adı kontrol ediliyor . Algoritmayı anlamaya çalışalım While döngüsü her döndüğünde :
  • index değişkenine i değişkeni atanıyor
  • username_length değişkenine kullanıcı adının uzunluğu atanıyor
  • username_length değişkeninin uzunluğu küçük eşit index ise(yani girilen kullanıcı adının uzunluğu kadar döngü çalışmış ise) while döngüsünden çık
  • Karakter _ ise degisken_1'e 0x01 değerini ata
  • i değişkenine 1 ekle
  • Başa dön
Bu algoritmayı cpp ile yazıp çalıştırdığımızda geçerli kullanıcı adını buluyoruz . Kullanıcı adında _ karakterinin olması ve uzunluğunun 6 karakterden büyük olması istenmekte . Bu şekilde kullanıcı adını elde etmiş olduk .
Sıra parola kısmına geldi .


LAB_001013b9:
  username_length = strlen((char *)password);
  if (username_length < 0xf) {
    hatavar();
  }
  if (parola_karakter_6 != 'i') {
    hatavar();
  }
  if (parola_karakter_12 != 'P') {
    hatavar();
  }
  if (password[0] != 0x50) {
    hatavar();
  }
  if (password[1] != '4') {
    hatavar();
  }
  if (password[3] != 's') {
    hatavar();
  }
  if (password[2] != 's') {
    hatavar();
  }
  if (parola_karakter_5 != 'H') {
    hatavar();
  }
  if (parola_karakter_7 != 'd') {
    hatavar();
  }
  if (parola_karakter_8 != 'd') {
    hatavar();
  }
  if (parola_karakter_9 != 'e') {
    hatavar();
  }
  if (parola_karakter_10 != 'n') {
    hatavar();
  }
  if (parola_karakter_13 != 'a') {
    hatavar();
  }
  if (parola_karakter_14 != 's') {
    hatavar();
  }
  if (parola_karakter_15 != 's') {
    hatavar();
  }
  if (parola_karakter_11 != '_') {
    hatavar();
  }

Kullanıcı adı aşamasında belirtilen 6 karakterden uzun olma şartı , parola kontrol kısımda 15 karakterden uzun olma şartı koşulmuş . Burada dikkat etmemiz gereken nokta byte password [4]; 4 bytle'lık parola değişkeni oluşturulmuş . 4 karakterden fazla girildiğinde overflow gerçekleşiyor . Statik değişkenler stack üzerinde yan yana tutulduğundan girilen fazlalık değerler password değişkenin yanındaki değişkenlerin alanlarına yazılıyor . Yani 4 karakterden sonraki karakterler değişkenlerin tanımlanma sıralarına göre sıraayla atanmış oluyor . Olayın anlaşılması açısından aşağıdaki cpp kodunda kullanıcıdan girdi alınıyor alınan girdi 4 byte'dan fazla olduğu için devamında tanımlanan değişkenlere taşma gerçekleşiyor . Yani 16 karakterlik parola girdiğimizde 12 tanesi diğer değişkenlere taşmış olacak.
Bu koşulları takip ederek sonuca ulaşıyoruz .

Priviahub | RevTwo

Orta zorluktaki RewTwo'ya yakından bakalım. İlk olarak bize verilen dosyayı tanımaya çalışıyoruz . Dosyayı çalıştırdığımızda bizden bir parola istemekte ve yanlış girişte sonlanıyor . Bu aşamada buffer overflow akıllara geliyor .
Dosyayı daha iyi tanımlamak için aşağıdaki komutları çalıştırdığımızda "Copyright (C) 1996-2020 the UPX Team. All Rights Reserved" yazısı dikkatimizi çekiyor . Araştırdığımızda UPX'in açık kaynka kodlu executeable packer olduğunu görüyoruz. Websitesini ziyaret ettiğimizde UPX'in dosyayı çok iyi sıkıştırdığına vurgu yapılmakta .
Dosyayı ghidra ile açtığımızda UPX ile paketlendiği için anlamsız veriler ile karşılaşıyoruz .ParrotOs üzerinde kurulu gelen UPX'in man sayfasına bakıyoruz ve dosyayı decompress ediyoruz .
Elde edilen yeni dosyayı ghıdra ile açtığımızda artık daha fazla veriye ulaşmaktayız . Programın yürütülmeye başladığı main fonksiyonunu arattığımızda sağ tarafta ghidra tarafından decompile edilmiş halini inceledğimizde müdehale etmemiz gereken noktaları anlamaya başlıyoruz .
local_c değişkeni 0 oludğu taktirde bize flag'i verdiğini kod üzerinde görmekteyiz. Yazılımın akışını bozup şartı atlayıp if'in içerisini çalıştırmasını sağlamak için Cuttter aracını kullanacağız . 0x00404a39 adresinde gerçekleştirilen karşılaştırmanın sonucunda JNZ(Jump If Not zero) instruction'ı ile parolanın yanlış olduğu duruma gidiyor . Bizde bu adresi değiştirerek 0x00404a43 adresine atlanmasını sağlayacağız .
Cutter aracı üzerinde Write-Mode'u aktifleştirdikten sonra adrese müdehale edioyoruz . Adresi değiştirdirip dosyayı çalıştırdığımızda flag'i elde ediyoruz .

Hack The Box | MetaTwo

  Makinayı nmap ile tarıyoruz . 21/tcp open  ftp? | fingerprint-strings: |   GenericLines: |     220 ProFTPD Server (Debian) [::ffff:10.10.1...