Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Lendo e processando arquivo XML com o Python

Utilizando-se dos anexos lista.txt e cve.xml desenvolva um script em Python que:

1) abra e leia o arquivo de extensão ".xml" disponibilizado ao final;

2) procure no arquivo todas as ocorrências de CVE ID no formato: “”, onde YYYY é o ano, com 4 dígitos, e NNNN é o número do CVE, que pode ter 4, 5, 6 ou 7 dígitos;

3) confirme se os CVEs recuperados do arquivo existem em uma lista localmente armazenada (arquivo "lista.txt" ). Se esse CVE não estiver na lista.txt, o script deve incluí-lo no final da lista, salvando 01(um) campo "CVE-YYYY-NNNN" por linha; e

4) imprima na tela "Novo CVE encontrado: CVE-xxxx-yyyy" para cada novo CVE gravado no arquivo "lista.txt". Caso não seja encontrado nenhum novo CVE no ".xml", imprima na tela "Sem CVE Novo".

lista.txt : https://drive.google.com/open?id=1RBbcrXQkfymjkXC-sP_nuiz9S3qO15dZ

cve.xml : https://drive.google.com/open?id=10l4oC9rmbdz4CbXwDukMk1gG5yANFdcY

Eu só consegui abrir o arquivo XML:

import xml.etree.ElementTree as ET

tree = ET.parse('cve.xml')

Alguem poderia ajudar?

Acho que dá pra resolver também apenas usando regex. Se alguem puder mostrar as duas soluções, ajudará muito no meu aprendizado!

2 respostas

Alguém poderia ajudar?

solução!

Opa Edson, tudo bem com você?

Esse exercício realmente é um pouco complicado, e eu não compreendo muito de Python para fazer da forma mais eficiente, mas consegui resolver o exercício, vou te mostrar a minha abordagem e você pode ir melhorando dado seus conhecimentos em python, ok?

Irei utilizar a regex para observar o padrão da CVE, com essa função:

def validaPadrao(texto):
    padrao = r"^CVE-\d{4}-\d{4,7}$"
    if re.search(padrao, texto):
        return True

    return False

Vamos utilizar ela para cada elemento do XML, eu sinceramente não tenho muito conhecimento de como percorrer em python de uma maneira bonita, então fui da maneira mais rústica:

def varrerXML(data):
    lista_cve = []
    for epl in data: 
        for canvas in epl:
            for exploits in canvas:
                if validaPadrao(exploits.get('cve')):
                    lista_cve.append(exploits.get('cve'))
    return lista_cve

O que estou fazendo é encadeando os for até chegar em nosso elemento procurado que é o :

<Exploit cve="CVE-2009-4178" desc="HP OpenView Network Node Manager OvWebHelp CGI Remote Overflow" name="wp_openviewnnm_ovcgi"/>

Para cada elemento Exploit eu estou pegando o cve e jogando na nossa função que valida o padrão, caso o formato seja valido eu estou adicionando numa lista que irá conter todos os CVE's

Agora irei criar uma função para comparar 2 listas, isso será útil para a gente observar quais ainda não foram inseridos:

def procuraElementosNaoExistentes(lista1, lista2):
    resultado = []
    for elemento in lista1:
        if( elemento not in lista2):
            resultado.append(elemento)

    return resultado

Veja que estou guardando todos elementos não inseridos em uma lista, eu utilizarei agora para adicionar um por um, na seguinte função:

def adicionaNaoExistente(arquivo, lista):

    if(len(lista) == 0):
        print(f"Nenhum CVE novo")
        return

    file = open(arquivo, "a")
    for elemento in lista:
        print(f"Novo CVE encontrado: {elemento}")
        file.write(f"\n{elemento}")
    file.close()

Veja que no começo eu já faço a validação para verificar se existem CVE's novos a serem inseridos, caso tenha eu irei abrir o arquivo e irei adicionar cada elemento

Por fim temos a nossa função main que será responsável por lidar com todo o fluxo:

def main():
    xml = ET.parse('cve.xml').getroot()
    lista_arquivo = open('lista_final.txt', 'r').read().split('\n')
    lista_xml = varrerXML(xml)
    cve_nao_existentes = procuraElementosNaoExistentes(lista_xml, lista_arquivo)

    adicionaNaoExistente("lista_final.txt", cve_nao_existentes)

Veja que eu pego o arquivo existente e transformo em uma lista, e utilizo a nossa função de varrer XML para criar outra, dessa forma eu comparo ambas e adiciono os não existentes em nosso arquivo :)

Na primeira execução teremos algo:

>> python3 main.py
Novo CVE encontrado: CVE-2016-0994
Novo CVE encontrado: CVE-2020-4387
Novo CVE encontrado: CVE-2019-3605
Novo CVE encontrado: CVE-2020-2240
Novo CVE encontrado: CVE-2016-0915
Novo CVE encontrado: CVE-2019-4467
Novo CVE encontrado: CVE-2020-2938

Na segunda execução:

>> python3 main.py
Nenhum CVE novo

Conseguiu compreender? Realmente são várias etapas para conseguir fazer essa filtragem, eu acredito que fui na mais trabalhosa hahahaha

Abraços e Bons Estudos :)