Post

FEAT:๐Ÿšฉ HTBใ€ŒExatlonใ€Easy

Easy, Linux, Rev, UPX

FEAT:๐Ÿšฉ HTBใ€ŒExatlonใ€Easy

stringsใฎ็ตๆžœใ‹ใ‚‰๏ผŒUPX 3.95 ใซใ‚ˆใฃใฆใƒ‘ใƒƒใ‚ฏใ•ใ‚Œใฆใ„ใ‚‹ใ“ใจใŒใ‚ใ‹ใ‚Šใพใ—ใŸ๏ผŽupxใ‚ณใƒžใƒณใƒ‰ใงใ‚ขใƒณใƒ‘ใƒƒใ‚ฏใ—ใฆใŠใใพใ™๏ผŽ

Surface Analysis

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ file exatlon_v1
exatlon_v1: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, no section header

$ checksec --file=exatlon_v1
[*] '/home/sl91994/wksp/sec/ctf/htb/challenges/rev/rev_easy_exatlon/exatlon_v1'
    Arch:       amd64-64-little
    RELRO:      No RELRO
    Stack:      No canary found
    NX:         NX enabled
    PIE:        No PIE (0x400000)
    Packer:     Packed with UPX
    
$ upx -d -o exatlon_v1_unpacked ./exatlon_v1
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2026
UPX 5.1.0       Markus Oberhumer, Laszlo Molnar & John Reiser    Jan 7th 2026

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
   2202568 <-    709524   32.21%   linux/amd64   exatlon_v1_unpacked

Unpacked 1 file.

$ objdump -d -M intel ./exatlon_v1_unpacked | grep -A 108 "<main>:"

Dynamic Analysis

1
2
3
4
5
6
7
8
9
10
11
12
13
$ ./exatlon_v1

โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•—      โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ•—   โ–ˆโ–ˆโ•—       โ–ˆโ–ˆโ•—   โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•—
โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ•šโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ•šโ•โ•โ–ˆโ–ˆโ•”โ•โ•โ•โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ•”โ•โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ•‘       โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ•‘
โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—   โ•šโ–ˆโ–ˆโ–ˆโ•”โ• โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•‘       โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ•šโ–ˆโ–ˆโ•‘
โ–ˆโ–ˆโ•”โ•โ•โ•   โ–ˆโ–ˆโ•”โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘โ•šโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘       โ•šโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•”โ• โ–ˆโ–ˆโ•‘
โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ• โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•‘ โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•  โ–ˆโ–ˆโ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•  โ•šโ•โ•โ•šโ•โ•  โ•šโ•โ•   โ•šโ•โ•   โ•šโ•โ•โ•โ•โ•โ•โ• โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•  โ•šโ•โ•โ•โ•โ•šโ•โ•โ•โ•โ•โ•โ• โ•šโ•โ•โ•โ•   โ•šโ•โ•


[+] Enter Exatlon Password  : 123
[-] ;(
# ไปฅ้™ใƒซใƒผใƒ—

Static Analysis

ๅ…ฅๅŠ›ๅ€คใ‚’ exatlon() ใจใ„ใ†้–ขๆ•ฐใซๆธกใ—ใฆ๏ผŒ่ฟ”ใฃใฆใใŸๆ•ฐๅˆ—ใจ 1152 1344 1056... ใจใ„ใ†ๆ•ฐๅˆ—ใ‚’ๆฏ”่ผƒใ—๏ผŒๅˆ่‡ดใ—ใฆใ„ใ‚Œใฐๆญฃ่งฃใจใชใ‚‹ใ‚ˆใ†ใงใ™๏ผŽ

main()

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
undefined4 main(void)

{
  bool is_correct;
  ostream *poVar1;
  undefined4 status;
  string input_password [32];
  string encrypted_password [32];
  
  do {
    std::operator<<((ostream *)&std::cout,"\n");
    std::operator<<((ostream *)&std::cout,&DAT_0054b018);
    std::operator<<((ostream *)&std::cout,&DAT_0054b0d8);
    sleep(1);
    std::operator<<((ostream *)&std::cout,&DAT_0054b1a8);
    std::operator<<((ostream *)&std::cout,&DAT_0054b260);
    sleep(1);
    std::operator<<((ostream *)&std::cout,&DAT_0054b320);
    sleep(1);
    std::operator<<((ostream *)&std::cout,&DAT_0054b400);
    sleep(1);
    std::__cxx11::string::string(input_password);
                    /* try { // try from 00404cfe to 00404dce has its CatchHandler @ 00404def */
    std::operator<<((ostream *)&std::cout,"[+] Enter Exatlon Password  : ");
    std::operator>>((istream *)&std::cin,input_password);
    exatlon(encrypted_password);
    is_correct = std::operator==(encrypted_password,
                                 "1152 1344 1056 ..." // <confidential>
                                );
    std::__cxx11::string::~string(encrypted_password);
    if (is_correct) {
      poVar1 = std::operator<<((ostream *)&std::cout,"[+] Looks Good ^_^ \n\n\n");
      std::ostream::operator<<(poVar1,std::endl<>);
      status = 0;
      is_correct = false;
    }
    else {
      is_correct = std::operator==(input_password,"q");
      if (is_correct) {
        status = 0;
        is_correct = false;
      }
      else {
        poVar1 = std::operator<<((ostream *)&std::cout,"[-] ;(\n");
        std::ostream::operator<<(poVar1,std::endl<>);
        is_correct = true;
      }
    }
    std::__cxx11::string::~string(input_password);
  } while (is_correct);
  return status;
}

exatlon() ้–ขๆ•ฐใงใฏ๏ผŒๅ…ฅๅŠ›ใ•ใ‚ŒใŸๆ–‡ๅญ—ๅˆ—ใ‚’๏ผŒๆฏ”่ผƒใฎใŸใ‚ใซๅ…ˆใปใฉใฎ 1152 1344 1056... ใฎใ‚ˆใ†ใชๅฝขๅผใซๆš—ๅทๅŒ–ใ™ใ‚‹ๅ‡ฆ็†ใŒๆ›ธใ‹ใ‚Œใฆใ„ใพใ™๏ผŽๅ…ทไฝ“็š„ใซใฏ๏ผŒๅ…ฅๅŠ›ๆ–‡ๅญ—ๅˆ—ใ‚’asciiใ‚ณใƒผใƒ‰ใซๅค‰ๆ›ใ—๏ผŒ1ๆ–‡ๅญ—ๆฏŽใฎasciiๆ•ฐๅ€คใ‚’ 4bit ๅทฆใ‚ทใƒ•ใƒˆ (2^4=16ๅ€) ใ—ใŸใ‚‚ใฎใ‚’่ฟ”ใ—ใฆใ„ใ‚‹ใ‚ˆใ†ใงใ™๏ผŽ

ใใฎใŸใ‚๏ผŒ1152 1344 1056... ใ‚’ใ‚นใƒšใƒผใ‚นๆฏŽใซ 16ใง้™ค็ฎ— ใ—ใŸๆ•ฐๅ€คใ‚’asciiใซๅŸบใฅใ„ใฆๅ…ƒใฎๆ–‡ๅญ—ใซๅค‰ๆ›ใ™ใ‚‹ใ“ใจใงFlagใŒๅ…ฅๆ‰‹ใงใใพใ™๏ผŽ

exatlon()

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/* exatlon(std::__cxx11::string const&) */

string * exatlon(string *out_encrypted)

{
  bool has_next;
  char *current_char_ptr;
  string *input_str;
  undefined8 end_iter;
  undefined8 char_iter;
  allocator string_allocator;
  string formatted_str [32];
  __cxx11 shifted_str [39];
  char one_password;
  string *input_password;
  
  std::allocator<char>::allocator();
                    /* try { // try from 00404ae8 to 00404aec has its CatchHandler @ 00404bc1 */
  std::__cxx11::string::string(out_encrypted,"",&string_allocator);
  std::allocator<char>::~allocator((allocator<char> *)&string_allocator);
  input_password = input_str;
  char_iter = std::__cxx11::string::begin(input_str);
  end_iter = std::__cxx11::string::end(input_password);
  while( true ) {
    has_next = __gnu_cxx::operator!=((__normal_iterator *)&char_iter,(__normal_iterator *)&end_iter);
    if (!has_next) break;
    current_char_ptr = (char *)__gnu_cxx::__normal_iterator<>::operator*((__normal_iterator<> *)&char_iter);
    one_password = *current_char_ptr;
                    /* try { // try from 00404b63 to 00404b67 has its CatchHandler @ 00404bfd */
    std::__cxx11::to_string(shifted_str,(int)one_password << 4);
                    /* try { // try from 00404b7d to 00404b81 has its CatchHandler @ 00404bec */
    std::operator+(formatted_str,(char *)shifted_str);
                    /* try { // try from 00404b93 to 00404b97 has its CatchHandler @ 00404bdb */
    std::__cxx11::string::operator+=(out_encrypted,formatted_str);
    std::__cxx11::string::~string(formatted_str);
    std::__cxx11::string::~string((string *)shifted_str);
    __gnu_cxx::__normal_iterator<>::operator++((__normal_iterator<> *)&char_iter);
  }
  return out_encrypted;
}

ๅพฉๅท

decrypt.py

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env python3

# ๆš—ๅทๅŒ–ใ•ใ‚ŒใŸๆ•ฐๅญ—ๅˆ—
encrypted_data = "1152 1344 1056 ..."

# ใ‚นใƒšใƒผใ‚นใงๅˆ†ๅ‰ฒใ—ใฆๆ•ดๆ•ฐใฎใƒชใ‚นใƒˆใซๅค‰ๆ›
numbers = [int(x) for x in encrypted_data.split()]

# ๅ„ๆ•ฐๅ€คใ‚’16ใงๅ‰ฒใ‚Š๏ผŒchr()ใงASCIIๆ–‡ๅญ—ใซๅค‰ๆ›ใ—ใฆ็ตๅˆ
flag = "".join(chr(num // 16) for num in numbers)

print(f"[+] Decrypted Flag: {flag}")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ chmod +x ./exatlon_decrypt.py

$ ./exatlon_decrypt.py
[+] Decrypted Flag: <confidential>

$ ./exatlon_v1

โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•—      โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ•—   โ–ˆโ–ˆโ•—       โ–ˆโ–ˆโ•—   โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•—
โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ•šโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ•šโ•โ•โ–ˆโ–ˆโ•”โ•โ•โ•โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ•”โ•โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ•‘       โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ•‘
โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—   โ•šโ–ˆโ–ˆโ–ˆโ•”โ• โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•‘       โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ•šโ–ˆโ–ˆโ•‘
โ–ˆโ–ˆโ•”โ•โ•โ•   โ–ˆโ–ˆโ•”โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘โ•šโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘       โ•šโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•”โ• โ–ˆโ–ˆโ•‘
โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ• โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•‘ โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•  โ–ˆโ–ˆโ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•  โ•šโ•โ•โ•šโ•โ•  โ•šโ•โ•   โ•šโ•โ•   โ•šโ•โ•โ•โ•โ•โ•โ• โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•  โ•šโ•โ•โ•โ•โ•šโ•โ•โ•โ•โ•โ•โ• โ•šโ•โ•โ•โ•   โ•šโ•โ•


[+] Enter Exatlon Password  : <credentials>
[+] Looks Good ^_^
This post is licensed under CC BY 4.0 by the author.