Created
May 23, 2014 15:08
-
-
Save robmiller/d32dc4826639b69c92e7 to your computer and use it in GitHub Desktop.
Script, designed to be run on a cron job, to scan for files (in this case PHP files) that have been modified and notify a Slack channel with the changes. Just for information, not for proper intrusion detection or anything
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'net/http' | |
require "json" | |
require "pathname" | |
require "logger" | |
class Slack | |
attr_reader :account, :token, :channel | |
def initialize(account, token, channel) | |
@account = account | |
@token = token | |
@channel = channel | |
end | |
def uri | |
URI.parse("https://#{account}.slack.com/services/hooks/incoming-webhook?token=#{token}&channel=#{channel}") | |
end | |
def notify(text) | |
http = Net::HTTP.new(uri.host, uri.port) | |
http.use_ssl = true | |
req = Net::HTTP::Post.new(uri.request_uri) | |
req.body = { text: text }.to_json | |
res = http.request(req) | |
res === Net::HTTPSuccess | |
end | |
end | |
class Watcher | |
LOG_FILE = ENV["SCANPHP_LOG_FILE"] || "/var/log/scan-php" | |
def initialize | |
@notified = [] | |
@logger = Logger.new(LOG_FILE) | |
@logger.level = ENV["SCANPHP_DEBUG"] ? Logger::DEBUG : Logger::INFO | |
@slack = Slack.new(ENV["SLACK_ACCOUNT"], ENV["SLACK_TOKEN"], ENV["SLACK_CHANNEL"]) | |
end | |
def call | |
@logger.info("Running scan in #{Dir.pwd}") | |
unless something_new? | |
@logger.info("No new files found in scan") | |
return | |
end | |
@slack.notify(message) | |
@logger.debug(message) | |
end | |
def something_new? | |
files.length > 0 | |
end | |
def files | |
@files ||= begin | |
raw_files = `find . -iname '*.php' -mtime 0` | |
@logger.debug("Raw files:\n" + raw_files) | |
raw_files = raw_files.split("\n").map { |file| Pathname(file) } | |
raw_files.reject do |file| | |
Time.now - File.mtime(file) > 3600 || | |
/gravity_forms\/captcha/.match(file.to_s) || | |
/cache\/index\.php$/.match(file.to_s) | |
end | |
end | |
end | |
def sites | |
files.group_by do |file| | |
elements = [] | |
file.each_filename { |f| elements << f } | |
elements[1] | |
end | |
end | |
def message | |
@message ||= begin | |
message = "#{Time.now.strftime('%H:%M:%S')}: #{files.length} PHP file#{'s' if files.length != 1} modified across #{sites.length} site#{'s' if sites.length != 1}\n\n" | |
sites.each do |site, site_files| | |
message << "On #{site}:\n" | |
site_files.each do |file| | |
elements = [] | |
file.each_filename { |f| elements << f } | |
elements = elements[2..-1] | |
relative_path = elements.join("/") | |
message << "\t" << relative_path << "\n" | |
end | |
end | |
message | |
end | |
end | |
end | |
Watcher.new.call |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment