BCA CTF 2019 - Writeup

- 35 mins

Disini saya akan membagikan writeup beberapa soal BCA CTF 2019 yang saya berhasil selesaikan .

Category : Welcome

hello-world 50 Pts

Flag : bcactf{hello!}

net-cat 50 Pts

Jalankan commandnya dan muncullah flagnya

Flag : bcactf{5urf1n_7h3_n37c47_c2VydmVyc2lkZQ

wuphf 50 Pts

Buka setiap sosmed dari BCACTF dan terdapat pecahan dari flag pada setiap sosmednya .

Flag : bcactf{h17_u5_uP_d3VwaGYuY29t}

Category : Binary Exploitation

executable 150 Pts

Disini saya menggunakan radare2 untuk melakukan debugging dan ghidra untuk melakukan decompiling.

Berikut hasil decompile file executable

undefined8 main(void)

{
  uint uVar1;
  long lVar2;
  undefined8 *puVar3;
  undefined8 *puVar4;
  long in_FS_OFFSET;
  int local_49c;
  undefined8 local_498 [48];
  char local_318 [754];
  undefined local_26;
  long local_20;
  
  local_20 = *(long *)(in_FS_OFFSET + 0x28);
  lVar2 = 0x2f;
  puVar3 = &DAT_004008c0;
  puVar4 = local_498;
  while (lVar2 != 0) {
    lVar2 = lVar2 + -1;
    *puVar4 = *puVar3;
    puVar3 = puVar3 + 1;
    puVar4 = puVar4 + 1;
  }
  *(undefined *)puVar4 = *(undefined *)puVar3;
  puts("Welcome to the lottery!");
  puts("So now we\'re going to pick a ginormous number!");
  puts("If it\'s 1, you win!");
  uVar1 = rand();
  printf("Your number is %d!\n",(ulong)uVar1);
  if (uVar1 == 1) {
    puts("Congratulations, you\'re our lucky winner!");
    local_49c = 0;
    while (local_49c < 0x179) {
      local_318[(long)(local_49c * 2)] = *(char *)((long)local_498 + (long)local_49c);
      local_318[(long)(local_49c * 2 + 1)] = '\n';
      local_49c = local_49c + 1;
    }
    local_26 = 0;
    printf(local_318);
  }
  else {
    puts("Try again next time!");
  }
  if (local_20 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
   stack_chk_fail();
  }
  return 0;
}

Jadi disini puVar3 mengambil data dari section .rodata pada address 004008c0 yang mana data tersebut nantinya disimpan pada local_498. Dan kemudian terdapat while looping yang mengisi local_318 yang mana setiap index genap merupakan value dari local_498, misal ketika local_49c=0 maka local_318[0*2] =local_498[0] dan untuk index ganjil diisi dengan "\n" sampai memenuhi local_49c < 377 . Nantinya local_318 ini lah yang diprint jika uVar1 == 1. Namun bagaimana caranya menjadikan uVar1 = 1 sedangkan uVar1 sendiri memiliki value rand() ? . Disini kita dapat menggunakan radare2 untuk mengubah value register yang nantinya di bandingkan dengan 1 .

r2 -d executable-ubuntu
[0x7fcf6a482c30]> aa
[0x7fcf6a482c30]> pdf @main

Perbandingan tadi terdapat pada address 0x004006a4 , yaitu cmp ebx,0x1 . Jadi disini kita cukup mengubah value dari register ebx menjadi 1 agar hasilnya True.

Karena ini file binary 64 bit maka yang kita ubah adalah register rbx (ebx untuk 32 bit)

Dan berhasil , dibawah tulisan Congratulations terdapat string hasil encode dari brainfuck sebagai berikut.

--[----->+<]>----.+.--.++.-[--->+<]>--.+++[->+++<]>+.+[----->+<]>.>-[----->+<]>.+[--->++<]>.[++>---<]>-.-[->++<]>-.-[--->+<]>-.-.>-[----->+<]>+.---[->++<]>.++++++++++.[-->+<]>---.--[--->++<]>---.++[->+++<]>.[--->+<]>---.+++[->+++<]>.+++++++.-[--->+<]>--.-------.---------------.+[-->+<]>+.+.++.+[->++<]>.--.---.+++++++++++++.--[->+++++<]>.++++++++.+.-------.++.+.>--[-->+++<]>.

Yang jika didecode hasilnya adalah sebuah flag.

Flag : bcactf{3x3cut4bl3s_r_fun_124jher089245}

executable-2 250 Pts

Disini saya menggunakan radare2 untuk melakukan debugging dan ghidra untuk melakukan decompiling.

Berikut hasil decompile file executable-2

undefined8 main(void)

{
  int iVar1;
  long lVar2;
  undefined8 *puVar3;
  undefined8 *puVar4;
  long in_FS_OFFSET;
  int local_11fc;
  undefined8 local_11f8 [380];
  char local_618 [1517];
  undefined local_2b;
  undefined local_2a;
  long local_20;
  
  local_20 = *(long *)(in_FS_OFFSET + 0x28);
  lVar2 = 0x17b;
  puVar3 = &amp;DAT_004008e0;
  puVar4 = local_11f8;
  while (lVar2 != 0) {
    lVar2 = lVar2 + -1;
    *puVar4 = *puVar3;
    puVar3 = puVar3 + 1;
    puVar4 = puVar4 + 1;
  }
  puts("Welcome to the lottery!");
  puts("So now we\'re going to pick a ginormous number!");
  puts("If it\'s 1, you win!");
  iVar1 = rand();
  printf("Your number is %d!\n");
  if (iVar1 == 1) {
    puts("Congratulations, you\'re our lucky winner!");
    iVar1 = rand();
    local_618[0] = (char)iVar1;
    local_11fc = 0;
    while (local_11fc < 0x2f6) {
      local_618[(long)(local_11fc * 2 + 1)] =
           (char)(*(int *)((long)local_11f8 + (long)local_11fc * 4) / 100);
      local_618[(long)((local_11fc + 1) * 2)] = '\n';
      local_11fc = local_11fc + 1;
    }
    local_2b = 0;
    iVar1 = rand();
    local_2a = (undefined)iVar1;
    printf(local_618 + 1);
  }
  else {
    puts("Try again next time!");
  }
  if (local_20 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return 0;
}

Jadi disini puVar3 mengambil data dari section .rodata pada address 004008e0 yang mana data tersebut nantinya disimpan pada local_11f8. Dan kemudian terdapat while looping yang mengisi local_618 yang mana setiap index ganjil ke-n merupakan value dari local_11f8 index ke -n*4 dengan valuenya dibagi 100, misal ketika local_11fc=0 maka local_618[0*2+1] =local_11f8[0*4] (jika value dari local_11f8=4600 maka yang disimpan di local_618 adalah 46 )dan untuk index genap diisi dengan "\n" sampai memenuhi local_11fc < 758 . Nantinya local_618 ini lah yang diprint jika iVar1 == 1. Disini kita juga akan menggunakan radare2 untuk mengubah value register yang nantinya di bandingkan dengan 1 .

r2 -d executable-2-ubuntu
[0x7f7eb82c1c30]> aa
[0x7f7eb82c1c30]> pdf @main

Perbandingan tadi terdapat pada address 0x00400691 , yaitu cmp ebx,0x1 . Jadi disini kita cukup mengubah value dari register ebx menjadi 1 agar hasilnya True.

Karena ini file binary 64 bit maka yang kita ubah adalah register rbx (ebx untuk 32 bit)

Dan berhasil , dibawah tulisan Congratulations terdapat string hasil encode dari brainfuck sebagai berikut.

+[--------->++<]>.+.--.++.---------.++++++++++++.+++++.+[-->+<]>+++.--[----->+<]>-.-------------.+++++++++.++++++.+[->+++<]>.++++++.[--->+<]>+.-[->+++<]>.--.-[--->+<]>-.-.+[->+++<]>++.+.++++++++++.-------.[--->+<]>----.++[->+++<]>.+++++++.-[--->+<]>--.-------.[------>+<]>++.+[-->+++<]>-.[--->+++++<]>.[----->+++<]>.[--->+<]>-.------------.+.+++++.---.------------.[--->+<]>--.----.+[----->++<]>-.[--->+<]>--.+++[->+++<]>++.+++++++.-----.++++.--.+++++++++.--------.-[--->+<]>-.[->+++<]>.[--->+<]>--.---.+++++++.[->+++<]>--.++++++++.++++.++.[->+++<]>.+++++++++++++.+++[->+++<]>++.+++++++++.+[--->+<]>+.[->+++<]>.-----------.-[--->+<]>++.--[->+++<]>.[--->+<]>.[->+++<]>-.++++++++.-.+++++++++.--------.-[--->+<]>-.--.++[->+++<]>.[--->+<]>++.-------.+++++++++++.

Yang jika didecode hasilnya adalah sebagai berikut.

rsqsjv{Arent_executables_fun?_I_think_so_sdkfjhqiweuryiquwerajzncxbvaihqiwueyr}

Karena kita tahu bahwa format flag adalah bcactf{} , maka tentunya string tersebut bukanlah flag,jadi disini kita coba gunakan caesar cipher untuk menemukan flag sebenarnya.

Dan ketemulah flagnya.

Flag : bcactf{Aboxd_ohomedklvoc_pex?_I_drsxu_cy_cnuptrasgoebisaegobktjxmhlfksrasgeoib}

Category : Crypto

basic-number 50 Pts

Disini kita diberikan soal sebagai berikut

01100010 00110001 01101110 01100001 01110010 01111001 01011111 01110011
00110000 01101100 01110110 00110011 01100100 01011111 01100111 00110000
00110000 01100100 01011111 01110111 00110000 01110010 01101011

Setiap 8 digit biner tersebut ternyata membentuk suatu character , jadi disini saya membuat sebuah script yang melakukan konversi biner tersebut ke karakter ascii .

a="01100010 00110001 01101110 01100001 01110010 01111001 01011111 01110011 00110000 01101100 01110110 00110011 01100100 01011111 01100111 00110000 00110000 01100100 01011111 01110111 00110000 01110010 01101011".split(" ")
b=""
for i in a:
  l=0
  for j,k in enumerate(i[::-1]):
    m=(2**j)*int(k)
    l+=m
  b+=str(chr(l))
print b

Flag : bcactf{b1nary_s0lv3d_g00d_w0rk}

cracking-the-cipher 50 Pts

Disini kita diberikan sebuah soal yang mana terdapat clue yaitu Caesar Salad Dressing yang berarti terdapat sebuah string yang di encode menggunakan caesar cipher. Pada bagian akhir soal terdapat sebuah ciphertext yang sepertinya telah di encode menggunakan caesar cipher

vjg rcuuyqtf ku ngctpkpi_ecguct_ekrjgtu_ku_hwp!

Kemudian disini saya membuat sebuah script untuk mengembalikan cipher text tersebut menjadi plain text,karena disini kita tidak tahu text tersebut di encode menggunakan shift key berapa maka kita lakukan bf mulai dari 1 - 26 .

import string
cipher="vjg rcuuyqtf ku ngctpkpi_ecguct_ekrjgtu_ku_hwp!"
for i in range(1,27):
  plain=""
  for j in cipher:
    if(j in string.lowercase):  
      a=ord(j)+i
      if(a>122):
        plain+=chr(96+(a-122))
      else:
        plain+=chr(a)
    else:
      plain+=j
  print plain

Flag : bcactf{learning_caesar_ciphers_is_fun!}

three-step-program 125 Pts

Disini kita diberika sebuah file txt yang isinya sebagai berikut.

MzIgLSAgfDMgVGltZXMgQSBDaGFybXwgLSAzMg==



JJGTEVSLKNBVISSGINCU2VCTGJFVETCWKNGVGTKLKJEEKQ2VJNEUSNC2KZKVCS2OJFNE4RKPKNFUUSKSJNKTITSDKJFEERKUI5GTETKJLJGVMQ2RJNLEWUSLIZAVES2DJRFE2RKDK5JU2SKKJBCTEVKLJBDUSWSUI5KTETSLKZEVKS2TLJKEWUSFIU2FKU2WJRBEIVCFKFJVASKWIFKU2USLIRDUUR2FGJJEWQ2LKJGFMR2TJNCUYSSIIRFU2U2UJFCTEVKJKZJUMSKKJNKU6VK2KRFVES2VGZKEWUSKIJCVIR2XKNBEUNKGIZDVMMSEJRFEERKDKRJVOR2SJJKUGV2TJVFDKR2VGRLVGSKLJUZEKSKWJNHEWWSKKVDVCSSUJFJEERJUK5JVKTCCIZKEKVCDIVFFUQKWKFITEQSJJZEVKV2SGJDEYQSCKVBVMSSTJFFEMRSFKMZEISKFLJCVSTKTIZEUUTCGJ5JVUV2KJJAVKNSVKNMUWTSBKZKU2MSUJJLEYRCFKEZEETCKJNDECVCSKZFU4QSVI5ITEU2LJZCEMU2VJNDEYRSOIVKVCS2OJRFE4RKPKFNFIS2SINCTEUSTKZGEERCVKNJEGRKKGVDEISKXINBEOVSDIVGVES2DJM2UIVKXKNFUKSS2I5LE2VSLLBGEKWSVJFJFGUCLLJHEKQ2QJI2UQVJWKE6T2PJ5



lhlm oad lamaew eyhmgs. lg i sxsro rgu ntee qhj a qesg? dbfcp rgu stne xtve tm lhtl xac, b’dl rh wadr gn jhm ayw zayw at zowr. 
mvscey{bu57_j0n_o4i7_kgbhmffhlqe} bfm, te htjnpw, feim lixx at hhf’t mx ko dbepwx…

Dari list karakter yang membentuk string tersebut dapat ditentukan bahwa kemungkinan block 1 = base64 , block 2 = base32 .

Kemudian kita lakukan decode sesuai dengan encodingnya

Block 1 

32 - |3 Times A Charm| - 32 
( clue untuk block 2 , yaitu di encode menggunakan base32 3 kali )

Block 2

Why english so ard to tok. 
No speak more English. 
Ail gi you tu hints to read my encrypted languich.

1. SALT iz key to gret food!
2. 2. Le francais crypte le meilleur 

Dari block 2 kita dapat mengetahui bahwa block 3 menggunakan vignere cipher ( salah satu cipher yang diciptakan oleh orang prancis ) dengan key yaitu **SALT**. Berikut hasil decode nya

that was simple enough. so i heard you came for a flag? since you have made it this far, i’ll go easy on you and hand it over. bcactf{ju57_y0u_w4i7_znjhbmnhaxm} but, be warned, next time it won’t be so simple…

Flag : bcactf{ju57_y0u_w4i7_znjhbmnhaxm}

a-major-problem 200 Pts

Disini kita diberikan hint yaitu

The words translate to numbers, which then translate to the flag.

Berarti disini kita mengubah kata kata tersebut menjadi angka lalu mengubahnya ke karakter ascii . Cluenya disini adalah Major Mnemonic .

Saya menggunakan website https://major-system.info/en/ untuk melakukan translate ke angka dan didapatkan angka sebagai berikut .

>>> a="98 99 97 99 116 102 123 103 51 116 95 103 47 116 125".split(" ")
>>> print "".join(chr(int(i)) for i in a)
bcactf{g3t_g/t}

Ternyata karakter ke 13 bukanlah / melainkan 0.

Flag : bcactf{g3t_g0t}

Category : Forensics

split-the-red-sea 100 Pts

Berikut file redsea.png nya

Disini saya menggunakan exiftool untuk melakukan forensic terhadap file tersebut dan didapatkan flag sebagai berikut .

Flag : bcactf{7w0_r3d5_sdf3wqa}

bca-craft 125 Pts

Disini saya menemukan sebuah file dengan nama flag.mfunction yang didalamnya terdapat flag dengan format sebagai berikut .

"! The flag is: ", "b", "c", "a", "c", "t", "f", "{", {"text": "m1n3cr4f7_b347s_f0rtn1t3", ... }

Flag : bcactf{m1n3cr4f7_b347s_f0rtn1t3}

file-head 125 Pts

Terdapat sebuah file flag.png yang mana ketika dibuka error ( not a png file ). Dilihat dari clue nya maka disini kita diminta untuk merubah file header nya sehingga file tersebut dapat dikenali sebagai file png.

Kita ubah file header nya menjadi file header dari png

Kemudian buka kembali maka muncullah flagnya.

Flag : bcactf{f1l3_h3ad3rs_r_c001}

of-course-rachel 150 Pts

Isi dari file zip tersebut adalah screenshot dari hex sebuah file yang terbagi menjadi 5. Disini saya menggunakan tesseract untuk melakukan konversi img to txt lalu menjadikan file part1-5 tersebut menjadi satu file

Disini saya menamakan file nya sebagai **full**

Lalu setelah itu saya coba untuk mengembalikannya kembali dengan command **xxd -r -p**

Sepertinya file tersebut adalah script python, namun hanya beberapa baris kode saja yang readable. Kemungkinan besar kesalahan sewaktu konversi dari img ke txt,setelah saya betulkan dan menggabungkan semua part berikut adalah potongan kodenya .

import binascii
import random
class Vector(object):    """        
This class represents a vector of arbitray size.        
You need to give the vector components.         
Overview about the methods:        
constructor(components : list) : init the vector        
set(components : list) : changes the vector components.        
__str__() : toString method        
component(i : int): 
--------------------------snippet---------------------------

Pada script tersebut terdapat potongan kode yang menarik yaitu function int_to_text serta variable flag. Kemudian saya jadikan satu lalu coba run

def int_to_text(inp):
  hexed = hex(inp)    
  return bytearray.fromhex(hexed[2:]).decode()
flag = 820921601166721424573282546345206805820898697321521913920196691573868657577500743744203737234698
print(int_to_text(flag))

Flag : bcactf{0p71c4lly_r3c0gn1z3d_ch4r4c73rs

open-docs 150 Pts

Disini kita bisa mengexplore isi dari file docx dengan cara mengubah ekstensinya menjadi .zip

Saya menemukan sebuah file xml yang menarik bernama secrets.xml

Isi dari secrets.xml adalah sebuah string yang diencode menggunakan base64

PHNlY3JldCBmbGFnPSJiY2FjdGZ7ME94TWxfMXNfNG00ejFOZ30iIC8+

Setelah di decode ketemulah flagnya

Flag : bcactf{0OxMl_1s_4m4z1Ng}

study-of-roofs 150Pts

Diberikan sebuah file jpg , kemudian saya coba untuk menjalankan binwalk pada file jpg tersebut dan muncullah flagnya.

Flag : bcactf{r4i53_7h3_r00f_liz4rd}

wavey 150 Pts

Diberikan sebuah file straightfire.wav , disini saya coba langsung melihat spectogram dari file straightfire tersebut menggunakan audacity.

Flag : bcactf{f33lin_7h3_vib3z

corrupt-psd 200 Pts

Diberikan sebuah file psd yang mengalami error,dapat diketahui dari soal errornya disebabkan oleh file header yang salah , jadi disini saya merubah file header nya sesuai dengan file header psd.

Dan berikut ketika file tersebut dibuka

Flag : bcactf{corrupt3d_ph0705sh0p?_n0_pr0b5_1af4efb890}

the-flag-is 200 Pts

Disini saya membuka file flag.pdf dengan browser dan muncul lah flagnya

Flag : bcactf{d0n7_4g3t_4b0u7_1nCr3Men74l_uPd473s}

one-punch-zip 250 Pts

Diberikan sebuah file png dan juga file zip terpassword. Disini saya coba analisa file png karena passwordnya pasti ada hubungannya dengan file tersebut.

Setelah saya melakukan banyak percobaan forensic dan ternyata tidak membuahkan hasil akhirnya saya coba memanfaatkan string yang terdapat pada opm.png saat saya melakukan binwalk.

binwalk --dd=".*" opm.png

Disini saya coba melakukan bruteforce terhadap zip tersebut menggunakan string printable yang ada pada file 84.

strings 84 > bf.txt
mv bf.txt ../

Kemudian langsung saya coba crack dengan menggunakan fcrackzip dengan worldist pada bf.txt

fcrackzip -u -D -p bf.txt superSecure.zip

Dan hasilnya

Lalu saya extract dan ketemulah flagnya

Flag : bcactf{u5ing_4ll_string5_0f_1mag3_@s_dictionary?}

Category : Programming

1+1=window 75 Pts

Diberikan sebuah file one.txt dan two.txt yang isinya adalah hex,dilihat dari soal dapat disimpulkan bahwa flagnya adalah hasil penjumlahan dari one.txt dan two.txt yang dikonversi ke ascii.

flag=""
one="0x23 0x49 0x16 0x46 0x45 0x16 0x3c 0x3c 0x45 0x64 0x16 0x37 0x3c 0x3c 0x3c 0x16 0x46 0x45 0x37 0x1e 0x49 0x16 0x46 0x49 0x16 0x1e 0x16 0x32 0x32 0x3c 0x32 0x49 0x3c 0x64 0x1e 0x32 0x3c 0x18 0x64 0x32 0x32 0x50 0x14 0x64 0x32 0x5a 0x45 0x32 0x32 0x55 0x50 0x49 0x3c 0x14 0x3c 0x5f".split(" ")
two="0x26 0x2b 0x0a 0x23 0x2e 0x0a 0x29 0x25 0x2e 0x15 0x0a 0x37 0x25 0x25 0x2c 0x0a 0x23 0x2e 0x37 0x09 0x2b 0x0a 0x23 0x2b 0x0a 0x21 0x0a 0x30 0x31 0x25 0x31 0x2b 0x2a 0x17 0x13 0x2d 0x2c 0x18 0x0c 0x01 0x2d 0x29 0x1c 0x11 0x2d 0x1b 0x2e 0x01 0x2d 0x1b 0x29 0x2b 0x2c 0x1c 0x32 0x1e".split(" ")
for i in range(0,len(one)):
     flag+=chr(int(one[i],16)+int(two[i],16)) 
print flag

Flag : bcactf{1_h0p3_y0u_us3_pyth0n}

bca-store 75 Pts

Di berikan soal seperti diatas, dengan isi file input.txt sebagai berikut

 C B B C A 250
 A C D A 230
 A B C D 240
 D D D 225
 A A A A 150
 A A A A B B B B B C C C C C D D D D 1000
 A A A A B B B B B C C C C C D D D D 90

Disini saya menggunakan python untuk membuat solvernya .

a=45
b=52
c=67
d=75
e="C B B C A 250,A C D A 230,A B C D 240,D D D 225,A A A A 150,A A A A B B B B B C C C C C D D D D 1000,A A A A B B B B B C C C C C D D D D 900".split(",")
for i in e:
  n=i.split(" ")
  a1=n.count('A')
  b1=n.count('B')
  c1=n.count('C')
  d1=n.count('D')
  total=a1*a
  if(b1>1):
    b2=46.8
    total+=((b2*(b1/2))+(b*(b1-(b1/2))))
  elif(b1==0):
    total+=0
  elif(b1==1):
    total+=b
  if(c1>1):
    c2=33.5
    total+=((c2*(c1/2))+(c*(c1-(c1/2))))
  elif(c1==0):
    total+=0
  elif(c1==1):
    total+=c
  if(d1>2):
    total+=(d*(d1-(d1/3)))
  elif(d1==0):
    total+=0
  else:
    total+=(d*d1)
  if(int(n[-1])<total):
    print "-1"
  else:
    print '%.2f' % (int(n[-1])-total)

Output : 5.70 -1 1.00 75.00 -1 77.40 -1

instructions 175 Pts

Berikut isi pesannya

Dear Agent Reffef,

I have attached the super secret plans for operation 0x576f726b206f6e207468652070757a7a6c652c2073746f702072656164696e672068657821. You will need to decode it first though. 

The rules are simple: 

A line is "viable" if the length of a line is divisible by 3, and the line does not contain the & character. 

For every viable line, you will grab the `n`th character,  where `n` is the corresponding number at the top of the file (Counting from one!)  The first viable line will use the first number, etc. 

Put all the letters together to find the answer!  

- Agent Doposi

Disini saya menggunakan python untuk membuat solver soal diatas

f=open("flag.txt", "r")
f1=f.readlines()
flag=""
no="20 30 8 14 17 24 44 19 17 29 20 34 35 27 42 34 7 25 7 21 8 38 13 25 14 13 42 14 20 23 3 27 38 9 18 41 3 11 35".split(" ")
arr=[]
for i in f1:
  if('&amp;' not in i and (len(i)-1)%3==0):
    arr.append(i[:-1])  
for i in range(0,len(arr)):
  flag+=arr[i][int(no[i])-1]
print flag

public-library 200 Pts

Diberikan file .class lalu saya decompile file tersebut dan didapatlah file .java yang isinya sebagai berikut.

import kotlin.Metadata;

@Metadata(mv={1, 1, 13}, bv={1, 0, 3}, k=1, d1={"\000\024\n\002\030\002\n\002\020\000\n\002\b\002\n\002\020\016\n\002\b\002\030\0002\0020\001B\005¢\006\002\020\002J\006\020\005\032\0020\004R\016\020\003\032\0020\004XD¢\006\002\n\000¨\006\006"}, d2={"LPublicLibrary;", "", "()V", "flag", "", "getFlag", "public-library"})
public final class PublicLibrary { private final String flag = "bcactf{t4k3_4_j4v4_c7a55_789208694209642475}";
  
  @org.jetbrains.annotations.NotNull
  public final String getFlag() { return flag; }
  
  public PublicLibrary() {}
}

Flag : bcactf{t4k3_4_j4v4_c7a55_789208694209642475

manner-of-thpeaking 250 Pts

Berikut isi dari file inthtructhins.txt

cadadddddr, caddadddddr, caadddddr, caddadddddr, cadddddddddddddddddddadddddr, cadddddadddddr, caaddddddr, cadddddddddddadddr, cadadr, cadddddadr, cadddddddadr, caddddaddddr, caddddddddadr, caddddadr, cadddddadr, cadddadr, cadddadddddr, caddddaddddr, cadddddddddddddddadddddr, cadddddddddddddddddadddr, caadr, caddddddadddddr, cadddddddddddddddddadddr, caddddadr, caddddddddddddadddr, caddddddddddddadddddr, cadadr, cadddddddddddddadddddr, caddddddadddr, caddddaddddr, cadadr, cadddddadr, caddddaddddr, caddddadr, caddddddddddddddddddddddadddddr, cadddadr, caddddddddddddddddddadddr, caadr, caddddddddddddadddr, caddddadddddr, cadar, caddaddddddr

dan berikut isi dari file printableth.txt

(( !\"#$%&amp;'()*+,-./)(0123456789)(:;<=>?@)(ABCDEFGHIJKLMNOPQRSTUVWXYZ)([\]^_`)(abcdefghijklmnopqrstuvwxyz)({|}~))

Mekanisme encoding pada string di file inthructhins.txt adalah mengikuti urutan grup string pada printableth . Berikut penjelasannya

( !\"#$%&amp;'()*+,-./) --> Group 1 = *ar* 
(0123456789) --> Group 2 = *adr*
(:;<=>?@) --> Group 3 = *addr*
(ABCDEFGHIJKLMNOPQRSTUVWXYZ) --> Group 4 = *adddr*
([\]^_`) --> Group 5 = *addddr*
(abcdefghijklmnopqrstuvwxyz) --> Group 6 = *adddddr*
({|}~) --> Group 7 = *addddddr*

Example :
1. caadddddr = 'ca'+ 'adddddr' = group 6 karakter ke 1
2. 2. cadadddddr = 'cad'+ 'adddddr' = group 6 karakter ke 2
3. 3. caddadddddr = 'cadd'+ 'adddddr' = group 6 karakter ke 
4. Dst..

Berikut solver yang saya buat menggunakan python

a=['cadadddddr', 'caddadddddr', 'caadddddr', 'caddadddddr', 'cadddddddddddddddddddadddddr', 'cadddddadddddr', 'caaddddddr', 'cadddddddddddadddr', 'cadadr', 'cadddddadr', 'cadddddddadr', 'caddddaddddr', 'caddddddddadr', 'caddddadr', 'cadddddadr', 'cadddadr', 'cadddadddddr', 'caddddaddddr', 'cadddddddddddddddadddddr', 'cadddddddddddddddddadddr', 'caadr', 'caddddddadddddr', 'cadddddddddddddddddadddr', 'caddddadr', 'caddddddddddddadddr', 'caddddddddddddadddddr', 'cadadr', 'cadddddddddddddadddddr', 'caddddddadddr', 'caddddaddddr', 'cadadr', 'cadddddadr', 'caddddaddddr', 'caddddadr', 'caddddddddddddddddddddddadddddr', 'cadddadr', 'caddddddddddddddddddadddr', 'caadr', 'caddddddddddddadddr', 'caddddadddddr', 'cadar', 'caddaddddddr']
b=" !\"#$%&amp;'()*+,-./"
c="0123456789"
d=":;<=>?@"
e="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
f="[\]^_`"
g="abcdefghijklmnopqrstuvwxyz"
h="{|}~"
flag=""
for i in a:
  if 'addddddr' in i:
    flag+=h[len(i)-10]
  elif 'adddddr' in i:
    flag+=g[len(i)-9] 
  elif 'addddr' in i:
    flag+=f[len(i)-8] 
  elif 'adddr' in i:
    flag+=e[len(i)-7]
  elif 'addr' in i:
    flag+=d[len(i)-6]
  elif 'adr' in i:
    flag+=c[len(i)-5]
  elif 'ar' in i:
    flag+=b[len(i)-4]
print flag

Flag : bcactf{L157_8453d_pR0gR4Mm1nG_15_4w3S0Me!}

Category : Reversing

large-pass 100 Pts

Diberikan sebuah file binary large-linux , disini saya coba untuk melakukan decompile dengan ghidra

Terlihat jelas bahwa input kita tersimpan pada variable LStack32 yang mana dibandingkan dengan LStack24 dan jika sama maka akan melakukan print Correct password.

beriku adalah value dari variable LStack24 jika diubah ke decimal

5546068866699313608

Lalu jalankan ./{nama-file} lalu masukkan password tersebut maka outputnya adalah Correct password.

Flag : 5546068866699313608

basic-pass-1

Diberikan sebuah file binary basic-pass-1-linux , disini saya coba untuk melakukan decompile dengan ghidra.

Terlihat bahwa dibutuhkan setidaknya satu argument yang merupakan passwordnya sendiri yang dicocokkan dengan variable iVar1. Variable iVar1 sendiri jika diubah ke decimal adalah 1234. Jadi disini kita bisa tau langsung flagnya ataupun kita bisa juga menjalankan ./basic-pass-1-linux 1234 untuk mengetahui flagnya

Flag : bcactf{hey_its_a_password}

scratch-that 150 Pts

Link : https://scratch.mit.edu/projects/276674047/

Ketika kita membuka link tersebut maka akan tampil seperti gambar diatas,lalu disini saya coba menginputkan bebas dan berikut hasilnya

Dilihat dari judulnya adalah guess the flag, namun akan sangat sangat lama jika kita menebak flagnya karena tampilannya ketika salah flag hanya merah dan tulisan wrong , tidak ada info tambahan mengenai flagnya.

Jadi disini saya coba untuk melihat struktur dari program tersebut dan menemukan sesuatu yang menarik yaitu sebuah block generate flag dan variable flag.

Jadi saya coba menyalinnya ke function utama dengan struktur awal seperti berikut

Setelah saya ubah menjadi sebagai berikut

Dan berikut hasilnya setelah dijalankan

Flag : bcactf{scr4tch3d_Pourquoi_empty_23412342463682

another-pass 200 Pts

Diberikan sebuah file binary another-linux , disini saya coba untuk melakukan decompile dengan ghidra.

Hasil decompile fungsi main()

undefined8 main(void)

{
  undefined8 uVar1;
  long in_FS_OFFSET;
  undefined auStack72 [56];
  long lStack16;
  
  lStack16 = *(long *)(in_FS_OFFSET + 0x28);
  printf("Pass: ");
  __isoc99_scanf(&amp;DAT_001009d2,auStack72);
  checkInput(auStack72);
  putchar(10);
  uVar1 = 0;
  if (lStack16 != *(long *)(in_FS_OFFSET + 0x28)) {
    uVar1 = __stack_chk_fail();
  }
  return uVar1;
}

Terlihat disini inputkan kita disimpan sebagai string pada variable auStack72 dan kemudian variable tersebut digunakan sebagai parameter function checkinput()

Dan berikut hasil decompile fungsi checkinput()

void checkInput(long lParm1)

{
  ulong uVar1;
  ulong uVar2;
  long in_FS_OFFSET;
  undefined local_2d;
  int local_2c;
  int local_28;
  int local_24;
  long local_20;
  
  local_20 = *(long *)(in_FS_OFFSET + 0x28);
  local_28 = 0;
  local_24 = 0;
  do {
    uVar2 = SEXT48(local_24);
    uVar1 = strlen(lParm1);
    if (uVar1 <= uVar2) {
      printf("Incorrect.");
LAB_001008a0:
      if (local_20 != *(long *)(in_FS_OFFSET + 0x28)) {
        __stack_chk_fail();
      }
      return;
    }
    local_2d = *(undefined *)(lParm1 + (long)local_24);
    __isoc99_sscanf(&amp;local_2d,&amp;DAT_001009b4,&amp;local_2c);
    local_28 = local_28 + local_2c;
    if (local_28 == 0x4b) {
      printf("Correct.");
      goto LAB_001008a0;
    }
    local_24 = local_24 + 1;
  } while( true );
}

inputan kita tadi pada function checkinput dinamakan lParm1. Kemudian lParm1 dicek panjangnya dengan fungsi strlen() lalu dimasukkan ke variable uVar1 , jika panjang uVar1 lebih besar dari uVar2 yang mana uVar2 sendiri di increment 1 setiap akhir looping ( local_24+=1 ) maka program akan mengeluarkan output Incorrect dan berhenti. Namun didalam proses looping terdapat pengecekan lain , yaitu pengecekan local_28 == 0x4b (75 dalam decimal) , local_28 sendiri adalah hasil penjumlahan dari local_2c (local_2c adalah setiap karakter pada lParm1 , *(undefined *)(lParm1 + (long)local_24) seperti array lParm1[0] dikarenakan looping pertama local_24 = 0 ) , jika pengecekan tersebut bernilai True maka akan memunculkan output Correct dan program akan berhenti .

Jadi disini kita hanya perlu memberikan input angka yang jika setiap digitnya dijumlah bernilai 75 , contoh : 999999993

Flag : 999999993

basic-pass-2 200 Pts

Diberikan sebuah file binary basic-pass-2-linux , disini saya coba untuk melakukan decompile dengan ghidra.

Hasil decompile fungsi main()

undefined8 main(int iParm1,undefined8 *puParm2)

{
  int iVar1;
  undefined8 uVar2;
  long in_FS_OFFSET;
  undefined8 uStack72;
  undefined8 uStack64;
  undefined8 uStack56;
  undefined8 uStack48;
  undefined8 uStack40;
  undefined4 uStack32;
  undefined uStack28;
  long lStack16;
  
  lStack16 = *(long *)(in_FS_OFFSET + 0x28);
  if (iParm1 == 2) {
    uStack72 = 0x2073692073696874;
    uStack64 = 0x6d206863756d2061;
    uStack56 = 0x756365732065726f;
    uStack48 = 0x7773736170206572;
    uStack40 = 0x742069202c64726f;
    uStack32 = 0x6b6e6968;
    uStack28 = 0;
    iVar1 = strcmp(puParm2[1],&amp;uStack72,&amp;uStack72);
    if (iVar1 == 0) {
      puts("Congrats! The key is bcactf{its_another_password}");
      uVar2 = 0;
    }
    else {
      puts("Incorrect passcode.");
      uVar2 = 1;
    }
  }
  else {
    fprintf(stderr,"Usage: %s <password>",*puParm2);
    uVar2 = 1;
  }
  if (lStack16 != *(long *)(in_FS_OFFSET + 0x28)) {
    uVar2 = __stack_chk_fail();
  }
  return uVar2;
}

Password kita disimpan dalam variable puParm2[1] yang mana dicocokkan dengan string this is a much more secure password, i think , yang merupakan value dari variable uStack32 - Ustack72 dengan fungsi strcmp. Disini kita dapat mengetahui flag secara langsung melalui hasil decompile atau dengan menjalankan program sebagai berikut.

./basic-pass-2-linux ‘this is a much more secure password, i thin

Flag : bcactf{its_another_password

basic-pass-3 200 Pts

Pertama kita coba jalankan nc challenges.ctfd.io 30133 , berikut hasilnya

Karena kita tahu format flagnya adalah bcactf{} maka saya coba menginputkan b saja , hasilnya seperti diatas.

Jadi program akan mengeluarkan angka 1 jika input kita cocok dengan karakter yang ada index tersebut. contohnya jika saya menginputkan b sebanyak 38 kali (sesuai panjang flag) maka akan keluar angka 1 di index yang karakternya b.

Jadi disini saya langsung membuat script automation untuk melakukan percobaan semua string yang printable lalu melakukan print terhadap flagnya.

import string
from pwn import *

length=38
flag=["" for i in range(length)]
r=remote('challenges.ctfd.io',30133)
for i in string.printable[:-5]:
  pl=i*length
  r.recvuntil('Enter the password.\n')
  r.sendline(pl)
  a= r.recvline()
  for j,k in enumerate(a[:-2]):
    if('1'==k):
      flag[j]=i
  print "".join(flag)

Flag : bcactf{y0u_4r3_4_m4573rm1nD!_Ym9vbGlu}

compression 200 Pts

Disini kita diberikan sebuah file yang bernama 999 , tanpa ekstensi . Namun kita dapat tahu file tersebut jenis apa dari command file di linux , jadi disini intinya kita tinggal memberikan ekstensi lalu extract ( atau langsung extract jika bisa ) , dan terdapat juga file hasil dari hexdump, kita dapat mengembalikannya dengan command berikut .

awk '{print $2,$3,$4,$5,$6,$7,$8,$9}' filehexdump > filebaru

Kemudian jika sudah kita kembalikan lagi menjadi file aslinya dengan command berikut.

xxd -r -p filebaru  > filebaru.extension

Jika sudah kita lakukan hal yang sama , yaitu extract dan extract sampai menemukan sebuah file dengan nama 000 yang berisi flag.

Flag : bcactf{A_l0t_0f_c0mPr3s510n}

Category : Web

the-inspector 50 Pts

Disini kita cukup melakukan inspect element sesuai dengan judul soal dan muncullah flagnya

Flag : bcactf{1nsp3ct_3l3m3nt}

wite-out 50 Pts

Terdapat sebuah string di bawah challenge description dengan warna yang sama dengan background dan string tersebut adalah flagnya

Flag : bcactf{17s_r1gh7_h3r3_1n_wh1t3_1397856}

dig-dug 100 Pts

Disini kita cukup jalankan command berikut untuk mencari dns record berupa TXT pada domain tersebut.

dig -t txt hole.sketchy.de

Flag : bcactf{d1g-f0r-h073s-w/-dns-8044323}

cookie-clicker 150 Pts

Berikut adalah tampilan ketika kita membuka link tersebut

Ketika kita melakukan klik pada cookies maka angka cookie tersebut akan bertambah 1,kemudian saya coba klik shop.

Dan ternyata kita membutuhkan sekian banyak cookies untuk dapat membeli flag,namun berdasarkan judulnya dapat kita ketahui bahwa soal ini berhubungan dengan cookie. Selanjutnya saya coba untuk membeli flag dan berikut hasilnya

Saya coba untuk mengamati http request yang dilakukan saat mengklik buy flag tadi.


Dan ternyata terdapat paramter cookies pada bagian cookie,dan saya ubah menjadi sejumlah yang dibutuhkan lalu coba untuk melakukan send kembali.

Berikut hasilnya

Flag : bcactf{c00k13s_c71ck3d_34a2344d}

Terima kasih telah membaca :)

rss facebook twitter github gitlab youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora