preface

I just bought a Tencent server (CVM) two days ago. When I logged in to it this time, I used a special card. I found that the load was particularly high through the top.

I wanted to stop the docker and mysql background services and see if the load could be reduced, but I found that the common commands were not available.

Later, it was found that docker remote service invaded, so docker remote service and Redis service were used to simulate the invasion of their own server.

The problem reduction

It was just like any other day. When I tried to stop the background service by using the systemctl command, I found that I had no execution permission.

I’ve never seen anything like this before. In my mind, root is the highest being.

First I went to a wave of customer service, who said it was hacked and asked me to reinstall the system. Before reloading, I asked for help from my dear college roommate, a security boss: Feng Fat, no! Is feng guy.

Problem analysis

I: feng, I can’t use this systemctl, why?

Feng: I’ll go up and show you.

A few moments later….

fengWhat service is this port 2375? Is there any remote service enabled?

I: Well, if it isn’t the Docker remote service I just opened two days ago…

Feng: That’s right. I hacked your server through the Docker remote server, and then I used Masscan to scan the Docker remote service of other servers, and then I invaded. You’ve been hacked as a mining machine. Go to /usr/share for details

Then I looked at the catalogue.

Open the config_background.json file and check it out. Sure enough, monero.

Me: How does he log in to my server?

Did you forget that Docker can mount the host directory, mount the.ssh directory, and then put his host public key directly into authorized_keys, so he can log in without password?

Suddenly it dawned!! I went to look, and sure enough, I had a Puppet public key.

At the same time, there is an additional user directory under home.

Me: Last question, I use root user, why many commands can not execute?

Feng: Chmod first changes the command to read/write state, so it cannot be executed. Chattr is used to change the command attribute to read-only, so that chmod cannot change the command permission.

I: that I go to check information….

After checking the information, I tried the operation.

Here’s an example of ls. According to the 421 rule, 1 represents the execution permission. I first change the ls permission to 666, that is, only the read and write permission but no execution permission. Lsattr is used to view file attributes, and chattr is used to modify file attributes. It can also be understood as a command to manage file permissions at a lower level than chmod.

When I use lsattr, I want to change it to 755, which is ready to be executed, but I am not allowed to do so.

Then I use chattr -i to remove the ls read-only attribute. Then I can use chmod to change it to the 755 executable state. As shown in the figure, ls executes normally.

Me: But why don’t I even have permission to execute chattr?

feng:…

I: Big brother!!

Feng: Make a copy of chattr, give it a different name, and then use the new command to make chattr read-only, and then delete the command

I: not ashamed is my feng…

Feng: Where are we going to eat this weekend

I:…

SSH public key injection is implemented

By looking up some data, the principle is to write the public key of the host to the target drone through some service ports, so as to realize the login without password and obtain the permission of root user of the target drone.

We talked about SSH public keys before. Copy the public key of host A to the authorized_keys file in the ~/. SSH directory of host B to establish mutual trust and implement no-password login. That is, host A does not need to enter A password to log in to host B.

However, the intruder writes the public key of a host to authorized_keys through the remote service of Docker and the snapshot function of Redis, and logs in to the target host without password to obtain the root permission, which is the act of SSH public key privilege enhancement.

I’ve only heard about SQL injection and DDoS attacks before. For this can directly log in the server operation is the first time to meet, so I took my own server experiment, anyway in a short while to reinstall the system.

Two servers are prepared here. Host A is used to run Docker remote service and Redis service, and host B is used for remote connection.

Docker remote service intrusion

Its principle is to use the remote service of Docker, can remotely pick up a Docker container on the target drone, and mount the target drone. SSH directory to the container, and then enter the bash of Docker, directly write the public key into authorized_keys.

Enabling a remote Port

The default port is 2375. In order to avoid being scanned by other machines, change it to 6666 first.

Connect to Docker remotely

Log in to host B and run the following command to view which containers are running on the remote host.

Docker -h TCP: / / 47.102. XXX. XXX: ps - 6666 aCopy the code

Usually, we use Docker PS to view the container running on the local machine. Here, we use -h to specify the IP and port of host A, that is, we can view the remote host.

Let’s take a look at what mirrors are on this host:

Remote run container

Run the following command on host B to remotely run A container on host A using the image on host A:

The /etc/ssh directory is mounted to change PermitRootLogin in sshd_config to yes to allow root login
/etc/ssh/sshd_config; /etc/ssh/sshd_configDocker -h TCP: / / 47.102. XXX. XXX: 6666 run - it - v/root: / TMP/root - v/etc/SSH: / TMP/ect/SSH centos bashCopy the code

SSH directory is mounted to the/TMP /root directory in the container by using -v. In this case, the authorized_keys of host A can be directly changed in the container. In this case, I only need to add the public key of host B to the container, and then host B can log in to host A without password.

As you can see, once you’ve created and run a container, you enter it directly through bash.

Write the public key, to achieve invasion and login

In the container, view the contents of the authorized_keys file.

As shown in the figure, there is only one public key for authorized_keys. We add the public key of host B to it through vi, save wq and exit.

Then test whether you can log in without password.

As shown in the figure, host B is successfully logged in to host A without password.

Redis Dynamically configures intrusion

The principle is to use the redis RDB snapshot backup and the config command to dynamically modify the configuration function, change the RDB directory to. SSH, and change the file name to authorized_keys. Then write the public key to redis as value, and use bgsave command to start backup, then write the public key to authorized_keys successfully, and realize the login without password.

The premise condition

  1. Redis is running as the root user
  2. No password set
  3. The default port 6379 is used
  4. Allow remote IP access, i.e. comment outbindConfiguration and willprotected modeChange to no
  5. Dynamic configuration change is not disabled

Start the redis

Here, the Redis service is enabled on host A to allow remote access and the port is changed to 6666.

./redis-server .. /conf/redis.confCopy the code

Connect to Redis remotely

Log in to host B and remotely connect to the Redis service on host A.

/ reis -cli -h 47.102.xxx. XXX -p 6666Copy the code

Write the public key, to achieve invasion and login

As shown in the figure, the public key of host B is copied first. In order that the public key can occupy a single line after authorized_keys is written, line feeds are used before and after.

Then run the following command to write the public key of host B to Redis using the redis-cli.

The cat id_das. Pub |. / redis - cli - h 47.102. XXX. XXX - 6666 - x pset ssh-key
Copy the code

-h: specifies the IP address of host A, -p: specifies the port of redis, and -x: specifies the standard input as the parameter of the following command

After the public key is written to Redis, the RDB directory and file name are modified through dynamic configuration.

Config set dir /root/. SSH # Modify the filename of RBD config set dbfilename authorized_keys # Immediately save data to the file bgsaveCopy the code

Next, go to host A to see if the public key has been written to authorized_keys.

As shown in the figure, the public key of host B is written successfully, and finally the login without password is successful.

Now you might say, what is this, authorized_keys with question marks and other characters, doesn’t that affect login?

In fact, this is the RDB file format, so in order not to affect the public key file, I also added the public key before and after the new line, so that the public key can have an exclusive line, and not affect the password free login.

preventive measure

docker

  1. Example Change the default port number 2375
  2. Adding authentication for remote services
  3. Or simply disable remote services

redis

  1. Example Change the default port number 6379
  2. Run redis as a non-root user
  3. Use requirePass to set the password
  4. Dynamic configuration is prohibited
# rename command CONFIG "" # rename command CONFIG ""Copy the code

This makes dynamic configuration impossible on the command line using the config command.

conclusion

Above through Redis and Docker to obtain host rights means, the real scene may be much more complex, is not worth mentioning to the security leaders, but for me this kind of security zero-based people, encounter is still very novel, so through the article to record this experience, also as a very interesting experience.



After 95 small programmers, writing is daily work in practice, place oneself in the beginner’s point of view from 0 to 1, detailed and serious. Article will be in the public number [entry to give up the road] first, looking forward to your attention.