OpenCyber Academy
Graduação · Capítulo 27 · Português
Código do curso: OCA-114Capítulo 27: OCA-114-C027

Capítulo 27 — Segurança de TO, IoT e sistemas ciberfísicos: verificação

Ensino gratuito e aberto para quem deseja proteger pessoas e tecnologias. Não é preciso criar uma conta para estudar ou consultar as respostas.

Mapa da aula

Aula 27 publicada. Mapa, exemplo, EX079.

flowchart TD
  N0["27.1 Políticas precisam de testes"]
  N1["27.2 Projetando vetores"]
  N2["27.3 Lendo o resultado"]
  N3["27.4 Do laboratório para a planta"]
  N4["Síntese"]
  N0 --> N1 --> N2 --> N3 --> N4
  N4 --> EX["Exemplo resolvido"]
  EX --> Q["Exercício EX079"]

Desenho lógico

flowchart LR
  N0["27.1 Políticas precisam de testes"]
  N1["27.2 Projetando vetores"]
  N2["27.3 Lendo o resultado"]
  N3["27.4 Do laboratório para a planta"]
  N4["Síntese"]
  N0 --> N1 --> N2 --> N3 --> N4 --> Q["EX079"]
[27.1 Políticas precisam de testes]
    |
    v
[27.2 Projetando vetores]
    |
    v
[27.3 Lendo o resultado]
    |
    v
[27.4 Do laboratório para a planta]
    |
    v
[Síntese]
    |
    v
[Exemplo resolvido] --> [Exercício EX079]

Objetivos de aprendizagem

Você vai (1) escrever vetores de teste para uma política de lista de permissão; (2) incluir casos de limite, negativos e de origem desconhecida; (3) rodar testes de conformidade offline antes de qualquer implantação; e (4) explicar por que a evidência de verificação faz parte do ciclo de vida da IEC 62443.

27.1 Políticas precisam de testes

Um firewall ou uma lista de permissão sensível ao protocolo é código, mesmo quando escrito como regras. Verificar significa mostrar, com evidência registrada, que a política permite o que a operação precisa e bloqueia o que deve bloquear. A IEC 62443-4-1 (ciclo de vida de desenvolvimento seguro de produtos) e as atividades de comissionamento do integrador de sistemas esperam testes documentados. A política da LDHP para o PLC-H é pequena o bastante para caber numa linha: a HMI-1 pode ler com o código de função 3 e escrever nos registradores 100–119 com o código de função 6, o HIST-1 pode ler com os códigos de função 3 e 4, e todas as outras origens e funções são bloqueadas. O laboratório transforma essa linha em seis vetores com resultados esperados. Uma política que nunca foi executada contra vetores como esses é um palpite sobre o que o firewall faz.

27.2 Projetando vetores

Bons vetores incluem: cada par (origem, função) permitido; cada limite de uma faixa de registradores (primeiro, último, um depois do último); uma origem permitida usando uma função proibida; uma origem desconhecida; e uma função de escrita que a planta nunca usa (16, escrever vários registradores). Os resultados esperados são escritos antes de rodar o teste.

"""Lab 27: conformance test of a Modbus allow-list against a test vector table."""
ALLOW = {("HMI-1", 3), ("HMI-1", 6), ("HIST-1", 3), ("HIST-1", 4)}
WRITE_RANGE = range(100, 120)
def permit(src, fc, reg):
    if (src, fc) not in ALLOW: return "BLOCK"
    if fc == 6 and reg not in WRITE_RANGE: return "BLOCK"
    return "PASS"
vectors = [("HMI-1", 3, 100, "PASS"), ("HMI-1", 6, 119, "PASS"), ("HMI-1", 6, 120, "BLOCK"),
           ("HIST-1", 6, 105, "BLOCK"), ("ENG-WS", 16, 100, "BLOCK"), ("HIST-1", 4, 10, "PASS")]
fails = 0
for src, fc, reg, want in vectors:
    got = permit(src, fc, reg); fails += got != want
    print(f"{src:6} fc={fc:2} reg={reg:3} want={want:5} got={got:5} {'ok' if got == want else 'FAIL'}")
print("failures:", fails, "of", len(vectors))

Execute com python3 lab_allow.py. Saída verificada:

HMI-1  fc= 3 reg=100 want=PASS  got=PASS  ok
HMI-1  fc= 6 reg=119 want=PASS  got=PASS  ok
HMI-1  fc= 6 reg=120 want=BLOCK got=BLOCK ok
HIST-1 fc= 6 reg=105 want=BLOCK got=BLOCK ok
ENG-WS fc=16 reg=100 want=BLOCK got=BLOCK ok
HIST-1 fc= 4 reg= 10 want=PASS  got=PASS  ok
failures: 0 of 6

No laboratório, os seis vetores são: a HMI-1 lendo o registrador 100; a HMI-1 escrevendo no 119, o último registrador permitido; a HMI-1 escrevendo no 120, um depois do fim; o HIST-1 escrevendo no 105; a ENG-WS usando a função 16; e o HIST-1 lendo com a função 4.

27.3 Lendo o resultado

Os seis vetores coincidem. Observe o vetor 3: o registrador 120 está um depois do fim de range(100, 120), então precisa ser bloqueado — o clássico limite com erro de deslocamento de um. O vetor 4 confirma que o historiador não consegue escrever, mesmo dentro da faixa gravável. Uma execução limpa é evidência apenas para esses seis casos; ela não diz nada sobre o código de função 23 (ler/escrever vários registradores), a menos que você o acrescente. O pedido de mudança do colega de Maya mostra como os vetores são mantidos: estender a faixa gravável da HMI-1 para incluir o registrador 120, para um novo setpoint de velocidade de bomba, significou mudar o resultado esperado do vetor 3 para PASS, acrescentar um novo vetor (HMI-1, 6, 121, BLOCK) e só então editar o WRITE_RANGE.

27.4 Do laboratório para a planta

Antes de implantar uma política no firewall da zona de controle da LDHP, os mesmos vetores são repetidos num ambiente de bancada com o dispositivo real, primeiro em modo de monitoramento, e o resultado é anexado ao chamado de mudança. Modo de monitoramento significa que o firewall registra o que teria bloqueado, sem bloquear. Na LDHP, esse período deve cobrir pelo menos uma semana inteira, incluindo a execução do relatório semanal e uma janela de manutenção, porque uma origem legítima que escreve só de vez em quando, como a EWS-1 durante uma mudança de lógica, apareceria de outro modo pela primeira vez como uma escrita bloqueada no meio do turno de um operador. O chamado de mudança leva então os resultados dos vetores na bancada, o log do modo de monitoramento e a concordância do líder de turno com a imposição.

Exemplo resolvido (LDHP sintética)

Um colega propõe estender a faixa gravável da HMI-1 para incluir o registrador 120 (um novo setpoint de velocidade de bomba). Maya primeiro muda o resultado esperado do vetor 3 para PASS, acrescenta o vetor (HMI-1, 6, 121, BLOCK), depois edita o WRITE_RANGE para range(100, 121) e roda de novo. A mudança nos testes é revisada junto com a mudança na política.

Caso sintético — Lakeside District Heating Plant. Os números de registradores são inventados.

Erros e limites

Testes escritos depois do código tendem a confirmar o que o código faz, e não o que a planta precisa. A conformidade offline não prova o desempenho do dispositivo sob carga.

Exercícios

Síntese

Verificação é uma lista escrita de decisões esperadas, incluindo limites e desconhecidos, executada antes da implantação e guardada como evidência.

Respostas comentadas

EX079. Esperado BLOCK, e permit("HMI-1", 23, 105) devolve BLOCK porque o par (HMI-1, 23) não está em ALLOW — a política nega por padrão as funções não listadas.

EX080. (HMI-1, 6, 120) → PASS, o novo último registrador gravável; (HMI-1, 6, 121) → BLOCK, o primeiro registrador depois da faixa.

EX081. Se as expectativas vierem da execução do código, um defeito vira o resultado esperado. Escrevê-las primeiro a partir do requisito operacional (de quais registradores a HMI-1 realmente precisa) permite que o teste pegue a divergência.