<h1 id="Hack-The-Box">Hack The Box - Reversing (Very Easy)</h1>

Ghi chú:
<ul>
<li>Very Easy: 1-5 challenge</li>
<ul>
<li><a href="#WIDE">1. WIDE</a></li>
<li><a href="#Hunting License">2. Hunting License</a></li>
<li><a href="#Shattered Tablet">3. Shattered Tablet</a></li>
<li><a href="#Behind the Scenes">4. Behind the Scenes</a></li>
<li><a href="#Simple Encryptor">5. Simple Encryptor</a></li>
<li><a href="#FlagCasino">6. FlagCasino</a></li>
</ul>
</li>
</ul>
<h2>Difficulty: Very Easy </h2>
<div id="WIDE"></div>
<h3>Challenge 1: WIDE</h3>
We've received reports that Draeger has stashed a huge arsenal in the pocket dimension Flaggle Alpha. You've managed to smuggle a discarded access terminal to the Widely Inflated Dimension Editor from his headquarters, but the entry for the dimension has been encrypted. Can you make it inside and take control?
<a href="https://drive.google.com/file/d/16wHcK7TdeqydI2la9nrY-zpf0bwYlwpl/view?usp=drive_link">Download Challenge Here</a>
<h3>Solution</h3>
Chúng ta có thể sử dụng lệnh 'file' để cung cấp cái nhìn tổng quan về loại tệp. Sử dụng tùy chọn ký tự đại diện “*” sẽ cho phép chúng ta xem thông tin file của tất cả các file trong thư mục:

Có vẻ như 'wide', là một tệp thực thi ELF, vì vậy hãy thử chạy nó để xem liệu chúng tôi có thể lấy thêm thông tin nào không:

Nó gợi ý ta cần sử dụng tệp “db.ex” làm tham số.

Nếu chúng ta nhập ký tự [az/AZ/0] thì chúng ta sẽ không nhận được gì. Ngoài ra, nếu chúng tôi nhập một số lớn hơn 6, chúng tôi sẽ nhận được tùy chọn không hợp lệ.


Nhập [1-6], chúng ta có manh mối thú vị

Mở chương trình trong IDA

Chương trình yêu cầu đưa tệp `db.ex` làm tham số và thông báo một số lỗi phát sinh . Chức năng này cũng bao gồm các câu lệnh in cho giao diện menu CLI, liệt kê các mục.
Chương trình thực hiện tính toán rất nhiều. Nhưng không có gì quan trọng vì giá trị đó không bao giờ thay đổi. Chỉ cần bỏ qua nó và xem cuối chương trình, ta thấy hàm `menu`.

Nó so sánh giá trị đầu vào là `sup3rs3cr3tw1d3` . Nếu đúng thì in flag.
:::success
```
Flag: HTB{som3_str1ng5_4r3_w1d3}
```
:::
<div id="Hunting License"></div>
<h3>Challenge 2: Hunting License</h3>
STOP! Adventurer, have you got an up to date relic hunting license? If you don't, you'll need to take the exam again before you'll be allowed passage into the spacelanes!
<a href="https://drive.google.com/file/d/1S00iHD9gMKItQ7FnOE8rop9uTNreAepL/view?usp=drive_link">Download Challenge Here</a>
<h3>Solution</h3>
Chúng ta có thể sử dụng lệnh 'file' để cung cấp cái nhìn tổng quan về loại tệp.

Chúng ta có thể sử dụng lệnh 'ldd' để in các phần phụ thuộc của thư viện dùng chung.

Mở chương trình trong IDA.

Chương trình yêu cầu chúng ta nhập: “y” hoặc “Y” hoặc “\n” để tiếp tục. Ta sẽ kiểm tra nội dung của hàm `exam`.

* Mật khẩu đầu tiên: `NumeroUno`
* Dạng đảo ngược của mật khẩu thứ hai. Mật khẩu thứ hai: `P4ssw0rdTw0`
* `cipher_text ^ 0x13` để lấy mật khẩu thứ ba. Mật khẩu thứ ba: `ThirdAndFinal!!!`
Bây giờ chúng ta có thể bắt đầu làm việc trên dịch vụ từ xa.

:::success
```
Flag: HTB{l1c3ns3_4cquir3d-hunt1ng_t1m3!}
```
:::
<div id="Shattered Tablet"></div>
<h3>Challenge 3: Shattered Tablet</h3>
We've received reports that Draeger has stashed a huge arsenal in the pocket dimension Flaggle Alpha. You've managed to smuggle a discarded access terminal to the Widely Inflated Dimension Editor from his headquarters, but the entry for the dimension has been encrypted. Can you make it inside and take control?
<a href="https://drive.google.com/file/d/1xBjT0M2zNA0lb7o_qdgcbTfyZSblBloE/view?usp=sharing">Download Challenge Here</a>
<h3>Solution</h3>
Chúng ta có thể sử dụng lệnh 'file' để cung cấp cái nhìn tổng quan về loại tệp.

Mở chương trình trong IDA

Thật dễ dàng để biết rằng chương trình kiểm tra từng đầu vào một. Tôi không muốn làm thủ công nên tôi đã viết đoạn IDAPython script.
:::info
```python
from capstone import *
from capstone.x86 import *
import re
import time
def is_pattern(instructions):
# movzx eax, byte ptr [rbp - 0x2f]
curr = instructions[0]
inst = f"{curr.mnemonic} {curr.op_str}"
if not re.match(r"movzx eax, byte ptr \[rbp - 0x([0-9a-f])*\]", inst): return False
offset = (re.search(r'\b0x[0-9a-fA-F]+\b', inst).group())
# cmp al, 0x54
curr = instructions[1]
inst = f"{curr.mnemonic} {curr.op_str}"
if not re.match(r"cmp al, 0x([0-9a-f])*", inst): return False
value = int((re.search(r'\b0x[0-9a-fA-F]+\b', inst).group()),16)
dictionary[offset] = value
return True
file_data = None
with open("tablet", "rb") as fp:
file_data = bytearray(fp.read())
main_start_addr = 0x1155
main_end_addr = 0x138A
main_code = file_data[main_start_addr:main_end_addr]
dis_engine = Cs(CS_ARCH_X86, CS_MODE_64)
dis_engine.detail = True
disassembly = []
dictionary = {}
for item in dis_engine.disasm(main_code, main_start_addr):
disassembly.append(item)
for i in range(len(disassembly) - 2):
disasm = []
for j in range(2):
disasm.append(disassembly[i + j])
is_pattern(disasm)
flag = "".join([chr(dictionary[key]) for key in sorted(dictionary.keys(), reverse=True)])
print(flag)
```
:::
Bạn cũng có thể thay đổi kiểu dữ liệu từ `char s[8]` thành `char s[64]`.

:::success
```
Flag: HTB{br0k3n_4p4rt...n3ver_t0_b3_r3p41r3d}
```
:::
<div id="Behind the Scenes"></div>
<h3>Challenge 4: Behind the Scenes</h3>
After struggling to secure our secret strings for a long time, we finally figured out the solution to our problem: Make decompilation harder. It should now be impossible to figure out how our programs work!
<a href="https://drive.google.com/file/d/1Bgny4TCVf-CEYnVyC51bjARcx48YWdBU/view?usp=drive_link">Download Challenge Here</a>
<h3>Solution</h3>
Chúng ta có thể sử dụng lệnh 'file' để cung cấp cái nhìn tổng quan về loại tệp.

Mở chương trình trong IDA

Lúc đầu giả mã bị sai do lệnh ud2 - đây là một `invalid opcode`.

Tôi quyết định viết các tập lệnh IDAPython vào NOP tất cả các mã opcode không hợp lệ.
:::info
```python
import ida_bytes
start = 0x1000
end = 0x14B5
for i in range(start, end):
tmp1 = ida_bytes.get_byte(i)
tmp2 = ida_bytes.get_byte(i+1)
if tmp1 == 0x0F and tmp2 == 0x0B:
ida_bytes.patch_byte(i, 0x90)
ida_bytes.patch_byte(i+1, 0x90)
```
:::
Mã giả trông rất đẹp!! Bây giờ nó dễ đọc.

Nó kiểm tra độ dài tham số của chúng tôi là 12 và có là <b>Itz_0nLy_UD2</b>
:::success
```
Flag: HTB{Itz_0nLy_UD2}
```
:::
<div id="Simple Encryptor"></div>
<h3>Challenge 5: Simple Encryptor</h3>
On our regular checkups of our secret flag storage server we found out that we were hit by ransomware! The original flag data is nowhere to be found, but luckily we not only have the encrypted file but also the encryption program itself.
<a href="https://drive.google.com/file/d/1-xUNHvtdpB2dN5wJHOp_M8dLH_52-UP9/view?usp=drive_link">Download Challenge Here</a>
<h3>Solution</h3>
Chúng ta có thể sử dụng lệnh 'file' để cung cấp cái nhìn tổng quan về loại tệp. Sử dụng tùy chọn ký tự đại diện “*” sẽ cho phép chúng ta xem thông tin file của tất cả các file trong thư mục:

Mở chương trình trong IDA

Cơ chế tạo số ngẫu nhiên trong C dựa trên các thuật toán tạo số ngẫu nhiên. Đây là một thuật toán xác định tạo ra một chuỗi số có vẻ ngẫu nhiên, nhưng thực tế được xác định bởi một giá trị bắt đầu được gọi là `seed`. Cùng một `seed`, ta có thể sinh ra một bộ số ngẫu nhiên giống nhau.
Chương trình thực hiện như sau, anh chia nó thành 2 giai đoạn, thao tác với tệp và mã hóa dữ liệu tệp:
- stream = fopen("flag", "rb"): Mở tệp có tên "flag" ở chế độ đọc nhị phân.
- fseek(stream, 0LL, 2);: Di chuyển đến cuối tệp để xác định kích thước của nó.
- size = ftell(stream): Lấy kích thước tệp.
- fseek(stream, 0LL, 0): Đặt con trỏ tệp về đầu.
- ptr = malloc(size): Cấp phát bộ nhớ để chứa nội dung tệp.
- fread(ptr, size, 1uLL, stream): Đọc toàn bộ tệp vào bộ nhớ được cấp phát.
- fclose(stream): Đóng tệp.
==================================================
Thuật toán __ROL1__ được mô tả như sau
:::info
```cpp
inline uint8 __ROL1__(uint8 value, int count) { return __ROL__((uint8)value, count); }
template<class T> T __ROL__(T value, int count)
{
const uint nbits = sizeof(T) * 8;
if ( count > 0 )
{
count %= nbits;
T high = value >> (nbits - count);
if ( T(-1) < 0 ) // signed value
high &= ~((T(-1) << count));
value <<= count;
value |= high;
}
else
{
count = -count % nbits;
T low = value << (nbits - count);
value >>= count;
value |= low;
}
return value;
}
```
:::
- Tạo seed bằng hàm time(0), seed này sẽ được ghi vào file với 4 byte.
- Mã hóa từng kí tự của flag bằng cách: __ROL1__(flag[i] ^ rand_1(),rand_2() & 7)
<b><i>Quan trọng: Hàm C rand() hoạt động khác nhau trên Windows so với Linux. Bạn sẽ không nhận được kết quả tương tự do việc triển khai các chức năng khác nhau trên một trong hai nền tảng.</i></b>
Bây giờ là lúc để khai thác nó. Tôi biên dịch mã của mình bằng kali. Nếu bạn biên dịch trong Window10/11, nó sẽ không chạy chính xác.
:::info
```cpp
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
int main()
{
uint8_t rand1, rand2, x, size;
FILE *fp;
int seed; // 1655780698
uint8_t flag[29]; // +1 for null terminator
flag[28] = '\0'; // Null-terminate the flag string
fp = fopen("flag.enc", "rb");
fread(&seed, 4, 1, fp);
fread(&flag, 1, 28, fp);
srand(seed);
for(int i = 0; i < 28; i++){
rand1 = rand();
rand2 = rand() & 7;
flag[i] = (flag[i]>>rand2 | flag[i]<<8-rand2) ^ (rand1);
}
printf("%s\n",flag);
fclose(fp);
}
```
:::
:::success
```
Flag: HTB{vRy_s1MplE_F1LE3nCryp0r}
```
:::
<div id="FlagCasino"></div>
<h3>Challenge 6: FlagCasino</h3>
The team stumbles into a long-abandoned casino. As you enter, the lights and music whir to life, and a staff of robots begin moving around and offering games, while skeletons of prewar patrons are slumped at slot machines. A robotic dealer waves you over and promises great wealth if you can win - can you beat the house and gather funds for the mission?
<a href="https://drive.google.com/file/d/1Ff6JwgdTYRdV4rXjZJ7oFrtPD7PzCOix/view?usp=sharing">Download Challenge Here</a>
<h3>Solution</h3>
Mở chương trình trong IDA. Chương trình thực hiện vòng lặp, yêu cầu ta nhập số làm seed. Mục đích để tạo số giả ngẫu nhiên bàng với giá trị cần so sánh.

Mình dự đoán được giá trị nhập vào là từng kí tự của flag. Ta sẽ vét cạn giá trị này.
:::info
```cpp
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
int main() {
int check[30] = {
0x244B28BE, 0x0AF77805, 0x110DFC17, 0x07AFC3A1, 0x6AFEC533, 0x4ED659A2, 0x33C5D4B0, 0x286582B8,
0x43383720, 0x055A14FC, 0x19195F9F, 0x43383720, 0x19195F9F, 0x747C9C5E, 0x0F3DA237, 0x615AB299,
0x6AFEC533, 0x43383720, 0x0F3DA237, 0x6AFEC533, 0x615AB299, 0x286582B8, 0x055A14FC, 0x3AE44994,
0x06D7DFE9, 0x4ED659A2, 0x0CCD4ACD, 0x57D8ED64, 0x615AB299, 0x22E9BC2A
};
char flag[31];
flag[0] = '\0';
for (int i = 0; i < 30; ++i) {
for (int seed = 0x20; seed <= 0x7F; ++seed) {
srand(seed);
int rand_value = rand();
if (rand_value == check[i]) {
char ch = (char)seed;
int len = strlen(flag);
flag[len] = ch;
flag[len + 1] = '\0';
break;
}
}
}
printf("Flag: %s\n", flag);
return 0;
}
```
:::
:::success
```
Flag: HTB{r4nd_1s_sup3r_pr3d1ct4bl3}
```
:::