Applications that are connected to services often include connection strings that can be leaked if they are not protected sufficiently. In the following paragraphs, we will go through the process of enumerating and exploiting applications that are connected to other services in order to extend their functionality. This can help us collect information and move laterally or escalate our privileges during penetration testing.

ELF Executable Examination

The octopus_checker binary is found on a remote machine during the testing. Running the application locally reveals that it connects to database instances in order to verify that they are available.

sasorirose@htb[/htb]$ ./octopus_checker 

Program had started..
Attempting Connection 
Connecting ... 

The driver reported the following diagnostics whilst running SQLDriverConnect

01000:1:0:[unixODBC][Driver Manager]Can't open lib 'ODBC Driver 17 for SQL Server' : file not found
connected

The binary probably connects using a SQL connection string that contains credentials. Using tools like PEDA (Python Exploit Development Assistance for GDB) we can further examine the file. This is an extension of the standard GNU Debugger (GDB), which is used for debugging C and C++ programs. GDB is a command line tool that lets you step through the code, set breakpoints, and examine and change variables. Running the following command we can execute the binary through it.

sasorirose@htb[/htb]$ gdb ./octopus_checker

GNU gdb (Debian 9.2-1) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
    .

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./octopus_checker...
(No debugging symbols found in ./octopus_checker)

Once the binary is loaded, we set the disassembly-flavor to define the display style of the code, and we proceed with disassembling the main function of the program.

gdb-peda$ set disassembly-flavor intel
gdb-peda$ disas main

Dump of assembler code for function main:
   0x0000555555555456 <+0>: endbr64 
   0x000055555555545a <+4>: push   rbp
   0x000055555555545b <+5>: mov    rbp,rsp
 
 
 
   0x0000555555555625 <+463>:   call   0x5555555551a0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
   0x000055555555562a <+468>:   mov    rdx,rax
   0x000055555555562d <+471>:   mov    rax,QWORD PTR [rip+0x299c]        # 0x555555557fd0
   0x0000555555555634 <+478>:   mov    rsi,rax
   0x0000555555555637 <+481>:   mov    rdi,rdx
   0x000055555555563a <+484>:   call   0x5555555551c0 <_ZNSolsEPFRSoS_E@plt>
   0x000055555555563f <+489>:   mov    rbx,QWORD PTR [rbp-0x4a8]
   0x0000555555555646 <+496>:   lea    rax,[rbp-0x4b7]
   0x000055555555564d <+503>:   mov    rdi,rax
   0x0000555555555650 <+506>:   call   0x555555555220 <_ZNSaIcEC1Ev@plt>
   0x0000555555555655 <+511>:   lea    rdx,[rbp-0x4b7]
   0x000055555555565c <+518>:   lea    rax,[rbp-0x4a0]
   0x0000555555555663 <+525>:   lea    rsi,[rip+0xa34]        # 0x55555555609e
   0x000055555555566a <+532>:   mov    rdi,rax
   0x000055555555566d <+535>:   call   0x5555555551f0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_@plt>
   0x0000555555555672 <+540>:   lea    rax,[rbp-0x4a0]
   0x0000555555555679 <+547>:   mov    edx,0x2
   0x000055555555567e <+552>:   mov    rsi,rbx
   0x0000555555555681 <+555>:   mov    rdi,rax
   0x0000555555555684 <+558>:   call   0x555555555329 <_Z13extract_errorNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPvs>
   0x0000555555555689 <+563>:   lea    rax,[rbp-0x4a0]
   0x0000555555555690 <+570>:   mov    rdi,rax
   0x0000555555555693 <+573>:   call   0x555555555160 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
   0x0000555555555698 <+578>:   lea    rax,[rbp-0x4b7]
   0x000055555555569f <+585>:   mov    rdi,rax
   0x00005555555556a2 <+588>:   call   0x5555555551d0 <_ZNSaIcED1Ev@plt>
   0x00005555555556a7 <+593>:   cmp    WORD PTR [rbp-0x4b2],0x0



   0x0000555555555761 <+779>:   mov    rbx,QWORD PTR [rbp-0x8]
   0x0000555555555765 <+783>:   leave  
   0x0000555555555766 <+784>:   ret    
End of assembler dump.

This reveals several call instructions that point to addresses containing strings. They appear to be sections of a SQL connection string, but the sections are not in order, and the endianness entails that the string text is reversed. Endianness defines the order that the bytes are read in different architectures. Further down the function, we see a call to SQLDriverConnect.

   0x00005555555555ff <+425>:   mov    esi,0x0
   0x0000555555555604 <+430>:   mov    rdi,rax
   0x0000555555555607 <+433>:   call   0x5555555551b0 
   0x000055555555560c <+438>:   add    rsp,0x10
   0x0000555555555610 <+442>:   mov    WORD PTR [rbp-0x4b4],ax

Adding a breakpoint at this address and running the program once again, reveals a SQL connection string in the RDX register address, containing the credentials for a local database instance.

gdb-peda$ b *0x5555555551b0

Breakpoint 1 at 0x5555555551b0


gdb-peda$ run

Starting program: /htb/rollout/octopus_checker 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program had started..
Attempting Connection 
[----------------------------------registers-----------------------------------]
RAX: 0x55555556c4f0 --> 0x4b5a ('ZK')
RBX: 0x0 
RCX: 0xfffffffd 
RDX: 0x7fffffffda70 ("DRIVER={ODBC Driver 17 for SQL Server};SERVER=localhost, 1401;UID=username;PWD=password;")
RSI: 0x0 
RDI: 0x55555556c4f0 --> 0x4b5a ('ZK')

Apart from trying to connect to the MS SQL service, penetration testers can also check if the password is reusable from users of the same network.

DLL File Examination

A DLL file is a Dynamically Linked Library and it contains code that is called from other programs while they are running. The MultimasterAPI.dll binary is found on a remote machine during the enumeration process. Examination of the file reveals that this is a .Net assembly.

C:\> Get-FileMetaData .\MultimasterAPI.dll


M .NETFramework,Version=v4.6.1 TFrameworkDisplayName.NET Framework 4.6.1    api/getColleagues        ! htt
p://localhost:8081*POST         Ò^         øJ  ø,  RSDSœ»¡ÍuqœK£"Y¿bˆ   C:\Users\Hazard\Desktop\Stuff\Multimast

Using the debugger and .NET assembly editor dnSpy, we can view the source code directly. This tool allows reading, editing, and debugging the source code of a .NET assembly (C# and Visual Basic). Inspection of MultimasterAPI.Controllers -> ColleagueController reveals a database connection string containing the password.

Apart from trying to connect to the MS SQL service, attacks like password spraying can also be used to test the security of other services.

Questions:

What credentials were found for the local database instance while debugging the octopus_checker binary? (Format username:password)

htb-student@htb:~$ gdb ./octopus_checker
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.                                     
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
    .

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./octopus_checker...
(No debugging symbols found in ./octopus_checker)
gdb-peda$ set disassembly-flavor intel
gdb-peda$ disas main
Dump of assembler code for function main:
   0x0000000000001456 <+0>:     endbr64 
   0x000000000000145a <+4>:     push   rbp
   0x000000000000145b <+5>:     mov    rbp,rsp
   0x000000000000145e <+8>:     push   rbx
   0x000000000000145f <+9>:     sub    rsp,0x4b8
   0x0000000000001466 <+16>:    mov    rax,QWORD PTR fs:0x28
   0x000000000000146f <+25>:    mov    QWORD PTR [rbp-0x18],rax
   0x0000000000001473 <+29>:    xor    eax,eax
   0x0000000000001475 <+31>:    lea    rsi,[rip+0xbe5]        # 0x2061
   0x000000000000147c <+38>:    lea    rdi,[rip+0x2bbd]        # 0x4040 <_ZSt4cout@@GLIBCXX_3.4>                                                                            
   0x0000000000001483 <+45>:    call   0x11a0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>                                                                 
   0x0000000000001488 <+50>:    mov    rdx,rax
   0x000000000000148b <+53>:    mov    rax,QWORD PTR [rip+0x2b3e]        # 0x3fd0
   0x0000000000001492 <+60>:    mov    rsi,rax
   0x0000000000001495 <+63>:    mov    rdi,rdx
   0x0000000000001498 <+66>:    call   0x11c0 <_ZNSolsEPFRSoS_E@plt>
   0x000000000000149d <+71>:    lea    rax,[rbp-0x4b0]
   0x00000000000014a4 <+78>:    mov    rdx,rax
   0x00000000000014a7 <+81>:    mov    esi,0x0
   0x00000000000014ac <+86>:    mov    edi,0x1
   0x00000000000014b1 <+91>:    call   0x1170 
   0x00000000000014b6 <+96>:    mov    rax,QWORD PTR [rbp-0x4b0]
   0x00000000000014bd <+103>:   mov    ecx,0x0
   0x00000000000014c2 <+108>:   mov    edx,0x3
   0x00000000000014c7 <+113>:   mov    esi,0xc8
   0x00000000000014cc <+118>:   mov    rdi,rax
   0x00000000000014cf <+121>:   call   0x1230 
   0x00000000000014d4 <+126>:   mov    rax,QWORD PTR [rbp-0x4b0]
   0x00000000000014db <+133>:   lea    rdx,[rbp-0x4a8]
   0x00000000000014e2 <+140>:   mov    rsi,rax
   0x00000000000014e5 <+143>:   mov    edi,0x2
   0x00000000000014ea <+148>:   call   0x1170 
   0x00000000000014ef <+153>:   lea    rsi,[rip+0xb81]        # 0x2077
   0x00000000000014f6 <+160>:   lea    rdi,[rip+0x2b43]        # 0x4040 <_ZSt4cout@@GLIBCXX_3.4>                                                                            
   0x00000000000014fd <+167>:   call   0x11a0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>                                                                 
   0x0000000000001502 <+172>:   mov    rdx,rax
   0x0000000000001505 <+175>:   mov    rax,QWORD PTR [rip+0x2ac4]        # 0x3fd0
   0x000000000000150c <+182>:   mov    rsi,rax
   0x000000000000150f <+185>:   mov    rdi,rdx
   0x0000000000001512 <+188>:   call   0x11c0 <_ZNSolsEPFRSoS_E@plt>
   0x0000000000001517 <+193>:   movabs rax,0x7b3d524556495244
   0x0000000000001521 <+203>:   movabs rdx,0x697244204342444f
   0x000000000000152b <+213>:   mov    QWORD PTR [rbp-0x480],rax
   0x0000000000001532 <+220>:   mov    QWORD PTR [rbp-0x478],rdx
   0x0000000000001539 <+227>:   movabs rax,0x6620373120726576
   0x0000000000001543 <+237>:   movabs rdx,0x53204c515320726f
   0x000000000000154d <+247>:   mov    QWORD PTR [rbp-0x470],rax
   0x0000000000001554 <+254>:   mov    QWORD PTR [rbp-0x468],rdx
   0x000000000000155b <+261>:   movabs rax,0x533b7d7265767265
   0x0000000000001565 <+271>:   movabs rdx,0x6f6c3d5245565245
   0x000000000000156f <+281>:   mov    QWORD PTR [rbp-0x460],rax
   0x0000000000001576 <+288>:   mov    QWORD PTR [rbp-0x458],rdx
   0x000000000000157d <+295>:   movabs rax,0x2c74736f686c6163
   0x0000000000001587 <+305>:   movabs rdx,0x49553b3130343120
   0x0000000000001591 <+315>:   mov    QWORD PTR [rbp-0x450],rax
   0x0000000000001598 <+322>:   mov    QWORD PTR [rbp-0x448],rdx
   0x000000000000159f <+329>:   movabs rax,0x4457503b41533d44
   0x00000000000015a9 <+339>:   movabs rdx,0x7263335374304e3d
   0x00000000000015b3 <+349>:   mov    QWORD PTR [rbp-0x440],rax
   0x00000000000015ba <+356>:   mov    QWORD PTR [rbp-0x438],rdx
   0x00000000000015c1 <+363>:   mov    DWORD PTR [rbp-0x430],0x3b217433
   0x00000000000015cb <+373>:   mov    BYTE PTR [rbp-0x42c],0x0
   0x00000000000015d2 <+380>:   mov    rax,QWORD PTR [rbp-0x4a8]
   0x00000000000015d9 <+387>:   lea    rsi,[rbp-0x420]
   0x00000000000015e0 <+394>:   lea    rdx,[rbp-0x480]
   0x00000000000015e7 <+401>:   push   0x0
   0x00000000000015e9 <+403>:   lea    rcx,[rbp-0x4b6]
   0x00000000000015f0 <+410>:   push   rcx
   0x00000000000015f1 <+411>:   mov    r9d,0x400
   0x00000000000015f7 <+417>:   mov    r8,rsi
   0x00000000000015fa <+420>:   mov    ecx,0xfffffffd
   0x00000000000015ff <+425>:   mov    esi,0x0
   0x0000000000001604 <+430>:   mov    rdi,rax
   0x0000000000001607 <+433>:   call   0x11b0 
   0x000000000000160c <+438>:   add    rsp,0x10
   0x0000000000001610 <+442>:   mov    WORD PTR [rbp-0x4b4],ax
   0x0000000000001617 <+449>:   lea    rsi,[rip+0xa70]        # 0x208e
   0x000000000000161e <+456>:   lea    rdi,[rip+0x2a1b]        # 0x4040 <_ZSt4cout@@GLIBCXX_3.4>                                                                            
   0x0000000000001625 <+463>:   call   0x11a0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>                                                                 
   0x000000000000162a <+468>:   mov    rdx,rax
   0x000000000000162d <+471>:   mov    rax,QWORD PTR [rip+0x299c]        # 0x3fd0
   0x0000000000001634 <+478>:   mov    rsi,rax
   0x0000000000001637 <+481>:   mov    rdi,rdx
   0x000000000000163a <+484>:   call   0x11c0 <_ZNSolsEPFRSoS_E@plt>
   0x000000000000163f <+489>:   mov    rbx,QWORD PTR [rbp-0x4a8]
   0x0000000000001646 <+496>:   lea    rax,[rbp-0x4b7]
   0x000000000000164d <+503>:   mov    rdi,rax
   0x0000000000001650 <+506>:   call   0x1220 <_ZNSaIcEC1Ev@plt>
   0x0000000000001655 <+511>:   lea    rdx,[rbp-0x4b7]
   0x000000000000165c <+518>:   lea    rax,[rbp-0x4a0]
   0x0000000000001663 <+525>:   lea    rsi,[rip+0xa34]        # 0x209e
   0x000000000000166a <+532>:   mov    rdi,rax
   0x000000000000166d <+535>:   call   0x11f0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_@plt>                                                        
   0x0000000000001672 <+540>:   lea    rax,[rbp-0x4a0]
   0x0000000000001679 <+547>:   mov    edx,0x2
   0x000000000000167e <+552>:   mov    rsi,rbx
   0x0000000000001681 <+555>:   mov    rdi,rax
   0x0000000000001684 <+558>:   call   0x1329 <_Z13extract_errorNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPvs>                                                    
   0x0000000000001689 <+563>:   lea    rax,[rbp-0x4a0]
   0x0000000000001690 <+570>:   mov    rdi,rax
   0x0000000000001693 <+573>:   call   0x1160 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>                                                               
   0x0000000000001698 <+578>:   lea    rax,[rbp-0x4b7]
   0x000000000000169f <+585>:   mov    rdi,rax
   0x00000000000016a2 <+588>:   call   0x11d0 <_ZNSaIcED1Ev@plt>
   0x00000000000016a7 <+593>:   cmp    WORD PTR [rbp-0x4b2],0x0
   0x00000000000016af <+601>:   je     0x16e5 
   0x00000000000016b1 <+603>:   cmp    WORD PTR [rbp-0x4b2],0x1
   0x00000000000016b9 <+611>:   je     0x16e5 
   0x00000000000016bb <+613>:   lea    rsi,[rip+0x9ed]        # 0x20af
   0x00000000000016c2 <+620>:   lea    rdi,[rip+0x2977]        # 0x4040 <_ZSt4cout@@GLIBCXX_3.4>                                                                            
   0x00000000000016c9 <+627>:   call   0x11a0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>                                                                 
   0x00000000000016ce <+632>:   mov    rdx,rax
   0x00000000000016d1 <+635>:   mov    rax,QWORD PTR [rip+0x28f8]        # 0x3fd0
   0x00000000000016d8 <+642>:   mov    rsi,rax
   0x00000000000016db <+645>:   mov    rdi,rdx
   0x00000000000016de <+648>:   call   0x11c0 <_ZNSolsEPFRSoS_E@plt>
   0x00000000000016e3 <+653>:   jmp    0x170d 
   0x00000000000016e5 <+655>:   lea    rsi,[rip+0x9d3]        # 0x20bf
   0x00000000000016ec <+662>:   lea    rdi,[rip+0x294d]        # 0x4040 <_ZSt4cout@@GLIBCXX_3.4>                                                                            
   0x00000000000016f3 <+669>:   call   0x11a0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>                                                                 
   0x00000000000016f8 <+674>:   mov    rdx,rax
   0x00000000000016fb <+677>:   mov    rax,QWORD PTR [rip+0x28ce]        # 0x3fd0
   0x0000000000001702 <+684>:   mov    rsi,rax
   0x0000000000001705 <+687>:   mov    rdi,rdx
   0x0000000000001708 <+690>:   call   0x11c0 <_ZNSolsEPFRSoS_E@plt>
   0x000000000000170d <+695>:   mov    eax,0x0
   0x0000000000001712 <+700>:   mov    rcx,QWORD PTR [rbp-0x18]
   0x0000000000001716 <+704>:   xor    rcx,QWORD PTR fs:0x28
   0x000000000000171f <+713>:   je     0x1761 
   0x0000000000001721 <+715>:   jmp    0x175c 
   0x0000000000001723 <+717>:   endbr64 
   0x0000000000001727 <+721>:   mov    rbx,rax
   0x000000000000172a <+724>:   lea    rax,[rbp-0x4a0]
   0x0000000000001731 <+731>:   mov    rdi,rax
   0x0000000000001734 <+734>:   call   0x1160 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>                                                               
   0x0000000000001739 <+739>:   jmp    0x1742 
   0x000000000000173b <+741>:   endbr64 
   0x000000000000173f <+745>:   mov    rbx,rax
   0x0000000000001742 <+748>:   lea    rax,[rbp-0x4b7]
   0x0000000000001749 <+755>:   mov    rdi,rax
   0x000000000000174c <+758>:   call   0x11d0 <_ZNSaIcED1Ev@plt>
   0x0000000000001751 <+763>:   mov    rax,rbx
   0x0000000000001754 <+766>:   mov    rdi,rax
   0x0000000000001757 <+769>:   call   0x1210 <_Unwind_Resume@plt>
   0x000000000000175c <+774>:   call   0x11e0 <__stack_chk_fail@plt>
   0x0000000000001761 <+779>:   mov    rbx,QWORD PTR [rbp-0x8]
   0x0000000000001765 <+783>:   leave  
   0x0000000000001766 <+784>:   ret    
End of assembler dump.
gdb-peda$ 

Step 1: Find the Database Connection Function

If you scan down the assembly, you'll see a very interesting function call at offset <+433>:

SQLDriverConnect is a standard function used to connect to SQL databases. To work, it requires a connection string (which usually contains the server IP, username, and password). The instructions right before this call are responsible for building that string in memory.

Step 2: Spot the Hardcoded Data

Look at the block of instructions starting at <+193> down to <+363>. You will see a bunch of movabs instructions pushing large hexadecimal values into the stack ([rbp-0x...]).

This is the program taking a long, hardcoded text string and writing it into memory in 8-byte chunks.

Step 3: Decode the Hex (The Little Endian Trick)

To read these strings, we have to convert the hex to ASCII text. However, x86 architecture uses Little Endian, which means it stores bytes in reverse order.

Let's decode the very first line as an example:

  1. The Hex: 0x7b3d524556495244
  1. Split into bytes: 7b 3d 52 45 56 49 52 44
  1. Reverse the order: 44 52 49 56 45 52 3d 7b
  1. Convert to ASCII text: D R I V E R = {

Step 4: Assemble the Puzzle

If we apply that same reverse-and-convert trick to the entire block of movabs instructions, here is what the program is spelling out:

  • 0x7b3d524556495244 -> DRIVER={
  • 0x697244204342444f -> ODBC Dri
  • 0x6620373120726576 -> ver 17 f
  • 0x53204c515320726f -> or SQL S
  • 0x533b7d7265767265 -> erver};S
  • 0x6f6c3d5245565245 -> ERVER=lo
  • 0x2c74736f686c6163 -> calhost,
  • 0x49553b3130343120 -> 1401;UI
  • 0x4457503b41533d44 -> D=SA;PWD
  • 0x7263335374304e3d -> =N0tS3cr
  • 0x3b217433 -> 3t!;

When you squish all of those pieces together, you get the full, hardcoded connection string: DRIVER={ODBC Driver 17 for SQL Server};SERVER=localhost, 1401;UID=SA;PWD=N0tS3cr3t!;

Answer:SA:N0tS3cr3t!