[OSCCTF Qual 2022] – Flip

Untuk soal ini, kami menggunakan referensi dari ctf luar https://r00tstici.unisalento.it/davincictf-2021-writeups/

Seperti pada writeup soal sebelumnya https://petircysec.com/oscctf-qual-2022-book/ , nampaknya soal ini juga menggunakan konsep oracle padding attack namun bedanya di soal ini terdapat !P[input | flag] dan P[input | flag].

Seperti pada referensi, yang memiliki ! dianggap sebagai hasil enkripsi yang salah sehingga kita fokus saja pada yang P[input | flag]. Untuk pemecahannya kira-kira menggunakan konsep yang mirip pada soal book, input dipad dengan flag sehingga kita dapat mencari flag dengan membruteforce flag per karakter jika diletakkan pada ujung block.

Script 1 (mendapatkan setengah awal):

from pwn import *
import string
import codecs
import binascii

r = remote(‘139.59.117.189’, 4441)
BLOCK_SIZE = 32 – 2


res = “”
while True:
  print(binascii.unhexlify(res))
  while True:
      r.sendline(b’0’*BLOCK_SIZE)
      turn = r.recvuntil(b’flag] = ‘).decode()
      # print(turn)
      if “!” in turn:
          continue
      else:
          encrypted_flag = r.recvline().strip().decode()
          print(encrypted_flag, len(encrypted_flag))
          break
  print(‘phase2’)
  go = True
  for c in range(0, 256):
      # print(c)
      if go:
          while True:
              charbrute = “{:02x}”.format(c)
              # print(payload + charbrute, len(payload + charbrute))
              r.sendline((‘0’*BLOCK_SIZE + res+ charbrute).encode())
              r.recvuntil(b’flag] = ‘)
              # print(turn)
              if “!” in turn:
                  # print(‘a’)
                  continue
              else:
                  encrypted_char = r.recvline().strip().decode()
                  # print(encrypted_char[0:32], encrypted_flag[0:32])
                  if encrypted_flag[0:32] == encrypted_char[0:32]:
                      print(‘get’, charbrute)
                      go = False
                      BLOCK_SIZE -= 2
                      res+=charbrute
                  break

Output script 1:

Script 2 (mendapatkan setengah akhir):

from pwn import *
import string
import codecs
import binascii

r = remote(‘139.59.117.189’, 4441)
BLOCK_SIZE = 32 – 2

res = “4f5343323032327b3343425f346e6772” #hex encoded of OSC2022{3CB_4ngr
while True:
    print(binascii.unhexlify(res))
    while True:
        r.sendline(‘0’*BLOCK_SIZE)
        turn = r.recvuntil(‘flag] = ‘).decode()
        # print(turn)
        if “!” in turn:
            continue
        else:
            encrypted_flag = r.recvline().strip().decode()
            print(encrypted_flag, len(encrypted_flag))
            break
    print(‘phase2’)
    go = True
    for c in range(0, 256):
        # print(c)
        if go:
            while True:
                charbrute = “{:02x}”.format(c)
                # print(payload + charbrute, len(payload + charbrute))
                r.sendline(‘0’*BLOCK_SIZE + res+ charbrute)
                r.recvuntil(‘flag] = ‘)
                # print(turn)
                if “!” in turn:
                    # print(‘a’)
                    continue
                else:
                    encrypted_char = r.recvline().strip().decode()
                    # print(encrypted_char[0:32], encrypted_flag[0:32])
                    if encrypted_flag[0:64] == encrypted_char[0:64]:
                        print(‘get’, charbrute)
                        go = False
                        BLOCK_SIZE -= 2
                        res+=charbrute
                    break

Output script 2:

Flag = OSC2022{3CB_4ngry_0r4cl3?!?}

Leave a Reply

Your email address will not be published. Required fields are marked *