Tryhackme — Regular Expression (Bahasa Indonesia)

Alex
16 min readAug 3, 2023
Learn and practise using regular expressions

Kali ini, kita akan belajar regex (regular expression). Apa itu regex? Kenapa kita harus belajar regex? Gimana cara bikin regex? Tenang, itu semua akan kita ketahui setelah mulai belajar di room regex ini. Tapi, sebelum kita mulai, mari kita saksikan cuplikan video penggunaan regex oleh Elliot dari serial MrRobot ketika membuat exploit, berikut:

source: https://www.youtube.com/watch?v=67gYEK4FtzA

Oke, kita mulai masuk ke materi…

[SPOILER ALERT!]

Membaca WU ini berarti siap untuk membaca kunci jawaban!!! Resiko ditanggung pembaca!!!

Task 1 — Introduction

regex intro

Regex sederhananya adalah serangkaian karakter yang mendefinisikan sebuah pola pencarian (Wikipedia). Dengan regex, kita dapat memperoleh banyak string hanya dengan satu baris regex saja. Nah, jadi, regex sangat cocok digunakan untuk mereka yang “malas”, xixi.

Pada room ini, kita tidak perlu melakukan deploy machine karena kita akan menjawab soal-soal yang disediakan dengan bantuan website regexr.com. Sebenarnya, ada banyak website lain yang dapat digunakan untuk berlatih regex, misalnya regex101, regexlearn, regexone, dan lainnya. Tapi, saya akan gunakan regexr karena direkomendasikan pembuat room ini, hehe. Kira-kira, seperti ini penampakan website regexr.

regexr.com

Ada 2 bagian utama yang akan banyak kita gunakan di website regexr.com ini, yaitu bagian “Expression” dan “Text”. Pada bagian “Expression”, kita akan masukkan regex-nya, sementara di bagian “Text” akan berisi string yang akan dicocokkan oleh regex tersebut.

Nice! Biar makin paham, kita masuk ke task berikutnya.

Task 2 — Charset

When searching for a specific string in a file or block of text, you can search for it as is, with grep 'string' <file> . But what happens if you want to search for patterns of text? For example, you could be looking for a word that starts with a specific letter, or any words that end with numbers. That's where Regular Expressions come in.

Umumnya, ketika kita mencari string pada sebuah file, kita akan menggunakan perintah grep. Contohnya, saya ingin mencari string “wildan” dari file rockyou.txt. Maka, saya tinggal mengetikkan perintah berikut:

grep command

Pertanyaannya, bagaimana jika saya ingin mencari pola teks atau pola string? Misalnya, saya ingin mencari sebuah kata yang dimulai dengan huruf tertentu, atau misalnya sebuah kata yang memiliki akhiran angka. Nah, di sinilah fungsi regex diperlukan…

Both of the aforementioned problems can be solved by using charsets. A charset is defined by enclosing in [ square brackets ] the character(s), or range of characters that you want to match. Then, it finds every occurrence of the pattern you have defined in the file/text you are searching.

Permasalahan tadi dapat diselesaikan dengan charset. Charset atau character set dibuat dengan melampirkan karakter atau rentang karakter yang ingin kita cocokkan di dalam tanda kurung siku.

Contoh:

contoh charset
  1. [abc] akan match dengan setiap huruf a, b, dan c.
  2. [abc]zz akan match dengan azz, bzz, dan czz.
  3. Kita bisa menggunakan simbol dash (-) untuk membuat range. Artinya, [a-c]zz sama dengan [abc]zz.
  4. Kita juga dapat menggabungkan beberapa range. Misalnya, [a-cx-z]zz berarti akan match dengan azz, bzz, czz, xzz, yzz, dan zzz.
  5. Kita juga bisa menggunakan [A-Za-z] agar match dengan setiap karakter huruf alfabet, baik huruf kecil maupun huruf besar.
  6. Sampel lain, misalnya file[1-3] akan match dengan file1, file2, dan file3.
  7. Untuk mengecualikan atau meng-eksklud karakter tertentu, kita dapat menggunakan simbol hat di dalam kurung persegi. Jadi, [^k]ing akan match dengan ring, sing, $ing, 0ing, Bing, dan *ing lainnya, kecuali king.
  8. Kita tidak hanya dapat mengecualikan satu karakter saja, tapi juga bisa meng-eksklud range karakter. Jadi, [^a-c]at akan match dengan fat, hat, dan *at lainnya kecuali aat, bat, dan cat.
contoh charset 2

Beberapa catatan (penting):

  1. Jangan samakan string dan charset. Charset [abc] akan match dengan string abc, cba, dan ca. Jadi, bukan mencocokkan string, tapi setiap karakter yang terdapat pada string tersebut.
  2. Ketika menulis charset, kita harus mengetikan huruf-hurufnya sesuai dengan urutan yang muncul di soal. Intinya, jangan ngetik sesuatu yang benar tapi gak menjawab soal.
  3. Menjawab beberapa soal di room ini memang agak tricky. Jadi, kudu ngetik jawaban yang menjawab pertanyaan, gak hanya benar. Jawaban yang benar adalah regex yang paling efisien. Efisien dalam konteks ini berarti dua hal:

(a) Spesifik. Misalnya, kita bisa mencocokkan karakter dari a hingga c dengan charset [a-z]. Tapi, kalau yang diminta soal hanya a sampai c, kita cukup pake charset [a-c].

(b) Jangan terlalu spesifik. Misalnya, kalau soalnya minta untuk match karakter a, c, f, r, s, z, kita boleh menggunakan charset [a-z] saja. Sebab, kalau kita terlalu spesifik untuk bikin charset yang hanya cocok untuk karakter2 itu saja, nanti regex-nya akan terlalu panjang.

“Akan ada banyak solusi jawaban yang benar. Jadi, kalau kalian nanti nge-test jawaban kalian dan benar, tapi belum menjawab soal, istirahat dulu. Tida usah frustasi.”

  • Match all of the following characters: c, o, g
  • Match all of the following words: cat, fat, hat
  • Match all of the following words: Cat, cat, Hat, hat
  • Match all of the following filenames: File1, File2, file3, file4, file5, File7, file9
  • Match all of the filenames of question 4, except “File7” (use the hat symbol)

Task 3 — Wildcards and optional characters

wildcards and optional characters

Wildcard yang biasa digunakan untuk mencocokkan setiap karakter (kecuali baris baru atau enter) adalah tanda titik. Artinya, a.c akan cocok untuk aac, abc, a0c, a!c, dan seterusnya.

Kita juga dapat menentukan karakter opsional dalam regex dengan tanda tanya. Artinya, abc? akan match untuk ab dan abc, karena c-nya opsional.

Catatan: Kalau kita ingin menyertakan tanda titik sebagai karakter yang dicari, kita harus menyertakan tanda slash terbalik sebelum tanda titik di dalam regex. Artinya, a.c tidak hanya akan match dengan a.c saja, tapi juga dengan abc, a@c, dan seterusnya. Tapi, a\.c hanya akan match dengan a.c saja.

  • Match all of the following words: Cat, fat, hat, rat
  • Match all of the following words: Cat, cats
  • Match the following domain name: cat.xyz
  • Match all of the following domain names: cat.xyz, cats.xyz, hats.xyz
  • Match every 4-letter string that doesn’t end in any letter from n to z

Kita akan mengasumsikan 4 huruf dengan ****, tapi huruf terakhirnya bukan yang berakhiran n sampai z. Jadi, kita perlu membuat charset untuk persyaratan tersebut, sehingga charset-nya seperti ini ***[^n-z]. Sekarang, ketiga huruf di depannya bisa berupa huruf apapun yang diasumsikan dengan titik, sehingga jawabannya adalah …[^n-z].

Soal ini memang agak “imajinatif” karena kalau kita masukkan ke regexr charset-nya, memang gak 100% match dengan kriteria yang dipersyaratkan sebelumnya. Contohnya, saya akan buat 4 kata yang terdiri dari 4 huruf, yaitu Boaz, lack, geez, dan Roll yang akan dicocokkan dengan charset regex barusan.

hmmm…

Mungkin ini adalah salah satu bentuk soal yang disebut tadi sebagai “soal tricky”. Jadi, kalau kita mau menjawabnya dengan solusi yang benar, tentu …[^n-z] bukan jawaban yang paling tepat. Tapi, kita di sini mencari jawaban yang paling sesuai dengan yang diharapkan. Jadi, stay calm, stay cool, and proceed to the next question(s).

  • Match bat, bats, hat, hats, but not rat or rats (use the hat symbol)

Kita diberikan hint 8 karakter untuk menjawab soal ini. Kita diminta untuk menggunakan simbol hat untuk mengecualikan rat atau rats. Dari soal tersebut, kita juga tahu bahwa huruf s dibelakang kata-kata tersebut bersifat opsional. Oleh karena itu, jawaban yang paling sesuai dengan soal yang ditanyakan adalah sebagai berikut:

Task 4 — Metacharacters and repetitions

intro to metachar and repetition

Ada cara yang lebih mudah untuk handling charset yang lebih banyak. Misalnya, \d digunakan untuk me-match dengan setiap satu digit. Lengkapnya:

  1. \d digunakan untuk match sebuah karakter digit, contohnya 9.
  2. \D untuk match sebuah karakter non-digit, contohnya A atau @.
  3. \w untuk match dengan satu karakter alphanumeric (huruf dan angka), seperti a atau 3.
  4. \W untuk match dengan satu karakter non-alphanumeric, contohnya ! atau #.
  5. \s untuk match dengan satu karakter whitespace (spasi, tab, dan enter).
  6. \S untuk match dengan karakter apapun (karakter alphanumeric dan simbol).

Catatan: karakter underscore ( _ ) masuk pada metachar \w, bukan di \W. Artinya, \w akan match dengan setiap karakter di test_file.

underscore di \w, bukan \W
underscore di \w, bukan di \W

Kalau kita ingin agar regex charset dapat match untuk karakter yang berulang, kita dapat menggunakan tanda kurung kurawal. Contohnya, z{2} akan match untuk zz.

Berikut adalah referensi untuk tiap perulangan beserta berapa kali akan match dengan pola charset-nya.

  1. {12} artinya berulang tepat 12 kali.
  2. {1,5} artinya berulang 1 hingga 5 kali.
  3. {2,} artinya berulang 2 kali atau lebih.
  4. * artinya berulang 0 kali atau lebih.
  5. + artinya berulang 1 kali atau lebih.
  • Match the following word: catssss
  • Match all of the following words (use the * sign): Cat, cats, catsss

Sebagaimana di-mention sebelumnya, karakter * digunakan untuk perulangan karakter sebanyak 0 kali atau lebih. Charset [Cc]ats* artinya, kita akan melakukan pencocokan pada kata dengan awalan huruf c, baik c kapital atau c kecil, lalu dilanjut huruf ats, dimana huruf s ini bisa tidak ada atau ada banyak juga bisa.

  • Match all of the following sentences (use the + sign): regex go br, regex go brrrrrr

Pada soal ini, kita menggunakan tanda tambah +. Jadi, charset regex go br+ artinya kita akan mencocokkan string yang memuat regex go br, dimana huruf r-nya minimal ada satu, atau lebih dari satu.

  • Match all of the following filenames: ab0001, bb0000, abc1000, cba0110, c0000 (don’t use a metacharacter)

Jika kita perhatikan, ada 4 angka (nol dan satu) di setiap akhir filename tersebut. Di depannya, ada 1 hingga 3 huruf kecil (a, b, dan c). Untuk menjawab soal ini, kita dilarang menggunakan metachar.

Saya akan coba jawab soal ini dari belakang. Jadi, untuk mendapatkan 4 karakter angka nol dan satu itu, maka charset yang saya perlukan adalah [01]{4}. Selanjutnya, tinggal menambahkan huruf a, b, c di depannya. Jadi, charset yang diperlukan adalah [abc]. Terakhir, karena jumlah huruf pada setiap filename berbeda (ada yang 1 huruf saja, ada yang dua, ada yang tiga), maka kita tinggal memberikan charset perulangan agar dapat match dengan setiap filename, yaitu {1–3}.

Beginilah hasilnya:

  • Match all of the following filenames: File01, File2, file12, File20, File99

Saya kira soal ini lebih mudah dibanding soal sebelumnya karena kita tidak dilarang menggunakan metachar. Alurnya, kita akan mulai regex-nya dengan huruf F, kapital ataupun kecil, jadi kita perlu charset [Ff]. Setelahnya, tambahkan huruf ‘ile’. Kemudian, kita akan menambahkan metachar digit \d sehingga jika digabungkan, charset-nya adalah [Ff]ile\d.

Tapi, kita juga sadar bahwa tidak semua filename memiliki 2 digit angka di belakangnya, tapi ada juga yang hanya satu. Artinya, kita perlu perulangan digit agar filename dengan minimal satu digit angka di akhir bisa ikut terseleksi. Jadi, lagi-lagi, kita dapat menambahkan tanda perulangan + sebagai penutup regex-nya.

  • Match all of the following folder names: kali tools, kali tools

Jika diperhatikan soal aslinya, sebenarnya dua rangkaian kata tersebut sama persis. Yang membedakan adalah jumlah spasinya. Jika rangkaian kata pertama hanya memiliki satu spasi, rangkaian kata yang kedua memiliki lima spasi. Apa regex yang tepat agar keduanya dapat terseleksi?

Sebagai contoh eksperimen, kalau saya hanya mengetikkan string ‘kali tools’ saja, maka hanya rangkaian kata pertama saja yang terpilih, yang kedua tidak.

Atau sebaliknya, kalau saya tambahkan jumlah spasinya hingga lima, maka hanya rangkaian kata kedua saja yang match, yang pertama tidak.

Jadi, kita dapat memanfaatkan metachar yang memang dirancang untuk meng-handle karakter whitespace seperti spasi, tab, dan enter, yaitu \s. Kita hanya perlu menambahkan metachar \s diantara kata ‘kali’ dan ‘tools’ seperti ini:

Berikutnya, kita perlu perulangan agar dapat mendeteksi jumlah karakter spasi-nya. Artinya, kita membutuhkan bantuan perulangan +. Akhirnya, regex lengkapnya adalah sebagai berikut:

  • Match all of the following filenames: notes~, stuff@, gtfob#, lmaoo!

Terlihat makin sulit? Kuncinya tenang, jangan panik.

Perhatikan baik-baik! Empat string tersebut punya dua hal konsisten, yaitu 5 karakter pertamanya berupa abjad huruf kecil semua. Baru setelahnya, ada satu karakter unik pada masing-masing string, ada tilde (~), ada at (@), ada tagar (#), dan ada tanda seru (!).

Lagi-lagi, penggunaan metachar akan sangat membantu kita.

Pertama, kita akan menggunakan metachar \w untuk menyeleksi huruf di awal. Tapi, karena ada lima huruf yang akan diseleksi, kita harus menambahkan perulangan sebanyak lima kali setelahnya, sehingga charset-nya adalah \w{5}.

Kedua, agar karakter unik tadi juga bisa ikut terseleksi, kita boleh menggunakan metachar \W yang memang berfungsi untuk menyeleksi karakter non-alphanumeric seperti tagar dkk tadi.

  • Match the string in quotes (use the * sign and the \s, \S metacharacters): “2f0h@f0j0%! a)K!F49h!FFOK”

Di soal ini, kita diminta untuk menyeleksi kumpulan karakter random pertama yang dipisahkan oleh 5 spasi dengan kumpulan karakter random kedua berikut:

Di soal, kita juga diminta untuk menggunakan dua metachar dan satu tanda perulangan, yaitu \s, \S, dan *.

Mudah, kumpulan karakter random bagian pertama akan kita seleksi dengan metachar \S dan tanda perulangan *. Kemudian, 5 spasi tersebut akan kita seleksi dengan metachar \s dan tanda perulangan *. Terakhir, kita kembali akan menyeleksi random karakter bagian kedua dengan metachar \S dan tanda perulangan *.

Ingat! Jika kalian berpikir ada charset yang lebih tepat dari charset regex ini, mungkin kalian benar. Tapi, tujuan kita di sini bukan mencari charset yang paling benar saja, tapi charset yang paling sesuai dengan jawaban yang diharapkan di room ini!

  • Match every 9-character string (with letters, numbers, and symbols) that doesn’t end in a “!” sign

Mari kita coba buatkan contoh 2 string yang memenuhi kriteria tersebut dan 1 string yang menyalahi kriteria tersebut. 2 string pertama adalah Asoka128_ dan #antiLGBT. Adapun 1 string lainnya adalah capekbun!.

Berdasarkan permintaan soal, kita hanya akan mengambil 2 string pertama saja. Adapun string capekbun! tidak akan kita seleksi karena berakhiran tanda seru.

Bagaimana caranya?

Pertama, kita akan gunakan metachar \S untuk menyeleksi karakter apapun (alphanumeric dan symbol) yang ada di dalam string. Selanjutnya, kita memerlukan perulangan karakter tersebut sebanyak 8 kali. Kenapa 8 kali? Karena nanti kita perlu membuat rule sendiri untuk karakter ke-9, kan? Yepp…, jadi, regex sementaranya adalah \S{8}.

Kedua, karakter kesembilan harus kita berikan aturan khusus, yaitu bukan tanda seru. Sehingga, untuk meng-eksklud tanda seru, kita bisa menggunakan charset [^!]. Simple!

Kalau digabung, jadinya seperti ini, deh:

  • Match all of these filenames (use the + symbol): .bash_rc, .unnecessarily_long_filename, and note1

Kita diminta untuk pake simbol perulangan + untuk menyeleksi ketiga filename tersebut. Oke!

Langkah pertama, kita akan menyeleksi titik di awal filename dengan \..

Kedua, kita akan menyeleksi setiap huruf setelah titik tersebut dengan metachar dan perulangan, \w+.

Ketiga, kita perlu sadari bahwa ada filename yang tidak dimulai dengan titik. Oleh karena itu, titik tersebut bisa kita anggap opsional. so, kita tinggal menambahkan tanda tanya setelah titik. Sehingga, hasil akhir regex-nya adalah sebagai berikut:

Note: Untuk menyeleksi titik di filename, kenapa kita perlu menambahkan reverse backslash sebelumnya? Kenapa tidak langsung titik saja? Tentu saja karena jika kita menginputkan titik saja, artinya, alih-alih menyeleksi titik, kita menyeleksi semua karakter yang ada (coba lihat kembali Task 1). Oleh karena itu, kita perlu memberikan reverse backslash sebelum tanda titik untuk menyeleksinya.

Task 5 — Starts with / ends with, groups, and either / or

intro to Task 5

Terkadang, kita dapat men-spesifikkan pencarian kita dengan menentukan permulaan dan akhir sebuah baris. Kita melakukan hal tersebut dengan dua karakter, yaitu simbol hat ( ^ ) untuk men-spesifikkan awal string dan simbol dolar ( $ ) untuk akhir string.

Jadi, misalnya kita ingin mencari baris yang dimulai dengan abc, kita dapat menemukannya dengan menulis regex ^abc. Atau kalau kita ingin mencari suatu baris yang berakhiran xyz, kita dapat mengetikkan regex xyz$.

Catatan: simbol hat ( ^ ) digunakan untuk meng-eksklud atau mengecualikan charset ketika berada dalam kurung siku, [^]. Adapun jika di luar kurung siku, simbol hat tersebut berfungsi untuk mencari awal baris.

Kita dapat membuat grup dengan memasukkan suatu pola dalam tanda kurung. Grup-ing ini dapat berfungsi untuk menyeleksi charset “either / or” dan juga mengulang suatu pola. Contohnya, pola (no){5} akan match untuk nonononono.

Dalam regex, kita dapat menggunakan tanda pipe ( | ) untuk mengatakan “atau”.

  • Match every string that starts with “Password:” followed by any 10 characters excluding “0”

Misalkan, saya punya 2 string yang memenuhi kriteria soal tersebut dan 1 string yang tidak sesuai kriteria, yaitu Password:1234567891, Password:GANTI!@lol, dan Password:#$apasi018.

Bagaimana caranya akan regex kita hanya menyeleksi string pertama dan kedua saja?

Pertama, kita akan seleksi string Password:.

Kedua, kita akan meng-eksklud 0 dari string dengan charset [^0].

Ketiga, kita akan mengulang karakter tersebut sebanyak 10 kali, sehingga kita hanya perlu menambahkan perulangan {10}.

  • Match “username: “ in the beginning of a line (note the space!)

Mudah,

  • Match every line that doesn’t start with a digit (use a metacharacter)

Juga mudah, ^\D

  • Match this string at the end of a line: EOF$
  • Match all of the following sentences:

I use nano

I use vim

  • Match all lines that start with $, followed by any single digit,
    followed by $, followed by one or more non-whitespace characters

Coba kita visualisasikan kriteria soal ini dengan beberapa contoh…

$3$iniAdalahHASHpwd, $9$NTLMv2HASH, $0$salah

Mungkin kita akan terkecoh dengan kata-kata “dimulai dengan” seperti yang tertulis di soal. Sehingga, sepertinya kita perlu memulai regex dengan simbol hat ( ^ ). Padahal, kalau kita gak overthinking, kita punya banyak alternatif jawaban. Misalnya,

Dimulai dengan dolar, \$.

Diikuti dengan sebuah digit angka, \d.

Diikuti lagi dengan dolar, \$.

Dan diikuti lagi dengan satu atau lebih karakter non-whitespace, \S+.

  • Match every possible IPv4 IP address (use metacharacters and groups)

Sebagai contoh, kita punya empat sampel IPv4, yaitu 192.168.20.56, 10.81.9.2, 79.23.44.8, 8.8.8.8.

Untuk menyeleksi keempat IPv4 tersebut, kita akan gunakan metachar dan group-ing.

Kita tahu bahwa IPv4 terdiri atas 4 oktet, dimana setiap oktet diakhiri oleh titik, kecuali yang terakhir. Masing-masing oktet terdiri dari 1 hingga 3 digit angka. Artinya, kita dapat melakukan group-ing untuk menyeleksi tiga oktet pertama dari setiap IPv4 tersebut.

Terakhir, kita perlu menambahkan regex lagi untuk menyeleksi sisa digit di belakangnya.

Soal terakhir ini mengharuskan kita untuk menggunakan metachar \w. Kita juga hanya perlu membuat regex untuk username dan domain-nya saja karena TLD-nya cukup kita tulis manual (.com) nanti di akhir. Jangan lupa gunakan group-ing.

Di sini, saya akan membentuk 2 group, pertama, group untuk username dan group untuk domain. Jika melihat format jawaban yang ada di kolom jawaban, kita disediakan 12 karakter untuk membuat regex sebelum .com. Jadi, berdasarkan hint tersebut, regex kita tidak boleh kurang atau lebih dari 12 karakter.

Beberapa susunan regex yang saya coba sebenarnya match dengan ketiga email tersebut. Tapi, sebenar-benarnya regex, kalau dia tidak bisa menjawab soal di room ini, maka regex itu bukan yang paling benar :”.

Beberapa regex yang match:

Perhatikan! jumlah karakter sebelum ‘.com’ juga sudah 12 karakter. wkwk

Tapi, setelah beberapa kali mencoba kemungkinan jawaban, jawaban yang paling sesuai adalah sebagai berikut:

Jawaban ini muncul ketika saya akhirnya terpikir untuk menambahkan reverse backslash sebelum titik karena saya teringat dengan pelajaran di Task 3. Konsekuensinya, karena tanda reverse backslash-nya saya pindah ke sebelum titik, maka simbol at ( @ )-nya jadi tidak pakai reverse backslash. Lho, kenapa? Ya, jelas, supaya karaker regex-nya tetap konsisten 12 karakter…

Yang baru saya sadari adalah kenapa saya harus meletakkan reverse backslash sebelum simbol at di percobaan-percobaan sebelumnya? wkwkw, agak kocak kalau dipikir-pikir…

Okehh, sekian untuk pembelajaran kita kali ini tentang regex. Intinya, tidak ada regex yang salah. Maksudnya, regex yang salah hanyalah regex yang tidak bisa membantu kita memperoleh hasil pencarian string yang diinginkan. Selagi regex tersebut bisa match dengan apa yang kita cari/butuhkan, regex itu tetaplah benar. Prinsipnya 2: be spesific & don’t be too spesific.

See you guys,,..

elliot

--

--

Alex

A college student. A writer. Cyber security enthusiast.