Skip to content

Commit fd34d1e

Browse files
committed
update visualizations
1 parent 4ff9b54 commit fd34d1e

File tree

7 files changed

+43
-32
lines changed

7 files changed

+43
-32
lines changed

visualization/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Usage:
1919
* Generate the JSON file
2020

2121
```bash
22-
python3 world_map.py -c ~/Downloads/country_asn.mmdb -4 ~/Downloads/risk_ip4_med.json -6 ~/Downloads/risk_ip6_med.json
22+
python3 world_map.py -c ~/Downloads/ipinfo_lite.mmdb -4 ~/Downloads/risk_ip4_med.json -6 ~/Downloads/risk_ip6_med.json
2323
```
2424

2525
2. For testing - run the minimal python3 webserver to enable JS to access the JSON file:
@@ -69,7 +69,7 @@ Usage:
6969
* Generate the JSON file
7070

7171
```bash
72-
python3 net_tree.py -a ~/Downloads/country_asn.mmdb -n ~/Downloads/risk_net4_med.json
72+
python3 net_tree.py -a ~/Downloads/ipinfo_lite.mmdb -n ~/Downloads/risk_net4_med.json
7373
```
7474

7575
2. For testing - run the minimal python3 webserver to enable JS to access the JSON file:

visualization/asn_chart.html

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
.bubble {
1111
overflow: hidden;
1212
}
13+
.bubble:hover {
14+
cursor: pointer;
15+
}
1316

1417
.bubble-asn {
1518
font-weight: bold;
@@ -69,6 +72,11 @@
6972
"#E37F6F", "#C5824E", "#FDCA29", "#D99620", "#E7C014", "#F9C630", "#F6BC55", "#B9AB58", "#DB8E94",
7073
"#D27E7E",
7174
];
75+
const URL_KEY_MAP = {
76+
'oxl_geoip': 'OXL GeoIP',
77+
'ipinfo': 'IPInfo',
78+
'shodan': 'Shodan',
79+
};
7280

7381
function numberWithDot(x) {
7482
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
@@ -88,23 +96,17 @@
8896
}
8997
infoContainer.innerHTML += `<b>IPv4 Addresses</b>: ${numberWithDot(infos.info.ipv4)}<br>`;
9098
infoContainer.innerHTML += `<b>IPv6 Addresses</b>: ${numberWithDot(infos.info.ipv6)}<br>`;
91-
let kinds = [];
92-
for (let [k, v] of Object.entries(infos.kind)) {
93-
if (v === true) {
94-
kinds.push(k);
95-
}
96-
}
97-
if (kinds.length > 0) {
98-
infoContainer.innerHTML += `<b>Kind</b>: ${kinds.join(', ')}<br>`;
99+
if (infos.kind.length > 0) {
100+
infoContainer.innerHTML += `<b>Kind</b>: ${infos.kind.join(', ')}<br>`;
99101
}
100-
let urls = [`<a href="https://risk.oxl.app/api/asn/${infos.asn}">oxl_riskdb</a>`];
102+
let urls = [`<a href="https://risk.oxl.app/api/asn/${infos.asn}">OXL RiskDB</a>`];
101103
for (let [k, v] of Object.entries(infos.info.url)) {
102-
urls.push(`<a href="${v}">${k}</a>`);
104+
urls.push(`<a href="${v}">${URL_KEY_MAP[k]}</a>`);
103105
}
104106
infoContainer.innerHTML += `<b>URLs</b>: ${urls.join(', ')}<br><hr>`;
105-
infoContainer.innerHTML += `<small><b>Relative Reports</b>: ${infos.reports.rel_by_ip4} (by IPv4)</small><br>`;
107+
infoContainer.innerHTML += `<small><b>Relative Reports</b>: ${infos.reports.relative_by_ipv4} (by IPv4)</small><br>`;
106108
for (let [k, v] of Object.entries(infos.reports)) {
107-
if (k == 'rel_by_ip4') {
109+
if (k == 'relative_by_ipv4') {
108110
continue;
109111
}
110112
infoContainer.innerHTML += `<small><b>Reports ${k}</b>: ${numberWithDot(v)}</small><br>`;
@@ -118,11 +120,11 @@
118120
for (let [asn, values] of Object.entries(resp)) {
119121
data.push({
120122
asn: asn, info: values.info, kind: values.kind, reports: values.reports,
121-
sortBy: values.reports.all,
123+
sortBy: values.reports.sum,
122124
})
123125
}
124126

125-
const sortedData = data.sort((a, b) => b.reports.all - a.reports.all).slice(0, TOP_N);
127+
const sortedData = data.sort((a, b) => b.reports.sum - a.reports.sum).slice(0, TOP_N);
126128
console.log(sortedData);
127129

128130
const colorScale = d3.scaleOrdinal()
@@ -165,7 +167,7 @@
165167
.text(d => JSON.stringify(d.data));
166168

167169
for (let b of document.querySelectorAll(".bubble")) {
168-
b.addEventListener("mouseover", showASNInfos);
170+
b.addEventListener("click", showASNInfos);
169171
}
170172

171173
});
12.4 KB
Loading

visualization/net_tree.html

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
font-weight: bold;
1818
transform
1919
}
20+
.net:hover {
21+
cursor: pointer;
22+
}
2023

2124
.net-cidr {
2225
display: inline-block;
@@ -58,7 +61,7 @@
5861
const WIDTH = window.innerWidth;
5962
const HEIGHT = window.innerHeight - 50;
6063
const NET_PAD = 5;
61-
const CATEGORIES = ['all', 'bot', 'probe', 'rate', 'attack', 'crawler'];
64+
const CATEGORIES = ['sum', 'bot', 'probe', 'rate', 'attack', 'crawler'];
6265
const COLORSCHEME = [
6366
// red-ish
6467
"#B93022", "#FF383D", "#D32669", "#C43F03", "#E70291", "#E211C0", "#6A3D52", "#C75839", "#E7A8B0",
@@ -70,6 +73,13 @@
7073
"#E37F6F", "#C5824E", "#FDCA29", "#D99620", "#E7C014", "#F9C630", "#F6BC55", "#B9AB58", "#DB8E94",
7174
"#D27E7E",
7275
];
76+
const URL_KEY_MAP_NET = {
77+
'asn': 'OXL RiskDB ASN',
78+
'net': 'OXL RiskDB Network',
79+
'ipinfo_1': 'IPInfo Network-IP',
80+
'ipinfo_2': 'IPInfo Network-Range',
81+
'ipinfo_asn': 'IPInfo ASN',
82+
}
7383

7484
function numberWithDot(x) {
7585
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
@@ -87,6 +97,9 @@
8797
infoContainer.innerHTML += `<b>Reputation</b>: ${infos.reputation.toUpperCase()}<br>`;
8898
infoContainer.innerHTML += `<b>ASN</b>: ${infos.asn}<br>`;
8999
infoContainer.innerHTML += `<b>Org</b>: ${infos.as_name}<br>`;
100+
if (infos.kind.length > 0) {
101+
infoContainer.innerHTML += `<b>Kind</b>: ${infos.kind.join(', ')}<br>`;
102+
}
90103

91104
if (infos.country !== undefined) {
92105
infoContainer.innerHTML += `<b>Country</b>: ${infos.country}<br>`;
@@ -114,7 +127,7 @@
114127
.parentId(function(d) { if (d.name == 'root') { return null } else { return 'root' }; })
115128
(data.children);
116129

117-
root.sum(function(d) { return +d.all })
130+
root.sum(function(d) { return +d.sum })
118131

119132
d3.treemap()
120133
.size([WIDTH, HEIGHT])
@@ -159,7 +172,7 @@
159172
let c = n.querySelectorAll("text")[0];
160173
c.setAttribute("transform", `translate(${r.x.baseVal.value + NET_PAD}, ${r.y.baseVal.value + NET_PAD + 30})`);
161174

162-
n.addEventListener("mouseover", showNetInfos);
175+
n.addEventListener("click", showNetInfos);
163176
}
164177

165178
});

visualization/net_tree.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
SRC_PATH = Path(__file__).resolve().parent
1313
TOP_N = 30
14-
CATEGORIES = ['sum', 'bot', 'probe', 'rate', 'attack', 'crawler']
1514

1615
# todo: add change to last month
1716
DATA = {
@@ -49,20 +48,17 @@ def main():
4948
'name': net,
5049
'asn': asn,
5150
'as_name': as_name,
52-
'url': {
53-
'riskdb_asn': f'https://risk.oxl.app/api/asn/{asn}',
54-
'riskdb_net': f'https://risk.oxl.app/api/net/{ip}',
55-
'ipinfo': f'https://ipinfo.io/{ip}',
56-
'ipinfo_asn': f'https://ipinfo.io/AS{asn}',
57-
},
5851
**infos,
5952
}
53+
data['url']['net'] = f'https://risk.oxl.app/api/net/{asn}'
54+
data['url']['ipinfo_asn'] = f'https://ipinfo.io/AS{asn}'
55+
reports = data.pop('reports')
56+
data = {**data, **reports}
6057

61-
if 'country' in ip_md:
62-
data['country'] = ip_md['country']
58+
if 'country_code' in ip_md:
59+
data['country'] = ip_md['country_code']
6360

6461
DATA['children'].append(data)
65-
6662
i += 1
6763

6864
with open(SRC_PATH / 'net_tree.json', 'w', encoding='utf-8') as f:
@@ -71,7 +67,7 @@ def main():
7167

7268
if __name__ == '__main__':
7369
parser = ArgumentParser()
74-
parser.add_argument('-a', '--asn-db', help='MMDB ASN data to use (OXL/IPInfo)', default='country_asn.mmdb')
70+
parser.add_argument('-a', '--asn-db', help='MMDB ASN data to use (OXL/IPInfo)', default='ipinfo_lite.mmdb')
7571
parser.add_argument('-n', '--file-net', help='IPv4 or IPv6 JSON file to parse', default='risk_net4_med.json')
7672
args = parser.parse_args()
7773
main()

visualization/world_map.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,6 @@ def main():
9595
parser = ArgumentParser()
9696
parser.add_argument('-4', '--file-ip4', help='IPv4 JSON file to parse', default='risk_ip4_med.json')
9797
parser.add_argument('-6', '--file-ip6', help='IPv6 JSON file to parse', default='risk_ip6_med.json')
98-
parser.add_argument('-c', '--country-db', help='MMDB country data to use (IPInfo)', default='country_asn.mmdb')
98+
parser.add_argument('-c', '--country-db', help='MMDB country data to use (IPInfo)', default='ipinfo_lite.mmdb')
9999
args = parser.parse_args()
100100
main()
29 KB
Loading

0 commit comments

Comments
 (0)