fix: [reportlab] Galaxies and Clusters printing

pull/358/head
Falconieri 2019-03-01 09:06:01 +01:00
parent 24e1a1732c
commit a06c8cf5b8
16 changed files with 356 additions and 217 deletions

View File

@ -10,10 +10,9 @@ codecov = "*"
requests-mock = "*"
[packages]
pymisp = {editable = true,extras = ["fileobjects", "neo", "openioc", "virustotal"],path = "."}
pymisp = {editable = true,extras = ["fileobjects", "neo", "openioc", "virustotal", "pdfexport"],path = "."}
pydeep = {editable = true,git = "https://github.com/kbandla/pydeep.git"}
pymispwarninglists = {editable = true,git = "https://github.com/MISP/PyMISPWarningLists.git"}
reportlab = "*"
[requires]
python_version = "3.6"

218
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "2551d32f7430eba34eac975cc1b28eca13fe9faff7197d83f312d7de8df187da"
"sha256": "c95b6920af9d48d6e38e0456394f752479064c9f3091cf3e6b93e751de21cfad"
},
"pipfile-spec": 6,
"requires": {
@ -23,6 +23,13 @@
],
"version": "==0.24.0"
},
"attrs": {
"hashes": [
"sha256:10cbf6e27dbce8c30807caf056c8eb50917e0eaafe86347671b57254006c3e69",
"sha256:ca4be454458f9dec299268d472aaa5a11f67a4ff70093396e1ceae9c76cf4bbb"
],
"version": "==18.2.0"
},
"beautifulsoup4": {
"hashes": [
"sha256:034740f6cb549b4e932ae1ab975581e6103ac8f942200a0e9759065984391858",
@ -40,40 +47,36 @@
},
"cffi": {
"hashes": [
"sha256:151b7eefd035c56b2b2e1eb9963c90c6302dc15fbd8c1c0a83a163ff2c7d7743",
"sha256:1553d1e99f035ace1c0544050622b7bc963374a00c467edafac50ad7bd276aef",
"sha256:1b0493c091a1898f1136e3f4f991a784437fac3673780ff9de3bcf46c80b6b50",
"sha256:2ba8a45822b7aee805ab49abfe7eec16b90587f7f26df20c71dd89e45a97076f",
"sha256:3bb6bd7266598f318063e584378b8e27c67de998a43362e8fce664c54ee52d30",
"sha256:3c85641778460581c42924384f5e68076d724ceac0f267d66c757f7535069c93",
"sha256:3eb6434197633b7748cea30bf0ba9f66727cdce45117a712b29a443943733257",
"sha256:495c5c2d43bf6cebe0178eb3e88f9c4aa48d8934aa6e3cddb865c058da76756b",
"sha256:4c91af6e967c2015729d3e69c2e51d92f9898c330d6a851bf8f121236f3defd3",
"sha256:57b2533356cb2d8fac1555815929f7f5f14d68ac77b085d2326b571310f34f6e",
"sha256:770f3782b31f50b68627e22f91cb182c48c47c02eb405fd689472aa7b7aa16dc",
"sha256:79f9b6f7c46ae1f8ded75f68cf8ad50e5729ed4d590c74840471fc2823457d04",
"sha256:7a33145e04d44ce95bcd71e522b478d282ad0eafaf34fe1ec5bbd73e662f22b6",
"sha256:857959354ae3a6fa3da6651b966d13b0a8bed6bbc87a0de7b38a549db1d2a359",
"sha256:87f37fe5130574ff76c17cab61e7d2538a16f843bb7bca8ebbc4b12de3078596",
"sha256:95d5251e4b5ca00061f9d9f3d6fe537247e145a8524ae9fd30a2f8fbce993b5b",
"sha256:9d1d3e63a4afdc29bd76ce6aa9d58c771cd1599fbba8cf5057e7860b203710dd",
"sha256:a36c5c154f9d42ec176e6e620cb0dd275744aa1d804786a71ac37dc3661a5e95",
"sha256:a6a5cb8809091ec9ac03edde9304b3ad82ad4466333432b16d78ef40e0cce0d5",
"sha256:ae5e35a2c189d397b91034642cb0eab0e346f776ec2eb44a49a459e6615d6e2e",
"sha256:b0f7d4a3df8f06cf49f9f121bead236e328074de6449866515cea4907bbc63d6",
"sha256:b75110fb114fa366b29a027d0c9be3709579602ae111ff61674d28c93606acca",
"sha256:ba5e697569f84b13640c9e193170e89c13c6244c24400fc57e88724ef610cd31",
"sha256:be2a9b390f77fd7676d80bc3cdc4f8edb940d8c198ed2d8c0be1319018c778e1",
"sha256:ca1bd81f40adc59011f58159e4aa6445fc585a32bb8ac9badf7a2c1aa23822f2",
"sha256:d5d8555d9bfc3f02385c1c37e9f998e2011f0db4f90e250e5bc0c0a85a813085",
"sha256:e55e22ac0a30023426564b1059b035973ec82186ddddbac867078435801c7801",
"sha256:e90f17980e6ab0f3c2f3730e56d1fe9bcba1891eeea58966e89d352492cc74f4",
"sha256:ecbb7b01409e9b782df5ded849c178a0aa7c906cf8c5a67368047daab282b184",
"sha256:ed01918d545a38998bfa5902c7c00e0fee90e957ce036a4000a88e3fe2264917",
"sha256:edabd457cd23a02965166026fd9bfd196f4324fe6032e866d0f3bd0301cd486f",
"sha256:fdf1c1dc5bafc32bc5d08b054f94d659422b05aba244d6be4ddc1c72d9aa70fb"
"sha256:00b97afa72c233495560a0793cdc86c2571721b4271c0667addc83c417f3d90f",
"sha256:0ba1b0c90f2124459f6966a10c03794082a2f3985cd699d7d63c4a8dae113e11",
"sha256:0bffb69da295a4fc3349f2ec7cbe16b8ba057b0a593a92cbe8396e535244ee9d",
"sha256:21469a2b1082088d11ccd79dd84157ba42d940064abbfa59cf5f024c19cf4891",
"sha256:2e4812f7fa984bf1ab253a40f1f4391b604f7fc424a3e21f7de542a7f8f7aedf",
"sha256:2eac2cdd07b9049dd4e68449b90d3ef1adc7c759463af5beb53a84f1db62e36c",
"sha256:2f9089979d7456c74d21303c7851f158833d48fb265876923edcb2d0194104ed",
"sha256:3dd13feff00bddb0bd2d650cdb7338f815c1789a91a6f68fdc00e5c5ed40329b",
"sha256:4065c32b52f4b142f417af6f33a5024edc1336aa845b9d5a8d86071f6fcaac5a",
"sha256:51a4ba1256e9003a3acf508e3b4f4661bebd015b8180cc31849da222426ef585",
"sha256:59888faac06403767c0cf8cfb3f4a777b2939b1fbd9f729299b5384f097f05ea",
"sha256:59c87886640574d8b14910840327f5cd15954e26ed0bbd4e7cef95fa5aef218f",
"sha256:610fc7d6db6c56a244c2701575f6851461753c60f73f2de89c79bbf1cc807f33",
"sha256:70aeadeecb281ea901bf4230c6222af0248c41044d6f57401a614ea59d96d145",
"sha256:71e1296d5e66c59cd2c0f2d72dc476d42afe02aeddc833d8e05630a0551dad7a",
"sha256:8fc7a49b440ea752cfdf1d51a586fd08d395ff7a5d555dc69e84b1939f7ddee3",
"sha256:9b5c2afd2d6e3771d516045a6cfa11a8da9a60e3d128746a7fe9ab36dfe7221f",
"sha256:9c759051ebcb244d9d55ee791259ddd158188d15adee3c152502d3b69005e6bd",
"sha256:b4d1011fec5ec12aa7cc10c05a2f2f12dfa0adfe958e56ae38dc140614035804",
"sha256:b4f1d6332339ecc61275bebd1f7b674098a66fea11a00c84d1c58851e618dc0d",
"sha256:c030cda3dc8e62b814831faa4eb93dd9a46498af8cd1d5c178c2de856972fd92",
"sha256:c2e1f2012e56d61390c0e668c20c4fb0ae667c44d6f6a2eeea5d7148dcd3df9f",
"sha256:c37c77d6562074452120fc6c02ad86ec928f5710fbc435a181d69334b4de1d84",
"sha256:c8149780c60f8fd02752d0429246088c6c04e234b895c4a42e1ea9b4de8d27fb",
"sha256:cbeeef1dc3c4299bd746b774f019de9e4672f7cc666c777cd5b409f0b746dac7",
"sha256:e113878a446c6228669144ae8a56e268c91b7f1fafae927adc4879d9849e0ea7",
"sha256:e21162bf941b85c0cda08224dade5def9360f53b09f9f259adb85fc7dd0e7b35",
"sha256:fb6934ef4744becbda3143d30c6604718871495a5e36c408431bf33d9c146889"
],
"version": "==1.11.5"
"version": "==1.12.2"
},
"chardet": {
"hashes": [
@ -98,27 +101,27 @@
},
"cryptography": {
"hashes": [
"sha256:05b3ded5e88747d28ee3ef493f2b92cbb947c1e45cf98cfef22e6d38bb67d4af",
"sha256:06826e7f72d1770e186e9c90e76b4f84d90cdb917b47ff88d8dc59a7b10e2b1e",
"sha256:08b753df3672b7066e74376f42ce8fc4683e4fd1358d34c80f502e939ee944d2",
"sha256:2cd29bd1911782baaee890544c653bb03ec7d95ebeb144d714b0f5c33deb55c7",
"sha256:31e5637e9036d966824edaa91bf0aa39dc6f525a1c599f39fd5c50340264e079",
"sha256:42fad67d7072216a49e34f923d8cbda9edacbf6633b19a79655e88a1b4857063",
"sha256:4946b67235b9d2ea7d31307be9d5ad5959d6c4a8f98f900157b47abddf698401",
"sha256:522fdb2809603ee97a4d0ef2f8d617bc791eb483313ba307cb9c0a773e5e5695",
"sha256:6f841c7272645dd7c65b07b7108adfa8af0aaea57f27b7f59e01d41f75444c85",
"sha256:7d335e35306af5b9bc0560ca39f740dfc8def72749645e193dd35be11fb323b3",
"sha256:8504661ffe324837f5c4607347eeee4cf0fcad689163c6e9c8d3b18cf1f4a4ad",
"sha256:9260b201ce584d7825d900c88700aa0bd6b40d4ebac7b213857bd2babee9dbca",
"sha256:9a30384cc402eac099210ab9b8801b2ae21e591831253883decdb4513b77a3cd",
"sha256:9e29af877c29338f0cab5f049ccc8bd3ead289a557f144376c4fbc7d1b98914f",
"sha256:ab50da871bc109b2d9389259aac269dd1b7c7413ee02d06fe4e486ed26882159",
"sha256:b13c80b877e73bcb6f012813c6f4a9334fcf4b0e96681c5a15dac578f2eedfa0",
"sha256:bfe66b577a7118e05b04141f0f1ed0959552d45672aa7ecb3d91e319d846001e",
"sha256:e091bd424567efa4b9d94287a952597c05d22155a13716bf5f9f746b9dc906d3",
"sha256:fa2b38c8519c5a3aa6e2b4e1cf1a549b54acda6adb25397ff542068e73d1ed00"
"sha256:066f815f1fe46020877c5983a7e747ae140f517f1b09030ec098503575265ce1",
"sha256:210210d9df0afba9e000636e97810117dc55b7157c903a55716bb73e3ae07705",
"sha256:26c821cbeb683facb966045e2064303029d572a87ee69ca5a1bf54bf55f93ca6",
"sha256:2afb83308dc5c5255149ff7d3fb9964f7c9ee3d59b603ec18ccf5b0a8852e2b1",
"sha256:2db34e5c45988f36f7a08a7ab2b69638994a8923853dec2d4af121f689c66dc8",
"sha256:409c4653e0f719fa78febcb71ac417076ae5e20160aec7270c91d009837b9151",
"sha256:45a4f4cf4f4e6a55c8128f8b76b4c057027b27d4c67e3fe157fa02f27e37830d",
"sha256:48eab46ef38faf1031e58dfcc9c3e71756a1108f4c9c966150b605d4a1a7f659",
"sha256:6b9e0ae298ab20d371fc26e2129fd683cfc0cfde4d157c6341722de645146537",
"sha256:6c4778afe50f413707f604828c1ad1ff81fadf6c110cb669579dea7e2e98a75e",
"sha256:8c33fb99025d353c9520141f8bc989c2134a1f76bac6369cea060812f5b5c2bb",
"sha256:9873a1760a274b620a135054b756f9f218fa61ca030e42df31b409f0fb738b6c",
"sha256:9b069768c627f3f5623b1cbd3248c5e7e92aec62f4c98827059eed7053138cc9",
"sha256:9e4ce27a507e4886efbd3c32d120db5089b906979a4debf1d5939ec01b9dd6c5",
"sha256:acb424eaca214cb08735f1a744eceb97d014de6530c1ea23beb86d9c6f13c2ad",
"sha256:c8181c7d77388fe26ab8418bb088b1a1ef5fde058c6926790c8a0a3d94075a4a",
"sha256:d4afbb0840f489b60f5a580a41a1b9c3622e08ecb5eec8614d4fb4cd914c4460",
"sha256:d9ed28030797c00f4bc43c86bf819266c76a5ea61d006cd4078a93ebf7da6bfd",
"sha256:e603aa7bb52e4e8ed4119a58a03b60323918467ef209e6ff9db3ac382e5cf2c6"
],
"version": "==2.5"
"version": "==2.6.1"
},
"decorator": {
"hashes": [
@ -143,10 +146,10 @@
},
"jsonschema": {
"hashes": [
"sha256:000e68abd33c972a5248544925a0cae7d1125f9bf6c58280d37546b946769a08",
"sha256:6ff5f3180870836cae40f06fa10419f557208175f13ad7bc26caa77beb1f6e02"
"sha256:acc8a90c31d11060516cfd0b414b9f8bcf4bc691b21f0f786ea57dd5255c79db",
"sha256:dd3f8ecb1b52d94d45eedb67cb86cac57b94ded562c5d98f63719e55ce58557b"
],
"version": "==2.6.0"
"version": "==3.0.0"
},
"lief": {
"hashes": [
@ -156,9 +159,9 @@
},
"neobolt": {
"hashes": [
"sha256:f70df7422568f3f92f065482237dabe3b96cd49a921c5e17feb1c9e68fdd0357"
"sha256:3324f2b319e84acb82e37a81ef75f3f7ce71c149387daf900589377db48bed2a"
],
"version": "==1.7.3"
"version": "==1.7.4"
},
"neotime": {
"hashes": [
@ -166,13 +169,48 @@
],
"version": "==1.7.4"
},
"pillow": {
"hashes": [
"sha256:051de330a06c99d6f84bcf582960487835bcae3fc99365185dc2d4f65a390c0e",
"sha256:0ae5289948c5e0a16574750021bd8be921c27d4e3527800dc9c2c1d2abc81bf7",
"sha256:0b1efce03619cdbf8bcc61cfae81fcda59249a469f31c6735ea59badd4a6f58a",
"sha256:163136e09bd1d6c6c6026b0a662976e86c58b932b964f255ff384ecc8c3cefa3",
"sha256:18e912a6ccddf28defa196bd2021fe33600cbe5da1aa2f2e2c6df15f720b73d1",
"sha256:24ec3dea52339a610d34401d2d53d0fb3c7fd08e34b20c95d2ad3973193591f1",
"sha256:267f8e4c0a1d7e36e97c6a604f5b03ef58e2b81c1becb4fccecddcb37e063cc7",
"sha256:3273a28734175feebbe4d0a4cde04d4ed20f620b9b506d26f44379d3c72304e1",
"sha256:4c678e23006798fc8b6f4cef2eaad267d53ff4c1779bd1af8725cc11b72a63f3",
"sha256:4d4bc2e6bb6861103ea4655d6b6f67af8e5336e7216e20fff3e18ffa95d7a055",
"sha256:505738076350a337c1740a31646e1de09a164c62c07db3b996abdc0f9d2e50cf",
"sha256:5233664eadfa342c639b9b9977190d64ad7aca4edc51a966394d7e08e7f38a9f",
"sha256:5d95cb9f6cced2628f3e4de7e795e98b2659dfcc7176ab4a01a8b48c2c2f488f",
"sha256:7eda4c737637af74bac4b23aa82ea6fbb19002552be85f0b89bc27e3a762d239",
"sha256:801ddaa69659b36abf4694fed5aa9f61d1ecf2daaa6c92541bbbbb775d97b9fe",
"sha256:825aa6d222ce2c2b90d34a0ea31914e141a85edefc07e17342f1d2fdf121c07c",
"sha256:9c215442ff8249d41ff58700e91ef61d74f47dfd431a50253e1a1ca9436b0697",
"sha256:a3d90022f2202bbb14da991f26ca7a30b7e4c62bf0f8bf9825603b22d7e87494",
"sha256:a631fd36a9823638fe700d9225f9698fb59d049c942d322d4c09544dc2115356",
"sha256:a6523a23a205be0fe664b6b8747a5c86d55da960d9586db039eec9f5c269c0e6",
"sha256:a756ecf9f4b9b3ed49a680a649af45a8767ad038de39e6c030919c2f443eb000",
"sha256:b117287a5bdc81f1bac891187275ec7e829e961b8032c9e5ff38b70fd036c78f",
"sha256:ba04f57d1715ca5ff74bb7f8a818bf929a204b3b3c2c2826d1e1cc3b1c13398c",
"sha256:cd878195166723f30865e05d87cbaf9421614501a4bd48792c5ed28f90fd36ca",
"sha256:cee815cc62d136e96cf76771b9d3eb58e0777ec18ea50de5cfcede8a7c429aa8",
"sha256:d1722b7aa4b40cf93ac3c80d3edd48bf93b9208241d166a14ad8e7a20ee1d4f3",
"sha256:d7c1c06246b05529f9984435fc4fa5a545ea26606e7f450bdbe00c153f5aeaad",
"sha256:e9c8066249c040efdda84793a2a669076f92a301ceabe69202446abb4c5c5ef9",
"sha256:f227d7e574d050ff3996049e086e1f18c7bd2d067ef24131e50a1d3fe5831fbc",
"sha256:fc9a12aad714af36cf3ad0275a96a733526571e52710319855628f476dcb144e"
],
"version": "==5.4.1"
},
"prompt-toolkit": {
"hashes": [
"sha256:88002cc618cacfda8760c4539e76c3b3f148ecdb7035a3d422c7ecdc90c2a3ba",
"sha256:c6655a12e9b08edb8cf5aeab4815fd1e1bdea4ad73d3bbf269cf2e0c4eb75d5e",
"sha256:df5835fb8f417aa55e5cafadbaeb0cf630a1e824aad16989f9f0493e679ec010"
"sha256:11adf3389a996a6d45cc277580d0d53e8a5afd281d0c9ec71b28e6f121463780",
"sha256:2519ad1d8038fd5fc8e770362237ad0364d16a7650fb5724af6997ed5515e3c1",
"sha256:977c6583ae813a37dc1c2e1b715892461fcbdaa57f6fc62f33a528c4886c8f55"
],
"version": "==2.0.8"
"version": "==2.0.9"
},
"py2neo": {
"hashes": [
@ -204,7 +242,8 @@
"fileobjects",
"neo",
"openioc",
"virustotal"
"virustotal",
"pdfexport"
],
"path": "."
},
@ -220,6 +259,12 @@
],
"version": "==19.0.0"
},
"pyrsistent": {
"hashes": [
"sha256:3ca82748918eb65e2d89f222b702277099aca77e34843c5eb9d52451173970e2"
],
"version": "==0.14.11"
},
"python-dateutil": {
"hashes": [
"sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb",
@ -241,6 +286,39 @@
],
"version": "==2018.9"
},
"reportlab": {
"hashes": [
"sha256:069f684cd0aaa518a27dc9124aed29cee8998e21ddf19604e53214ec8462bdd7",
"sha256:09b68ec01d86b4b120456b3f3202570ec96f57624e3a4fc36f3829323391daa4",
"sha256:0c32be9a406172c29ea20ff55a709ccac1e7fb09f15aba67cb7b455fd1d3dbe0",
"sha256:233196cf25e97cfe7c452524ea29d9a4909f1cb66599299233be1efaaaa7a7a3",
"sha256:2b5e4533f3e5b962835a5ce44467e66d1ecc822761d1b508077b5087a06be338",
"sha256:2e860bcdace5a558356802a92ae8658d7e5fdaa00ded82e83a3f2987c562cb66",
"sha256:3546029e63a9a9dc24ee38959eb417678c2425b96cd27b31e09e216dafc94666",
"sha256:4452b93f9c73b6b70311e7d69082d64da81b38e91bfb4766397630092e6da6fd",
"sha256:528c74a1c6527d1859c2c7a64a94a1cba485b00175162ea23699ae58a1e94939",
"sha256:6116e750f98018febc08dfee6df20446cf954adbcfa378d2c703d56c8864aff3",
"sha256:6b2b3580c647d75ef129172cb3da648cdb24566987b0b59c5ebb80ab770748d6",
"sha256:727b5f2bed08552d143fc99649b1863c773729f580a416844f9d9967bb0a1ae8",
"sha256:74c24a3ec0a3d4f8acb13a07192f45bdb54a1cc3c2286241677e7e8bcd5011fa",
"sha256:98ccd2f8b4f8636db05f3f14db0b471ad6bb4b66ae0dc9052c4822b3bd5d6a7d",
"sha256:a5905aa567946bc938b489a7249c7890c3fd3c9b7b5680dece5bc551c2ddbe0d",
"sha256:acbb7f676b8586b770719e9683eda951fdb38eb7970d46fcbf3cdda88d912a64",
"sha256:b5e30f865add48cf880f1c363eb505b97f2f7baaa88c155f87a335a76515a3e5",
"sha256:be2a7c33a2c28bbd3f453ffe4f0e5200b88c803a097f4cf52d69c6b53fad7a8f",
"sha256:c356bb600f59ac64955813d6497a08bfd5d0c451cb5829b61e3913d0ac084e26",
"sha256:c7ec4ae2393beab584921b1287a04e94fd98c28315e348362d89b85f4b464546",
"sha256:d476edc831bb3e9ebd04d1403abaf3ea57b3e4c2276c91a54fdfb6efbd3f9d97",
"sha256:db059e1a0691c872784062421ec51848539eb4f5210142682e61059a5ca7cc55",
"sha256:dd423a6753509ab14a0ac1b5be39d219c8f8d3781cce3deb4f45eda31969b5e8",
"sha256:ed9b7c0d71ce6fe2b31c6cde530ad8238632b876a5d599218739bda142a77f7c",
"sha256:f0a2465af4006f97b05e1f1546d67d3a3213d414894bf28be7f87f550a7f4a55",
"sha256:f20bfe26e57e8e1f575a9e0325be04dd3562db9f247ffdd73b5d4df6dec53bc2",
"sha256:f3463f2cb40a1b515ac0133ba859eca58f53b56760da9abb27ed684c565f853c",
"sha256:facc3c9748ab1525fb8401a1223bce4f24f0d6aa1a9db86c55db75777ccf40f9"
],
"version": "==3.5.13"
},
"requests": {
"hashes": [
"sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e",
@ -257,10 +335,10 @@
},
"soupsieve": {
"hashes": [
"sha256:466910df7561796a60748826781ebe9a888f7a1668a636ae86783f44d10aae73",
"sha256:87db12ae79194f0ff9808d2b1641c4f031ae39ffa3cab6b907ea7c1e5e5ed445"
"sha256:afa56bf14907bb09403e5d15fbed6275caa4174d36b975226e3b67a3bb6e2c4b",
"sha256:eaed742b48b1f3e2d45ba6f79401b2ed5dc33b2123dfe216adb90d4bfa0ade26"
],
"version": "==1.7.3"
"version": "==1.8"
},
"urllib3": {
"extras": [
@ -347,11 +425,11 @@
},
"coveralls": {
"hashes": [
"sha256:ab638e88d38916a6cedbf80a9cd8992d5fa55c77ab755e262e00b36792b7cd6d",
"sha256:b2388747e2529fa4c669fb1e3e2756e4e07b6ee56c7d9fce05f35ccccc913aa0"
"sha256:6f213e461390973f4a97fb9e9d4ebd4956af296ff0a4d868e622108145835cb7",
"sha256:a7d0078c9e9b5692c03dcd3884647e837836c265c01e98094632feadef767d36"
],
"index": "pypi",
"version": "==1.5.1"
"version": "==1.6.0"
},
"docopt": {
"hashes": [

View File

@ -4,6 +4,8 @@ README
[![Documentation Status](https://readthedocs.org/projects/pymisp/badge/?version=latest)](http://pymisp.readthedocs.io/?badge=latest)
[![Build Status](https://travis-ci.org/MISP/PyMISP.svg?branch=master)](https://travis-ci.org/MISP/PyMISP)
[![Coverage Status](https://coveralls.io/repos/github/MISP/PyMISP/badge.svg?branch=master)](https://coveralls.io/github/MISP/PyMISP?branch=master)
[![Python 3.6](https://img.shields.io/badge/python-3.6+-blue.svg)](https://www.python.org/downloads/release/python-360/)
[![PyPi version](https://img.shields.io/pypi/v/pymisp.svg)](https://pypi.python.org/pypi/pymisp/)
# PyMISP - Python Library to access MISP

View File

@ -23,7 +23,7 @@
"misp_url = 'http://127.0.0.1:8080'\n",
"# Can be found in the MISP web interface under \n",
"# http://+MISP_URL+/users/view/me -> Authkey\n",
"misp_key = 'LBelWqKY9SQyG0huZzAMqiEBl6FODxpgRRXMsZFu'\n",
"misp_key = 'aJAmQQoBhVL5jqUDSucIkPrEYIbFyW0wwQnxyBfc'\n",
"# Should PyMISP verify the MISP certificate\n",
"misp_verifycert = False"
]
@ -87,10 +87,11 @@
},
"outputs": [],
"source": [
"response = misp.search(publish_timestamp='2h')\n",
"response = misp.search(publish_timestamp='2d')\n",
"\n",
"print (response)\n",
"events = []\n",
"for event in response['response']:\n",
"for event in response:\n",
" me = MISPEvent()\n",
" me.load(event)\n",
" events.append(me)\n",
@ -133,7 +134,7 @@
"response = misp.search(timestamp=ts-36000)\n",
"\n",
"events = []\n",
"for event in response['response']:\n",
"for event in response:\n",
" me = MISPEvent()\n",
" me.load(event)\n",
" events.append(me)\n",
@ -179,10 +180,10 @@
"metadata": {},
"outputs": [],
"source": [
"response = misp.search(controller='attributes', publish_timestamp='1h')\n",
"response = misp.search(controller='attributes', publish_timestamp='1d')\n",
"\n",
"attributes = []\n",
"for attribute in response['response']['Attribute']:\n",
"for attribute in response['Attribute']:\n",
" ma = MISPAttribute()\n",
" ma.from_dict(**attribute)\n",
" attributes.append(ma)\n",
@ -197,10 +198,10 @@
"metadata": {},
"outputs": [],
"source": [
"response = misp.search(controller='attributes', publish_timestamp=['2h', '1h'])\n",
"response = misp.search(controller='attributes', publish_timestamp=['2d', '1h'])\n",
"\n",
"attributes = []\n",
"for attribute in response['response']['Attribute']:\n",
"for attribute in response['Attribute']:\n",
" ma = MISPAttribute()\n",
" ma.from_dict(**attribute)\n",
" attributes.append(ma)\n",
@ -229,7 +230,7 @@
"response = misp.search(controller='attributes', timestamp=ts - 36000)\n",
"\n",
"attributes = []\n",
"for attribute in response['response']['Attribute']:\n",
"for attribute in response['Attribute']:\n",
" ma = MISPAttribute()\n",
" ma.from_dict(**attribute)\n",
" attributes.append(ma)\n",
@ -256,7 +257,7 @@
"response = misp.search_index(eventinfo='Cobalt Strike')\n",
"\n",
"events = []\n",
"for event in response['response']:\n",
"for event in response:\n",
" me = MISPEvent()\n",
" me.from_dict(**event)\n",
" events.append(me)\n",
@ -280,10 +281,10 @@
"metadata": {},
"outputs": [],
"source": [
"response = misp.search_index(tag='malware_classification:malware-category=\"Ransomware\"')\n",
"response = misp.search_index(tags='malware_classification:malware-category=\"Ransomware\"')\n",
"\n",
"events = []\n",
"for event in response['response']:\n",
"for event in response:\n",
" me = MISPEvent()\n",
" me.from_dict(**event)\n",
" events.append(me)\n",
@ -303,7 +304,7 @@
"response = misp.search_index(timestamp='1h')\n",
"\n",
"events = []\n",
"for event in response['response']:\n",
"for event in response:\n",
" me = MISPEvent()\n",
" me.from_dict(**event)\n",
" events.append(me)\n",
@ -328,8 +329,9 @@
"outputs": [],
"source": [
"event = MISPEvent()\n",
"event.load(misp.get(events[0].id))\n",
"print(event.to_json())"
"#event.load(misp.get(events[0].id))\n",
"print (misp.get(events[0].id))\n",
"#print(event.to_json())"
]
},
{
@ -345,7 +347,7 @@
"metadata": {},
"outputs": [],
"source": [
"complex_query = misp.build_complex_query(or_parameters=['59.157.4.2', 'hotfixmsupload.com'])\n",
"complex_query = misp.build_complex_query(or_parameters=['59.157.4.2', 'hotfixmsupload.com', '8.8.8.8'])\n",
"events = misp.search(value=complex_query, pythonify=True)\n",
"\n",
"for e in events:\n",
@ -365,7 +367,7 @@
"metadata": {},
"outputs": [],
"source": [
"misp.sighting(value=e.attributes[3].value)"
"misp.sighting(value=e.attributes[1].value)"
]
},
{
@ -374,7 +376,7 @@
"metadata": {},
"outputs": [],
"source": [
"misp.sighting_list(e.attributes[3].id)"
"misp.sighting_list(e.attributes[1].id)"
]
},
{

View File

@ -42,7 +42,17 @@ try:
from .tools import openioc # noqa
from .tools import load_warninglists # noqa
from .tools import ext_lookups # noqa
from .tools import reportlab_generator # noqa
if sys.version_info >= (3, 4):
# Let's not bother with python 2
try:
from .tools import reportlab_generator # noqa
except ImportError:
# FIXME: The import should not raise an exception if reportlab isn't installed
pass
except NameError:
# FIXME: The import should not raise an exception if reportlab isn't installed
pass
if sys.version_info >= (3, 6):
from .aping import ExpandedPyMISP # noqa
logger.debug('pymisp loaded properly')

View File

@ -69,9 +69,10 @@ class PyMISP(object):
:param proxies: Proxy dict as describes here: http://docs.python-requests.org/en/master/user/advanced/#proxies
:param cert: Client certificate, as described there: http://docs.python-requests.org/en/master/user/advanced/#client-side-certificates
:param asynch: Use asynchronous processing where possible
:param auth: The auth parameter is passed directly to requests, as described here: http://docs.python-requests.org/en/master/user/authentication/
"""
def __init__(self, url, key, ssl=True, out_type='json', debug=None, proxies=None, cert=None, asynch=False):
def __init__(self, url, key, ssl=True, out_type='json', debug=None, proxies=None, cert=None, asynch=False, auth=None):
if not url:
raise NoURL('Please provide the URL of your MISP instance.')
if not key:
@ -83,6 +84,7 @@ class PyMISP(object):
self.proxies = proxies
self.cert = cert
self.asynch = asynch
self.auth = auth
if asynch and not ASYNC_OK:
logger.critical("You turned on Async, but don't have requests_futures installed")
self.asynch = False
@ -169,6 +171,7 @@ class PyMISP(object):
else:
local_session = requests.Session
with local_session() as s:
req.auth = self.auth
prepped = s.prepare_request(req)
prepped.headers.update(
{'Authorization': self.key,
@ -1779,7 +1782,7 @@ class PyMISP(object):
def get_roles_list(self):
"""Get the list of existing roles"""
url = urljoin(self.root_url, '/roles')
url = urljoin(self.root_url, 'roles')
response = self._prepare_request('GET', url)
return self._check_response(response)
@ -1787,13 +1790,13 @@ class PyMISP(object):
def get_tags_list(self):
"""Get the list of existing tags."""
url = urljoin(self.root_url, '/tags')
url = urljoin(self.root_url, 'tags')
response = self._prepare_request('GET', url)
return self._check_response(response)['Tag']
def get_tag(self, tag_id):
"""Get a tag by id."""
url = urljoin(self.root_url, '/tags/view/{}'.format(tag_id))
url = urljoin(self.root_url, 'tags/view/{}'.format(tag_id))
response = self._prepare_request('GET', url)
return self._check_response(response)
@ -1827,7 +1830,7 @@ class PyMISP(object):
old_tag = self.get_tag(tag_id)
new_tag = self._set_tag_parameters(name, colour, exportable, hide_tag, org_id, count, user_id,
numerical_value, attribute_count, old_tag)
url = urljoin(self.root_url, '/tags/edit/{}'.format(tag_id))
url = urljoin(self.root_url, 'tags/edit/{}'.format(tag_id))
response = self._prepare_request('POST', url, json.dumps(new_tag))
return self._check_response(response)
@ -1835,7 +1838,7 @@ class PyMISP(object):
"""Edit the tag using a json file."""
with open(json_file, 'rb') as f:
jdata = json.load(f)
url = urljoin(self.root_url, '/tags/edit/{}'.format(tag_id))
url = urljoin(self.root_url, 'tags/edit/{}'.format(tag_id))
response = self._prepare_request('POST', url, json.dumps(jdata))
return self._check_response(response)
@ -1853,38 +1856,38 @@ class PyMISP(object):
def get_taxonomies_list(self):
"""Get all the taxonomies."""
url = urljoin(self.root_url, '/taxonomies')
url = urljoin(self.root_url, 'taxonomies')
response = self._prepare_request('GET', url)
return self._check_response(response)
def get_taxonomy(self, taxonomy_id):
"""Get a taxonomy by id."""
url = urljoin(self.root_url, '/taxonomies/view/{}'.format(taxonomy_id))
url = urljoin(self.root_url, 'taxonomies/view/{}'.format(taxonomy_id))
response = self._prepare_request('GET', url)
return self._check_response(response)
def update_taxonomies(self):
"""Update all the taxonomies."""
url = urljoin(self.root_url, '/taxonomies/update')
url = urljoin(self.root_url, 'taxonomies/update')
response = self._prepare_request('POST', url)
return self._check_response(response)
def enable_taxonomy(self, taxonomy_id):
"""Enable a taxonomy by id."""
url = urljoin(self.root_url, '/taxonomies/enable/{}'.format(taxonomy_id))
url = urljoin(self.root_url, 'taxonomies/enable/{}'.format(taxonomy_id))
response = self._prepare_request('POST', url)
return self._check_response(response)
def disable_taxonomy(self, taxonomy_id):
"""Disable a taxonomy by id."""
self.disable_taxonomy_tags(taxonomy_id)
url = urljoin(self.root_url, '/taxonomies/disable/{}'.format(taxonomy_id))
url = urljoin(self.root_url, 'taxonomies/disable/{}'.format(taxonomy_id))
response = self._prepare_request('POST', url)
return self._check_response(response)
def get_taxonomy_tags_list(self, taxonomy_id):
"""Get all the tags of a taxonomy by id."""
url = urljoin(self.root_url, '/taxonomies/view/{}'.format(taxonomy_id))
url = urljoin(self.root_url, 'taxonomies/view/{}'.format(taxonomy_id))
response = self._prepare_request('GET', url)
return self._check_response(response)["entries"]
@ -1892,13 +1895,13 @@ class PyMISP(object):
"""Enable all the tags of a taxonomy by id."""
enabled = self.get_taxonomy(taxonomy_id)['Taxonomy']['enabled']
if enabled:
url = urljoin(self.root_url, '/taxonomies/addTag/{}'.format(taxonomy_id))
url = urljoin(self.root_url, 'taxonomies/addTag/{}'.format(taxonomy_id))
response = self._prepare_request('POST', url)
return self._check_response(response)
def disable_taxonomy_tags(self, taxonomy_id):
"""Disable all the tags of a taxonomy by id."""
url = urljoin(self.root_url, '/taxonomies/disableTag/{}'.format(taxonomy_id))
url = urljoin(self.root_url, 'taxonomies/disableTag/{}'.format(taxonomy_id))
response = self._prepare_request('POST', url)
return self._check_response(response)
@ -1906,19 +1909,19 @@ class PyMISP(object):
def get_warninglists(self):
"""Get all the warninglists."""
url = urljoin(self.root_url, '/warninglists')
url = urljoin(self.root_url, 'warninglists')
response = self._prepare_request('GET', url)
return self._check_response(response)
def get_warninglist(self, warninglist_id):
"""Get a warninglist by id."""
url = urljoin(self.root_url, '/warninglists/view/{}'.format(warninglist_id))
url = urljoin(self.root_url, 'warninglists/view/{}'.format(warninglist_id))
response = self._prepare_request('GET', url)
return self._check_response(response)
def update_warninglists(self):
"""Update all the warninglists."""
url = urljoin(self.root_url, '/warninglists/update')
url = urljoin(self.root_url, 'warninglists/update')
response = self._prepare_request('POST', url)
return self._check_response(response)
@ -1940,7 +1943,7 @@ class PyMISP(object):
query['name'] = warninglist_name
if force_enable is not None:
query['enabled'] = force_enable
url = urljoin(self.root_url, '/warninglists/toggleEnable')
url = urljoin(self.root_url, 'warninglists/toggleEnable')
response = self._prepare_request('POST', url, json.dumps(query))
return self._check_response(response)
@ -1954,7 +1957,7 @@ class PyMISP(object):
def check_warninglist(self, value):
"""Check if IOC values are in warninglist"""
url = urljoin(self.root_url, '/warninglists/checkValue')
url = urljoin(self.root_url, 'warninglists/checkValue')
response = self._prepare_request('POST', url, json.dumps(value))
return self._check_response(response)
@ -1962,31 +1965,31 @@ class PyMISP(object):
def get_noticelists(self):
"""Get all the noticelists."""
url = urljoin(self.root_url, '/noticelists')
url = urljoin(self.root_url, 'noticelists')
response = self._prepare_request('GET', url)
return self._check_response(response)
def get_noticelist(self, noticelist_id):
"""Get a noticelist by id."""
url = urljoin(self.root_url, '/noticelists/view/{}'.format(noticelist_id))
url = urljoin(self.root_url, 'noticelists/view/{}'.format(noticelist_id))
response = self._prepare_request('GET', url)
return self._check_response(response)
def update_noticelists(self):
"""Update all the noticelists."""
url = urljoin(self.root_url, '/noticelists/update')
url = urljoin(self.root_url, 'noticelists/update')
response = self._prepare_request('POST', url)
return self._check_response(response)
def enable_noticelist(self, noticelist_id):
"""Enable a noticelist by id."""
url = urljoin(self.root_url, '/noticelists/enableNoticelist/{}/true'.format(noticelist_id))
url = urljoin(self.root_url, 'noticelists/enableNoticelist/{}/true'.format(noticelist_id))
response = self._prepare_request('POST', url)
return self._check_response(response)
def disable_noticelist(self, noticelist_id):
"""Disable a noticelist by id."""
url = urljoin(self.root_url, '/noticelists/enableNoticelist/{}'.format(noticelist_id))
url = urljoin(self.root_url, 'noticelists/enableNoticelist/{}'.format(noticelist_id))
response = self._prepare_request('POST', url)
return self._check_response(response)
@ -1994,19 +1997,19 @@ class PyMISP(object):
def get_galaxies(self):
"""Get all the galaxies."""
url = urljoin(self.root_url, '/galaxies')
url = urljoin(self.root_url, 'galaxies')
response = self._prepare_request('GET', url)
return self._check_response(response)
def get_galaxy(self, galaxy_id):
"""Get a galaxy by id."""
url = urljoin(self.root_url, '/galaxies/view/{}'.format(galaxy_id))
url = urljoin(self.root_url, 'galaxies/view/{}'.format(galaxy_id))
response = self._prepare_request('GET', url)
return self._check_response(response)
def update_galaxies(self):
"""Update all the galaxies."""
url = urljoin(self.root_url, '/galaxies/update')
url = urljoin(self.root_url, 'galaxies/update')
response = self._prepare_request('POST', url)
return self._check_response(response)
@ -2046,7 +2049,7 @@ class PyMISP(object):
if tags:
if isinstance(tags, list):
tags = "&&".join(tags)
url = urljoin(self.root_url, "/events/stix/download/{}/{}/{}/{}/{}".format(
url = urljoin(self.root_url, "events/stix/download/{}/{}/{}/{}/{}".format(
event_id, with_attachments, tags, from_date, to_date))
logger.debug("Getting STIX event from %s", url)
response = self._prepare_request('GET', url)
@ -2064,7 +2067,7 @@ class PyMISP(object):
:param context: Add event level context (event_info,event_member_org,event_source_org,event_distribution,event_threat_level_id,event_analysis,event_date,event_tag)
:param ignore: Returns the attributes even if the event isn't published, or the attribute doesn't have the to_ids flag set
"""
url = urljoin(self.root_url, '/events/csv/download')
url = urljoin(self.root_url, 'events/csv/download')
to_post = {}
if eventid:
to_post['eventid'] = eventid
@ -2217,7 +2220,7 @@ class PyMISP(object):
:extend: Allow the organisation to extend the group
'''
to_jsonify = {'sg_id': sharing_group, 'org_id': organisation, 'extend': extend}
url = urljoin(self.root_url, '/sharingGroups/addOrg')
url = urljoin(self.root_url, 'sharingGroups/addOrg')
response = self._prepare_request('POST', url, json.dumps(to_jsonify))
return self._check_response(response)
@ -2227,7 +2230,7 @@ class PyMISP(object):
:organisation: Organisation's local instance ID, or Organisation's global UUID, or Organisation's name as known to the curent instance
'''
to_jsonify = {'sg_id': sharing_group, 'org_id': organisation}
url = urljoin(self.root_url, '/sharingGroups/removeOrg')
url = urljoin(self.root_url, 'sharingGroups/removeOrg')
response = self._prepare_request('POST', url, json.dumps(to_jsonify))
return self._check_response(response)
@ -2238,7 +2241,7 @@ class PyMISP(object):
:all_orgs: Add all the organisations of the server to the group
'''
to_jsonify = {'sg_id': sharing_group, 'server_id': server, 'all_orgs': all_orgs}
url = urljoin(self.root_url, '/sharingGroups/addServer')
url = urljoin(self.root_url, 'sharingGroups/addServer')
response = self._prepare_request('POST', url, json.dumps(to_jsonify))
return self._check_response(response)
@ -2248,7 +2251,7 @@ class PyMISP(object):
:server: Server's local instance ID, or URL of the Server, or Server's name as known to the curent instance
'''
to_jsonify = {'sg_id': sharing_group, 'server_id': server}
url = urljoin(self.root_url, '/sharingGroups/removeServer')
url = urljoin(self.root_url, 'sharingGroups/removeServer')
response = self._prepare_request('POST', url, json.dumps(to_jsonify))
return self._check_response(response)
@ -2324,7 +2327,7 @@ class PyMISP(object):
return self._check_response(response)
def update_object_templates(self):
url = urljoin(self.root_url, '/objectTemplates/update')
url = urljoin(self.root_url, 'objectTemplates/update')
response = self._prepare_request('POST', url)
return self._check_response(response)

@ -1 +1 @@
Subproject commit 75ae30f44df997280255eec60b981b9f376c5ac4
Subproject commit d0886ba6aff1526868efcd59fccb99e920372f3b

View File

@ -34,7 +34,6 @@ try:
HAS_REPORTLAB = True
except ImportError:
HAS_REPORTLAB = False
print("ReportLab cannot be imported. Please verify that ReportLab is installed on the system.")
########################################################################
@ -190,6 +189,17 @@ analysis_map = {"0": "<font color =" + HIGH_THREAT_COLOR + "> Initial (0)</fon
"1": "<font color =" + MEDIUM_THREAT_COLOR + "> Ongoing (1)</font>",
"2": "<font color =" + LOW_THREAT_COLOR + "> Completed (2)</font>"}
# == Parameters for Sightings ==
POSITIVE_SIGHT_COLOR = 'green'
NEGATIVE_SIGHT_COLOR = 'red'
MISC_SIGHT_COLOR = 'orange'
# == Parameters for galaxies ==
DO_SMALL_GALAXIES = True
FIRST_LEVEL_GALAXY_WIDTHS = ["15%","85%"]
SECOND_LEVEL_GALAXY_WIDTHS = ["20%","80%"]
CLUSTER_COLORS = [0] # or 1
OFFSET = 1
########################################################################
# "UTILITIES" METHODS. Not meant to be used except for development purposes
@ -315,6 +325,9 @@ def lines_style_generator(data, line_alternation):
# Last line
lines_list.append(('LINEBELOW', (0, len(data) - 1), (-1, len(data) - 1), LINE_THICKNESS, LINE_COLOR))
elif line_alternation == [] :
# Do nothing
return lines_list
else:
if data_len > len(line_alternation) :
logger.warning("Line alternation for PDF display isn't correctly set. Looping on given values only.")
@ -374,6 +387,30 @@ def get_table_styles():
return custom_body_style_col_1, custom_body_style_col_2
def get_clusters_table_styles():
'''
Create and returns the two mains styles for the columns of a table describing a cluster.
:return: two styles, one for each columns of the document, describing the MISP object.
'''
col1, col2 = get_table_styles()
custom_body_style_col_1 = ParagraphStyle(name='Column_1_small',
parent=col1,
fontName=FIRST_COL_FONT,
textColor=FIRST_COL_FONT_COLOR,
fontSize=TEXT_FONT_SIZE - 2,
leading=LEADING_SPACE- 1,
alignment=FIRST_COL_ALIGNEMENT)
custom_body_style_col_2 = ParagraphStyle(name='Column_2_small',
parent=col2,
fontName=SECOND_COL_FONT,
textColor=SECOND_COL_FONT_COLOR,
fontSize=TEXT_FONT_SIZE - 2,
leading=LEADING_SPACE- 1,
alignment=TA_JUSTIFY)
return custom_body_style_col_1, custom_body_style_col_2
########################################################################
# Checks
@ -413,18 +450,22 @@ class Value_Formatter():
'''
# ----------------------------------------------------------------------
def __init__(self, config, col1_style, col2_style):
def __init__(self, config, col1_style, col2_style, col1_small_style, col2_small_style):
self.config = config
self.col1_style = col1_style
self.col2_style = col2_style
self.col1_small_style = col1_small_style
self.col2_small_style = col2_small_style
# ----------------------------------------------------------------------
########################################################################
# General attribut formater
def get_col1_paragraph(self, dirty_string):
return self.get_unoverflowable_paragraph(dirty_string, self.col1_style)
def get_col1_paragraph(self, dirty_string, do_small=False):
if do_small :
return self.get_unoverflowable_paragraph(dirty_string, self.col1_small_style, do_small=do_small)
return self.get_unoverflowable_paragraph(dirty_string, self.col1_style, do_small=do_small)
def get_unoverflowable_paragraph(self, dirty_string, curr_style=None, do_escape_string=True):
def get_unoverflowable_paragraph(self, dirty_string, curr_style=None, do_escape_string=True, do_small=False):
'''
Create a paragraph that can fit on a cell displayed one page maximum.
This method can be improved (get the exact size of the current frame, and limit the paragraph to this size.)
@ -439,8 +480,12 @@ class Value_Formatter():
else:
sanitized_str = dirty_string
if curr_style is None:
curr_style = self.col2_style
if curr_style is None :
if do_small :
curr_style = self.col2_small_style
else :
curr_style = self.col2_style
# Get the space that the paragraph needs to be printed
w, h = Paragraph(sanitized_str, curr_style).wrap(FRAME_MAX_WIDTH, FRAME_MAX_HEIGHT)
@ -721,10 +766,10 @@ class Value_Formatter():
if is_safe_dict_attribute(misp_galaxy, item[1]):
return self.get_unoverflowable_paragraph(safe_string(misp_galaxy[item[1]])
+ " <i>from</i> " + safe_string(misp_galaxy[item[3]]) + ":"
+ safe_string(misp_galaxy[item[4]]), do_escape_string=False)
return self.get_unoverflowable_paragraph(item[2])
+ safe_string(misp_galaxy[item[4]]), do_escape_string=False, do_small=True)
return self.get_unoverflowable_paragraph(item[2], do_small=True)
def get_galaxy_cluster_name_value(self, misp_cluster):
def get_galaxy_cluster_name_value(self, misp_cluster, do_small=False):
item = ["Name", 'value', "None", "source", "meta", "synonyms"]
tmp_text = ""
@ -742,8 +787,8 @@ class Value_Formatter():
tmp_text += " / "
tmp_text += safe_string(synonyme)
return self.get_unoverflowable_paragraph(tmp_text, do_escape_string=False)
return self.get_unoverflowable_paragraph(item[2])
return self.get_unoverflowable_paragraph(tmp_text, do_escape_string=False, do_small=do_small)
return self.get_unoverflowable_paragraph(item[2], do_small=do_small)
class Event_Metadata():
@ -826,6 +871,8 @@ class Event_Metadata():
flowable_table.append(create_flowable_table_from_data(data))
flowable_table.append(PageBreak())
# Galaxies
item = ["Related Galaxies", 'Galaxy', "None"]
curr_Galaxy = Galaxy(self.config, self.value_formatter)
@ -962,7 +1009,7 @@ class Attributes():
# There is some attributes for this object
for item in getattr(misp_event, "Attribute"):
# you can use a spacer instead of title to separate paragraph: flowable_table.append(Spacer(1, 5 * mm))
flowable_table.append(Paragraph("Attribute #" + str(i), self.sample_style_sheet['Heading4']))
flowable_table.append(Paragraph("Attribute #" + str(i+OFFSET), self.sample_style_sheet['Heading4']))
flowable_table += self.create_flowable_table_from_one_attribute(item)
i += 1
else:
@ -1036,8 +1083,9 @@ class Attributes():
# Galaxies
item = ["Related Galaxies", 'Galaxy', "None"]
curr_Galaxy = Galaxy(self.config, self.value_formatter)
flowable_table += curr_Galaxy.get_galaxy_value(misp_attribute, item)
if is_safe_attribute_table(misp_attribute, item[1]) :
curr_Galaxy = Galaxy(self.config, self.value_formatter)
flowable_table += curr_Galaxy.get_galaxy_value(misp_attribute, item)
return flowable_table
@ -1121,11 +1169,7 @@ class Sightings():
:return: a table of flowable to add to the pdf
'''
col1_style, col2_style = get_table_styles()
i = 0
POSITIVE_SIGHT_COLOR = 'green'
NEGATIVE_SIGHT_COLOR = 'red'
MISC_SIGHT_COLOR = 'orange'
list_sighting = [0, 0, 0]
if is_safe_attribute_table(misp_attribute, item[1]):
@ -1151,6 +1195,7 @@ class Sightings():
return answer_sighting
class Object():
# ----------------------------------------------------------------------
@ -1161,6 +1206,7 @@ class Object():
# ----------------------------------------------------------------------
def create_flowable_table_from_objects(self, misp_event, config=None):
'''
Returns a list of flowables representing the list of objects of a misp event.
@ -1178,7 +1224,7 @@ class Object():
# There is a list of objects
for item in getattr(misp_event, "Object"):
# you can use a spacer instead of title to separate paragraph: flowable_table.append(Spacer(1, 5 * mm))
flowable_table.append(Paragraph("Object #" + str(i), self.sample_style_sheet['Heading3']))
flowable_table.append(Paragraph("Object #" + str(i+OFFSET), self.sample_style_sheet['Heading3']))
flowable_table += self.create_flowable_table_from_one_object(item, config)
i += 1
else:
@ -1187,6 +1233,7 @@ class Object():
return flowable_table
def create_flowable_table_from_one_object(self, misp_object, config=None):
'''
Returns a table (flowable) representing the object
@ -1194,7 +1241,6 @@ class Object():
:return: a table representing this misp's object's attributes, to add to the pdf as a flowable
'''
data = []
col1_style, col2_style = get_table_styles()
# To reduce code size, and automate it a bit, triplet (Displayed Name, object_attribute_name,
# to_display_if_not_present) are store in the following list
@ -1217,7 +1263,7 @@ class Object():
# Timestamp
item = ["Object date", 'timestamp', "None"]
data.append([Paragraph(item[0], col1_style), self.value_formatter.get_timestamp_value(misp_object, item)])
data.append([self.value_formatter.get_col1_paragraph(item[0]), self.value_formatter.get_timestamp_value(misp_object, item)])
# Transform list of value in a table
data = [create_flowable_table_from_data(data)]
@ -1275,19 +1321,20 @@ class Galaxy():
:param misp_event: A misp event
:return: a table of flowables to add to the pdf
'''
flowable_table = []
scheme_alternation = []
curr_color = 0
i = 0
if is_safe_attribute_table(misp_event, "Galaxy"):
# There is some galaxies for this object
for curr_galaxy in getattr(misp_event, "Galaxy"):
# For each galaxy of the misp object
galaxy_title = Paragraph("Galaxy # " + str(i), self.sample_style_sheet['Heading6'])
txt_title = "Galaxy #" + str(i+OFFSET) + " - " + safe_string(curr_galaxy["name"])
galaxy_title = Paragraph(txt_title, self.sample_style_sheet['Heading6'])
flowable_table.append(galaxy_title)
i += 1
@ -1298,21 +1345,12 @@ class Galaxy():
# Construct the line color scheme and line scheme
scheme_alternation += [curr_color] * nb_added_item
# Apply the scheme
# answer_tags = create_flowable_table_from_data(flowable_table)
# Add metadata about clusters
curr_cluster = Galaxy_cluster(self.config, self.value_formatter)
clusters_metadata = curr_cluster.create_flowable_table_from_galaxy_clusters(curr_galaxy)
flowable_table += clusters_metadata
'''
# Construct the line color scheme and line scheme
scheme_alternation += [curr_color] * nb_added_item
curr_color += 1 if curr_color == 0 else 0
'''
else:
# No galaxies for this object
answer_tags = [self.value_formatter.get_unoverflowable_paragraph("No galaxies")]
@ -1332,15 +1370,15 @@ class Galaxy():
# Name
item = ["Name", 'name', "None"]
if is_safe_dict_attribute(misp_galaxy, item[1]):
data.append([self.value_formatter.get_col1_paragraph(item[0]),
data.append([self.value_formatter.get_col1_paragraph(item[0], do_small=DO_SMALL_GALAXIES),
self.value_formatter.get_galaxy_name_value(misp_galaxy)])
nb_added_item += 1
# Description
item = ["Description", 'description', "None"]
if is_safe_dict_attribute(misp_galaxy, item[1]):
data.append([self.value_formatter.get_col1_paragraph(item[0]),
self.value_formatter.get_unoverflowable_paragraph(misp_galaxy[item[1]])])
data.append([self.value_formatter.get_col1_paragraph(item[0], do_small=DO_SMALL_GALAXIES),
self.value_formatter.get_unoverflowable_paragraph(misp_galaxy[item[1]], do_small=DO_SMALL_GALAXIES)])
nb_added_item += 1
flowable_table = []
@ -1349,6 +1387,7 @@ class Galaxy():
return flowable_table, nb_added_item
class Galaxy_cluster():
# ----------------------------------------------------------------------
@ -1366,37 +1405,31 @@ class Galaxy_cluster():
'''
data = []
i = 0
item = ["Cluster #", 'name', "None"]
if is_safe_dict_attribute(misp_galaxy, "GalaxyCluster"):
# There is some clusters for this object
for curr_cluster in misp_galaxy["GalaxyCluster"]:
for i, curr_cluster in enumerate(misp_galaxy["GalaxyCluster"]):
'''
galaxy_title = [Paragraph("Cluster #" + str(i), self.sample_style_sheet['Heading6'])]
data.append(galaxy_title)
i += 1
'''
# If title is needed :
# galaxy_title = [Paragraph("Cluster #" + str(i), self.sample_style_sheet['Heading6'])]
# data.append(galaxy_title)
item[0] = "Cluster #" + str(i + OFFSET)
# For each cluster
tmp_data = self.create_flowable_table_from_one_galaxy_cluster(curr_cluster)
tmp_flowable_table = []
tmp_flowable_table.append(create_flowable_table_from_data(tmp_data, color_alternation = [0], line_alternation=[0]))
data.append([self.value_formatter.get_col1_paragraph(item[0]), tmp_flowable_table])
# data += tmp_data
tmp_flowable_table.append(create_flowable_table_from_data(tmp_data, col_w=SECOND_LEVEL_GALAXY_WIDTHS, color_alternation = CLUSTER_COLORS, line_alternation=[]))
data.append([self.value_formatter.get_col1_paragraph(item[0], do_small=DO_SMALL_GALAXIES), tmp_flowable_table]) # Cluster #X - 3 lines
else:
# No galaxies for this object
data = [self.value_formatter.get_unoverflowable_paragraph("No galaxy cluster")]
data = [self.value_formatter.get_unoverflowable_paragraph("No galaxy cluster", do_small=DO_SMALL_GALAXIES)]
flowable_table = []
flowable_table.append(create_flowable_table_from_data(data))
flowable_table.append(create_flowable_table_from_data(data, col_w=FIRST_LEVEL_GALAXY_WIDTHS, color_alternation = CLUSTER_COLORS))
return flowable_table
@ -1410,15 +1443,19 @@ class Galaxy_cluster():
# Name
item = ["Name", 'name', "None"]
data.append([self.value_formatter.get_col1_paragraph(item[0]),
self.value_formatter.get_galaxy_cluster_name_value(misp_cluster)])
data.append([self.value_formatter.get_col1_paragraph(item[0], do_small=True),
self.value_formatter.get_galaxy_cluster_name_value(misp_cluster, do_small=True)])
# Description
item = ["Description", 'description', "None"]
data.append([self.value_formatter.get_col1_paragraph(item[0]),
self.value_formatter.get_unoverflowable_paragraph(misp_cluster[item[1]])])
if misp_cluster['value'] != misp_cluster['description'] : # Prevent name that are same as description
# Description
item = ["Description", 'description', "None"]
data.append([self.value_formatter.get_col1_paragraph(item[0], do_small=True),
self.value_formatter.get_unoverflowable_paragraph(misp_cluster[item[1]], do_small=True)])
# Refs ?
# item = ["Description", 'description', "None"]
# data.append([self.value_formatter.get_col1_paragraph(item[0]),
# self.value_formatter.get_unoverflowable_paragraph(misp_cluster[item[1]])])
return data
@ -1506,7 +1543,8 @@ def collect_parts(misp_event, config=None):
# Get the list of available styles
sample_style_sheet = getSampleStyleSheet()
col1_style, col2_style = get_table_styles()
curr_val_f = Value_Formatter(config, col1_style, col2_style)
col1_small_style, col2_small_style = get_clusters_table_styles()
curr_val_f = Value_Formatter(config, col1_style, col2_style, col1_small_style, col2_small_style)
# Create stuff
title_style = ParagraphStyle(name='Column_1', parent=sample_style_sheet['Heading1'], alignment=TA_CENTER)

View File

@ -41,12 +41,13 @@ setup(
],
install_requires=['six', 'requests', 'python-dateutil', 'jsonschema',
'python-dateutil', 'enum34;python_version<"3.4"',
'functools32;python_version<"3.0"', 'reportlab'],
'functools32;python_version<"3.0"'],
extras_require={'fileobjects': ['lief>=0.8', 'python-magic'],
'neo': ['py2neo'],
'openioc': ['beautifulsoup4'],
'virustotal': ['validators'],
'docs': ['sphinx-autodoc-typehints']},
'docs': ['sphinx-autodoc-typehints'],
'pdfexport': ['reportlab']},
tests_require=[
'jsonschema',
'python-magic',

View File

@ -31,7 +31,7 @@
"name": "file",
"sharing_group_id": "0",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15",
"template_version": "16",
"uuid": "a"
},
{

View File

@ -23,7 +23,7 @@
"name": "file",
"sharing_group_id": "0",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15",
"template_version": "16",
"uuid": "a"
},
{
@ -48,7 +48,7 @@
"name": "file",
"sharing_group_id": "0",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15",
"template_version": "16",
"uuid": "b"
}
]

View File

@ -715,7 +715,7 @@
"meta-category": "file",
"description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15",
"template_version": "16",
"event_id": "1203",
"uuid": "1db36cab-7b13-4758-b16a-9e9862d0973e",
"timestamp": "1550871228",
@ -887,7 +887,7 @@
"meta-category": "file",
"description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15",
"template_version": "16",
"event_id": "1203",
"uuid": "3b8f6a45-0b7f-4bea-ad61-0369f01cc306",
"timestamp": "1550871228",
@ -1059,7 +1059,7 @@
"meta-category": "file",
"description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15",
"template_version": "16",
"event_id": "1203",
"uuid": "8cc1ffb8-e4b2-4641-a536-ea843ff9bc7a",
"timestamp": "1550871228",
@ -1231,7 +1231,7 @@
"meta-category": "file",
"description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15",
"template_version": "16",
"event_id": "1203",
"uuid": "89e0ad73-a186-4959-b978-2311ee49e4af",
"timestamp": "1550871229",
@ -1403,7 +1403,7 @@
"meta-category": "file",
"description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15",
"template_version": "16",
"event_id": "1203",
"uuid": "4dbf697b-11ce-447f-85c6-cd02a2365a7f",
"timestamp": "1550871229",
@ -1575,7 +1575,7 @@
"meta-category": "file",
"description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15",
"template_version": "16",
"event_id": "1203",
"uuid": "6860e975-938c-413d-b144-74cde72c25dc",
"timestamp": "1550871229",
@ -1747,7 +1747,7 @@
"meta-category": "file",
"description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15",
"template_version": "16",
"event_id": "1203",
"uuid": "df5dd372-ecd6-4595-ab34-45bff1decb63",
"timestamp": "1550871229",
@ -1919,7 +1919,7 @@
"meta-category": "file",
"description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15",
"template_version": "16",
"event_id": "1203",
"uuid": "3061d73f-2f4f-4c6e-8478-3d5d1e74c1bc",
"timestamp": "1550871229",
@ -2091,7 +2091,7 @@
"meta-category": "file",
"description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15",
"template_version": "16",
"event_id": "1203",
"uuid": "fd57be37-61cc-4452-85b5-518d55586335",
"timestamp": "1550871230",
@ -2263,7 +2263,7 @@
"meta-category": "file",
"description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15",
"template_version": "16",
"event_id": "1203",
"uuid": "56b391e4-f005-4caa-ae12-a90db6664ebd",
"timestamp": "1550871270",
@ -2487,4 +2487,4 @@
}
]
}
}
}

View File

@ -70,7 +70,7 @@
"timestamp": "1543921748",
"description": "File object describing a file with meta-information",
"distribution": "3",
"template_version": "15",
"template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "",
"name": "file",
@ -114,7 +114,7 @@
"timestamp": "1543921750",
"description": "File object describing a file with meta-information",
"distribution": "3",
"template_version": "15",
"template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "",
"name": "file",
@ -158,7 +158,7 @@
"timestamp": "1543921751",
"description": "File object describing a file with meta-information",
"distribution": "3",
"template_version": "15",
"template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "",
"name": "file",
@ -482,7 +482,7 @@
"timestamp": "1543921755",
"description": "File object describing a file with meta-information",
"distribution": "3",
"template_version": "15",
"template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "",
"name": "file",
@ -875,7 +875,7 @@
"timestamp": "1543921759",
"description": "File object describing a file with meta-information",
"distribution": "3",
"template_version": "15",
"template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "",
"name": "file",
@ -988,7 +988,7 @@
"timestamp": "1543921762",
"description": "File object describing a file with meta-information",
"distribution": "3",
"template_version": "15",
"template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "",
"name": "file",
@ -1089,4 +1089,4 @@
}
]
}
}
}

View File

@ -82,7 +82,7 @@
"timestamp": "1543922168",
"description": "File object describing a file with meta-information",
"distribution": "3",
"template_version": "15",
"template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "",
"name": "file",
@ -126,7 +126,7 @@
"timestamp": "1543922169",
"description": "File object describing a file with meta-information",
"distribution": "3",
"template_version": "15",
"template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "",
"name": "file",
@ -450,7 +450,7 @@
"timestamp": "1543922173",
"description": "File object describing a file with meta-information",
"distribution": "3",
"template_version": "15",
"template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "",
"name": "file",
@ -857,7 +857,7 @@
"timestamp": "1543922178",
"description": "File object describing a file with meta-information",
"distribution": "3",
"template_version": "15",
"template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "",
"name": "file",
@ -974,4 +974,4 @@
}
]
}
}
}

View File

@ -9,8 +9,13 @@ import unittest
from pymisp import MISPEvent
from pymisp.tools import reportlab_generator
manual_testing = True
manual_testing = False
if sys.version_info < (3, 6):
print('This test suite requires Python 3.6+, breaking.')
sys.exit(0)
else:
from pymisp import reportlab_generator
class TestMISPEvent(unittest.TestCase):
@ -226,7 +231,6 @@ class TestMISPEvent(unittest.TestCase):
if self.check_python_2():
self.assertTrue(True)
else:
config = {}
config[self.moduleconfig[0]] = "http://localhost:8080"
config[self.moduleconfig[1]] = "My Wonderful CERT"
@ -309,6 +313,8 @@ class TestMISPEvent(unittest.TestCase):
config[self.moduleconfig[0]] = "http://localhost:8080"
config[self.moduleconfig[1]] = "My Wonderful CERT"
config[self.moduleconfig[2]] = True
config[self.moduleconfig[3]] = True
file_nb = str(len(os.listdir(self.test_batch_folder)))
i = 0

View File

@ -496,7 +496,7 @@ class TestComprehensive(unittest.TestCase):
self.assertEqual(new_obj['Object']['distribution'], str(Distribution.inherit.value))
self.assertEqual(new_obj['Object']['Attribute'][0]['distribution'], str(Distribution.inherit.value))
# Object - edit
clean_obj = MISPObject(**new_obj['Object'])
clean_obj = MISPObject(strict=True, **new_obj['Object'])
clean_obj.from_dict(**new_obj['Object'])
clean_obj.add_attribute('filename', value='blah.exe')
new_obj = self.user_misp_connector.edit_object(clean_obj)