вторник, 7 февраля 2017 г.

Splunk. XML Data Input

Приветствую, уважаемый читатель!

В этом посте я хотел бы рассказать про возможности Splunk при работе с XML-файлами. Несмотря на активное использование JSON как формата передачи и хранения данных, XML всё е щё популярен и поддерживается большим количеством решений. В качестве «подопытного» инструмента выступит сканер Nmap.




Цель данного поста продемонстрировать, что возможностей Splunk вполне может хватить для парсинга XML-файлов и создания собственного «XML Data Inputs». Для экспериментов нам понадобится несколько файлов-отчетов Nmap с результатом сканирования, выгруженные в формате XML.

1. Получаем XML-отчёты из Nmap

Nmap позволяет выгружать результаты сканирования в различных форматах с использованием специальных ключей, а именно:
-oN (консольный вывод);
-oX (вывод в формате XML);
-oS (вывод в формате script kiddi; не знаю зачем, но забавно J);
-oG (вывод в формате пригодном для использования grep);

Нам интересен XML-формат, поэтому запускаем Nmap:

nmap 190.140.200.20 -oX /usr/18.xml --stylesheet=nmap.xsl

Содержимое файла 18.xml будет примерно следующим (сократил для экономии места):

<?xml version="1.0"?>
<?xml-stylesheet href="nmap.xsl" type="text/xsl"?>
<!-- Nmap 6.00 scan initiated Mon Feb  6 16:48:32 2017 as: nmap -oX /usr/18.xml -&#45;stylesheet=nmap.xsl 190.140.200.20 -->
<nmaprun scanner="nmap" args="nmap -oX /usr/18.xml -&#45;stylesheet=nmap.xsl 190.140.200.20" start="1486388912" startstr="Mon Feb  6 16:48:32 2017" version="6.00" xmloutputversion="1.04">
<host starttime="1486388912" endtime="1486388915"><status state="up" reason="localhost-response"/>
<address addr="190.140.200.20" addrtype="ipv4"/>
<hostnames>
<hostname name="Test.ru" type="PTR"/>
</hostnames>
<ports><extraports state="closed" count="991">
<extrareasons reason="resets" count="991"/>
</extraports>
<port protocol="tcp" portid="22"><state state="open" reason="syn-ack" reason_ttl="64"/><service name="ssh" method="table" conf="3"/></port>
<port protocol="tcp" portid="80"><state state="open" reason="syn-ack" reason_ttl="64"/><service name="http" method="table" conf="3"/></port>
<port protocol="tcp" portid="111"><state state="open" reason="syn-ack" reason_ttl="64"/><service name="rpcbind" method="table" conf="3"/></port>
</ports>
<times srtt="7" rttvar="0" to="100000"/>
</host>
</nmaprun>


2. Создаём «XML Data Input»

Для получения данных в Splunk из XML-отчётов необходимо создать новый «Data Input» типа «Monitor»  и указать директорию, из которой получать новые файлы.  

inputs.conf

[monitor:///usr/NmapXML]
disabled = false
sourcetype = BASXML

Нам нужно, чтобы Splunk воспринимал каждый XML-файл с отчётом как отдельное событие и не разделял его дальше на части. Для этого необходимо описать в props.conf некоторые дополнительные параметры, а самое главное разделитель событий:

props.conf

[BASXML]
BREAK_ONLY_BEFORE = <?xml version="1.0"?>
DATETIME_CONFIG =
NO_BINARY_CHECK = true
category = Custom
pulldown_type = true

BREAK_ONLY_BEFORE – задаёт разделитель для событий в файлах (т.к. каждый XML-файл  отчёта начинается с <?xml version="1.0"?> всё содержимое файла будет одним большим событием);

DATETIME_CONFIG  – пустое значение означает, что Splunk автоматически ищет timestamp;


Теперь после перезагрузки Splunk и загрузки файла-отчета в директорию «/usr/NmapXML/» вы увидите:



3. Парсим XML в Splunk

Для разбора XML-документов можно использовать оператор SPL - spath. У него есть всего 3 параметра:
input указывается поле, откуда необходимо извлекать значения (по умолчанию значения извлекаются из поля _raw);
output имя поля для сохранения извлеченных значений;
path – путь до извлекаемого значения.

Запрос ниже позволяет получить информацию об объектах сканирования из XML-отчётов и представить её в табличном виде.

sourcetype=BASXML
| spath output=host path=nmaprun.host
| mvexpand host
| spath input=host output=state path=status{@state}
| spath input=host output=addr path=address{1}{@addr}
| spath input=host output=port path=ports.port{@portid}
| spath input=host output=proto path=ports.port{@protocol}
| spath input=host output=state path=ports.port.state{@state}
| spath input=host output=service path=ports.port.service{@name}
| table _time,addr,port,proto,state,service


Использование оператора mvexpand позволяет выделить из отчёта результаты сканирования нескольких хостов.

Всем удачного использования.

1 комментарий:

  1. Подскажите а возможно извлечь поле address{1}{@addr} на этапе загрузки
    файла?
    Если адресов будет больше одного то возможно автоматически извлекать их?

    ОтветитьУдалить