A simple investigation about the state of IT/ICS security on Intrawebz. For regional entities of Bosnia-Herzegovina based on CIDR and ISP ASN provided range. It scans whole Bosnia-Herzegovina IPv4 addresses for top 1000 ports. Later, it parses those for further investigation.
Pretty simple. First thing first, get an ASN list based on your country. Then, extract CIDR ranges from the ASN list. After you've completed the first part, you need to clean up all IPv6 samples from the CIDR list -- so Masscan will not fail. Anyway, lets see how I did it.
- I got the ASN list from here and then copied them in a file so I can parse with some xnu-fu skillz =p
$ more asn-list-details.txt
AS9146 BH Telecom d.d. Sarajevo 172,800
AS42560 Telemach d.o.o. Sarajevo 143,360
AS25144 Telekomunikacije Republike Srpske akcionarsko drustvo Banja Luka 123,392
AS20875 HT d.o.o. Mostar 73,728
AS198252 ELTA KABEL d.o.o. 38,144
AS16178 Logosoft , information engineering and Internet providing 35,840
AS21107 Blicnet d.o.o. 33,280
AS35567 DASTO semtel d.o.o. 29,440
AS42571 Telrad Net doo 21,504
AS202632 TXTV d.o.o. Tuzla 18,688
AS43752 Ministry for Scientific and Technological Development, Higher Education and Information Society of the Republic of Srpska 16,384
AS57869 MISS.NET d.o.o. 11,264
AS43179 Team Consulting d.o.o. 10,240
AS8670 University of Sarajevo 8,192
...
$ awk '{print $1}' asn-list-details.txt > asn.txt && more asn.txt
AS9146
AS42560
AS25144
AS20875
AS198252
AS16178
...
Nice, after getting all ASN listed in asn.txt
file, I've used ASN to CIDR conversion tool located here.
Using wget
I pulled the CIDR range to another file which we will name cidrs.txt
.
Lets see:
$ wget https://pastebin.com/raw/gk9q56dV -O cidrs.txt
What was left to do is increase the chance of some findings via masscan
preferences of my own. You can refer to man masscan
for more detailed usage, or by reading the source code =p.
- Download, compile and install masscan.
- Test your installation
$ masscan --regress
regression test: success!
- Run masscan against cidr ranges:
$ masscan --top-ports 1000 --rate 100000 -oG ms-out.txt -oJ ms-out.json -iL cidrs.txt --open-only --wait 2 --banners --interactive
This will scan top ports with a rate of 100k p/p/s. It will output positive (--open-only
) results in plain text (-oG
) and json (-oJ
) and it will print to stdout due to interactive flag. The arg --wait 2
means the proc will wait 2 seconds before giving up (just making things quicker).
Author's Terminal Output:
0xduraki@ ~/dev/asn-scan-bh masscan --top-ports 1000 --rate 100000 -oG ms-out.txt -oJ ms-out.json -iL cidrs.txt --open-only --wait 2 --banners --interactive
Starting masscan 1.3.2 (....) at 2021-04-18 05:44:11 GMT
Initiating SYN Stealth Scan
Scanning 766976 hosts [1000 ports/host]
Discovered open port 9876/tcp on 80.87.241.29
rate: 98.78-kpps, 0.71% done, 2:06:40 remaining, found=1
rate: 98.71-kpps, 0.72% done, 2:06:46 remaining, found=1
Discovered open port 53/tcp on 178.209.2.102
Discovered open port 23/tcp on 91.191.6.207
...
As you can see, we have a total of ~766k IPv4 to scan. Which is not a lot, but it's stil a very large set for a country as small as Bosnia-Herzegovina. This is, of course, excluding IPv6 which I will write about very soon.
Total scan time of the IPv4 address space for given ASN on my ISP with bandwith i/o: BANDWITH HERE speedresult.net via (im sooory) Wi-Fi (next to AP) took about ~2h. Meanwhile, as interactive
flag was given, I could really see what is happening, which shortened the time somehow =p and also offered me to play while the scans finish. Once I have a positive IPv4:PORT
match, I asked Unix what port is for which stuff. See terminal output below:
# => ie masscan stdout prints:
...
Discovered open port 1723/tcp on 195.34.71.161
# => me, in another tty:
$ cat /etc/services | grep 1723
pptp 1723/udp # pptp
pptp 1723/tcp # pptp
ssh-mgmt 17235/tcp # SSH Tectia Manager
ssh-mgmt 17235/udp # SSH Tectia Manager
# 17236-17728 Unassigned
This way, I had more to look at and objectively junk on unfiltered ports hanging in the wild. Ie. why is Fortinet FW obviously sitting in the pubnet, all while whole world can access it? Doesn't seems like a good sec practice to me. A lot of time, I've been looking to what service it yields back to me and then see if there are possible exploits available:
# => Port availability
$ cat /etc/services | grep ssdp
ssdp 1900/udp # SSDP
ssdp 1900/tcp # SSDP
msf6 auxiliary(scanner/smb/smb_login) > search ssdp
Matching Modules
================
# Name Disclosure Date Rank Check Description
- ---- --------------- ---- ----- -----------
0 exploit/linux/upnp/dlink_dir859_exec_ssdpcgi 2019-12-24 excellent No D-Link Devices Unauthenticated Remote Command Execution in ssdpcgi
1 exploit/multi/upnp/libupnp_ssdp_overflow 2013-01-29 normal No Portable UPnP SDK unique_service_name() Remote Code Execution
2 auxiliary/scanner/upnp/ssdp_amp normal No SSDP ssdp:all M-SEARCH Amplification Scanner
3 auxiliary/scanner/upnp/ssdp_msearch normal No UPnP SSDP M-SEARCH Information Discovery
As for the why I'm writing this blog? It's because I'm heading towards more specialised industry as I'm switching jobs and leaving great, great Infigo where I've met very smart people, and joining Applied Risk from Amsterdam, de-facto company dealing with ICS on another level. Fantastic, I can't wait to express my inner thoughts once I get my hands dirty on those PLCs.
For SCADA in particular, I've chose to visit back my private GitHub repo sitting in ics_bh that already defines some of the juicy stuff. I've spent a few days collecting all sources for scadasec and internal stuff via Webinars. Then I resumed and researched what I had and started working on this tool.
The ics_bh
utility I wrote a few weeks earlier does some banner grabbing on famous ICS vendors installed in Europe. I'm yet to open-source this little guy, but I hope you will forgive due to me trying C++.
snippet from /vendors.h:
/* icsbh - State of SCADA security in Bosnia-Herzegovina
* Copyright (c) 2021 Halis Duraki (0xduraki)
*/
...
typedef enum : int { /* u = udp , t = tcp*/
FLNet = 55000, // to ..55003, u
Fieldbus_HSE = 1089, // to 1091, t,u
BACnet = 47808, // u
DNP3 = 20000, // u,t
EtherNet_IP = 44818, // u,t
EtherCAT = 34980, // u
ModBus = 502, // u,t
ProCon_PLC = 20547, // u,t
Wago_PLC = 2455, // u,t
RedLion_Crimson = 789, // t
SIEMENS_S7 = 102, // t
NIAGRA_FW_0 = 1911, // ???
NIAGRA_FW_1 = 4911, // ???
IEC104 = 2404, // ???
IEC60870, // 2404 as above
GeneralElectric, // like EtherNet
Omron, // same as DeviceNet, RS-232C
PCWorx = 20547, 2455, 9600, 1962,
OPC_UA_DiscoveryServer = 4840,
PROFINET = t[34962..34964], u[34962 to 34964],
ROC_PLUS = tu[4000],
DCSFOXAPI = 55555 // tu
DCSAIMAPI = 45678 // tu
Sielco_Sistemi_Winlog = 46824, // remotely exploitable with vulnerability winlog_runtime_2 from metasploit
} Protocols;
Therefore, we can all agree that reusing masscan might be more appropriate, but where is the fun in that? =p I came up with this command-line. Can you come up with something better?
Hold up!! As per masscan documentation, [masscan] supports banner checking on the [...] protocols
, tho below it says: [...] problem with this is that masscan contains its own TCP/IP stack [...] when the local system receives a SYN-ACK, it responds with a RST packet that kills the connection ...
.
That makes sense, see masscan (8) section SPURIOUS RESETS. We can force this to make masscan tunnel through additional ipaddr inside your home network, or as per MacOS documentation:
# => find available range for port choice
$ sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last
net.inet.ip.portrange.first: 49152
net.inet.ip.portrange.last: 65535
$ echo "block in proto tcp from any to any port 53337" >> /etc/pf.conf
$ pfctl -E
Now masscan
will run more powerful, we just need to pass --adapter-port
flag. Like so:
# => tcp scan of scada ports
$ masscan --rate 100000 -p 102,789,1089-1091,1541,1911,1962,2404,2455,4000,4840,4911,5052,5056,5450,9600,11001,12135-12137,18000,55555,20000,20547,34962-34964,38000-38015,38200-38700,44818,45678,46824,50001-50028,50110-50111,56001-56099,62900-62930 -oG ms-scada-out.txt -oJ ms-scada-out.json -iL cidrs.txt --open-only --banners --interactive --adapter-port 53337
# => udp scan of scada ports
$ masscan --rate 100000 -p U:502,U:789,U:1089-1091,U:1541,U:1911,U:2404,U:2455,U:4000,U:4911,U:5050-5065,U:11001,U:20000,U:20547,U:34960-34964,U:44818,U:47808,U:45678,U:50020-50021,U:55000-55003,U:55555 -oG ms-scada-out-udp.txt -oJ ms-scada-out-udp.json -iL cidrs.txt --open-only --banners --interactive --adapter-port 53337
Bonus points!! for hard-core router ddos, try =p:
$ masscan cidrs.txt --rate 1000000000 -p0-65535,U:0-65535 -e eth0 -oG output.txt
For IoT on other hand , I've referenced to old stuff used famously by Mirai and alike. DDoS attacks were prevelent some time when I was young, but using exposed cctvs via high bandwith was really interesting art piece. Also .. the fire on the industry. dayyyuum
Ah. This was actually my favoruite part, as I had various things to play with - network levels, and also sittings on the servers. I see a lot of guys pushing towards web. Yeah, I agree, but I'd also agree with Phineas Phisher when she told us that web can give you only much. If you really want to dig into hacking more naturally, you will have to explore deeper topics. If you are not prepared for that, then .. don't try. Is hacking really your passion? You can think about it and let me know =)
Again, all this was done just to experiment with recon on more mature level, not chashing papers only. I guess.
After I've completed the above task (due to masscan
being really, really fast with rate/packets, the capnet occured - therefore I've waited for above masscan to finish) -- ie. extract live hosts on top*1000 ports. Later, I figured out, I could reverse the IPv4 and ASN for that matter, and try all DNS hosted on this address space. Mostly of what I thought would be .ba
ccTLD for Bosnia-Herzegovina.
Hint: You can always Ctrl+C to
masscan
command line, and later resume the scan. This means you can turn of your computer, go with your things, and continue later when you are in mood.
# => Ctrl+C
Scanning 766976 hosts [1000 ports/host]
^Cwaiting several seconds to exit...
saving resume file to: paused.conf
# => After a few days
$ masscan --resume paused.conf
Starting masscan 1.3.2 (.....) at 2021-04-18 06:58:55 GMT
Initiating SYN Stealth Scan
Scanning 766976 hosts [1000 ports/host]
rate: 98.62-kpps, 56.62% done, 0:55:02 remaining, found=x
Note: By the time of writing, the latest official release of masscan -- version
1.3.2
will fail if--resume paused.conf
is used due to robertdavidgraham/masscan#576. Compile from master if you want it, otherwise, don't send signals to tty.
I figured out I could use amass
which most of the haxors use for recon, and try to extract domains matching those hosts. I could just pass multiple ASNs to amass
intel command by -asn
flag. But first, I had to convert those ASN to Integer types (ie. remove AS), because amass
will accept only those. Again, Unix comes handy here to replace all 'AS' prefixes with nullbytes.
$ head -1 asn.txt | sed 's/AS//' # => ~smoke-test
9146
$ cat asn.txt | sed 's/AS//' | sed -e :begin -e '$!N;s/\n/,/; tbegin'
9146,42560,25144,20875,198252,16178,21107,35567,42571,202632,43752,57869,43179,8670,16145,59457,200698,34943,47959,59847,50537,199051,198994,212665,203744,209491,200914,201719,39826,35107,208881,209098,206474,205913,209271,43947,50249,39689,43604,61222,35143,42432,42450,42983,212572,47840,48443,50938,51386,197687,209493
Cool, now we have ASNs that we can pass to amass
in a similar way:
$ amass intel -active -o asn-amass-intel.txt -ipv4 -src -asn 9146,42560,25144,20875,198252,16178,21107,35567,42571,202632,43752,57869,43179,8670,16145,59457,200698,34943,47959,59847,50537,199051,198994,212665,203744,209491,200914,201719,39826,35107,208881,209098,206474,205913,209271,43947,50249,39689,43604,61222,35143,42432,42450,42983,212572,47840,48443,50938,51386,197687,209493
I know, it's kinda stupid. But hey, it works properly. Don't forget to setup all API keys in amass.ini
config file. The results:
-
[Reverse DNS] telemach.ba 109.237.32.4
[Reverse DNS] urbzdk.ba 77.239.29.254
[Reverse DNS] fis.ba 141.170.204.210
[Reverse DNS] telemach.co.ba 77.78.192.15
[Reverse DNS] imbih.gov.ba 77.78.198.102
[Reverse DNS] tmch.net.ba 77.78.192.1
[Reverse DNS] googlevideo.com 77.77.193.135
[Reverse DNS] telemachhosting.ba 77.77.192.21
[Reverse DNS] cloudhosting.ba 77.77.207.42
[Reverse DNS] telemachhosting.co.ba 77.77.207.221
[Reverse DNS] mojposao.ba 77.77.209.106
[Reverse DNS] jamax.ba 77.77.212.182
[Reverse DNS] standard-furniture.ba 77.221.1.99
[Reverse DNS] vinet.ba 77.221.22.89
[Reverse DNS] messer.ba 185.6.105.42
[Reverse DNS] icitapeng.us 185.6.105.220
[Reverse DNS] uniqaosiguranje.ba 185.6.104.36
[Reverse DNS] ghb.ba 185.6.105.204
[Reverse DNS] hs-hkb.ba 185.6.106.63
[Reverse DNS] epprojects.net 77.78.199.21
[Reverse DNS] ferk.ba 77.78.200.8
[Reverse DNS] megamix.ba 77.78.196.33
...