Crea una broma para cortar la conexión entre la conexión TCP y el proceso

¿Quieres jugar otra broma? ?

Cuando muchas operaciones y mantenimiento encuentran que hay una conexión tcp anormal en el sistema, usarán el comando netstat / ss para averiguar el proceso de procesamiento correspondiente a la conexión tcp y luego pasarán al proceso de depuración de I + D. como:

[root@localhost ~]# netstat -ntp
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 192.168.56.110:22       192.168.56.1:50069      ESTABLISHED 1420/sshd: root@pts
tcp        0      0 192.168.56.110:22       192.168.56.1:50048      ESTABLISHED 1357/sshd: root@pts
tcp        0      0 192.168.56.110:22       192.168.56.1:50060      ESTABLISHED 1378/sshd: root@pts
tcp        0      0 192.168.56.110:22       192.168.56.1:50063      ESTABLISHED 1399/sshd: root@pts

¿Qué sucede si elimino la asociación entre la conexión tcp y el proceso? ¿Haciendo malabares con un oficio para ver su desempeño?

O, lo que es más importante, ¿puedo lograr el objetivo de culpar a otros intercambiando las conexiones tcp manejadas por el proceso 1 y el proceso 2? Quiero que compruebes, quiero que compruebes un ovillo de hilo.

Para lograr esto, primero debe comprender cómo se establece la asociación entre la conexión tcp y el proceso en Linux.

Bien, comencemos.

En el sistema Linux, una conexión tcp está representada por un objeto tcp_sock en la parte inferior.

En el diseño OO de sock, existe la siguiente relación de herencia, partimos de la clase base sock_common:
sock_common <- sock <- inet_sock <- inet_connection_sock <- tcp_sock

sin embargo…

Sin embargo, el proceso y tcp_sock no se apuntan entre sí, porque una conexión tcp no es la única que corresponde a un proceso. Sabemos que tcp_sock existe como un descriptor de archivo en el contexto del proceso, y múltiples procesos pueden operar la misma conexión tcp.

Por lo tanto, puede corresponder a una conexión tcp desde el descriptor de archivo de un proceso, pero no al revés, no puede confirmar el proceso al que pertenece a través de un tcp_sock.
Inserte la descripción de la imagen aquí

En base al hecho de que no existe una correspondencia uno a uno entre una conexión TCP y un proceso, en términos de implementación, para asociar una conexión TCP con un proceso, se debe manejar en dos pasos:

  • Linux exporta todo tcp_sock en / proc / net / tcp, donde el campo de inodo apunta al campo i_ino de la dirección de inodo del objeto de estructura socket_alloc de la capa de socket Berkeley.
  • Linux exporta todos los procesos en el directorio / proc / $ pid y exporta todos los descriptores de archivos abiertos por el proceso en el subdirectorio / proc / $ pid / fd.

Cuando ejecuta netstat -antp, las acciones de netstat son las siguientes:

  1. Guarde los números de inodo de todas las conexiones tcp en / proc / net / tcp en una lista vinculada.
  2. Recorra los enlaces en el directorio / proc / $ pid / fd de todos los procesos exportados bajo / proc, y use el número de inodo del enlace para que coincida con el número de inodo en la lista de inodo tcp.
  3. Establezca una asociación entre el número de inodo tcp coincidente con éxito y / proc / $ pid / fd / $ fd-> inode.

Si usa ss en lugar de netstat, el proceso sigue siendo el mismo, la única diferencia es que la lista de inodos tcp ya no se obtiene a través de / proc / net / tcp, sino a través de netlink.

Puede observar todo esto a través de strace netstat / ss sin analizar el código fuente de netstat / ss.

¡Este proceso es muy similar al proceso de la sonda mutua de controlador / dispositivo en el bus en el mecanismo de administración de controladores del kernel de Linux!

Para completar esta broma, la idea convencional es enganchar / proc / $ pid / fd / x, de modo que el enlace que originalmente era un socket tcp se muestre apuntando a otras cosas como / dev / null.

Pero con la comprensión del proceso del proceso a la conexión tcp, es más fácil eliminar la asociación entre ellos. No es necesario conectar ninguna interfaz de operación de archivos procfs, como se muestra en la siguiente figura:
Inserte la descripción de la imagen aquí
obviamente, este es un tipo de archivo que hook procfs. La interfaz de operación está más cerca del enfoque esencial. Personalmente, no me gustan los hook procfs. Es complicado y poco elegante, ¡y no resuelve el problema fundamentalmente! El esquema descrito en el diagrama anterior es el esquema esencial.

El código para lograr esto es el siguiente:

#!/usr/bin/stap -g

function relieve(fd:long)
%{
    
    
	struct dentry *dentry = current->files->fdt->fd[STAP_ARG_fd]->f_path.dentry;
	struct inode *ino = current->files->fdt->fd[0]->f_path.dentry->d_inode;
	dentry->d_inode = ino;
%}

probe kernel.function("__schedule").return
{
    
    
	if (pid() == $1) {
    
    
		relieve($2);
		exit()
	}
}

function wakeup(pid:long)
%{
    
    
	struct task_struct *tsk;

	tsk = pid_task(find_vpid(STAP_ARG_pid), PIDTYPE_PID);
	if (tsk)
		wake_up_process(tsk);
%}

probe timer.ms(500)
{
    
    
	wakeup($1)
}

Código súper súper súper simple.

Explique por qué necesita enganchar __schedule.return, porque en esta posición puede asegurarse de que el proceso programado no mantenga un bloqueo de giro (mantener un bloqueo de giro está prohibido para programar), y otros procesos en la misma CPU no retienen el giro Bloquear (de lo contrario, no se cambiará)

Ven y mira el efecto. Tome el ejemplo al principio de este artículo como un experimento. Mi propósito es eliminar la visualización del pid del proceso y el nombre del proceso detrás de netstat -ntp:

[root@localhost test]# for pid in $(netstat -ntp|egrep -o [0-9]+\/|egrep -o [0-9]+); do ./relieve.stp $pid 3;done
[root@localhost test]# netstat -ntp
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 192.168.56.110:22       192.168.56.1:50069      ESTABLISHED -
tcp        0      0 192.168.56.110:22       192.168.56.1:50048      ESTABLISHED -
tcp        0      0 192.168.56.110:22       192.168.56.1:50060      ESTABLISHED -
tcp        0      0 192.168.56.110:22       192.168.56.1:50063      ESTABLISHED -
[root@localhost test]#
[root@localhost test]# netstat -ntp|egrep -o [0-9]+\/|egrep -o [0-9]+
[root@localhost test]# echo $?
1
[root@localhost test]#

¡Oh si!

Un amigo sugirió que es aburrido deshacerse de él directamente. Es mejor confundir la relación entre el proceso y la conexión tcp, que es más confusa. Está bien, esto es realmente genial. El código simple es el siguiente:

struct dentry *den1 = tsk1->files->fdt->fd[STAP_ARG_fd1]->f_path.dentry;
struct dentry *den2 = tsk2->files->fdt->fd[STAP_ARG_fd2]->f_path.dentry;
struct inode *tmp;

tmp = den1->d_inode;
den1->d_inode = den2->d_inode;
den2->d_inode = tmp;

Reemplace el código con el anterior, simplemente demuestre un ejemplo.

Primero acceda a dos conexiones tcp, como se muestra a continuación:
Inserte la descripción de la imagen aquí

[root@localhost ~]# netstat -ntp
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 192.168.56.110:22       192.168.56.1:52105      ESTABLISHED 1046/sshd: root@pts
tcp        0      0 192.168.56.110:22       192.168.56.1:53346      ESTABLISHED 1523/sshd: root@pts

Luego use el código anterior para intercambiar f_path.dentry-> d_inode de los dos, lo que confunde el audiovisual, como se muestra a continuación:
Inserte la descripción de la imagen aquí

[root@localhost ~]# netstat -ntp
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 192.168.56.110:22       192.168.56.1:52105      ESTABLISHED 1523/sshd: root@pts
tcp        0      0 192.168.56.110:22       192.168.56.1:53346      ESTABLISHED 1046/sshd: root@pts

Fíjate bien, se ha intercambiado la relación entre el proceso y la conexión. Si la operación y mantenimiento encuentra alguna anormalidad en este momento, ¿puedes burlarte de ellos? ¡Al menos déjalos tener una reunión para esto, jaja!

¿Qué? ¿Puede estar abajo? Para jugar en este negocio, es imprescindible soportar el tiempo de inactividad, y debe pulirse lentamente para producir productos de calidad, jaja.

En cuanto a cómo descifrar este tipo de truco, es muy simple. En lugar de seguir la pista de procfs, podemos seguir la pista de socket / sock:

  • ¡La pista de encaje / calcetín es interminable!

Inserte la descripción de la imagen aquí

Usaré el complemento de bloqueo para demostrar más tarde, en cuanto al truco de hoy, me detendré aquí.


Los zapatos de cuero en Wenzhou, Zhejiang están mojados, por lo que no engordan con la lluvia.

Supongo que te gusta

Origin blog.csdn.net/dog250/article/details/108113329
Recomendado
Clasificación