Selam millet! Bu yazımda HackTheBox platformunda bulunan "Flag Command" isimli meydan okumanın çözümünü göstereceğim. Çözümü çok kolay olmakla birlikte küçük bir de hikayesi bulunuyor.
Arkadaşlarımızla dışarıya çıktığımız sırada onlardan koparak kendimizi ormanın en ücra köşesinde buluyoruz. Ağaçların gün ışığını engellediği bu ormanda yönümüzü bulmaya çalışırken çalılıkların ardında, insanı andıran sıska bir varlık olduğunu fark ediyoruz. Bu varlık, yorgun düşmemizi bekliyormuş gibi hafifçe sırıtarak bizi izliyor. Amacımız, hava daha fazla kararmadan yönümüzü bulup bu ormandan çıkmaktır.
Gördüğünüz üzere web uygulamasında terminal benzeri bir şey bulunuyor. Start komutunu kullanarak oyuna başlayabiliriz ama önce sayfanın kaynak kodlarına bakmak istedim ve oyunun javascript ile yapıldığını öğrendim.
Bu durumda oyunu oynamadan sadece Javascript kodlarını okuyarak çözebilmemiz gerekiyor. Kodları anlayabilmek için herhangi bir programlama dilini bilmek yeterli olacaktır.
Öncelikle main.js dosyasındaki startCommander() fonksiyonunun çalıştırıldığını görüyoruz. Bu fonksiyon içerisinde de fetchOptions() fonksiyonunu çalıştırılıyor.
fetchOptions() fonksiyonu ise /api/options adresine GET methoduyla bir HTTP isteği gönderiyor.
/api/options adresine gittiğimizde ise daha fazla komut ile karşılaşıyoruz.
Start komutunu kullandıktan sonra buradaki komutları yerine göre çalıştırabiliyoruz. Sırasıyla sorulan sorulara karşılık gelen komutlar tabi. Secret değişkeninde ki komut diğerlerinden farklı görünüyor. Diğerleri sırasına uygun isim alırken onun ismi bir STR ifade. Bu bilgiden yola çıkarak komutun bir sıra gerekmeksizin çalıştırılabildiğini tahmin edebiliriz.
Gönderilen komutlar, /api/monitor adresinden teyit edildiği için kaynak koduna bakarak bayrağı bulamayız. Bu durumda komutu uygulamada çalıştırmamız gerekiyor. Komutu kullanmadan önce "start" komutunu kullanıp oyunu başlatalım. Daha sonra ise bahsettiğim komutu girdiğimizde bayrağa ulaşıyor ve oyunu kazanıyoruz.
Söylediğim gibi çok basit bir meydan okumaydı. Yazılan kodları okuyamasak bile geliştirici ayarlarını açıp sayfayı yenileseydik aynı şekilde komutu öğrenip kolayca bayrağa ulaşabilirdik.
Arkadaşlarımızla dışarıya çıktığımız sırada onlardan koparak kendimizi ormanın en ücra köşesinde buluyoruz. Ağaçların gün ışığını engellediği bu ormanda yönümüzü bulmaya çalışırken çalılıkların ardında, insanı andıran sıska bir varlık olduğunu fark ediyoruz. Bu varlık, yorgun düşmemizi bekliyormuş gibi hafifçe sırıtarak bizi izliyor. Amacımız, hava daha fazla kararmadan yönümüzü bulup bu ormandan çıkmaktır.
Gördüğünüz üzere web uygulamasında terminal benzeri bir şey bulunuyor. Start komutunu kullanarak oyuna başlayabiliriz ama önce sayfanın kaynak kodlarına bakmak istedim ve oyunun javascript ile yapıldığını öğrendim.
JavaScript:
<script src="/static/terminal/js/commands.js" type="module"></script>
<script src="/static/terminal/js/main.js" type="module"></script>
<script src="/static/terminal/js/game.js" type="module"></script>
<script type="module">
import { startCommander, enterKey, userTextInput } from "/static/terminal/js/main.js";
startCommander();
window.addEventListener("keyup", enterKey);
// event listener for clicking on the terminal
document.addEventListener("click", function () {
userTextInput.focus();
});
</script>
Bu durumda oyunu oynamadan sadece Javascript kodlarını okuyarak çözebilmemiz gerekiyor. Kodları anlayabilmek için herhangi bir programlama dilini bilmek yeterli olacaktır.
JavaScript:
import { startCommander, enterKey, userTextInput } from "/static/terminal/js/main.js";
startCommander();
window.addEventListener("keyup", enterKey);
// event listener for clicking on the terminal
document.addEventListener("click", function () {
userTextInput.focus();
});
Öncelikle main.js dosyasındaki startCommander() fonksiyonunun çalıştırıldığını görüyoruz. Bu fonksiyon içerisinde de fetchOptions() fonksiyonunu çalıştırılıyor.
JavaScript:
export const startCommander = async () => {
await fetchOptions();
userTextInput.value = "";
commandText.innerHTML = userTextInput.value;
await displayLinesInTerminal({ lines: INFO });
userTextInput.focus();
};
fetchOptions() fonksiyonu ise /api/options adresine GET methoduyla bir HTTP isteği gönderiyor.
JavaScript:
const fetchOptions = () => {
fetch('/api/options')
.then((data) => data.json())
.then((res) => {
availableOptions = res.allPossibleCommands;
})
.catch(() => {
availableOptions = undefined;
})
}
/api/options adresine gittiğimizde ise daha fazla komut ile karşılaşıyoruz.
Start komutunu kullandıktan sonra buradaki komutları yerine göre çalıştırabiliyoruz. Sırasıyla sorulan sorulara karşılık gelen komutlar tabi. Secret değişkeninde ki komut diğerlerinden farklı görünüyor. Diğerleri sırasına uygun isim alırken onun ismi bir STR ifade. Bu bilgiden yola çıkarak komutun bir sıra gerekmeksizin çalıştırılabildiğini tahmin edebiliriz.
Gönderilen komutlar, /api/monitor adresinden teyit edildiği için kaynak koduna bakarak bayrağı bulamayız. Bu durumda komutu uygulamada çalıştırmamız gerekiyor. Komutu kullanmadan önce "start" komutunu kullanıp oyunu başlatalım. Daha sonra ise bahsettiğim komutu girdiğimizde bayrağa ulaşıyor ve oyunu kazanıyoruz.
Söylediğim gibi çok basit bir meydan okumaydı. Yazılan kodları okuyamasak bile geliştirici ayarlarını açıp sayfayı yenileseydik aynı şekilde komutu öğrenip kolayca bayrağa ulaşabilirdik.


