Edit File by line
/home/barbar84/public_h.../wp-conte.../plugins/sujqvwi/AnonR/smanonr..../opt/sharedra.../oldrads
File: scrape_fails.py
#!/opt/imh-python/bin/python3
[0] Fix | Delete
[1] Fix | Delete
from collections import Counter
[2] Fix | Delete
import pika
[3] Fix | Delete
import platform
[4] Fix | Delete
import re
[5] Fix | Delete
from pathlib import Path
[6] Fix | Delete
[7] Fix | Delete
FQDN = platform.node()
[8] Fix | Delete
[9] Fix | Delete
[10] Fix | Delete
def scrape_http():
[11] Fix | Delete
# 28/Aug/2017:13:07:21
[12] Fix | Delete
"""Check for modsec hits"""
[13] Fix | Delete
hits_list = []
[14] Fix | Delete
log_file = Path('/usr/local/apache/logs/modsec_audit.log')
[15] Fix | Delete
line_number = 0
[16] Fix | Delete
inode = log_file.stat().st_ino
[17] Fix | Delete
try:
[18] Fix | Delete
prev_inode = get_previous('modsec')[0]
[19] Fix | Delete
prev_line = get_previous('modsec')[1]
[20] Fix | Delete
except Exception:
[21] Fix | Delete
# Files dont exist, or were removed. Assume starting from scratch
[22] Fix | Delete
prev_inode = int(0)
[23] Fix | Delete
prev_line = int(0)
[24] Fix | Delete
if int(inode) != int(prev_inode):
[25] Fix | Delete
# Inode changed. Logfile was most likely rotated. Start over
[26] Fix | Delete
with open(log_file, encoding='ascii') as file:
[27] Fix | Delete
for line in file.readlines():
[28] Fix | Delete
line_number += 1 # Line number counter
[29] Fix | Delete
try:
[30] Fix | Delete
if line.split()[-1] in ('80', '443'):
[31] Fix | Delete
remote_ip = line.split()[3]
[32] Fix | Delete
hits_list.append(remote_ip)
[33] Fix | Delete
except Exception:
[34] Fix | Delete
pass
[35] Fix | Delete
else:
[36] Fix | Delete
with open(log_file, encoding='ascii') as file:
[37] Fix | Delete
line_number = int(prev_line)
[38] Fix | Delete
for _ in range(int(prev_line)):
[39] Fix | Delete
next(file) # Skip ahead past the lines we already did
[40] Fix | Delete
for line in file:
[41] Fix | Delete
line_number += 1 # Line number counter
[42] Fix | Delete
try:
[43] Fix | Delete
if line.split()[-1] in ('80', '443'):
[44] Fix | Delete
remote_ip = line.split()[3]
[45] Fix | Delete
hits_list.append(remote_ip)
[46] Fix | Delete
except Exception:
[47] Fix | Delete
pass
[48] Fix | Delete
# update the cache file so we know where to pick up next time
[49] Fix | Delete
update_marker('modsec', inode, line_number)
[50] Fix | Delete
return hits_list
[51] Fix | Delete
[52] Fix | Delete
[53] Fix | Delete
def scrape_ftp():
[54] Fix | Delete
"""Check /var/log/messages for failed FTP logins"""
[55] Fix | Delete
hits_list = []
[56] Fix | Delete
log_file = Path('/var/log/messages')
[57] Fix | Delete
line_number = 0
[58] Fix | Delete
inode = log_file.stat().st_ino
[59] Fix | Delete
try:
[60] Fix | Delete
prev_inode = get_previous('ftp')[0]
[61] Fix | Delete
prev_line = get_previous('ftp')[1]
[62] Fix | Delete
except Exception: # No cache files, start over
[63] Fix | Delete
prev_inode = int(0)
[64] Fix | Delete
prev_line = int(0)
[65] Fix | Delete
if int(inode) != int(prev_inode): # log rotated, start from beginning
[66] Fix | Delete
with open(log_file, encoding='ascii') as file:
[67] Fix | Delete
for line in file.readlines():
[68] Fix | Delete
line_number += 1 # Increase line counter
[69] Fix | Delete
if 'pure-ftpd' in line and 'Authentication failed' in line:
[70] Fix | Delete
ip = line.split()[5].split("@")[1][:-1]
[71] Fix | Delete
hits_list.append(ip)
[72] Fix | Delete
else:
[73] Fix | Delete
with open(log_file, encoding='ascii') as file:
[74] Fix | Delete
line_number = int(prev_line)
[75] Fix | Delete
for _ in range(int(prev_line)):
[76] Fix | Delete
next(file) # Skip past lines we already parsed
[77] Fix | Delete
for line in file:
[78] Fix | Delete
line_number += 1 # Increase line counter
[79] Fix | Delete
if 'pure-ftpd' in line and 'Authentication failed' in line:
[80] Fix | Delete
ip = line.split()[5].split("@")[1][:-1]
[81] Fix | Delete
hits_list.append(ip)
[82] Fix | Delete
# update the cache file so we know where to pick up next time
[83] Fix | Delete
update_marker('ftp', inode, line_number)
[84] Fix | Delete
return hits_list
[85] Fix | Delete
[86] Fix | Delete
[87] Fix | Delete
def scrape_mysql():
[88] Fix | Delete
"""check /var/lib/mysql/$server.err for failed logins"""
[89] Fix | Delete
hits_list = []
[90] Fix | Delete
log_file = Path(f'/var/lib/mysql/{FQDN}.err')
[91] Fix | Delete
line_number = 0
[92] Fix | Delete
inode = log_file.stat().st_ino
[93] Fix | Delete
try:
[94] Fix | Delete
prev_inode = get_previous('mysql')[0]
[95] Fix | Delete
prev_line = get_previous('mysql')[1]
[96] Fix | Delete
except Exception: # No cache files, start over
[97] Fix | Delete
prev_inode = int(0)
[98] Fix | Delete
prev_line = int(0)
[99] Fix | Delete
if int(inode) != int(prev_inode): # log rotated, start from beginning
[100] Fix | Delete
with open(log_file, encoding='ascii') as file:
[101] Fix | Delete
for line in file.readlines():
[102] Fix | Delete
line_number += 1 # increase line counter
[103] Fix | Delete
if "Access denied" in line:
[104] Fix | Delete
ip = re.findall(r'[0-9]+(?:\.[0-9]+){3}', line)
[105] Fix | Delete
hits_list = hits_list + ip
[106] Fix | Delete
print(len(hits_list))
[107] Fix | Delete
else:
[108] Fix | Delete
with open(log_file, encoding='ascii') as file:
[109] Fix | Delete
line_number = int(prev_line)
[110] Fix | Delete
for _ in range(int(prev_line)):
[111] Fix | Delete
next(file) # skip through
[112] Fix | Delete
for line in file:
[113] Fix | Delete
line_number += 1 # increase line counter
[114] Fix | Delete
if 'Access denied' in line:
[115] Fix | Delete
ip = re.findall(r'[0-9]+(?:\.[0-9]+){3}', line)
[116] Fix | Delete
hits_list = hits_list + ip
[117] Fix | Delete
update_marker('mysql', inode, line_number) # update the cache file
[118] Fix | Delete
return hits_list
[119] Fix | Delete
[120] Fix | Delete
[121] Fix | Delete
def update_marker(file_name, inode, line_number):
[122] Fix | Delete
"""Update the file in /var/cache with the inode and line number"""
[123] Fix | Delete
try:
[124] Fix | Delete
store_folder = Path('/var/cache/iptrack')
[125] Fix | Delete
store_folder.mkdir(mode=0o755, parents=True, exist_ok=True)
[126] Fix | Delete
store_file = store_folder / file_name
[127] Fix | Delete
with open(store_file, 'w+', encoding='ascii') as file:
[128] Fix | Delete
file.write(str(inode) + ':' + str(line_number))
[129] Fix | Delete
file.close()
[130] Fix | Delete
except Exception as e: # If this fails, something is seriously wrong
[131] Fix | Delete
print(e)
[132] Fix | Delete
[133] Fix | Delete
[134] Fix | Delete
def get_previous(log_name):
[135] Fix | Delete
"""Get the previous line number we were on"""
[136] Fix | Delete
with Path('/var/cache/iptrack', log_name).open(encoding='ascii') as file:
[137] Fix | Delete
for line in file:
[138] Fix | Delete
inode = line.split(":")[0]
[139] Fix | Delete
line_no = line.split(":")[1]
[140] Fix | Delete
return [inode, line_no]
[141] Fix | Delete
[142] Fix | Delete
[143] Fix | Delete
def send_message(channel, service, server, ip, hits):
[144] Fix | Delete
"""Send a message to rabbitmq"""
[145] Fix | Delete
channel.basic_publish(
[146] Fix | Delete
exchange='',
[147] Fix | Delete
routing_key='iptrack',
[148] Fix | Delete
properties=pika.BasicProperties(
[149] Fix | Delete
headers=({'service': service, 'server': server, 'hits': hits})
[150] Fix | Delete
),
[151] Fix | Delete
body=ip,
[152] Fix | Delete
)
[153] Fix | Delete
[154] Fix | Delete
[155] Fix | Delete
def main():
[156] Fix | Delete
"""Scrape the log files, get some ips, and sent it to rabbitmq"""
[157] Fix | Delete
with open('/opt/sharedrads/etc/rabbit_pass', encoding='ascii') as file:
[158] Fix | Delete
for line in file.readlines():
[159] Fix | Delete
rabbit_pass = line.strip()
[160] Fix | Delete
host = 'ash-sys-pro-iptrack1.imhadmin.net'
[161] Fix | Delete
credentials = pika.PlainCredentials('iptrack', rabbit_pass)
[162] Fix | Delete
connection = pika.BlockingConnection(
[163] Fix | Delete
pika.ConnectionParameters(host, credentials=credentials)
[164] Fix | Delete
)
[165] Fix | Delete
channel = connection.channel()
[166] Fix | Delete
channel.queue_declare(queue='iptrack')
[167] Fix | Delete
try:
[168] Fix | Delete
for key, val in Counter(scrape_http()).items():
[169] Fix | Delete
send_message(channel, 'http', FQDN, key, val)
[170] Fix | Delete
for key, val in Counter(scrape_ftp()).items():
[171] Fix | Delete
send_message(channel, 'ftp', FQDN, key, val)
[172] Fix | Delete
for key, val in Counter(scrape_mysql()).items():
[173] Fix | Delete
send_message(channel, 'mysql', FQDN, key, val)
[174] Fix | Delete
except Exception as e:
[175] Fix | Delete
print(e)
[176] Fix | Delete
connection.close()
[177] Fix | Delete
[178] Fix | Delete
[179] Fix | Delete
if __name__ == '__main__':
[180] Fix | Delete
main()
[181] Fix | Delete
[182] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function