1 Baby RE

CHALLENGE DESCRIPTION

Show us your basic skills! (P.S. There are 4 ways to solve this, are you willing to try them all?)

Maybe

Method 1:

First, we extract the given zip file:

xi@onlywans:~/hackthebox/challenges/babyReV$ 7z x Baby\ RE.zip 

7-Zip 24.07 (x64) : Copyright (c) 1999-2024 Igor Pavlov : 2024-06-19
 64-bit locale=en_US.UTF-8 Threads:4 OPEN_MAX:1024

Scanning the drive for archives:
1 file, 2885 bytes (3 KiB)

Extracting archive: Baby RE.zip
--
Path = Baby RE.zip
Type = zip
Physical Size = 2885

    
Enter password (will not be echoed):
Everything is Ok

Size:       16760
Compressed: 2885

Then we execute the binary( and we know it's a linux executable based on the output from file ) after giving it execution permissions:

xi@onlywans:~/hackthebox/challenges/babyReV$ file baby  
baby: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=25adc53b89f781335a27bf1b81f5c4cb74581022, for GNU/Linux 3.2.0, not stripped

xi@onlywans:~/hackthebox/challenges/babyReV$ ./baby       
Insert key: 

As we can see it's asking for a key, and after guessing a random key:

xi@onlywans:~/hackthebox/challenges/babyReV$ ./baby       
Insert key: 
abc123
Try again later.

Now let’s statically analyze it, we are going to start with the program strings and see if we can find any strings that may help us:

xi@onlywans:~/hackthebox/challenges/babyReV$ strings baby        
/lib64/ld-linux-x86-64.so.2
mgUa
libc.so.6
puts
stdin
fgets
__cxa_finalize
strcmp
__libc_start_main
GLIBC_2.2.5
_ITM_deregisterTMCloneTable
__gmon_start__
_ITM_registerTMCloneTable
u/UH
HTB{B4BYH
_R3V_TH4H
TS_Ef
[]A\A]A^A_
Dont run `strings` on this challenge, that is not the way!!!!
Insert key: 
abcde122313
Try again later.
;*3$"
GCC: (Debian 9.2.1-8) 9.2.1 20190909
crtstuff.c
deregister_tm_clones
__do_global_dtors_aux
completed.7444
__do_global_dtors_aux_fini_array_entry
frame_dummy
__frame_dummy_init_array_entry
baby.c
__FRAME_END__
__init_array_end
_DYNAMIC
__init_array_start
__GNU_EH_FRAME_HDR
_GLOBAL_OFFSET_TABLE_
__libc_csu_fini
_ITM_deregisterTMCloneTable
puts@@GLIBC_2.2.5
stdin@@GLIBC_2.2.5
_edata
__libc_start_main@@GLIBC_2.2.5
fgets@@GLIBC_2.2.5
__data_start
strcmp@@GLIBC_2.2.5
__gmon_start__
__dso_handle
_IO_stdin_used
__libc_csu_init
__bss_start
main
__TMC_END__
_ITM_registerTMCloneTable
__cxa_finalize@@GLIBC_2.2.5
.symtab
.strtab
.shstrtab
.interp
.note.gnu.build-id
.note.ABI-tag
.gnu.hash
.dynsym
.dynstr
.gnu.version
.gnu.version_r
.rela.dyn
.rela.plt
.init
.plt.got
.text
.fini
.rodata
.eh_frame_hdr
.eh_frame
.init_array
.fini_array
.dynamic
.got.plt
.data
.bss
.comment

lots of strings there let's clean it up and go through the most obvious ones:

2024-07-31_23-13.png

Now we have the flag and the password with just the strings command, let's try some dynamic analysis with ltrace

xi@onlywans:~/hackthebox/challenges/babyReV$ ./baby 
Insert key: 
abcde122313
HTB{B4BY_R3V_TH4TS_EZ} 

ltrace

2024-07-31_23-27.png

first the function fgets gets called to take input from user input then the user input is passed to strcmp which compares the input against the password abcde122313

2 You Cant C Me

CHALLENGE DESCRIPTION

Can you see me?

Lets try that

Static analysis

xi@onlywans:~/hackthebox/challenges/YouCantCMe$ file auth 
auth: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, stripped
xi@onlywans:~/hackthebox/challenges/YouCantCMe$ strings auth > strings

2024-08-01_00-19.png

Now we have the password, we can can simply use it when asked and get the flag easily:

xi@onlywans:~/hackthebox/challenges/YouCantCMe$ ./auth                
Welcome!
m^&&fi
Uo&kUZ'ZUYUcI said, you can't c me

Nope that wasn’t the password

Dynamic Analysis

We can perform a dynamic analysis with ltrace

xi@onlywans:~/hackthebox/challenges/YouCantCMe$ ltrace ./auth          
printf("Welcome!\n"Welcome!
)                                                     = 9
malloc(21)                                                               = 0xc596b0
fgets(lmao
"lmao\n", 21, 0x7fa6b25328e0)                                      = 0xc596b0
strcmp("wh00ps!_y0u_d1d_c_m3", "lmao\n")                                 = 11
printf("I said, you can't c me!\n"I said, you can't c me!
)                                      = 24
+++ exited (status 0) +++

We really got the password:

xi@onlywans:~/hackthebox/challenges/YouCantCMe$ ./auth       
Welcome!
wh00ps!_y0u_d1d_c_m3
HTB{wh00ps!_y0u_d1d_c_m3}

3 Baby Crypt

Baby Crypt is an Reversing challenge. Players use basic analysis to find an XOR decryption, and use known plaintext in order to uncover a key to retrieve the flag.

When run, the binary prompts the user for a key and prints out some mangled text, which changes depending on the user input

xi@onlywans:~/hackthebox/challenges/BabyCrypt$ ./baby_crypt 
Give me the key and I'll give you the flag: mmmmmmh
R	Xa%*h+ioin~E?cE5.bmh; 

We can open the binary in a de-compiler such as Ghidra and navigate to the code browser. Here’s the decompiled output of the main() function:

undefined8 main(void)

{
  char *__s;
  long in_FS_OFFSET;
  int local_44;
  undefined8 local_38;
  undefined8 local_30;
  undefined8 local_28;
  undefined2 local_20;
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  printf("Give me the key and I\'ll give you the flag: ");
  __s = (char *)malloc(4);
  fgets(__s,4,stdin);
  local_38 = 0x6f0547480c35643f;
  local_30 = 0x28130304026f0446;
  local_28 = 0x5000f4358280e52;
  local_20 = 0x4d56;
  for (local_44 = 0; local_44 < 0x1a; local_44 = local_44 + 1) {
    *(byte *)((long)&local_38 + (long)local_44) =
         *(byte *)((long)&local_38 + (long)local_44) ^ __s[local_44 % 3];
  }
  printf("%.26s\n",&local_38);
  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return 0;
}

Basically, it asks for a 3-byte key then performs a XOR cipher. Since the expected output is the flag and we know the format, we can reverse the XOR cipher and get the expected key.

Let m be the plaintext byte, k the key byte and c be the ciphertext byte. XOR cipher this property

$$ c = m \oplus k \iff k = c \oplus m $$

Hence, we can take the first three bytes of the ciphertext (variable called local_38, in little endian format) and XOR them with the plaintext bytes:

$ python3 -q
>>> chr(ord('H') ^ 0x3f)  
'w'
>>> chr(ord('T') ^ 0x64)
'0'
>>> chr(ord('B') ^ 0x35)
'w'

Here is the full exploit:

def xor_bytes(m_byte, k_byte):
    # XOR the plaintext byte with the key byte
    return m_byte ^ k_byte

def to_little_endian_bytes(key):
    # Convert key to bytes and reverse for little-endian order
    return key.to_bytes(8, byteorder='little')

# Original key in hexadecimal
key = 0x6f0547480c35643f

# Convert key to little-endian byte representation
little_endian_key_bytes = to_little_endian_bytes(key)

# Characters to XOR
characters = ['H', 'T', 'B']

# XOR each character's ASCII value with the corresponding key byte
results = {}
for i, char in enumerate(characters):
    m_byte = ord(char)
    k_byte = little_endian_key_bytes[i % len(little_endian_key_bytes)]
    c_byte = xor_bytes(m_byte, k_byte)
    results[char] = c_byte

# Convert XOR results back to plaintext characters
plaintext_results = {char: chr(result) for char, result in results.items()}

# Print the results
for char, result in plaintext_results.items():
    print(f"Plaintext result for '{char}': {result}")

Explanation:

  1. XOR Operation: Each character's ASCII value is XORed with the corresponding byte from the little-endian key.
  2. Convert Back to Plain Text: After XORing, each result (which is a byte value) is converted back to a character using the chr() function.
  3. Output: The script prints the plaintext characters resulting from the XOR operation.

Example Output:

If you run the script, it will output the plaintext characters obtained from XORing 'H', 'T', and 'B' with the corresponding bytes from the little-endian version of the key 0x6f0547480c35643f.

Each XORed byte is mapped back to a character, producing the plaintext equivalent of the XOR operation.

4 Anti Flag

Anti flag is an easy Reversing challenge.Players will bypass an anti-debugging measure in order to pass a check and recover the flag

If we execute the binary, it simply prints a failure message and exits:

image.png

If its run under a tracing tool such as ltrace or strace, a different message is is printed.

image.png

image.png

The binary instead prints Well done!! and then exits. Before that, a call to ptrace() is made Using ptrace(PTRACE_TRACEME) is a common and very simple anti-debugging measure in Linux, a process may call PTRACE_TRACEME to request that its parent attach to it is for debugging. However, if a process is already debugging it will return the error EPERM. The process can check this, and exit if it fails.

Decompilatiom

If we open it in Ghidra, we will see this main function:


/* WARNING: Removing unreachable block (ram,0x00101525) */

undefined8
main(undefined8 param_1,undefined8 param_2,undefined8 param_3,undefined8 param_4,undefined8 param_5,
    undefined8 param_6)

{
  size_t sVar1;
  long lVar2;
  
  sVar1 = strlen(&DAT_00102011);
  malloc(sVar1 << 2);
  lVar2 = ptrace(PTRACE_TRACEME,0,1,0,param_5,param_6,param_2);
  if (lVar2 == -1) {
    puts("Well done!!");
  }
  else {
    puts("No flag for you :(");
  }
  return 0;
}

Assembly code analysis

Disassembly of section .text:

00000000000010e0 <.text>:
    10e0:	f3 0f 1e fa          	endbr64
    10e4:	31 ed                	xor    ebp,ebp
    10e6:	49 89 d1             	mov    r9,rdx
    10e9:	5e                   	pop    rsi
    10ea:	48 89 e2             	mov    rdx,rsp
    10ed:	48 83 e4 f0          	and    rsp,0xfffffffffffffff0
    10f1:	50                   	push   rax
    10f2:	54                   	push   rsp
    10f3:	4c 8d 05 c6 04 00 00 	lea    r8,[rip+0x4c6]        # 15c0 <ptrace@plt+0x4f0>
    10fa:	48 8d 0d 4f 04 00 00 	lea    rcx,[rip+0x44f]        # 1550 <ptrace@plt+0x480>
    1101:	48 8d 3d 7e 03 00 00 	lea    rdi,[rip+0x37e]        # 1486 <ptrace@plt+0x3b6>
    1108:	ff 15 d2 2e 00 00    	call   QWORD PTR [rip+0x2ed2]        # 3fe0 <ptrace@plt+0x2f10>
    110e:	f4                   	hlt
    110f:	90                   	nop
    1110:	48 8d 3d f9 2e 00 00 	lea    rdi,[rip+0x2ef9]        # 4010 <ptrace@plt+0x2f40>
    1117:	48 8d 05 f2 2e 00 00 	lea    rax,[rip+0x2ef2]        # 4010 <ptrace@plt+0x2f40>
    111e:	48 39 f8             	cmp    rax,rdi
    1121:	74 15                	je     1138 <ptrace@plt+0x68>
    1123:	48 8b 05 ae 2e 00 00 	mov    rax,QWORD PTR [rip+0x2eae]        # 3fd8 <ptrace@plt+0x2f08>
    112a:	48 85 c0             	test   rax,rax
    112d:	74 09                	je     1138 <ptrace@plt+0x68>
    112f:	ff e0                	jmp    rax
    1131:	0f 1f 80 00 00 00 00 	nop    DWORD PTR [rax+0x0]
    1138:	c3                   	ret
    1139:	0f 1f 80 00 00 00 00 	nop    DWORD PTR [rax+0x0]
    1140:	48 8d 3d c9 2e 00 00 	lea    rdi,[rip+0x2ec9]        # 4010 <ptrace@plt+0x2f40>
    1147:	48 8d 35 c2 2e 00 00 	lea    rsi,[rip+0x2ec2]        # 4010 <ptrace@plt+0x2f40>
    114e:	48 29 fe             	sub    rsi,rdi
    1151:	48 89 f0             	mov    rax,rsi
    1154:	48 c1 ee 3f          	shr    rsi,0x3f
    1158:	48 c1 f8 03          	sar    rax,0x3
    115c:	48 01 c6             	add    rsi,rax
    115f:	48 d1 fe             	sar    rsi,1
    1162:	74 14                	je     1178 <ptrace@plt+0xa8>
    1164:	48 8b 05 85 2e 00 00 	mov    rax,QWORD PTR [rip+0x2e85]        # 3ff0 <ptrace@plt+0x2f20>
    116b:	48 85 c0             	test   rax,rax
    116e:	74 08                	je     1178 <ptrace@plt+0xa8>
    1170:	ff e0                	jmp    rax
    1172:	66 0f 1f 44 00 00    	nop    WORD PTR [rax+rax*1+0x0]
    1178:	c3                   	ret
    1179:	0f 1f 80 00 00 00 00 	nop    DWORD PTR [rax+0x0]
    1180:	f3 0f 1e fa          	endbr64
    1184:	80 3d 85 2e 00 00 00 	cmp    BYTE PTR [rip+0x2e85],0x0        # 4010 <ptrace@plt+0x2f40>
    118b:	75 2b                	jne    11b8 <ptrace@plt+0xe8>
    118d:	55                   	push   rbp
    118e:	48 83 3d 62 2e 00 00 	cmp    QWORD PTR [rip+0x2e62],0x0        # 3ff8 <ptrace@plt+0x2f28>
    1195:	00 
    1196:	48 89 e5             	mov    rbp,rsp
    1199:	74 0c                	je     11a7 <ptrace@plt+0xd7>
    119b:	48 8b 3d 66 2e 00 00 	mov    rdi,QWORD PTR [rip+0x2e66]        # 4008 <ptrace@plt+0x2f38>
    11a2:	e8 d9 fe ff ff       	call   1080 <__cxa_finalize@plt>
    11a7:	e8 64 ff ff ff       	call   1110 <ptrace@plt+0x40>
    11ac:	c6 05 5d 2e 00 00 01 	mov    BYTE PTR [rip+0x2e5d],0x1        # 4010 <ptrace@plt+0x2f40>
    11b3:	5d                   	pop    rbp
    11b4:	c3                   	ret
    11b5:	0f 1f 00             	nop    DWORD PTR [rax]
    11b8:	c3                   	ret
    11b9:	0f 1f 80 00 00 00 00 	nop    DWORD PTR [rax+0x0]
    11c0:	f3 0f 1e fa          	endbr64
    11c4:	e9 77 ff ff ff       	jmp    1140 <ptrace@plt+0x70>
    11c9:	f3 0f 1e fa          	endbr64
    11cd:	55                   	push   rbp
    11ce:	48 89 e5             	mov    rbp,rsp
    11d1:	48 89 7d e8          	mov    QWORD PTR [rbp-0x18],rdi
    11d5:	48 89 75 e0          	mov    QWORD PTR [rbp-0x20],rsi
    11d9:	48 8b 45 e8          	mov    rax,QWORD PTR [rbp-0x18]
    11dd:	0f b6 00             	movzx  eax,BYTE PTR [rax]
    11e0:	0f b6 c0             	movzx  eax,al
    11e3:	89 45 fc             	mov    DWORD PTR [rbp-0x4],eax
    11e6:	48 8b 45 e0          	mov    rax,QWORD PTR [rbp-0x20]
    11ea:	0f b6 10             	movzx  edx,BYTE PTR [rax]
    11ed:	48 8b 45 e8          	mov    rax,QWORD PTR [rbp-0x18]
    11f1:	88 10                	mov    BYTE PTR [rax],dl
    11f3:	8b 45 fc             	mov    eax,DWORD PTR [rbp-0x4]
    11f6:	89 c2                	mov    edx,eax
    11f8:	48 8b 45 e0          	mov    rax,QWORD PTR [rbp-0x20]
    11fc:	88 10                	mov    BYTE PTR [rax],dl
    11fe:	90                   	nop
    11ff:	5d                   	pop    rbp
    1200:	c3                   	ret
    1201:	f3 0f 1e fa          	endbr64
    1205:	55                   	push   rbp
    1206:	48 89 e5             	mov    rbp,rsp
    1209:	48 83 ec 20          	sub    rsp,0x20
    120d:	48 89 7d e8          	mov    QWORD PTR [rbp-0x18],rdi
    1211:	48 89 75 e0          	mov    QWORD PTR [rbp-0x20],rsi
    1215:	48 8b 45 e8          	mov    rax,QWORD PTR [rbp-0x18]
    1219:	48 89 c7             	mov    rdi,rax
    121c:	e8 7f fe ff ff       	call   10a0 <strlen@plt>
    1221:	89 45 fc             	mov    DWORD PTR [rbp-0x4],eax
    1224:	c7 45 f0 00 00 00 00 	mov    DWORD PTR [rbp-0x10],0x0
    122b:	c7 45 f4 00 00 00 00 	mov    DWORD PTR [rbp-0xc],0x0
    1232:	eb 16                	jmp    124a <ptrace@plt+0x17a>
    1234:	8b 45 f4             	mov    eax,DWORD PTR [rbp-0xc]
    1237:	48 63 d0             	movsxd rdx,eax
    123a:	48 8b 45 e0          	mov    rax,QWORD PTR [rbp-0x20]
    123e:	48 01 d0             	add    rax,rdx
    1241:	8b 55 f4             	mov    edx,DWORD PTR [rbp-0xc]
    1244:	88 10                	mov    BYTE PTR [rax],dl
    1246:	83 45 f4 01          	add    DWORD PTR [rbp-0xc],0x1
    124a:	81 7d f4 ff 00 00 00 	cmp    DWORD PTR [rbp-0xc],0xff
    1251:	7e e1                	jle    1234 <ptrace@plt+0x164>
    1253:	c7 45 f8 00 00 00 00 	mov    DWORD PTR [rbp-0x8],0x0
    125a:	eb 72                	jmp    12ce <ptrace@plt+0x1fe>
    125c:	8b 45 f8             	mov    eax,DWORD PTR [rbp-0x8]
    125f:	48 63 d0             	movsxd rdx,eax
    1262:	48 8b 45 e0          	mov    rax,QWORD PTR [rbp-0x20]
    1266:	48 01 d0             	add    rax,rdx
    1269:	0f b6 00             	movzx  eax,BYTE PTR [rax]
    126c:	0f b6 d0             	movzx  edx,al
    126f:	8b 45 f0             	mov    eax,DWORD PTR [rbp-0x10]
    1272:	8d 0c 02             	lea    ecx,[rdx+rax*1]
    1275:	8b 45 f8             	mov    eax,DWORD PTR [rbp-0x8]
    1278:	99                   	cdq
    1279:	f7 7d fc             	idiv   DWORD PTR [rbp-0x4]
    127c:	89 d0                	mov    eax,edx
    127e:	48 63 d0             	movsxd rdx,eax
    1281:	48 8b 45 e8          	mov    rax,QWORD PTR [rbp-0x18]
    1285:	48 01 d0             	add    rax,rdx
    1288:	0f b6 00             	movzx  eax,BYTE PTR [rax]
    128b:	0f be c0             	movsx  eax,al
    128e:	8d 14 01             	lea    edx,[rcx+rax*1]
    1291:	89 d0                	mov    eax,edx
    1293:	c1 f8 1f             	sar    eax,0x1f
    1296:	c1 e8 18             	shr    eax,0x18
    1299:	01 c2                	add    edx,eax
    129b:	0f b6 d2             	movzx  edx,dl
    129e:	29 c2                	sub    edx,eax
    12a0:	89 d0                	mov    eax,edx
    12a2:	89 45 f0             	mov    DWORD PTR [rbp-0x10],eax
    12a5:	8b 45 f0             	mov    eax,DWORD PTR [rbp-0x10]
    12a8:	48 63 d0             	movsxd rdx,eax
    12ab:	48 8b 45 e0          	mov    rax,QWORD PTR [rbp-0x20]
    12af:	48 01 c2             	add    rdx,rax
    12b2:	8b 45 f8             	mov    eax,DWORD PTR [rbp-0x8]
    12b5:	48 63 c8             	movsxd rcx,eax
    12b8:	48 8b 45 e0          	mov    rax,QWORD PTR [rbp-0x20]
    12bc:	48 01 c8             	add    rax,rcx
    12bf:	48 89 d6             	mov    rsi,rdx
    12c2:	48 89 c7             	mov    rdi,rax
    12c5:	e8 ff fe ff ff       	call   11c9 <ptrace@plt+0xf9>
    12ca:	83 45 f8 01          	add    DWORD PTR [rbp-0x8],0x1
    12ce:	81 7d f8 ff 00 00 00 	cmp    DWORD PTR [rbp-0x8],0xff
    12d5:	7e 85                	jle    125c <ptrace@plt+0x18c>
    12d7:	b8 00 00 00 00       	mov    eax,0x0
    12dc:	c9                   	leave
    12dd:	c3                   	ret
    12de:	f3 0f 1e fa          	endbr64
    12e2:	55                   	push   rbp
    12e3:	48 89 e5             	mov    rbp,rsp
    12e6:	48 83 ec 40          	sub    rsp,0x40
    12ea:	48 89 7d d8          	mov    QWORD PTR [rbp-0x28],rdi
    12ee:	48 89 75 d0          	mov    QWORD PTR [rbp-0x30],rsi
    12f2:	48 89 55 c8          	mov    QWORD PTR [rbp-0x38],rdx
    12f6:	c7 45 e4 00 00 00 00 	mov    DWORD PTR [rbp-0x1c],0x0
    12fd:	c7 45 e8 00 00 00 00 	mov    DWORD PTR [rbp-0x18],0x0
    1304:	48 c7 45 f0 00 00 00 	mov    QWORD PTR [rbp-0x10],0x0
    130b:	00 
    130c:	48 8b 45 d0          	mov    rax,QWORD PTR [rbp-0x30]
    1310:	48 89 c7             	mov    rdi,rax
    1313:	e8 88 fd ff ff       	call   10a0 <strlen@plt>
    1318:	48 89 45 f8          	mov    QWORD PTR [rbp-0x8],rax
    131c:	e9 c9 00 00 00       	jmp    13ea <ptrace@plt+0x31a>
    1321:	8b 45 e4             	mov    eax,DWORD PTR [rbp-0x1c]
    1324:	8d 50 01             	lea    edx,[rax+0x1]
    1327:	89 d0                	mov    eax,edx
    1329:	c1 f8 1f             	sar    eax,0x1f
    132c:	c1 e8 18             	shr    eax,0x18
    132f:	01 c2                	add    edx,eax
    1331:	0f b6 d2             	movzx  edx,dl
    1334:	29 c2                	sub    edx,eax
    1336:	89 d0                	mov    eax,edx
    1338:	89 45 e4             	mov    DWORD PTR [rbp-0x1c],eax
    133b:	8b 45 e4             	mov    eax,DWORD PTR [rbp-0x1c]
    133e:	48 63 d0             	movsxd rdx,eax
    1341:	48 8b 45 d8          	mov    rax,QWORD PTR [rbp-0x28]
    1345:	48 01 d0             	add    rax,rdx
    1348:	0f b6 00             	movzx  eax,BYTE PTR [rax]
    134b:	0f b6 d0             	movzx  edx,al
    134e:	8b 45 e8             	mov    eax,DWORD PTR [rbp-0x18]
    1351:	01 c2                	add    edx,eax
    1353:	89 d0                	mov    eax,edx
    1355:	c1 f8 1f             	sar    eax,0x1f
    1358:	c1 e8 18             	shr    eax,0x18
    135b:	01 c2                	add    edx,eax
    135d:	0f b6 d2             	movzx  edx,dl
    1360:	29 c2                	sub    edx,eax
    1362:	89 d0                	mov    eax,edx
    1364:	89 45 e8             	mov    DWORD PTR [rbp-0x18],eax
    1367:	8b 45 e8             	mov    eax,DWORD PTR [rbp-0x18]
    136a:	48 63 d0             	movsxd rdx,eax
    136d:	48 8b 45 d8          	mov    rax,QWORD PTR [rbp-0x28]
    1371:	48 01 c2             	add    rdx,rax
    1374:	8b 45 e4             	mov    eax,DWORD PTR [rbp-0x1c]
    1377:	48 63 c8             	movsxd rcx,eax
    137a:	48 8b 45 d8          	mov    rax,QWORD PTR [rbp-0x28]
    137e:	48 01 c8             	add    rax,rcx
    1381:	48 89 d6             	mov    rsi,rdx
    1384:	48 89 c7             	mov    rdi,rax
    1387:	e8 3d fe ff ff       	call   11c9 <ptrace@plt+0xf9>
    138c:	8b 45 e4             	mov    eax,DWORD PTR [rbp-0x1c]
    138f:	48 63 d0             	movsxd rdx,eax
    1392:	48 8b 45 d8          	mov    rax,QWORD PTR [rbp-0x28]
    1396:	48 01 d0             	add    rax,rdx
    1399:	0f b6 10             	movzx  edx,BYTE PTR [rax]
    139c:	8b 45 e8             	mov    eax,DWORD PTR [rbp-0x18]
    139f:	48 63 c8             	movsxd rcx,eax
    13a2:	48 8b 45 d8          	mov    rax,QWORD PTR [rbp-0x28]
    13a6:	48 01 c8             	add    rax,rcx
    13a9:	0f b6 00             	movzx  eax,BYTE PTR [rax]
    13ac:	01 d0                	add    eax,edx
    13ae:	0f b6 d0             	movzx  edx,al
    13b1:	48 8b 45 d8          	mov    rax,QWORD PTR [rbp-0x28]
    13b5:	48 01 d0             	add    rax,rdx
    13b8:	0f b6 00             	movzx  eax,BYTE PTR [rax]
    13bb:	0f b6 c0             	movzx  eax,al
    13be:	89 45 ec             	mov    DWORD PTR [rbp-0x14],eax
    13c1:	48 8b 55 d0          	mov    rdx,QWORD PTR [rbp-0x30]
    13c5:	48 8b 45 f0          	mov    rax,QWORD PTR [rbp-0x10]
    13c9:	48 01 d0             	add    rax,rdx
    13cc:	0f b6 00             	movzx  eax,BYTE PTR [rax]
    13cf:	8b 55 ec             	mov    edx,DWORD PTR [rbp-0x14]
    13d2:	31 d0                	xor    eax,edx
    13d4:	89 c1                	mov    ecx,eax
    13d6:	48 8b 55 c8          	mov    rdx,QWORD PTR [rbp-0x38]
    13da:	48 8b 45 f0          	mov    rax,QWORD PTR [rbp-0x10]
    13de:	48 01 d0             	add    rax,rdx
    13e1:	89 ca                	mov    edx,ecx
    13e3:	88 10                	mov    BYTE PTR [rax],dl
    13e5:	48 83 45 f0 01       	add    QWORD PTR [rbp-0x10],0x1
    13ea:	48 8b 45 f0          	mov    rax,QWORD PTR [rbp-0x10]
    13ee:	48 3b 45 f8          	cmp    rax,QWORD PTR [rbp-0x8]
    13f2:	0f 82 29 ff ff ff    	jb     1321 <ptrace@plt+0x251>
    13f8:	b8 00 00 00 00       	mov    eax,0x0
    13fd:	c9                   	leave
    13fe:	c3                   	ret
    13ff:	f3 0f 1e fa          	endbr64
    1403:	55                   	push   rbp
    1404:	48 89 e5             	mov    rbp,rsp
    1407:	48 81 ec 30 01 00 00 	sub    rsp,0x130
    140e:	48 89 bd e8 fe ff ff 	mov    QWORD PTR [rbp-0x118],rdi
    1415:	48 89 b5 e0 fe ff ff 	mov    QWORD PTR [rbp-0x120],rsi
    141c:	48 89 95 d8 fe ff ff 	mov    QWORD PTR [rbp-0x128],rdx
    1423:	64 48 8b 04 25 28 00 	mov    rax,QWORD PTR fs:0x28
    142a:	00 00 
    142c:	48 89 45 f8          	mov    QWORD PTR [rbp-0x8],rax
    1430:	31 c0                	xor    eax,eax
    1432:	48 8d 95 f0 fe ff ff 	lea    rdx,[rbp-0x110]
    1439:	48 8b 85 e8 fe ff ff 	mov    rax,QWORD PTR [rbp-0x118]
    1440:	48 89 d6             	mov    rsi,rdx
    1443:	48 89 c7             	mov    rdi,rax
    1446:	e8 b6 fd ff ff       	call   1201 <ptrace@plt+0x131>
    144b:	48 8b 95 d8 fe ff ff 	mov    rdx,QWORD PTR [rbp-0x128]
    1452:	48 8b 8d e0 fe ff ff 	mov    rcx,QWORD PTR [rbp-0x120]
    1459:	48 8d 85 f0 fe ff ff 	lea    rax,[rbp-0x110]
    1460:	48 89 ce             	mov    rsi,rcx
    1463:	48 89 c7             	mov    rdi,rax
    1466:	e8 73 fe ff ff       	call   12de <ptrace@plt+0x20e>
    146b:	b8 00 00 00 00       	mov    eax,0x0
    1470:	48 8b 4d f8          	mov    rcx,QWORD PTR [rbp-0x8]
    1474:	64 48 33 0c 25 28 00 	xor    rcx,QWORD PTR fs:0x28
    147b:	00 00 
    147d:	74 05                	je     1484 <ptrace@plt+0x3b4>
    147f:	e8 2c fc ff ff       	call   10b0 <__stack_chk_fail@plt>
    1484:	c9                   	leave
    1485:	c3                   	ret
    1486:	f3 0f 1e fa          	endbr64
    148a:	55                   	push   rbp
    148b:	48 89 e5             	mov    rbp,rsp
    148e:	48 83 ec 30          	sub    rsp,0x30
    1492:	89 7d dc             	mov    DWORD PTR [rbp-0x24],edi
    1495:	48 89 75 d0          	mov    QWORD PTR [rbp-0x30],rsi
    1499:	c7 45 e4 00 00 00 00 	mov    DWORD PTR [rbp-0x1c],0x0
    14a0:	48 8d 05 5d 0b 00 00 	lea    rax,[rip+0xb5d]        # 2004 <ptrace@plt+0xf34>
    14a7:	48 89 45 e8          	mov    QWORD PTR [rbp-0x18],rax
    14ab:	48 8d 05 5f 0b 00 00 	lea    rax,[rip+0xb5f]        # 2011 <ptrace@plt+0xf41>
    14b2:	48 89 45 f0          	mov    QWORD PTR [rbp-0x10],rax
    14b6:	48 8b 45 f0          	mov    rax,QWORD PTR [rbp-0x10]
    14ba:	48 89 c7             	mov    rdi,rax
    14bd:	e8 de fb ff ff       	call   10a0 <strlen@plt>
    14c2:	48 c1 e0 02          	shl    rax,0x2
    14c6:	48 89 c7             	mov    rdi,rax
    14c9:	e8 f2 fb ff ff       	call   10c0 <malloc@plt>
    14ce:	48 89 45 f8          	mov    QWORD PTR [rbp-0x8],rax
    14d2:	b9 00 00 00 00       	mov    ecx,0x0
    14d7:	ba 01 00 00 00       	mov    edx,0x1
    14dc:	be 00 00 00 00       	mov    esi,0x0
    14e1:	bf 00 00 00 00       	mov    edi,0x0
    14e6:	b8 00 00 00 00       	mov    eax,0x0
    14eb:	e8 e0 fb ff ff       	call   10d0 <ptrace@plt>
    14f0:	48 83 f8 ff          	cmp    rax,0xffffffffffffffff
    14f4:	75 13                	jne    1509 <ptrace@plt+0x439>
    14f6:	48 8d 3d 2e 0b 00 00 	lea    rdi,[rip+0xb2e]        # 202b <ptrace@plt+0xf5b>
    14fd:	e8 8e fb ff ff       	call   1090 <puts@plt>
    1502:	b8 00 00 00 00       	mov    eax,0x0
    1507:	eb 44                	jmp    154d <ptrace@plt+0x47d>
    1509:	81 7d e4 39 05 00 00 	cmp    DWORD PTR [rbp-0x1c],0x539
    1510:	74 13                	je     1525 <ptrace@plt+0x455>
    1512:	48 8d 3d 1e 0b 00 00 	lea    rdi,[rip+0xb1e]        # 2037 <ptrace@plt+0xf67>
    1519:	e8 72 fb ff ff       	call   1090 <puts@plt>
    151e:	b8 00 00 00 00       	mov    eax,0x0
    1523:	eb 28                	jmp    154d <ptrace@plt+0x47d>
    1525:	48 8b 55 f8          	mov    rdx,QWORD PTR [rbp-0x8]
    1529:	48 8b 4d f0          	mov    rcx,QWORD PTR [rbp-0x10]
    152d:	48 8b 45 e8          	mov    rax,QWORD PTR [rbp-0x18]
    1531:	48 89 ce             	mov    rsi,rcx
    1534:	48 89 c7             	mov    rdi,rax
    1537:	e8 c3 fe ff ff       	call   13ff <ptrace@plt+0x32f>
    153c:	48 8b 45 f8          	mov    rax,QWORD PTR [rbp-0x8]
    1540:	48 89 c7             	mov    rdi,rax
    1543:	e8 48 fb ff ff       	call   1090 <puts@plt>
    1548:	b8 00 00 00 00       	mov    eax,0x0
    154d:	c9                   	leave
    154e:	c3                   	ret
    154f:	90                   	nop
    1550:	f3 0f 1e fa          	endbr64
    1554:	41 57                	push   r15
    1556:	4c 8d 3d 3b 28 00 00 	lea    r15,[rip+0x283b]        # 3d98 <ptrace@plt+0x2cc8>
    155d:	41 56                	push   r14
    155f:	49 89 d6             	mov    r14,rdx
    1562:	41 55                	push   r13
    1564:	49 89 f5             	mov    r13,rsi
    1567:	41 54                	push   r12
    1569:	41 89 fc             	mov    r12d,edi
    156c:	55                   	push   rbp
    156d:	48 8d 2d 2c 28 00 00 	lea    rbp,[rip+0x282c]        # 3da0 <ptrace@plt+0x2cd0>
    1574:	53                   	push   rbx
    1575:	4c 29 fd             	sub    rbp,r15
    1578:	48 83 ec 08          	sub    rsp,0x8
    157c:	e8 7f fa ff ff       	call   1000 <__cxa_finalize@plt-0x80>
    1581:	48 c1 fd 03          	sar    rbp,0x3
    1585:	74 1f                	je     15a6 <ptrace@plt+0x4d6>
    1587:	31 db                	xor    ebx,ebx
    1589:	0f 1f 80 00 00 00 00 	nop    DWORD PTR [rax+0x0]
    1590:	4c 89 f2             	mov    rdx,r14
    1593:	4c 89 ee             	mov    rsi,r13
    1596:	44 89 e7             	mov    edi,r12d
    1599:	41 ff 14 df          	call   QWORD PTR [r15+rbx*8]
    159d:	48 83 c3 01          	add    rbx,0x1
    15a1:	48 39 dd             	cmp    rbp,rbx
    15a4:	75 ea                	jne    1590 <ptrace@plt+0x4c0>
    15a6:	48 83 c4 08          	add    rsp,0x8
    15aa:	5b                   	pop    rbx
    15ab:	5d                   	pop    rbp
    15ac:	41 5c                	pop    r12
    15ae:	41 5d                	pop    r13
    15b0:	41 5e                	pop    r14
    15b2:	41 5f                	pop    r15
    15b4:	c3                   	ret
    15b5:	66 66 2e 0f 1f 84 00 	data16 cs nop WORD PTR [rax+rax*1+0x0]
    15bc:	00 00 00 00 
    15c0:	f3 0f 1e fa          	endbr64
    15c4:	c3                   	ret

Patching

One way of solving this issue is by changing jmp 154d (e2 28) in machine code to nop; nop (90 90), so that there is no unconditional jump:

xxd -p anti_flag | tr -d \\n | sed s/eb28/9090/g | xxd -r -p > anti_flag_patched

Another way we can open the binary in Ghidra. All strings can be viewed by navigating to Windows > Defined strings

image.png

We can see the Well done!! string in the list. Hit CTRL + SHIFT + F to look at it’s cross-references and then click on the result.

image.png

At the end of the first block, we see it calling ptrace() and checking if the result is -1 . If this is true, the binary prints Well done!!! and exits.

However, the execution proceeds if it’s not being debugged. The function compares the RBP-0x1c variable with 0x539 (1337). It goes on and prints No flag for you if this is false, else calls another function.

It's likely that this function ends up printing the flag. As the program takes no input, we will have to manually set the variable to 1337 . Note: The function FUN_001013ff is a decryption routine and need not be reversed.

Let's use GDB to debug the binary. Add a breakpoint at ptrace and run the binary.

pwndbg> b ptrace
Breakpoint 1 at 0x10d0
pwndbg> r
Starting program: /home/xi/hackthebox/challenges/Anti Flag/anti_flag 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, ptrace (request=PTRACE_TRACEME)
    at ../sysdeps/unix/sysv/linux/ptrace.c:30
30	../sysdeps/unix/sysv/linux/ptrace.c: No such file or directory.
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────[ REGISTERS / show-flags off / show-compact-regs off ]─────────────
 RAX  0x0
*RBX  0x7fffffffdd18 —▸ 0x7fffffffe0a4 ◂— '/home/xi/hackthebox/challenges/Anti Flag/anti_flag'
 RCX  0x0
*RDX  0x1
 RDI  0x0
 RSI  0x0
*R8   0x70
*R9   0x1
*R10  0x4
 R11  0x0
 R12  0x0
*R13  0x7fffffffdd28 —▸ 0x7fffffffe0d7 ◂— 'SYSTEMD_EXEC_PID=1935'
*R14  0x7ffff7ffd000 (_rtld_global) —▸ 0x7ffff7ffe2c0 —▸ 0x555555554000 ◂— 0x10102464c457f
 R15  0x0
*RBP  0x7fffffffdc00 ◂— 0x1
*RSP  0x7fffffffdbc8 —▸ 0x5555555554f0 ◂— cmp rax, -1
*RIP  0x7ffff7ec48b0 (ptrace) ◂— sub rsp, 0x68
──────────────────────[ DISASM / x86-64 / set emulate on ]──────────────────────
 ► 0x7ffff7ec48b0 <ptrace>       sub    rsp, 0x68
   0x7ffff7ec48b4 <ptrace+4>     lea    r8d, [rdi - 1]
   0x7ffff7ec48b8 <ptrace+8>     mov    qword ptr [rsp + 0x38], rsi
   0x7ffff7ec48bd <ptrace+13>    lea    r10, [rsp + 8]
   0x7ffff7ec48c2 <ptrace+18>    mov    qword ptr [rsp + 0x40], rdx
   0x7ffff7ec48c7 <ptrace+23>    mov    qword ptr [rsp + 0x48], rcx
   0x7ffff7ec48cc <ptrace+28>    mov    rax, qword ptr fs:[0x28]
   0x7ffff7ec48d5 <ptrace+37>    mov    qword ptr [rsp + 0x28], rax
   0x7ffff7ec48da <ptrace+42>    xor    eax, eax
   0x7ffff7ec48dc <ptrace+44>    lea    rax, [rsp + 0x70]
   0x7ffff7ec48e1 <ptrace+49>    cmp    r8d, 3
───────────────────────────────────[ STACK ]────────────────────────────────────
00:0000│ rsp 0x7fffffffdbc8 —▸ 0x5555555554f0 ◂— cmp rax, -1
01:0008│-030 0x7fffffffdbd0 —▸ 0x7fffffffdd18 —▸ 0x7fffffffe0a4 ◂— '/home/xi/hackthebox/challenges/Anti Flag/anti_flag'
02:0010│-028 0x7fffffffdbd8 ◂— 0x100000000
03:0018│-020 0x7fffffffdbe0 ◂— 0x0
04:0020│-018 0x7fffffffdbe8 —▸ 0x555555556004 ◂— '2asdf-012=14'
05:0028│-010 0x7fffffffdbf0 —▸ 0x555555556011 ◂— 0x2a23d90c4f35c0d0
06:0030│-008 0x7fffffffdbf8 —▸ 0x5555555592a0 ◂— 0x0
07:0038│ rbp 0x7fffffffdc00 ◂— 0x1
─────────────────────────────────[ BACKTRACE ]──────────────────────────────────
 ► 0   0x7ffff7ec48b0 ptrace
   1   0x5555555554f0
   2   0x7ffff7de3c8a __libc_start_call_main+122
   3   0x7ffff7de3d45 __libc_start_main+133
   4   0x55555555510e

When the breakpoint hits, enter finish to step out of the function. This should bring us back to the function where the comparison occurs.

pwndbg> finish
Run till exit from #0  ptrace (request=PTRACE_TRACEME)
    at ../sysdeps/unix/sysv/linux/ptrace.c:30
0x00005555555554f0 in ?? ()
Value returned is $1 = -1
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────[ REGISTERS / show-flags off / show-compact-regs off ]─────────────
*RAX  0xffffffffffffffff
 RBX  0x7fffffffdd18 —▸ 0x7fffffffe0a4 ◂— '/home/xi/hackthebox/challenges/Anti Flag/anti_flag'
*RCX  0x7ffff7ec490a (ptrace+90) ◂— cmp rax, -0x1000 /* 'H=' */
*RDX  0x0
 RDI  0x0
 RSI  0x0
*R8   0xffffffff
 R9   0x1
*R10  0x0
*R11  0x286
 R12  0x0
 R13  0x7fffffffdd28 —▸ 0x7fffffffe0d7 ◂— 'SYSTEMD_EXEC_PID=1935'
 R14  0x7ffff7ffd000 (_rtld_global) —▸ 0x7ffff7ffe2c0 —▸ 0x555555554000 ◂— 0x10102464c457f
 R15  0x0
 RBP  0x7fffffffdc00 ◂— 0x1
*RSP  0x7fffffffdbd0 —▸ 0x7fffffffdd18 —▸ 0x7fffffffe0a4 ◂— '/home/xi/hackthebox/challenges/Anti Flag/anti_flag'
*RIP  0x5555555554f0 ◂— cmp rax, -1
──────────────────────[ DISASM / x86-64 / set emulate on ]──────────────────────
 ► 0x5555555554f0    cmp    rax, -1
   0x5555555554f4    jne    0x555555555509                <0x555555555509>
 
   0x5555555554f6    lea    rdi, [rip + 0xb2e]
   0x5555555554fd    call   puts@plt                <puts@plt>
 
   0x555555555502    mov    eax, 0
   0x555555555507    jmp    0x55555555554d                <0x55555555554d>
 
   0x555555555509    cmp    dword ptr [rbp - 0x1c], 0x539
   0x555555555510    je     0x555555555525                <0x555555555525>
 
   0x555555555512    lea    rdi, [rip + 0xb1e]
   0x555555555519    call   puts@plt                <puts@plt>
 
   0x55555555551e    mov    eax, 0
───────────────────────────────────[ STACK ]────────────────────────────────────
00:0000│ rsp 0x7fffffffdbd0 —▸ 0x7fffffffdd18 —▸ 0x7fffffffe0a4 ◂— '/home/xi/hackthebox/challenges/Anti Flag/anti_flag'
01:0008│-028 0x7fffffffdbd8 ◂— 0x100000000
02:0010│-020 0x7fffffffdbe0 ◂— 0x0
03:0018│-018 0x7fffffffdbe8 —▸ 0x555555556004 ◂— '2asdf-012=14'
04:0020│-010 0x7fffffffdbf0 —▸ 0x555555556011 ◂— 0x2a23d90c4f35c0d0
05:0028│-008 0x7fffffffdbf8 —▸ 0x5555555592a0 ◂— 0x0
06:0030│ rbp 0x7fffffffdc00 ◂— 0x1
07:0038│+008 0x7fffffffdc08 —▸ 0x7ffff7de3c8a (__libc_start_call_main+122) ◂— mov edi, eax
─────────────────────────────────[ BACKTRACE ]──────────────────────────────────
 ► 0   0x5555555554f0
   1   0x7ffff7de3c8a __libc_start_call_main+122
   2   0x7ffff7de3d45 __libc_start_main+133
   3   0x55555555510e

We change the value of rax to 1 to bypass the check and hit ni to step.

pwndbg> set $rax=1
pwndbg> ni
0x00005555555554f4 in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────[ REGISTERS / show-flags off / show-compact-regs off ]─────────────
 RAX  0x1
 RBX  0x7fffffffdd18 —▸ 0x7fffffffe0a4 ◂— '/home/xi/hackthebox/challenges/Anti Flag/anti_flag'
 RCX  0x7ffff7ec490a (ptrace+90) ◂— cmp rax, -0x1000 /* 'H=' */
 RDX  0x0
 RDI  0x0
 RSI  0x0
 R8   0xffffffff
 R9   0x1
 R10  0x0
 R11  0x286
 R12  0x0
 R13  0x7fffffffdd28 —▸ 0x7fffffffe0d7 ◂— 'SYSTEMD_EXEC_PID=1935'
 R14  0x7ffff7ffd000 (_rtld_global) —▸ 0x7ffff7ffe2c0 —▸ 0x555555554000 ◂— 0x10102464c457f
 R15  0x0
 RBP  0x7fffffffdc00 ◂— 0x1
 RSP  0x7fffffffdbd0 —▸ 0x7fffffffdd18 —▸ 0x7fffffffe0a4 ◂— '/home/xi/hackthebox/challenges/Anti Flag/anti_flag'
*RIP  0x5555555554f4 ◂— jne 0x555555555509
──────────────────────[ DISASM / x86-64 / set emulate on ]──────────────────────
   0x5555555554f0    cmp    rax, -1
 ► 0x5555555554f4  ✔ jne    0x555555555509                <0x555555555509>
    ↓
   0x555555555509    cmp    dword ptr [rbp - 0x1c], 0x539
   0x555555555510    je     0x555555555525                <0x555555555525>
 
   0x555555555512    lea    rdi, [rip + 0xb1e]
   0x555555555519    call   puts@plt                <puts@plt>
 
   0x55555555551e    mov    eax, 0
   0x555555555523    jmp    0x55555555554d                <0x55555555554d>
 
   0x555555555525    mov    rdx, qword ptr [rbp - 8]
   0x555555555529    mov    rcx, qword ptr [rbp - 0x10]
   0x55555555552d    mov    rax, qword ptr [rbp - 0x18]
───────────────────────────────────[ STACK ]────────────────────────────────────
00:0000│ rsp 0x7fffffffdbd0 —▸ 0x7fffffffdd18 —▸ 0x7fffffffe0a4 ◂— '/home/xi/hackthebox/challenges/Anti Flag/anti_flag'
01:0008│-028 0x7fffffffdbd8 ◂— 0x100000000
02:0010│-020 0x7fffffffdbe0 ◂— 0x0
03:0018│-018 0x7fffffffdbe8 —▸ 0x555555556004 ◂— '2asdf-012=14'
04:0020│-010 0x7fffffffdbf0 —▸ 0x555555556011 ◂— 0x2a23d90c4f35c0d0
05:0028│-008 0x7fffffffdbf8 —▸ 0x5555555592a0 ◂— 0x0
06:0030│ rbp 0x7fffffffdc00 ◂— 0x1
07:0038│+008 0x7fffffffdc08 —▸ 0x7ffff7de3c8a (__libc_start_call_main+122) ◂— mov edi, eax
─────────────────────────────────[ BACKTRACE ]──────────────────────────────────
 ► 0   0x5555555554f4
   1   0x7ffff7de3c8a __libc_start_call_main+122
   2   0x7ffff7de3d45 __libc_start_main+133
   3   0x55555555510e

Step for a couple of times should bring us to the comparison with 1337. We can manually set the variable and bypass this check as well

pwndbg> step
0x0000555555555509 in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────[ REGISTERS / show-flags off / show-compact-regs off ]─────────────
 RAX  0x1
 RBX  0x7fffffffdd18 —▸ 0x7fffffffe0a4 ◂— '/home/xi/hackthebox/challenges/Anti Flag/anti_flag'
 RCX  0x7ffff7ec490a (ptrace+90) ◂— cmp rax, -0x1000 /* 'H=' */
 RDX  0x0
 RDI  0x0
 RSI  0x0
 R8   0xffffffff
 R9   0x1
 R10  0x0
 R11  0x286
 R12  0x0
 R13  0x7fffffffdd28 —▸ 0x7fffffffe0d7 ◂— 'SYSTEMD_EXEC_PID=1935'
 R14  0x7ffff7ffd000 (_rtld_global) —▸ 0x7ffff7ffe2c0 —▸ 0x555555554000 ◂— 0x10102464c457f
 R15  0x0
 RBP  0x7fffffffdc00 ◂— 0x1
 RSP  0x7fffffffdbd0 —▸ 0x7fffffffdd18 —▸ 0x7fffffffe0a4 ◂— '/home/xi/hackthebox/challenges/Anti Flag/anti_flag'
*RIP  0x555555555509 ◂— cmp dword ptr [rbp - 0x1c], 0x539
──────────────────────[ DISASM / x86-64 / set emulate on ]──────────────────────
   0x5555555554f0    cmp    rax, -1
   0x5555555554f4    jne    0x555555555509                <0x555555555509>
    ↓
 ► 0x555555555509    cmp    dword ptr [rbp - 0x1c], 0x539
   0x555555555510    je     0x555555555525                <0x555555555525>
 
   0x555555555512    lea    rdi, [rip + 0xb1e]
   0x555555555519    call   puts@plt                <puts@plt>
 
   0x55555555551e    mov    eax, 0
   0x555555555523    jmp    0x55555555554d                <0x55555555554d>
 
   0x555555555525    mov    rdx, qword ptr [rbp - 8]
   0x555555555529    mov    rcx, qword ptr [rbp - 0x10]
   0x55555555552d    mov    rax, qword ptr [rbp - 0x18]
───────────────────────────────────[ STACK ]────────────────────────────────────
00:0000│ rsp 0x7fffffffdbd0 —▸ 0x7fffffffdd18 —▸ 0x7fffffffe0a4 ◂— '/home/xi/hackthebox/challenges/Anti Flag/anti_flag'
01:0008│-028 0x7fffffffdbd8 ◂— 0x100000000
02:0010│-020 0x7fffffffdbe0 ◂— 0x0
03:0018│-018 0x7fffffffdbe8 —▸ 0x555555556004 ◂— '2asdf-012=14'
04:0020│-010 0x7fffffffdbf0 —▸ 0x555555556011 ◂— 0x2a23d90c4f35c0d0
05:0028│-008 0x7fffffffdbf8 —▸ 0x5555555592a0 ◂— 0x0
06:0030│ rbp 0x7fffffffdc00 ◂— 0x1
07:0038│+008 0x7fffffffdc08 —▸ 0x7ffff7de3c8a (__libc_start_call_main+122) ◂— mov edi, eax
─────────────────────────────────[ BACKTRACE ]──────────────────────────────────
 ► 0   0x555555555509
   1   0x7ffff7de3c8a __libc_start_call_main+122
   2   0x7ffff7de3d45 __libc_start_main+133
   3   0x55555555510e

pwndbg> p $rbp-0x1c
$2 = (void *) 0x7fffffffdbe4
pwndbg> set *0x7fffffffdbe4=1337
pwndbg> c
Continuing.
HTB{y0u_trac3_m3_g00d!!!}
[Inferior 1 (process 177339) exited normally]

5 IRCWare

IRCWare is an easy Reversing challenge. Players will analyse a handwritten binary which connects to a backdoored IRC server.

Solution

Running the binary, it prints out a failure message. Using strace, we can see that it attempts a connection to 127.0.0.1:8000

image.png

As can be seen, the program is trying to connect to 127.0.0.1:8000:

connect(3, {sa_family=AF_INET, sin_port=htons(8000), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 ECONNREFUSED (Connection refused)

The program fails because there is nothing listening on that port. Let’s use nc for that, in another terminal:

image.png

Looks like we are connected to a server

Decompilation

Now in Ghidra, we can search for strings like USER or NICK and find this function via cross-references:

image.png

void FUN_00400349() {
  char cVar1;
  char cVar2;
  byte bVar3;
  byte bVar4;
  long lVar5;
  long lVar6;
  ulong uVar7;
  long lVar8;
  byte *pbVar9;
  char *pcVar10;
  char *pcVar11;
  byte *pbVar12;
  char *pcVar13;
  char *pcVar14;
  
  lVar8 = 0x1000;

  do {
    lVar6 = -lVar8;
    pcVar10 = (char *) (lVar6 + 0x6031a9);

    if (*pcVar10 == '\0') {
      return;
    }

    if (*pcVar10 == 'P') {
      lVar5 = 7;
      pcVar11 = pcVar10;
      pcVar13 = "PING :";

      do {
        if (lVar5 == 0) break;

        lVar5 = lVar5 + -1;
        cVar1 = *pcVar11;
        cVar2 = *pcVar13;
        pcVar11 = pcVar11 + 1;
        pcVar13 = pcVar13 + 1;
      } while (cVar1 == cVar2);

      if (lVar5 == 0) {
        DAT_006021aa = 0x4f;
        FUN_004002fb();
        lVar8 = _DAT_00601010;
        _DAT_00601010 = _DAT_00601010 + 1;

        if (lVar8 == 0) {
          FUN_004002fb();
          FUN_004002fb();
          FUN_004002fb();
        }

        return;
      }

      lVar5 = 0x18;
      pcVar11 = pcVar10;
      pcVar13 = "PRIVMSG #secret :@pass ";

      do {
        if (lVar5 == 0) break;
        lVar5 = lVar5 + -1;
        cVar1 = *pcVar11;
        cVar2 = *pcVar13;
        pcVar11 = pcVar11 + 1;
        pcVar13 = pcVar13 + 1;
      } while (cVar1 == cVar2);

      if (lVar5 == 0) {
        pbVar12 = (byte *) (lVar6 + 0x6031c0);
        pcVar10 = "RJJ3DSCP";
        pbVar9 = &DAT_00601147;
        uVar7 = 0;
        break;
      }

      lVar5 = 0x18;
      pcVar11 = pcVar10;
      pcVar13 = "PRIVMSG #secret :@exec ";

      do {
        pcVar14 = pcVar13;

        if (lVar5 == 0) break;

        lVar5 = lVar5 + -1;
        pcVar14 = pcVar13 + 1;
        cVar1 = *pcVar11;
        cVar2 = *pcVar13;
        pcVar11 = pcVar11 + 1;
        pcVar13 = pcVar14;
      } while (cVar1 == cVar2);

      if (lVar5 == 0) {
        if (_DAT_00601008 == 0) {
          FUN_00400485(pcVar14, "Requires password", &DAT_006021a9, 0x12);
          return;
        }

        DAT_0060108a = lVar6 + 0x6031c0;
        FUN_00400592();
        return;
      }

      lVar6 = 0x17;
      pcVar11 = pcVar10;
      pcVar13 = "PRIVMSG #secret :@flag";

      do {
        pcVar14 = pcVar13;

        if (lVar6 == 0) break;

        lVar6 = lVar6 + -1;
        pcVar14 = pcVar13 + 1;
        cVar1 = *pcVar11;
        cVar2 = *pcVar13;
        pcVar11 = pcVar11 + 1;
        pcVar13 = pcVar14;
      } while (cVar1 == cVar2);

      if (lVar6 == 0) {
        if (_DAT_00601008 == 0) {
          FUN_00400485(pcVar14, "Requires password", &DAT_006021a9, 0x12);
          return;
        }

        FUN_004004df(pcVar14,pcVar10);
        FUN_00400485();
        FUN_004004df();
        return;
      }
    }

    lVar8 = lVar8 + -1;

    if (lVar8 == 0) {
      return;
    }
  } while (true);

LAB_00400401:
  bVar3 = *pbVar12;
  *pbVar9 = bVar3;

  if (((bVar3 == 0) || (bVar3 == 10)) || (bVar3 == 0xd)) {
    if (uVar7 == 8) {
      _DAT_00601008 = _DAT_00601008 + 1;
      FUN_00400485(pcVar10, "Accepted", 8, 9);
    } else {
LAB_00400466:
      _DAT_00601008 = 0;
      FUN_00400485(pcVar10, "Rejected", uVar7, 9);
    }
  
    return;
  }

  if (8 < uVar7) goto LAB_00400466;

  bVar4 = bVar3;

  if (((0x40 < bVar3) && (bVar3 < 0x5b)) && (bVar4 = bVar3 + 0x11, 0x5a < bVar4)) {  
    bVar4 = bVar3 - 9;
  }

  if (*pcVar10 != bVar4) goto LAB_00400466;

  uVar7 = uVar7 + 1;
  pbVar9 = pbVar9 + 1;
  pbVar12 = pbVar12 + 1;
  pcVar10 = (char *) ((byte *) pcVar10 + 1);

  goto LAB_00400401;
}

If we analyze the code a bit deeper, the interesting part is at the bottom. We can rename some variables and change types to make the code more readable:

LAB_00400401:
  b = *p_input_;
  *p_input = b;

  if (((b == '\0') || (b == '\n')) || (b == '\r')) {
    if (i == 8) {
      _DAT_00601008 = _DAT_00601008 + 1;
      FUN_00400485(expected, "Accepted", 8, 9);
    } else {
LAB_00400466:
      _DAT_00601008 = 0;
      FUN_00400485(expected, "Rejected", i, 9);
    }

    return;
  }

  if (8 < i) goto LAB_00400466;

  _b = b;

  if ((('@' < b) && (b < '[')) && (_b = b + 0x11, 'Z' < _b)) {  
    _b = b - 9;
  }

  if (*expected != _b) goto LAB_00400466;

  i = i + 1;
  p_input = p_input + 1;
  p_input_ = p_input_ + 1;
  expected = (char *) ((byte *) expected + 1);

  goto LAB_00400401;
}

And also, the variable named expected is set to "RJJ3DSCP" some lines above.

Basically, we have a loop over the characters of a password, which are checked one by one. If after the operations, the result byte does not match with the expected one, the program will say "Rejected":

image.png

Decryption

"RJJ3DSCP" is not the password, it is the expected result of the byte operations applied on the password. These are the byte operations:

 _b = b;

  if ((('@' < b) && (b < '[')) && (_b = b + 0x11, 'Z' < _b)) {  
    _b = b - 9;
  }

Instead of reversing the operations, I will write a bit of C code using the above algorithm and try to find which input bytes give the expected result "RJJ3DSCP":

#include <stdio.h>

void main() {
        int i;
        char b;
        char _b;
        char expected[8] = "RJJ3DSCP";

        for (i = 0; i < 8; i++) {
                for (b = 0; b < 0x7f; b++) {
                        _b = b;

                        if ((('@' < b) && (b < '[')) && (_b = b + 0x11, 'Z' < _b)) {  
                                _b = b - 9;
                        }

                        if (_b == expected[i]) {
                                putchar(b);
                                break;
                        }
                }
        }

        putchar('\n');
}

image.png

image.png

6 Sekure Decrypt

Sekure Decrypt is an easy Reversing challenge. Players will analyze a binary along with a core dump in order to extract secrets, then reimplement the program, fixing a bug in the code

We are given a binary called dec , the C source code (src.c) and core file (core)

image.png

Source code analysis

Since we have the source code, let’s analyze it:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mcrypt.h>
#include <math.h>
#include <stdint.h>
#include <stdlib.h>

int encrypt(void* buffer, int buffer_len, char* IV, char* key, int key_len) {
  MCRYPT td = mcrypt_module_open("rijndael-128", NULL, "cbc", NULL);
  int blocksize = mcrypt_enc_get_block_size(td);

  if( buffer_len % blocksize != 0 ) { 
    return 1; 
  }

  mcrypt_generic_init(td, key, key_len, IV);
  mcrypt_generic(td, buffer, buffer_len);
  mcrypt_generic_deinit (td);
  mcrypt_module_close(td);
  
  return 0;
}

int decrypt(void* buffer, int buffer_len, char* IV, char* key, int key_len) {
  MCRYPT td = mcrypt_module_open("rijndael-128", NULL, "cbc", NULL);
  int blocksize = mcrypt_enc_get_block_size(td);

  if( buffer_len % blocksize != 0 ){ 
    return 1;
  }
  
  mcrypt_generic_init(td, key, key_len, IV);
  mdecrypt_generic(td, buffer, buffer_len);
  mcrypt_generic_deinit (td);
  mcrypt_module_close(td);
  
  return 0;
}

void* read_file(char* filename, int len) {
  FILE *fp = fopen(filename, "rb");
  void* data = malloc(len);
  fread(data, 1, len, fp);
  fclose(&fp);
  return data;
}

Looking at the source code, we see that it encrypts and decrypts files using the mcrypt library.

It uses AES cipher to decrypt a file called flag.enc

int main(int argc, char* argv[]) // gcc src.c -o dec -lmcrypt -ggdb
{
  char* IV = "AAAAAAAAAAAAAAAA";
  char *key = getenv("KEY");
  int keysize = 16;
  char* buffer;
  int buffer_len = 16;

  void *ciphertext = read_file("flag.enc", buffer_len);
  decrypt(ciphertext, buffer_len, IV, key, keysize);
  printf("Decrypted contents: %s\n", ciphertext);

  return 0;
}

The binary is compiled with debugging symbols, which means we can refer to variables and methods by their original names. The IV is constant, while the key is read from the environment variable named KEY. The flag.enc file is read and then passed to the decrypt() function. We aren’t given the flag.enc file, which means we’ll have to dump it from the core file.

We can load up the binary and core dump in GBD and use bt to look at the backtrace

image.png

7 Hissss

We have a binary called auth :

carbon.png

Decompilation

If we look at the strings of the binary, we will find a lot of references to Python:

carbon(1).png

Therefore, this binary is compiled from Python. Usually, the way to extract Python code is using https://github.com/extremecoders-re/pyinstxtractor/ to obtain bytecode and then https://github.com/zrax/pycdc to tranlste Python bytecode into source code

carbon(2).png

We find compiled python bytecode in the /auth_extracted/auth.pyc file.Let’s use https://github.com/rocky/python-decompile3 to reconstruct the source code.

carbon(3).png

The resulting source code is as follows:

carbon(4).png

The input is subjected to a few constrains which we need to solve:

carbon(5).png

We can use https://github.com/Z3Prover/z3 to solve it but I will just use ChatGPT lol