Red Green Repeat Adventures of a Spec Driven Junkie

Parsing SSH logs - Intermediate

This is part two of four in a series of articles about security.

  1. Text Processing Tools in UNIX
  2. Parsing SSH Logs
  3. Configuring fail2ban
  4. Configuring mail (and Slack) for SSH Notifications

This time, I will explore how many times SSH daemon’s own defenses stopped login attempts and use geoiplookup to lookup physical location data on IP addresses found in the log.

SSH daemon’s Defense

SSH itself is not completely defenseless against multiple login attempts in a short period of time. The SSH daemon will start to reject login attempts if the same IP address has multiple consecutive failures.

Total Rejections

From the log, the total number of times SSH disconnected a client because of too many failed attempts:

$ cat megaauth.log | grep -oE 'maximum authentication attempts.*' | wc -l`

SSH log shows there were 895 instances of too many failed attempts. This might not seem like a lot, but these are only the number of times the SSH daemon saw there was more than six failed attempts in a row.

Total Rejections for ‘root’

Number of Maximum Authentication attempts using ‘root’ as the username:

cat megaauth.log | grep -oE 'maximum authentication attempts.*for root' | wc -l

SSH rejected ‘root’ login 614 times in 24 days. This is a very good reason to disable root login on any openly accessible server. ‘root’ is the default administrative username for any UNIX system.

Total Rejections for other names

Number of Maximum Authentication attempts using name other than ‘root’:

cat megaauth.log | grep -oE 'maximum authentication attempts.*for invalid.*' | wc -l

278 login attempts were made using a username other than ‘root’. The most frequently used non-‘root’ username:

cat megaauth.log | grep -oE 'maximum authentication attempts.*for invalid.*' | awk '{ print $8 }' | sort | uniq -c | sort -n
# of attempts username
3 administrator
3 pi
4 mother
4 support
6 admin1
6 user
6 usuario
16 ubnt
17 test
169 admin

There is some overlap with the most frequently used login name, but it is not as frequent, due to SSH only counting these after the maximum number of attempts have been made.

Using geoiplookup to map Location

Let’s start with the most frequently seen IP address in the logs:

cat megaauth.log | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | sort | uniq -c | sort -n | tail
occurences address
634 182.61.21.189
696 88.150.230.127
732 121.42.48.1
972 113.5.255.22
1029 151.12.60.131
1128 107.155.6.41
1169 121.248.150.13
1704 61.183.15.243
2635 81.212.109.229
17869 155.133.16.246

Countries where these IP address are located:

cat megaauth.log | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | awk '{ system("geoiplookup " $1) }' | awk '{ $1="";$2="";$3=""; print $0 }' | sort | uniq -c | sort -n | tail
Country Occurrence
KR, Korea, Republic of 591
FR, France 607
RU, Russian Federation 665
GB, United Kingdom 730
IT, Italy 1223
NL, Netherlands 1579
US, United States 2424
TR, Turkey 3130
CN, China 10190
PL, Poland 17912

For the next section, to improve processing, creating an intermediate file, country_ip.log that maps IP address with its associated country.

cat auth.log | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | awk '{ print $0 system("geoiplookup " $1) }' | tr '\n' '|' | xargs -n 2 -d '|' | sed -n -e 's/0$//p' | sed -n -e 's/GeoIP Country Edition: //p' | awk '{ printf("%s %s\n", $(NF), $0 ) } END { print }' | awk '{ $(NF)=""; print $0 }' | head -n -1 > country_ip.log

note: this is pretty messy, so if there’s a better way to get this done, let me know!

How many Different Countries?

cat country_ip.log | awk '{ $1=""; print $0 }' | sort | uniq | wc -l

There were a total of 67 difference countries that showed up in the SSH log. There are 193 UN countries in the world. So, almost 33% of known countries in the world accessed this server in a period of 24 days.

Let’s take a look at how many times each country accessed the server, how many different IPs from the country, average, minimum, and maximum number of access.

country number of occurences unique IPs average occurences min max
FR, France 267 28 9 1 2
SE, Sweden 308 3 102 2 300
MY, Malaysia 313 2 156 13 300
JP, Japan 334 12 27 1 300
RU, Russian Federation 490 96 5 1 213
NL, Netherlands 1056 12 88 1 480
IT, Italy 1158 14 82 1 1029
US, United States 1588 85 18 1 692
CN, China 7228 299 24 1 1704
PL, Poland 17908 7 2558 1 17868

How items were calculated:

  • number of occurences: cat country_ip.log | awk '{ $1=""; print $0 }' | sort | uniq -c | sort -n | tail
  • unique IPs: cat country_ip.log | grep 'PL' | sort | uniq | wc -l
  • average : num occureneces / uniq IPs
  • min: cat country_ip.log | grep '<country code>' | sort | uniq -c | sort -n | head -n 1
  • max: cat country_ip.log | grep '<country code>' | sort | uniq -c | sort -n | tail -n 1

Poland really stood out, not only with the number of occurences, but basically a single individual showed up in the SSH log more than 17,000 times!

Port Scans per Country

The number of port scans performed by country can be obtained using this command:

cat megaauth.log | grep -oE 'Received disconnect.*' | awk '{ print $4 }' | sed -n -e 's/://p' |  awk '{ print $0 system("geoiplookup " $1) }' | tr '\n' '|' | xargs -n 2 -d '|' | sed -n -e 's/0$//p' | sed -n -e 's/GeoIP Country Edition: //p' | awk '{ printf("%s %s\n", $(NF), $0 ) } END { print }' | awk '{ $(NF)=""; print $0 }' | head -n -1 | awk '{ $1=""; print $0 }' | sort | uniq -c | sort -n | tail
Country Port scans
VN, Vietnam 140
RU, Russian Federation 228
GB, United Kingdom 379
NL, Netherlands 439
KR, Korea, Republic of 518
IT, Italy 609
TR, Turkey 743
US, United States 762
PL, Poland 4686
CN, China 5627

Interesting, China & Poland based IP addresses seemed to have done the most port scans.

Attempted logins per Country

cat megaauth.log | grep -oE 'Invalid user.*' | awk '{ print $5 }' | awk '{ print $0 system("geoiplookup " $1) }' | tr '\n' '|' | xargs -n 2 -d '|' | sed -n -e 's/0$//p' | sed -n -e 's/GeoIP Country Edition: //p' | awk '{ printf("%s %s\n", $(NF), $0 ) } END { print }' | awk '{ $(NF)=""; print $0 }' | head -n -1 | awk '{ $1=""; print $0 }' | sort | uniq -c | sort -n | tail
Country Attempted logins
PA, Panama 106
RU, Russian Federation 117
FR, France 135
VN, Vietnam 147
NL, Netherlands 230
CN, China 251
GB, United Kingdom 325
US, United States 444
IT, Italy 494
TR, Turkey 618

The number of attempted logins was not really dominated by any one country like port scans.

ubnt???

From part 1 of this, I encountered many login attempts with the username: ubnt. How many countries tried to login with ubnt username?

cat megaauth.log | grep -oE 'Invalid user ubnt.*' | awk '{ print $5 }' | awk '{ print $0 system("geoiplookup " $1) }' | tr '\n' '|' | xargs -n 2 -d '|' | sed -n -e 's/0$//p' | sed -n -e 's/GeoIP Country Edition: //p' | awk '{ printf("%s %s\n", $(NF), $0 ) } END { print }' | awk '{ $(NF)=""; print $0 }' | head -n -1 | awk '{ $1=""; print $0 }' | sort | uniq | wc -l

A total of 19 different countries used ubnt to login.

How about which countries attempted the most?

cat megaauth.log | grep -oE 'Invalid user ubnt.*' | awk '{ print $5 }' | awk '{ print $0 system("geoiplookup " $1) }' | tr '\n' '|' | xargs -n 2 -d '|' | sed -n -e 's/0$//p' | sed -n -e 's/GeoIP Country Edition: //p' | awk '{ printf("%s %s\n", $(NF), $0 ) } END { print }' | awk '{ $(NF)=""; print $0 }' | head -n -1 | awk '{ $1=""; print $0 }' | sort | uniq -c | sort -n | tail
Country Number of ‘ubnt’ attempts
TW, Taiwan 1
UA, Ukraine 1
CA, Canada 2
AR, Argentina 3
BR, Brazil 3
US, United States 4
FR, France 11
NL, Netherlands 27
RU, Russian Federation 34
CN, China 330

Most are non-English speaking countries, but even Canada and the United States are on this list.

City level

The interesting thing about geoiplookup, is that there is an option of using the city database to get finer

  • most seen IP in log in general (city)
cat auth.log | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | awk '{ system("geoiplookup -f /usr/share/GeoIP/GeoLiteCity.dat " $1) }' | awk '{ $1="";$2="";$3="";$4="";$5=""; print $0 }' | sort | uniq -c | sort -n | tail
City level data Occurences
IT, 07, Lazio, Rome, 00141, 41.891899, 12.511300, 0, 0 1029
CN, 08, Heilongjiang, Harbin, N/A, 45.750000, 126.650002, 0, 0 1043
US, CA, California, Los Angeles, 90017, 34.058399, -118.278000, 803, 213 1129
CN, 02, Zhejiang, Hangzhou, N/A, 30.293600, 120.161400, 0, 0 1281
CN, 22, Beijing, Beijing, N/A, 39.928902, 116.388298, 0, 0 1481
CN, 04, Jiangsu, Nanjing, N/A, 32.061699, 118.777802, 0, 0 1595
CN, 10, Hebei, Hebei, N/A, 39.889702, 115.275002, 0, 0 1602
CN, 12, Hubei, Wuhan, N/A, 30.580099, 114.273399, 0, 0 1753
TR, N/A, N/A, N/A, N/A, 41.021400, 28.994801, 0, 0 2709
PL, 78, Mazowieckie, Warsaw, 03-428, 52.250000, 21.000000, 0, 0 17871

Conclusion

This time, exploring the SSH log with geoiplookup mapped IP addresses to physical locations and how many times SSH daemon rejected login attempts.

If there is a server openly accessible on the Internet, find a way to lock it down! If it can be accessed, someone, somewhere will try!

Next time, I will talk about using Fail2Ban to reduce continued failed access.