diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/conftest.py | 1 | ||||
| -rw-r--r-- | tests/data/nmaprun1.xml | 68 | ||||
| -rw-r--r-- | tests/data/nmaprun2.xml | 118 | ||||
| -rw-r--r-- | tests/managers/network/__init__.py | 0 | ||||
| -rw-r--r-- | tests/managers/network/label.py | 202 | ||||
| -rw-r--r-- | tests/managers/network/tool_run.py | 48 | ||||
| -rw-r--r-- | tests/models/network/__init__.py | 0 | ||||
| -rw-r--r-- | tests/models/network/nmap.py | 32 | ||||
| -rw-r--r-- | tests/models/network/rdns.py | 23 | ||||
| -rw-r--r-- | tests/models/network/tool_run.py | 8 |
10 files changed, 500 insertions, 0 deletions
diff --git a/tests/conftest.py b/tests/conftest.py index 30ed1c7..2482269 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -13,6 +13,7 @@ pytest_plugins = [ "test_utils.managers.conftest", "test_utils.managers.contest.conftest", "test_utils.managers.ledger.conftest", + "test_utils.managers.network.conftest", "test_utils.managers.upk.conftest", # -- Models "test_utils.models.conftest", diff --git a/tests/data/nmaprun1.xml b/tests/data/nmaprun1.xml new file mode 100644 index 0000000..c5fed6c --- /dev/null +++ b/tests/data/nmaprun1.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE nmaprun> +<?xml-stylesheet href="file:///usr/bin/../share/nmap/nmap.xsl" type="text/xsl"?> +<!-- Nmap 7.80 scan initiated Wed Mar 4 12:59:08 2026 as: nmap -O -A -Pn -sV -p 22-1000,11000,1100,3389,61232 -oX - 108.171.53.1 --> +<nmaprun scanner="nmap" args="nmap -O -A -Pn -sV -p 22-1000,11000,1100,3389,61232 -oX - 108.171.53.1" start="1772650748" + startstr="Wed Mar 4 12:59:08 2026" version="7.80" xmloutputversion="1.04"> + <scaninfo type="syn" protocol="tcp" numservices="983" services="22-1000,1100,3389,11000,61232"/> + <scaninfo type="syn" protocol="udp" numservices="983" services="69,420"/> + <verbose level="0"/> + <debugging level="0"/> + <host starttime="1772650748" endtime="1772650901"> + <status state="up" reason="user-set" reason_ttl="0"/> + <address addr="108.171.53.1" addrtype="ipv4"/> + <hostnames> + <hostname name="108-171-53-1.aceips.com" type="PTR"/> + </hostnames> + <ports> + <extraports state="filtered" count="982"> + <extrareasons reason="no-responses" count="982"/> + </extraports> + <port protocol="tcp" portid="61232"> + <state state="open" reason="syn-ack" reason_ttl="47"/> + <service name="socks5" extrainfo="Username/password authentication required" method="probed" conf="10"/> + <script id="socks-auth-info" output="
 Username and password"> + <table> + <elem key="name">Username and password</elem> + <elem key="method">2</elem> + </table> + </script> + </port> + </ports> + <os> + <portused state="open" proto="tcp" portid="61232"/> + </os> + <uptime seconds="4063775" lastboot="Fri Jan 16 12:12:06 2026"/> + <distance value="21"/> + <tcpsequence index="263" difficulty="Good luck!" values="B67613E,2F0160C6,27FA849E,3B16FC3A,916ADEAF,18293FD7"/> + <ipidsequence class="All zeros" values="0,0,0,0,0,0"/> + <tcptssequence class="1000HZ" values="F2383963,F23839C0,F2383A24,F2383A8C,F2383AED,F2383B54"/> + <trace port="61232" proto="tcp"> + <hop ttl="1" ipaddr="192.168.86.1" rtt="3.83" host="_gateway"/> + <hop ttl="2" ipaddr="192.168.100.1" rtt="4.90"/> + <hop ttl="3" ipaddr="10.125.64.1" rtt="6.01"/> + <hop ttl="4" ipaddr="10.180.25.105" rtt="14.52"/> + <hop ttl="5" ipaddr="10.180.25.106" rtt="16.47"/> + <hop ttl="6" ipaddr="10.180.25.81" rtt="28.56"/> + <hop ttl="7" ipaddr="62.115.192.20" rtt="17.17" host="gdl-b2-link.ip.twelve99.net"/> + <hop ttl="8" ipaddr="62.115.140.131" rtt="29.56" host="mny-b4-link.ip.twelve99.net"/> + <hop ttl="9" ipaddr="62.115.124.12" rtt="27.68" host="mdc-b2-link.ip.twelve99.net"/> + <hop ttl="10" ipaddr="62.115.126.144" rtt="34.92" host="hou-b3-link.ip.twelve99.net"/> + <hop ttl="11" ipaddr="62.115.116.47" rtt="48.42" host="atl-b24-link.ip.twelve99.net"/> + <hop ttl="13" ipaddr="62.115.137.132" rtt="62.35" host="ash-bb2-link.ip.twelve99.net"/> + <hop ttl="14" ipaddr="62.115.139.34" rtt="67.51" host="nyk-bb5-link.ip.twelve99.net"/> + <hop ttl="16" ipaddr="62.115.136.13" rtt="64.75" host="ewr-b15-link.ip.twelve99.net"/> + <hop ttl="17" ipaddr="62.115.136.13" rtt="67.87" host="ewr-b15-link.ip.twelve99.net"/> + <hop ttl="19" ipaddr="75.76.132.68" rtt="72.32" host="hge0-1-0-6.aggr1.jfk.ny.rcn.net"/> + <hop ttl="20" ipaddr="207.237.73.98" rtt="68.13"/> + <hop ttl="21" ipaddr="108.171.53.1" rtt="64.76" host="108-171-53-1.aceips.com"/> + </trace> + <times srtt="54719" rttvar="23423" to="148411"/> + </host> + <runstats> + <finished time="1772650901" timestr="Wed Mar 4 13:01:41 2026" elapsed="153.06" + summary="Nmap done at Wed Mar 4 13:01:41 2026; 1 IP address (1 host up) scanned in 153.06 seconds" + exit="success"/> + <hosts up="1" down="0" total="1"/> + </runstats> +</nmaprun> diff --git a/tests/data/nmaprun2.xml b/tests/data/nmaprun2.xml new file mode 100644 index 0000000..932896c --- /dev/null +++ b/tests/data/nmaprun2.xml @@ -0,0 +1,118 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE nmaprun> +<?xml-stylesheet href="file:///usr/bin/../share/nmap/nmap.xsl" type="text/xsl"?> +<!-- Nmap 7.80 scan initiated Tue Mar 3 17:50:03 2026 as: nmap -T4 -A -oX - scanme.nmap.org --> +<nmaprun scanner="nmap" args="nmap -T4 -A -oX - scanme.nmap.org" start="1772581803" startstr="Tue Mar 3 17:50:03 2026" + version="7.80" xmloutputversion="1.04"> + <scaninfo type="connect" protocol="tcp" numservices="1000" + services="1,3-4,6-7,9,13,17,19-26,30,32-33,37,42-43,49,53,70,79-85,88-90,99-100,106,109-111,113,119,125,135,139,143-144,146,161,163,179,199,211-212,222,254-256,259,264,280,301,306,311,340,366,389,406-407,416-417,425,427,443-445,458,464-465,481,497,500,512-515,524,541,543-545,548,554-555,563,587,593,616-617,625,631,636,646,648,666-668,683,687,691,700,705,711,714,720,722,726,749,765,777,783,787,800-801,808,843,873,880,888,898,900-903,911-912,981,987,990,992-993,995,999-1002,1007,1009-1011,1021-1100,1102,1104-1108,1110-1114,1117,1119,1121-1124,1126,1130-1132,1137-1138,1141,1145,1147-1149,1151-1152,1154,1163-1166,1169,1174-1175,1183,1185-1187,1192,1198-1199,1201,1213,1216-1218,1233-1234,1236,1244,1247-1248,1259,1271-1272,1277,1287,1296,1300-1301,1309-1311,1322,1328,1334,1352,1417,1433-1434,1443,1455,1461,1494,1500-1501,1503,1521,1524,1533,1556,1580,1583,1594,1600,1641,1658,1666,1687-1688,1700,1717-1721,1723,1755,1761,1782-1783,1801,1805,1812,1839-1840,1862-1864,1875,1900,1914,1935,1947,1971-1972,1974,1984,1998-2010,2013,2020-2022,2030,2033-2035,2038,2040-2043,2045-2049,2065,2068,2099-2100,2103,2105-2107,2111,2119,2121,2126,2135,2144,2160-2161,2170,2179,2190-2191,2196,2200,2222,2251,2260,2288,2301,2323,2366,2381-2383,2393-2394,2399,2401,2492,2500,2522,2525,2557,2601-2602,2604-2605,2607-2608,2638,2701-2702,2710,2717-2718,2725,2800,2809,2811,2869,2875,2909-2910,2920,2967-2968,2998,3000-3001,3003,3005-3007,3011,3013,3017,3030-3031,3052,3071,3077,3128,3168,3211,3221,3260-3261,3268-3269,3283,3300-3301,3306,3322-3325,3333,3351,3367,3369-3372,3389-3390,3404,3476,3493,3517,3527,3546,3551,3580,3659,3689-3690,3703,3737,3766,3784,3800-3801,3809,3814,3826-3828,3851,3869,3871,3878,3880,3889,3905,3914,3918,3920,3945,3971,3986,3995,3998,4000-4006,4045,4111,4125-4126,4129,4224,4242,4279,4321,4343,4443-4446,4449,4550,4567,4662,4848,4899-4900,4998,5000-5004,5009,5030,5033,5050-5051,5054,5060-5061,5080,5087,5100-5102,5120,5190,5200,5214,5221-5222,5225-5226,5269,5280,5298,5357,5405,5414,5431-5432,5440,5500,5510,5544,5550,5555,5560,5566,5631,5633,5666,5678-5679,5718,5730,5800-5802,5810-5811,5815,5822,5825,5850,5859,5862,5877,5900-5904,5906-5907,5910-5911,5915,5922,5925,5950,5952,5959-5963,5987-5989,5998-6007,6009,6025,6059,6100-6101,6106,6112,6123,6129,6156,6346,6389,6502,6510,6543,6547,6565-6567,6580,6646,6666-6669,6689,6692,6699,6779,6788-6789,6792,6839,6881,6901,6969,7000-7002,7004,7007,7019,7025,7070,7100,7103,7106,7200-7201,7402,7435,7443,7496,7512,7625,7627,7676,7741,7777-7778,7800,7911,7920-7921,7937-7938,7999-8002,8007-8011,8021-8022,8031,8042,8045,8080-8090,8093,8099-8100,8180-8181,8192-8194,8200,8222,8254,8290-8292,8300,8333,8383,8400,8402,8443,8500,8600,8649,8651-8652,8654,8701,8800,8873,8888,8899,8994,9000-9003,9009-9011,9040,9050,9071,9080-9081,9090-9091,9099-9103,9110-9111,9200,9207,9220,9290,9415,9418,9485,9500,9502-9503,9535,9575,9593-9595,9618,9666,9876-9878,9898,9900,9917,9929,9943-9944,9968,9998-10004,10009-10010,10012,10024-10025,10082,10180,10215,10243,10566,10616-10617,10621,10626,10628-10629,10778,11110-11111,11967,12000,12174,12265,12345,13456,13722,13782-13783,14000,14238,14441-14442,15000,15002-15004,15660,15742,16000-16001,16012,16016,16018,16080,16113,16992-16993,17877,17988,18040,18101,18988,19101,19283,19315,19350,19780,19801,19842,20000,20005,20031,20221-20222,20828,21571,22939,23502,24444,24800,25734-25735,26214,27000,27352-27353,27355-27356,27715,28201,30000,30718,30951,31038,31337,32768-32785,33354,33899,34571-34573,35500,38292,40193,40911,41511,42510,44176,44442-44443,44501,45100,48080,49152-49161,49163,49165,49167,49175-49176,49400,49999-50003,50006,50300,50389,50500,50636,50800,51103,51493,52673,52822,52848,52869,54045,54328,55055-55056,55555,55600,56737-56738,57294,57797,58080,60020,60443,61532,61900,62078,63331,64623,64680,65000,65129,65389"/> + <verbose level="0"/> + <debugging level="0"/> + <host starttime="1772581804" endtime="1772581818"> + <status state="up" reason="syn-ack" reason_ttl="0"/> + <address addr="45.33.32.156" addrtype="ipv4"/> + <hostnames> + <hostname name="scanme.nmap.org" type="user"/> + <hostname name="scanme.nmap.org" type="PTR"/> + </hostnames> + <ports> + <extraports state="closed" count="995"> + <extrareasons reason="conn-refused" count="995"/> + </extraports> + <port protocol="tcp" portid="22"> + <state state="open" reason="syn-ack" reason_ttl="0"/> + <service name="ssh" product="OpenSSH" version="6.6.1p1 Ubuntu 2ubuntu2.13" + extrainfo="Ubuntu Linux; protocol 2.0" ostype="Linux" method="probed" conf="10"> + <cpe>cpe:/a:openbsd:openssh:6.6.1p1</cpe> + <cpe>cpe:/o:linux:linux_kernel</cpe> + </service> + <script id="ssh-hostkey" + output="
 1024 ac:00:a0:1a:82:ff:cc:55:99:dc:67:2b:34:97:6b:75 (DSA)
 2048 20:3d:2d:44:62:2a:b0:5a:9d:b5:b3:05:14:c2:a6:b2 (RSA)
 256 96:02:bb:5e:57:54:1c:4e:45:2f:56:4c:4a:24:b2:57 (ECDSA)
 256 33:fa:91:0f:e0:e1:7b:1f:6d:05:a2:b0:f1:54:41:56 (ED25519)"> + <table> + <elem key="bits">1024</elem> + <elem key="type">ssh-dss</elem> + <elem key="key"> + AAAAB3NzaC1kc3MAAACBAOe8o59vFWZGaBmGPVeJBObEfi1AR8yEUYC/Ufkku3sKhGF7wM2m2ujIeZDK5vqeC0S5EN2xYo6FshCP4FQRYeTxD17nNO4PhwW65qAjDRRU0uHFfSAh5wk+vt4yQztOE++sTd1G9OBLzA8HO99qDmCAxb3zw+GQDEgPjzgyzGZ3AAAAFQCBmE1vROP8IaPkUmhM5xLFta/xHwAAAIEA3EwRfaeOPLL7TKDgGX67Lbkf9UtdlpCdC4doMjGgsznYMwWH6a7Lj3vi4/KmeZZdix6FMdFqq+2vrfT1DRqx0RS0XYdGxnkgS+2g333WYCrUkDCn6RPUWR/1TgGMPHCj7LWCa1ZwJwLWS2KX288Pa2gLOWuhZm2VYKSQx6NEDOIAAACBANxIfprSdBdbo4Ezrh6/X6HSvrhjtZ7MouStWaE714ByO5bS2coM9CyaCwYyrE5qzYiyIfb+1BG3O5nVdDuN95sQ/0bAdBKlkqLFvFqFjVbETF0ri3v97w6MpUawfF75ouDrQ4xdaUOLLEWTso6VFJcM6Jg9bDl0FA0uLZUSDEHL + </elem> + <elem key="fingerprint">ac00a01a82ffcc5599dc672b34976b75</elem> + </table> + <table> + <elem key="bits">2048</elem> + <elem key="type">ssh-rsa</elem> + <elem key="key"> + AAAAB3NzaC1yc2EAAAADAQABAAABAQC6afooTZ9mVUGFNEhkMoRR1Btzu64XXwElhCsHw/zVlIx/HXylNbb9+11dm2VgJQ21pxkWDs+L6+EbYyDnvRURTrMTgHL0xseB0EkNqexs9hYZSiqtMx4jtGNtHvsMxZnbxvVUk2dasWvtBkn8J5JagSbzWTQo4hjKMOI1SUlXtiKxAs2F8wiq2EdSuKw/KNk8GfIp1TA+8ccGeAtnsVptTJ4D/8MhAWsROkQzOowQvnBBz2/8ecEvoMScaf+kDfNQowK3gENtSSOqYw9JLOza6YJBPL/aYuQQ0nJ74Rr5vL44aNIlrGI9jJc2x0bV7BeNA5kVuXsmhyfWbbkB8yGd + </elem> + <elem key="fingerprint">203d2d44622ab05a9db5b30514c2a6b2</elem> + </table> + <table> + <elem key="bits">256</elem> + <elem key="type">ecdsa-sha2-nistp256</elem> + <elem key="key"> + AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMD46g67x6yWNjjQJnXhiz/TskHrqQ0uPcOspFrIYW382uOGzmWDZCFV8FbFwQyH90u+j0Qr1SGNAxBZMhOQ8pc= + </elem> + <elem key="fingerprint">9602bb5e57541c4e452f564c4a24b257</elem> + </table> + <table> + <elem key="bits">256</elem> + <elem key="type">ssh-ed25519</elem> + <elem key="key">AAAAC3NzaC1lZDI1NTE5AAAAILzVjfIyIHfXyRd8jVBaVT8Yvk/UvHh5Afvho8sGciG7</elem> + <elem key="fingerprint">33fa910fe0e17b1f6d05a2b0f1544156</elem> + </table> + </script> + </port> + <port protocol="tcp" portid="25"> + <state state="filtered" reason="no-response" reason_ttl="0"/> + <service name="smtp" method="table" conf="3"/> + </port> + <port protocol="tcp" portid="80"> + <state state="open" reason="syn-ack" reason_ttl="0"/> + <service name="http" product="Apache httpd" version="2.4.7" extrainfo="(Ubuntu)" method="probed" + conf="10"> + <cpe>cpe:/a:apache:http_server:2.4.7</cpe> + </service> + <script id="http-server-header" output="Apache/2.4.7 (Ubuntu)"> + <elem>Apache/2.4.7 (Ubuntu)</elem> + </script> + <script id="http-title" output="Go ahead and ScanMe!"> + <elem key="title">Go ahead and ScanMe!</elem> + </script> + </port> + <port protocol="tcp" portid="9929"> + <state state="open" reason="syn-ack" reason_ttl="0"/> + <service name="nping-echo" product="Nping echo" method="probed" conf="10"/> + </port> + <port protocol="tcp" portid="31337"> + <state state="open" reason="syn-ack" reason_ttl="0"/> + <service name="tcpwrapped" method="probed" conf="8"/> + </port> + </ports> + <os> + <portused state="open" proto="tcp" portid="22"/> + <portused state="closed" proto="tcp" portid="1"/> + <portused state="closed" proto="udp" portid="31994"/> + <osmatch name="Linux 2.6.38 - 3.0" accuracy="100" line="43893"> + <osclass type="general purpose" vendor="Linux" osfamily="Linux" osgen="2.6.X" accuracy="100"> + <cpe>cpe:/o:linux:linux_kernel:2.6</cpe> + </osclass> + <osclass type="general purpose" vendor="Linux" osfamily="Linux" osgen="3.X" accuracy="100"> + <cpe>cpe:/o:linux:linux_kernel:3</cpe> + </osclass> + </osmatch> + <osfingerprint + fingerprint=" SEQ(SP=C5%GCD=1%ISR=C7%TI=Z%II=I%TS=8) ECN(R=Y%DF=Y%T=40%W=16D0%O=M5B4NNSNW2%CC=N%Q=) T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=) T2(R=N) T3(R=Y%DF=Y%T=40%W=16A0%S=O%A=S+%F=AS%O=M5B4ST11NW2%RD=0%Q=) T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=) T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=) U1(R=Y%DF=N%T=40%TOS=C0%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUL=G%RUD=G) IE(R=Y%DFI=N%T=40%TOSI=S%CD=S%SI=S%DLI=S) "/> + </os> + <hostscript> + <script id="sql-injection" output="Possible SQL injection vulnerability detected: + URI: /index.php?id=1' + Payload: id=1' OR '1'='1 + Output: SQL error detected"/> + </hostscript> + <times srtt="90053" rttvar="8723" to="124945"/> + </host> + <runstats> + <finished time="1772581818" timestr="Tue Mar 3 17:50:18 2026" elapsed="14.44" + summary="Nmap done at Tue Mar 3 17:50:18 2026; 1 IP address (1 host up) scanned in 14.44 seconds" + exit="success"/> + <hosts up="1" down="0" total="1"/> + </runstats> +</nmaprun> diff --git a/tests/managers/network/__init__.py b/tests/managers/network/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/managers/network/__init__.py diff --git a/tests/managers/network/label.py b/tests/managers/network/label.py new file mode 100644 index 0000000..5b9a790 --- /dev/null +++ b/tests/managers/network/label.py @@ -0,0 +1,202 @@ +import ipaddress + +import faker +import pytest +from psycopg.errors import UniqueViolation +from pydantic import ValidationError + +from generalresearch.managers.network.label import IPLabelManager +from generalresearch.models.network.label import ( + IPLabel, + IPLabelKind, + IPLabelSource, + IPLabelMetadata, +) +from generalresearch.models.thl.ipinfo import normalize_ip + +fake = faker.Faker() + + +@pytest.fixture +def ip_label(utc_now) -> IPLabel: + ip = ipaddress.IPv6Network((fake.ipv6(), 64), strict=False) + return IPLabel( + label_kind=IPLabelKind.VPN, + labeled_at=utc_now, + source=IPLabelSource.INTERNAL_USE, + provider="GeoNodE", + created_at=utc_now, + ip=ip, + metadata=IPLabelMetadata(services=["RDP"]) + ) + + +def test_model(utc_now): + ip = fake.ipv4_public() + lbl = IPLabel( + label_kind=IPLabelKind.VPN, + labeled_at=utc_now, + source=IPLabelSource.INTERNAL_USE, + provider="GeoNodE", + created_at=utc_now, + ip=ip, + ) + assert lbl.ip.prefixlen == 32 + print(f"{lbl.ip=}") + + ip = ipaddress.IPv4Network((ip, 24), strict=False) + lbl = IPLabel( + label_kind=IPLabelKind.VPN, + labeled_at=utc_now, + source=IPLabelSource.INTERNAL_USE, + provider="GeoNodE", + created_at=utc_now, + ip=ip, + ) + print(f"{lbl.ip=}") + + with pytest.raises(ValidationError, match="IPv6 network must be /64 or larger"): + IPLabel( + label_kind=IPLabelKind.VPN, + labeled_at=utc_now, + source=IPLabelSource.INTERNAL_USE, + provider="GeoNodE", + created_at=utc_now, + ip=fake.ipv6(), + ) + + ip = ipaddress.IPv6Network((fake.ipv6(), 64), strict=False) + lbl = IPLabel( + label_kind=IPLabelKind.VPN, + labeled_at=utc_now, + source=IPLabelSource.INTERNAL_USE, + provider="GeoNodE", + created_at=utc_now, + ip=ip, + ) + print(f"{lbl.ip=}") + + ip = ipaddress.IPv6Network((ip.network_address, 48), strict=False) + lbl = IPLabel( + label_kind=IPLabelKind.VPN, + labeled_at=utc_now, + source=IPLabelSource.INTERNAL_USE, + provider="GeoNodE", + created_at=utc_now, + ip=ip, + ) + print(f"{lbl.ip=}") + + +def test_create(iplabel_manager: IPLabelManager, ip_label: IPLabel): + iplabel_manager.create(ip_label) + + with pytest.raises( + UniqueViolation, match="duplicate key value violates unique constraint" + ): + iplabel_manager.create(ip_label) + + +def test_filter(iplabel_manager: IPLabelManager, ip_label: IPLabel, utc_hour_ago): + res = iplabel_manager.filter(ips=[ip_label.ip]) + assert len(res) == 0 + + iplabel_manager.create(ip_label) + res = iplabel_manager.filter(ips=[ip_label.ip]) + assert len(res) == 1 + + out = res[0] + assert out == ip_label + + res = iplabel_manager.filter(ips=[ip_label.ip], labeled_after=utc_hour_ago) + assert len(res) == 1 + + ip_label2 = ip_label.model_copy() + ip_label2.ip = fake.ipv4_public() + iplabel_manager.create(ip_label2) + res = iplabel_manager.filter(ips=[ip_label.ip, ip_label2.ip]) + assert len(res) == 2 + + +def test_filter_network( + iplabel_manager: IPLabelManager, ip_label: IPLabel, utc_hour_ago +): + print(ip_label) + ip_label = ip_label.model_copy() + ip_label.ip = ipaddress.IPv6Network((fake.ipv6(), 64), strict=False) + + iplabel_manager.create(ip_label) + res = iplabel_manager.filter(ips=[ip_label.ip]) + assert len(res) == 1 + + out = res[0] + assert out == ip_label + + res = iplabel_manager.filter(ips=[ip_label.ip], labeled_after=utc_hour_ago) + assert len(res) == 1 + + ip_label2 = ip_label.model_copy() + ip_label2.ip = fake.ipv4_public() + iplabel_manager.create(ip_label2) + res = iplabel_manager.filter(ips=[ip_label.ip, ip_label2.ip]) + assert len(res) == 2 + + +def test_network(iplabel_manager: IPLabelManager, utc_now): + # This is a fully-specific /128 ipv6 address. + # e.g. '51b7:b38d:8717:6c5b:cd3e:f5c3:3aba:17d' + ip = fake.ipv6() + # Generally, we'd want to annotate the /64 network + # e.g. '51b7:b38d:8717:6c5b::/64' + ip_64 = ipaddress.IPv6Network((ip, 64), strict=False) + + label = IPLabel( + label_kind=IPLabelKind.VPN, + labeled_at=utc_now, + source=IPLabelSource.INTERNAL_USE, + provider="GeoNodE", + created_at=utc_now, + ip=ip_64, + ) + iplabel_manager.create(label) + + # If I query for the /128 directly, I won't find it + res = iplabel_manager.filter(ips=[ip]) + assert len(res) == 0 + + # If I query for the /64 network I will + res = iplabel_manager.filter(ips=[ip_64]) + assert len(res) == 1 + + # Or, I can query for the /128 ip IN a network + res = iplabel_manager.filter(ip_in_network=ip) + assert len(res) == 1 + + +def test_label_cidr_and_ipinfo( + iplabel_manager: IPLabelManager, ip_information_factory, ip_geoname, utc_now +): + # We have network_iplabel.ip as a cidr col and + # thl_ipinformation.ip as a inet col. Make sure we can join appropriately + ip = fake.ipv6() + ip_information_factory(ip=ip, geoname=ip_geoname) + # We normalize for storage into ipinfo table + ip_norm, prefix = normalize_ip(ip) + + # Test with a larger network + ip_48 = ipaddress.IPv6Network((ip, 48), strict=False) + print(f"{ip=}") + print(f"{ip_norm=}") + print(f"{ip_48=}") + label = IPLabel( + label_kind=IPLabelKind.VPN, + labeled_at=utc_now, + source=IPLabelSource.INTERNAL_USE, + provider="GeoNodE", + created_at=utc_now, + ip=ip_48, + ) + iplabel_manager.create(label) + + res = iplabel_manager.test_join(ip_norm) + print(res) diff --git a/tests/managers/network/tool_run.py b/tests/managers/network/tool_run.py new file mode 100644 index 0000000..a598a71 --- /dev/null +++ b/tests/managers/network/tool_run.py @@ -0,0 +1,48 @@ +from uuid import uuid4 + +import faker + +from generalresearch.models.network.tool_run import ( + new_tool_run_from_nmap, + run_dig, +) +fake = faker.Faker() + + +def test_create_tool_run_from_nmap(nmap_run, toolrun_manager): + scan_group_id = uuid4().hex + run = new_tool_run_from_nmap(nmap_run, scan_group_id=scan_group_id) + + toolrun_manager.create_portscan_run(run) + + run_out = toolrun_manager.get_portscan_run(run.id) + + assert run == run_out + + +def test_create_tool_run_from_dig_fixture(reverse_dns_run, toolrun_manager): + + toolrun_manager.create_rdns_run(reverse_dns_run) + + run_out = toolrun_manager.get_rdns_run(reverse_dns_run.id) + + assert reverse_dns_run == run_out + + +def test_run_dig(toolrun_manager): + reverse_dns_run = run_dig(ip="65.19.129.53") + + toolrun_manager.create_rdns_run(reverse_dns_run) + + run_out = toolrun_manager.get_rdns_run(reverse_dns_run.id) + + assert reverse_dns_run == run_out + +def test_run_dig_empty(toolrun_manager): + reverse_dns_run = run_dig(ip=fake.ipv6()) + + toolrun_manager.create_rdns_run(reverse_dns_run) + + run_out = toolrun_manager.get_rdns_run(reverse_dns_run.id) + + assert reverse_dns_run == run_out
\ No newline at end of file diff --git a/tests/models/network/__init__.py b/tests/models/network/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/models/network/__init__.py diff --git a/tests/models/network/nmap.py b/tests/models/network/nmap.py new file mode 100644 index 0000000..4fc7014 --- /dev/null +++ b/tests/models/network/nmap.py @@ -0,0 +1,32 @@ +import os + +import pytest + +from generalresearch.models.network.xml_parser import NmapXmlParser + + +@pytest.fixture +def nmap_xml_str(request) -> str: + fp = os.path.join(request.config.rootpath, "data/nmaprun1.xml") + with open(fp, "r") as f: + data = f.read() + return data + + +@pytest.fixture +def nmap_xml_str2(request) -> str: + fp = os.path.join(request.config.rootpath, "data/nmaprun2.xml") + with open(fp, "r") as f: + data = f.read() + return data + + +def test_nmap_xml_parser(nmap_xml_str, nmap_xml_str2): + p = NmapXmlParser() + n = p.parse_xml(nmap_xml_str) + assert n.tcp_open_ports == [61232] + assert len(n.trace.hops) == 18 + + n = p.parse_xml(nmap_xml_str2) + assert n.tcp_open_ports == [22, 80, 9929, 31337] + assert n.trace is None diff --git a/tests/models/network/rdns.py b/tests/models/network/rdns.py new file mode 100644 index 0000000..9167749 --- /dev/null +++ b/tests/models/network/rdns.py @@ -0,0 +1,23 @@ +from generalresearch.models.network.rdns import dig_rdns +import faker + +fake = faker.Faker() + + +def test_dig_rdns(): + # Actually runs dig -x. Idk how stable this is + ip = "45.33.32.156" + rdns_result = dig_rdns(ip) + assert rdns_result.primary_hostname == "scanme.nmap.org" + assert rdns_result.primary_org == "nmap" + + ip = "65.19.129.53" + rdns_result = dig_rdns(ip) + assert rdns_result.primary_hostname == "in1-smtp.grlengine.com" + assert rdns_result.primary_org == "grlengine" + + ip = fake.ipv6() + rdns_result = dig_rdns(ip) + assert rdns_result.primary_hostname is None + assert rdns_result.primary_org is None + print(rdns_result.model_dump_postgres()) diff --git a/tests/models/network/tool_run.py b/tests/models/network/tool_run.py new file mode 100644 index 0000000..c643503 --- /dev/null +++ b/tests/models/network/tool_run.py @@ -0,0 +1,8 @@ +from uuid import uuid4 + +from generalresearch.models.network.tool_run import new_tool_run_from_nmap + + +def test_new_tool_run_from_nmap(nmap_run): + scan_group_id = uuid4().hex + run, scan = new_tool_run_from_nmap(nmap_run, scan_group_id=scan_group_id) |
