This room focuses on teaching the basics of assembly through reverse engineering

πŸ’’ We will cover the topics

  • Reverse Engineering

Task 1 Debugging and File Permission

In this task, we’ll be learning the basics of reverse engineering and assembly. Here are some important things to do before starting the task:

  • These files have been compiled with the lowest level of optimisation on Unix based machines and are intended to be run on Linux/Mac.
  • Make sure you set up a debugger - it would be good to get comfortable with radare2 which can be downloaded from here. You can also use other debuggers like gdb, which come installed in most Unix based operating systems.
  • When these files have been downloaded, change the permissions of these files using the command chmod +x filename

These tasks will make use of crackme files. The objective of these files is to understand the assembly code to uncover the right password for the file.

Here are some of the important things you will learn in this course:

  • If statements in assembly
  • Loops in assembly
  • standard function calls in assembly
  • Calling Convention in assembly
  1. Set up debugger(if you haven’t already)

No answer needed

Task 2 crackme1

This first crackme file will give you an introduction to if statements and basic function calling in assembly.

1
2
3
4
5
6
7
8
kali@kali:~/CTFs/tryhackme/Reverse Engineering$ file crackme1.bin
crackme1.bin: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=3864320789154e8960133afdf58ddf65f6f8273d, not stripped
kali@kali:~/CTFs/tryhackme/Reverse Engineering$ strings crackme1.bin

enter password
password is correct
password is incorrect
hax0r
  1. what is the correct password
1
2
3
4
kali@kali:~/CTFs/tryhackme/Reverse Engineering$ ./crackme1.bin
enter password
hax0r
password is correct

hax0r

Task 3 crackme2

This is the second crackme file - Unlike the first file, this will involve examining registers, how and where values are compared

 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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
kali@kali:~/CTFs/tryhackme/Reverse Engineering$ r2 -d ./crackme2.bin
Process with PID 78763 started...
= attach 78763 78763
bin.baddr 0x55fb45bf4000
Using 0x55fb45bf4000
asm.bits 64
Warning: r_bin_file_hash: file exceeds bin.hashlimit
[0x7f58df4df090]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Check for objc references
[x] Check for vtables
[TOFIX: aaft can't run in debugger mode.ions (aaft)
[x] Type matching analysis for all functions (aaft)
[x] Propagate noreturn information
[x] Use -AA or aaaa to perform additional experimental analysis.
[0x7f58df4df090]> afl
0x55fb45bf4610    1 42           entry0
0x55fb45df4fe0    1 4124         reloc.__libc_start_main
0x55fb45bf4640    4 50   -> 40   sym.deregister_tm_clones
0x55fb45bf4680    4 66   -> 57   sym.register_tm_clones
0x55fb45bf46d0    5 58   -> 51   entry.fini0
0x55fb45bf4600    1 6            sym..plt.got
0x55fb45bf4710    1 10           entry.init0
0x55fb45bf4810    1 2            sym.__libc_csu_fini
0x55fb45bf4814    1 9            sym._fini
0x55fb45bf47a0    4 101          sym.__libc_csu_init
0x55fb45bf471a    6 122          main
0x55fb45bf45a0    3 23           sym._init
0x55fb45bf45d0    1 6            sym.imp.puts
0x55fb45bf45e0    1 6            sym.imp.__stack_chk_fail
0x55fb45bf4000    2 25           map.home_kali_CTFs_tryhackme_Reverse_Engineering_crackme2.bin.r_x
0x55fb45bf45f0    1 6            sym.imp.__isoc99_scanf
[0x7f58df4df090]> pdf @main
            ; DATA XREF from entry0 @ 0x55fb45bf462d
β”Œ 122: int main (int argc, char **argv, char **envp);
β”‚           ; var int64_t var_ch @ rbp-0xc
β”‚           ; var int64_t var_8h @ rbp-0x8
β”‚           0x55fb45bf471a      55             push rbp
β”‚           0x55fb45bf471b      4889e5         mov rbp, rsp
β”‚           0x55fb45bf471e      4883ec10       sub rsp, 0x10
β”‚           0x55fb45bf4722      64488b042528.  mov rax, qword fs:[0x28]
β”‚           0x55fb45bf472b      488945f8       mov qword [var_8h], rax
β”‚           0x55fb45bf472f      31c0           xor eax, eax
β”‚           0x55fb45bf4731      488d3dec0000.  lea rdi, qword str.enter_your_password ; 0x55fb45bf4824 ; "enter your password"
β”‚           0x55fb45bf4738      e893feffff     call sym.imp.puts       ; int puts(const char *s)
β”‚           0x55fb45bf473d      488d45f4       lea rax, qword [var_ch]
β”‚           0x55fb45bf4741      4889c6         mov rsi, rax
β”‚           0x55fb45bf4744      488d3ded0000.  lea rdi, qword [0x55fb45bf4838] ; "%d"
β”‚           0x55fb45bf474b      b800000000     mov eax, 0
β”‚           0x55fb45bf4750      e89bfeffff     call sym.imp.__isoc99_scanf ; int scanf(const char *format)
β”‚           0x55fb45bf4755      8b45f4         mov eax, dword [var_ch]
β”‚           0x55fb45bf4758      3d7c130000     cmp eax, 0x137c
β”‚       β”Œβ”€< 0x55fb45bf475d      750e           jne 0x55fb45bf476d
β”‚       β”‚   0x55fb45bf475f      488d3dd50000.  lea rdi, qword str.password_is_valid ; 0x55fb45bf483b ; "password is valid"
β”‚       β”‚   0x55fb45bf4766      e865feffff     call sym.imp.puts       ; int puts(const char *s)
β”‚      β”Œβ”€β”€< 0x55fb45bf476b      eb0c           jmp 0x55fb45bf4779
β”‚      │└─> 0x55fb45bf476d      488d3dd90000.  lea rdi, qword str.password_is_incorrect ; 0x55fb45bf484d ; "password is incorrect"
β”‚      β”‚    0x55fb45bf4774      e857feffff     call sym.imp.puts       ; int puts(const char *s)
β”‚      β”‚    ; CODE XREF from main @ 0x55fb45bf476b
β”‚      └──> 0x55fb45bf4779      b800000000     mov eax, 0
β”‚           0x55fb45bf477e      488b55f8       mov rdx, qword [var_8h]
β”‚           0x55fb45bf4782      644833142528.  xor rdx, qword fs:[0x28]
β”‚       β”Œβ”€< 0x55fb45bf478b      7405           je 0x55fb45bf4792
β”‚       β”‚   0x55fb45bf478d      e84efeffff     call sym.imp.__stack_chk_fail ; void __stack_chk_fail(void)
β”‚       └─> 0x55fb45bf4792      c9             leave
β””           0x55fb45bf4793      c3             ret
[0x7f58df4df090]>
1
2
kali@kali:~/CTFs/tryhackme/Reverse Engineering$ echo 'ibase=16; 137C' | bc
4988
  1. What is the correct password?
1
2
3
4
kali@kali:~/CTFs/tryhackme/Reverse Engineering$ ./crackme2.bin
enter your password
4988
password is valid

4988

Task 4 crackme3

This crackme will be significantly more challenging - it involves learning how loops work, and how they are represented in assembly

  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
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
kali@kali:~/CTFs/tryhackme/Reverse Engineering$ r2 -d ./crackme3.bin
Process with PID 78868 started...
= attach 78868 78868
bin.baddr 0x5613e9b22000
Using 0x5613e9b22000
asm.bits 64
Warning: r_bin_file_hash: file exceeds bin.hashlimit
[0x7f6163ed6090]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Check for objc references
[x] Check for vtables
[TOFIX: aaft can't run in debugger mode.ions (aaft)
[x] Type matching analysis for all functions (aaft)
[x] Propagate noreturn information
[x] Use -AA or aaaa to perform additional experimental analysis.
[0x7f6163ed6090]> afl
0x5613e9b22610    1 42           entry0
0x5613e9d22fe0    1 4124         reloc.__libc_start_main
0x5613e9b22640    4 50   -> 40   sym.deregister_tm_clones
0x5613e9b22680    4 66   -> 57   sym.register_tm_clones
0x5613e9b226d0    5 58   -> 51   entry.fini0
0x5613e9b22600    1 6            sym..plt.got
0x5613e9b22710    1 10           entry.init0
0x5613e9b22840    1 2            sym.__libc_csu_fini
0x5613e9b22844    1 9            sym._fini
0x5613e9b227d0    4 101          sym.__libc_csu_init
0x5613e9b2271a    9 170          main
0x5613e9b225a0    3 23           sym._init
0x5613e9b225d0    1 6            sym.imp.puts
0x5613e9b225e0    1 6            sym.imp.__stack_chk_fail
0x5613e9b22000    2 25           map.home_kali_CTFs_tryhackme_Reverse_Engineering_crackme3.bin.r_x
0x5613e9b225f0    1 6            sym.imp.__isoc99_scanf
[0x7f6163ed6090]> pdf @main
            ; DATA XREF from entry0 @ 0x5613e9b2262d
β”Œ 170: int main (int argc, char **argv, char **envp);
β”‚           ; var int64_t var_28h @ rbp-0x28
β”‚           ; var int64_t var_23h @ rbp-0x23
β”‚           ; var int64_t var_21h @ rbp-0x21
β”‚           ; var int64_t var_20h @ rbp-0x20
β”‚           ; var int64_t var_8h @ rbp-0x8
β”‚           0x5613e9b2271a      55             push rbp
β”‚           0x5613e9b2271b      4889e5         mov rbp, rsp
β”‚           0x5613e9b2271e      4883ec30       sub rsp, 0x30
β”‚           0x5613e9b22722      64488b042528.  mov rax, qword fs:[0x28]
β”‚           0x5613e9b2272b      488945f8       mov qword [var_8h], rax
β”‚           0x5613e9b2272f      31c0           xor eax, eax
β”‚           0x5613e9b22731      66c745dd617a   mov word [var_23h], 0x7a61 ; 'az'
β”‚           0x5613e9b22737      c645df74       mov byte [var_21h], 0x74 ; 't' ; 116
β”‚           0x5613e9b2273b      488d3d120100.  lea rdi, qword str.enter_your_password ; 0x5613e9b22854 ; "enter your password"
β”‚           0x5613e9b22742      e889feffff     call sym.imp.puts       ; int puts(const char *s)
β”‚           0x5613e9b22747      488d45e0       lea rax, qword [var_20h]
β”‚           0x5613e9b2274b      4889c6         mov rsi, rax
β”‚           0x5613e9b2274e      488d3d130100.  lea rdi, qword [0x5613e9b22868] ; "%s"
β”‚           0x5613e9b22755      b800000000     mov eax, 0
β”‚           0x5613e9b2275a      e891feffff     call sym.imp.__isoc99_scanf ; int scanf(const char *format)
β”‚           0x5613e9b2275f      c745d8000000.  mov dword [var_28h], 0
β”‚       β”Œβ”€< 0x5613e9b22766      eb2f           jmp 0x5613e9b22797
β”‚      β”Œβ”€β”€> 0x5613e9b22768      8b45d8         mov eax, dword [var_28h]
β”‚      β•Žβ”‚   0x5613e9b2276b      4898           cdqe
β”‚      β•Žβ”‚   0x5613e9b2276d      0fb65405e0     movzx edx, byte [rbp + rax - 0x20]
β”‚      β•Žβ”‚   0x5613e9b22772      8b45d8         mov eax, dword [var_28h]
β”‚      β•Žβ”‚   0x5613e9b22775      4898           cdqe
β”‚      β•Žβ”‚   0x5613e9b22777      0fb64405dd     movzx eax, byte [rbp + rax - 0x23]
β”‚      β•Žβ”‚   0x5613e9b2277c      38c2           cmp dl, al
β”‚     β”Œβ”€β”€β”€< 0x5613e9b2277e      7413           je 0x5613e9b22793
β”‚     β”‚β•Žβ”‚   0x5613e9b22780      488d3de40000.  lea rdi, qword str.password_is_incorrect ; 0x5613e9b2286b ; "password is incorrect"
β”‚     β”‚β•Žβ”‚   0x5613e9b22787      e844feffff     call sym.imp.puts       ; int puts(const char *s)
β”‚     β”‚β•Žβ”‚   0x5613e9b2278c      b800000000     mov eax, 0
β”‚    β”Œβ”€β”€β”€β”€< 0x5613e9b22791      eb1b           jmp 0x5613e9b227ae
β”‚    │└───> 0x5613e9b22793      8345d801       add dword [var_28h], 1
β”‚    β”‚ β•Žβ”‚   ; CODE XREF from main @ 0x5613e9b22766
β”‚    β”‚ β•Žβ””β”€> 0x5613e9b22797      837dd802       cmp dword [var_28h], 2
β”‚    β”‚ └──< 0x5613e9b2279b      7ecb           jle 0x5613e9b22768
β”‚    β”‚      0x5613e9b2279d      488d3ddd0000.  lea rdi, qword str.password_is_correct ; 0x5613e9b22881 ; "password is correct"
β”‚    β”‚      0x5613e9b227a4      e827feffff     call sym.imp.puts       ; int puts(const char *s)
β”‚    β”‚      0x5613e9b227a9      b800000000     mov eax, 0
β”‚    β”‚      ; CODE XREF from main @ 0x5613e9b22791
β”‚    └────> 0x5613e9b227ae      488b4df8       mov rcx, qword [var_8h]
β”‚           0x5613e9b227b2      6448330c2528.  xor rcx, qword fs:[0x28]
β”‚       β”Œβ”€< 0x5613e9b227bb      7405           je 0x5613e9b227c2
β”‚       β”‚   0x5613e9b227bd      e81efeffff     call sym.imp.__stack_chk_fail ; void __stack_chk_fail(void)
β”‚       └─> 0x5613e9b227c2      c9             leave
β””           0x5613e9b227c3      c3             ret
[0x7f6163ed6090]>
[0x5613e9b2275f]> ds
[0x5613e9b22766]> pdf @main
            ; DATA XREF from entry0 @ 0x5613e9b2262d
β”Œ 170: int main (int argc, char **argv, char **envp);
β”‚           ; var int64_t var_28h @ rbp-0x28
β”‚           ; var int64_t var_23h @ rbp-0x23
β”‚           ; var int64_t var_21h @ rbp-0x21
β”‚           ; var int64_t var_20h @ rbp-0x20
β”‚           ; var int64_t var_8h @ rbp-0x8
β”‚           0x5613e9b2271a      55             push rbp
β”‚           0x5613e9b2271b      4889e5         mov rbp, rsp
β”‚           0x5613e9b2271e      4883ec30       sub rsp, 0x30
β”‚           0x5613e9b22722      64488b042528.  mov rax, qword fs:[0x28]
β”‚           0x5613e9b2272b      488945f8       mov qword [var_8h], rax
β”‚           0x5613e9b2272f      31c0           xor eax, eax
β”‚           0x5613e9b22731      66c745dd617a   mov word [var_23h], 0x7a61 ; 'az'
β”‚           0x5613e9b22737      c645df74       mov byte [var_21h], 0x74 ; 't' ; 116
β”‚           0x5613e9b2273b      488d3d120100.  lea rdi, qword str.enter_your_password ; 0x5613e9b22854 ; "enter your password"
β”‚           0x5613e9b22742      e889feffff     call sym.imp.puts       ; int puts(const char *s)
β”‚           0x5613e9b22747      488d45e0       lea rax, qword [var_20h]
β”‚           0x5613e9b2274b      4889c6         mov rsi, rax
β”‚           0x5613e9b2274e      488d3d130100.  lea rdi, qword [0x5613e9b22868] ; "%s"
β”‚           0x5613e9b22755      b800000000     mov eax, 0
β”‚           0x5613e9b2275a      e891feffff     call sym.imp.__isoc99_scanf ; int scanf(const char *format)
β”‚           0x5613e9b2275f b    c745d8000000.  mov dword [var_28h], 0
β”‚           ;-- rip:
β”‚       β”Œβ”€< 0x5613e9b22766      eb2f           jmp 0x5613e9b22797
β”‚      β”Œβ”€β”€> 0x5613e9b22768      8b45d8         mov eax, dword [var_28h]
β”‚      β•Žβ”‚   0x5613e9b2276b      4898           cdqe
β”‚      β•Žβ”‚   0x5613e9b2276d      0fb65405e0     movzx edx, byte [rbp + rax - 0x20]
β”‚      β•Žβ”‚   0x5613e9b22772      8b45d8         mov eax, dword [var_28h]
β”‚      β•Žβ”‚   0x5613e9b22775      4898           cdqe
β”‚      β•Žβ”‚   0x5613e9b22777      0fb64405dd     movzx eax, byte [rbp + rax - 0x23]
β”‚      β•Žβ”‚   0x5613e9b2277c      38c2           cmp dl, al
β”‚     β”Œβ”€β”€β”€< 0x5613e9b2277e      7413           je 0x5613e9b22793
β”‚     β”‚β•Žβ”‚   0x5613e9b22780      488d3de40000.  lea rdi, qword str.password_is_incorrect ; 0x5613e9b2286b ; "password is incorrect"
β”‚     β”‚β•Žβ”‚   0x5613e9b22787      e844feffff     call sym.imp.puts       ; int puts(const char *s)
β”‚     β”‚β•Žβ”‚   0x5613e9b2278c      b800000000     mov eax, 0
β”‚    β”Œβ”€β”€β”€β”€< 0x5613e9b22791      eb1b           jmp 0x5613e9b227ae
β”‚    │└───> 0x5613e9b22793      8345d801       add dword [var_28h], 1
β”‚    β”‚ β•Žβ”‚   ; CODE XREF from main @ 0x5613e9b22766
β”‚    β”‚ β•Žβ””β”€> 0x5613e9b22797      837dd802       cmp dword [var_28h], 2
β”‚    β”‚ └──< 0x5613e9b2279b b    7ecb           jle 0x5613e9b22768
β”‚    β”‚      0x5613e9b2279d      488d3ddd0000.  lea rdi, qword str.password_is_correct ; 0x5613e9b22881 ; "password is correct"
β”‚    β”‚      0x5613e9b227a4      e827feffff     call sym.imp.puts       ; int puts(const char *s)
β”‚    β”‚      0x5613e9b227a9      b800000000     mov eax, 0
β”‚    β”‚      ; CODE XREF from main @ 0x5613e9b22791
β”‚    └────> 0x5613e9b227ae      488b4df8       mov rcx, qword [var_8h]
β”‚           0x5613e9b227b2      6448330c2528.  xor rcx, qword fs:[0x28]
β”‚       β”Œβ”€< 0x5613e9b227bb      7405           je 0x5613e9b227c2
β”‚       β”‚   0x5613e9b227bd      e81efeffff     call sym.imp.__stack_chk_fail ; void __stack_chk_fail(void)
β”‚       └─> 0x5613e9b227c2      c9             leave
β””           0x5613e9b227c3      c3             ret
[0x5613e9b22766]> px @ rbp-0x28
- offset -       0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0x7ffc957a00a8  0000 0000 0061 7a74 3132 3300 1356 0000  .....azt123..V..
0x7ffc957a00b8  1026 b2e9 1356 0000 c001 7a95 fc7f 0000  .&...V....z.....
0x7ffc957a00c8  00ab 71c8 1002 107d d027 b2e9 1356 0000  ..q....}.'...V..
0x7ffc957a00d8  cacc d163 617f 0000 c801 7a95 fc7f 0000  ...ca.....z.....
0x7ffc957a00e8  0000 0000 0100 0000 1a27 b2e9 1356 0000  .........'...V..
0x7ffc957a00f8  d9c7 d163 617f 0000 0000 0000 0000 0000  ...ca...........
0x7ffc957a0108  4133 bc38 9e6d 2fdc 1026 b2e9 1356 0000  A3.8.m/..&...V..
0x7ffc957a0118  0000 0000 0000 0000 0000 0000 0000 0000  ................
0x7ffc957a0128  0000 0000 0000 0000 4133 dc76 0e94 f18f  ........A3.v....
0x7ffc957a0138  4133 1aee 5979 ca8e 0000 0000 0000 0000  A3..Yy..........
0x7ffc957a0148  0000 0000 0000 0000 0000 0000 0000 0000  ................
0x7ffc957a0158  0100 0000 0000 0000 c801 7a95 fc7f 0000  ..........z.....
0x7ffc957a0168  d801 7a95 fc7f 0000 8011 f063 617f 0000  ..z........ca...
0x7ffc957a0178  0000 0000 0000 0000 0000 0000 0000 0000  ................
0x7ffc957a0188  1026 b2e9 1356 0000 c001 7a95 fc7f 0000  .&...V....z.....
0x7ffc957a0198  0000 0000 0000 0000 0000 0000 0000 0000  ................
  1. What are the first 3 letters of the correct password?
1
2
3
4
kali@kali:~/CTFs/tryhackme/Reverse Engineering$ ./crackme3.bin
enter your password
azt
password is correct

azt