SELinux: Obtendo um binário personalizado para mudar para outro contexto

1

Estou trabalhando em um novo projeto que deve ser protegido com o SELinux. Nós temos um binário customizado escrito em C (para o propósito desta questão, ele será chamado de "testprog") que precisa mudar para seu próprio contexto, para que possamos restringir suas operações, ao invés de deixá-lo rodar no domínio não confinado. / p>

Eu criei um arquivo de política de amostra simples com base no aprendizado que fiz até agora, mas o bash não executou o binário.

Aqui está o arquivo de políticas, conforme já existe:

policy_module(testprog, 0.1.6)

require {
type unconfined_t;
class file { ioctl getattr setattr create read write unlink open relabelto };
class process transition;
type fs_t;
class filesystem getattr;
}

type testprog_t;
type testprog_exec_t;

allow testprog_t fs_t:filesystem getattr;
allow testprog_t testprog_exec_t : file { ioctl read getattr lock execute execute_no_trans entrypoint open } ;
type_transition unconfined_t testprog_exec_t : process testprog_t;
allow unconfined_t testprog_t : process transition ;

Eu configurei o contexto do próprio binário da seguinte forma:

-rwxr-xr-x. root root system_u:object_r:testprog_exec_t:s0 /usr/bin/testprog

No entanto, se eu tentar executar o comando a partir do bash shell, receberei um erro permission denied e negação em auditoria.log:

[root@selinux-dev ~]# testprog
type=AVC msg=audit(1504546613.537:237): avc:  denied  { getattr } for  pid=1300 comm="bash" path="/usr/bin/testprog" dev="dm-0" ino=34637336 scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=system_u:object_r:testprog_exec_t:s0 tclass=file
type=SYSCALL msg=audit(1504546613.537:237): arch=c000003e syscall=4 success=no exit=-13 a0=2518ca0 a1=7ffd90223980 a2=7ffd90223980 a3=0 items=0 ppid=1296 pid=1300 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=2 comm="bash" exe="/usr/bin/bash" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=PROCTITLE msg=audit(1504546613.537:237): proctitle="-bash"
type=AVC msg=audit(1504546613.537:238): avc:  denied  { getattr } for  pid=1300 comm="bash" path="/usr/bin/testprog" dev="dm-0" ino=34637336 scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=system_u:object_r:testprog_exec_t:s0 tclass=file
type=SYSCALL msg=audit(1504546613.537:238): arch=c000003e syscall=4 success=no exit=-13 a0=2518ca0 a1=7ffd90223980 a2=7ffd90223980 a3=0 items=0 ppid=1296 pid=1300 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=2 comm="bash" exe="/usr/bin/bash" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=PROCTITLE msg=audit(1504546613.537:238): proctitle="-bash"
-bash: testprog: command not found

Claramente, minha política é um pouco exagerada. Por fim, quero poder executar o binário do systemd (meu arquivo de unidade, muito simples, é mostrado abaixo), mas quero fazer a transição do processo de um shell bash e de systemd para o tipo testprog_t que criei.

[Unit]
Description=SELinux Test Program

[Service]
#Type=forking
# The PID file is optional, but recommended in the manpage
# "so that systemd can identify the main process of the daemon"
PIDFile=/var/run/testprog.pid
ExecStart=/usr/bin/testprog /etc/testprog.conf /var/run/testprog.pid

[Install]
WantedBy=multi-user.target

Por favor alguém pode me ajudar a ver onde eu errei? O sistema operacional subjacente é o RHEL 7.4

Obrigado!

    
por James Freeman 04.09.2017 / 19:40

1 resposta

0

Eu consegui a transição trabalhando no final graças a várias referências - na verdade, ela se mostrou incrivelmente simples e eu acho que você poderia dizer que está relacionada a uma regra básica de boa programação?

Na política que publiquei na pergunta, defini dois novos tipos:

type testprog_t;
type testprog_exec_t;

Depois, permitimos que várias coisas acontecessem com esses tipos e também especificamos uma transição de tipo:

allow testprog_t fs_t:filesystem getattr;
allow testprog_t testprog_exec_t : file { ioctl read getattr lock execute execute_no_trans entrypoint open } ;
type_transition unconfined_t testprog_exec_t : process testprog_t;
allow unconfined_t testprog_t : process transition ;

No entanto, em nenhum momento eu realmente disse ao SELinux o que esses tipos realmente eram. Por exemplo, eu defino o contexto do arquivo /usr/bin/testprog como system_u:object_r:testprog_exec_t:s0 , mas na verdade nunca contei ao SELinux por meio de minha política que testprog_exec_t era um arquivo. Assim que mudei a política, adicionando especificações de tipo, as coisas começaram a parecer mais promissoras. Também precisei usar a instrução de função para permitir que testprog_t fosse executado sob a função unconfined_r que os comandos shell normalmente executam em um sistema RHEL no modo SELinux de destino. O atual fragmento da política relacionada a isso se parece com isso:

# Define our new types that testprog will use, and ensure that we tell the policy that testprog_exec_t is a file
type testprog_t;
domain_type(testprog_t);
type testprog_exec_t;
files_type(testprog_exec_t);
type testprog_etc_t;
files_type(testprog_etc_t);
type testprog_var_run_t;
files_type(testprog_var_run_t);
type testprog_data_t;
files_type(testprog_data_t);

# Allow the testprog_t type under the unconfined_r role
role unconfined_r types testprog_t;

# Tell SELinux that testprog_exec_t is an entrypoint to the tetprog_t domain
allow testprog_t testprog_exec_t : file { ioctl read getattr lock execute execute_no_trans entrypoint open } ;
# Make the type transition from unconfined_t (i.e. user shell) to testprog_t
type_transition unconfined_t testprog_exec_t : process testprog_t;
# Explicitly allow the type transition we have just created
allow unconfined_t testprog_t : process transition ;

Feito isso, a transição de tipo acontece perfeitamente e a tarefa de concluir a política tornou-se uma das que usam sealert para explorar o comportamento do programa e implementar as políticas certas para que funcione conforme desejado.

Espero montar um exemplo completo de um aplicativo que não seja o SELinux e que precise ser executado em seu próprio contexto confinado, em vez de não confinado para meus colegas (e para qualquer outra pessoa que precise dele) - é bastante esqueletal agora mas se alguém estiver interessado em rastreá-lo, você pode encontrar o código aqui:

link

    
por 06.09.2017 / 11:35