Improves the Plugins & Themes passive detection, fixes #674
This commit is contained in:
@@ -80,13 +80,31 @@ class WpItems < Array
|
||||
#
|
||||
# @return [ WpItems ]
|
||||
def passive_detection(wp_target, options = {})
|
||||
results = new(wp_target)
|
||||
body = Browser.get(wp_target.url).body
|
||||
results = new(wp_target)
|
||||
# improves speed
|
||||
body = remove_base64_images_from_html(body)
|
||||
names = body.scan(passive_detection_pattern(wp_target))
|
||||
body = remove_base64_images_from_html(Browser.get(wp_target.url).body)
|
||||
page = Nokogiri::HTML(remove_conditional_comments(body))
|
||||
names = []
|
||||
|
||||
names.flatten.uniq.each { |name| results.add(name) }
|
||||
page.css('link,script,style').each do |tag|
|
||||
%w(href src).each do |attribute|
|
||||
attr_value = tag.attribute(attribute).to_s
|
||||
next unless attr_value
|
||||
|
||||
names << Regexp.last_match[1] if attr_value.match(attribute_pattern(wp_target))
|
||||
end
|
||||
|
||||
next unless tag.name == 'script' || tag.name == 'style'
|
||||
|
||||
code = tag.text.to_s
|
||||
next if code.empty?
|
||||
|
||||
code.scan(code_pattern(wp_target)).flatten.uniq.each do |item_name|
|
||||
names << item_name
|
||||
end
|
||||
end
|
||||
|
||||
names.uniq.each { |name| results.add(name) }
|
||||
|
||||
results.sort!
|
||||
results
|
||||
@@ -97,13 +115,29 @@ class WpItems < Array
|
||||
# @param [ WpTarget ] wp_target
|
||||
#
|
||||
# @return [ Regex ]
|
||||
def passive_detection_pattern(wp_target)
|
||||
type = self.to_s.gsub(/Wp/, '').downcase
|
||||
regex1 = %r{(?:[^=:\(]+)\s?(?:=|:|\()\s?(?:"|')[^"']+\\?/}
|
||||
regex2 = %r{\\?/}
|
||||
regex3 = %r{\\?/([^/\\"']+)\\?(?:/|"|')}
|
||||
def item_pattern(wp_target)
|
||||
type = to_s.gsub(/Wp/, '').downcase
|
||||
wp_content_dir = wp_target.wp_content_dir
|
||||
wp_content_url = wp_target.uri.merge(wp_content_dir).to_s
|
||||
|
||||
/#{regex1}#{Regexp.escape(wp_target.wp_content_dir)}#{regex2}#{Regexp.escape(type)}#{regex3}/i
|
||||
url = /#{wp_content_url.gsub(%r{\A(?:http|https)}, 'https?').gsub('/', '\\\\\?\/')}/i
|
||||
content_dir = %r{(?:#{url}|\\?\/\\?\/?#{wp_content_dir})}i
|
||||
|
||||
%r{#{content_dir}\\?/#{type}\\?/}
|
||||
end
|
||||
|
||||
# @param [ WpTarget ] wp_target
|
||||
#
|
||||
# @return [ Regex ]
|
||||
def attribute_pattern(wp_target)
|
||||
/\A#{item_pattern(wp_target)}([^\/]+)/i
|
||||
end
|
||||
|
||||
# @param [ WpTarget ] wp_target
|
||||
#
|
||||
# @return [ Regex ]
|
||||
def code_pattern(wp_target)
|
||||
/["'\(]#{item_pattern(wp_target)}([^\\\/\)"']+)/i
|
||||
end
|
||||
|
||||
# The default request parameters
|
||||
|
||||
@@ -73,6 +73,10 @@ def add_trailing_slash(url)
|
||||
url =~ /\/$/ ? url : "#{url}/"
|
||||
end
|
||||
|
||||
def remove_conditional_comments(text)
|
||||
text.gsub(/<!--\[if[^>]+>(.*)<!\[end[^>]+>/im, '\1')
|
||||
end
|
||||
|
||||
# loading the updater
|
||||
require_files_from_directory(UPDATER_LIB_DIR)
|
||||
@updater = UpdaterFactory.get_updater(ROOT_DIR)
|
||||
|
||||
@@ -18,12 +18,21 @@ describe WpItems do
|
||||
vulnerable_targets_items: [ WpItem.new(uri, name: 'mr-smith'),
|
||||
WpItem.new(uri, name: 'neo')],
|
||||
|
||||
passive_detection: WpItems.new << WpItem.new(uri, name: 'js-source') <<
|
||||
WpItem.new(uri, name: 'escaped-url') <<
|
||||
WpItem.new(uri, name: 'link-tag') <<
|
||||
WpItem.new(uri, name: 'script-tag') <<
|
||||
WpItem.new(uri, name: 'style-tag') <<
|
||||
WpItem.new(uri, name: 'style-tag-import')
|
||||
# Any better way to do this ? :x
|
||||
passive_detection: WpItems.new << WpItem.new(uri, name: 'detect-me-1') <<
|
||||
WpItem.new(uri, name: 'detect-me-2') <<
|
||||
WpItem.new(uri, name: 'detect-me-3') <<
|
||||
WpItem.new(uri, name: 'detect-me-4') <<
|
||||
WpItem.new(uri, name: 'detect-me-5') <<
|
||||
WpItem.new(uri, name: 'detect-me-6') <<
|
||||
WpItem.new(uri, name: 'detect-me-7') <<
|
||||
WpItem.new(uri, name: 'detect-me-8') <<
|
||||
WpItem.new(uri, name: 'detect-me-9') <<
|
||||
WpItem.new(uri, name: 'detect-me-10') <<
|
||||
WpItem.new(uri, name: 'detect-me-11') <<
|
||||
WpItem.new(uri, name: 'detect-me-12') <<
|
||||
WpItem.new(uri, name: 'detect-me-13') <<
|
||||
WpItem.new(uri, name: 'detect-me-14')
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -19,8 +19,7 @@ describe WpPlugins do
|
||||
vulnerable_targets_items: [ WpPlugin.new(uri, name: 'mr-smith'),
|
||||
WpPlugin.new(uri, name: 'neo')],
|
||||
|
||||
passive_detection: WpPlugins.new << WpPlugin.new(uri, name: 'js-source') <<
|
||||
WpPlugin.new(uri, name: 'escaped-url') <<
|
||||
passive_detection: WpPlugins.new << WpPlugin.new(uri, name: 'escaped-url') <<
|
||||
WpPlugin.new(uri, name: 'link-tag') <<
|
||||
WpPlugin.new(uri, name: 'script-tag') <<
|
||||
WpPlugin.new(uri, name: 'style-tag') <<
|
||||
|
||||
@@ -1,65 +1,60 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="fr-FR">
|
||||
<!-- This file is malformed to make sure Nokogiri can process it -->
|
||||
|
||||
<head profile="http://gmpg.org/xfn/11">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<meta property="fb:page_id" content="18968879441564"/>
|
||||
<title>Example.com</title>
|
||||
<link rel="alternate" type="application/rss+xml" title="Example RSS Feed" href="http://example.com/feed"/>
|
||||
<link rel="alternate" type="application/atom+xml" title="Example Atom Feed" href="http://example.com/feed/atom"/>
|
||||
<link rel="pingback" href="http://example.com/xmlrpc.php"/>
|
||||
<link rel='stylesheet'
|
||||
href='http://example.com/wp-content/items/link-tag/cache/7f8155a5485bc445ed0adb136722b.css?m=1224763007'
|
||||
type='text/css' media='screen'/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<meta property="fb:page_id" content="18968879441564"/>
|
||||
<title>example.com</title>
|
||||
<link rel="alternate" type="application/rss+xml" title="Example RSS Feed" href="http://example.com/feed"/>
|
||||
<script type='text/javascript' src='http://platform.twitter.com/widgets.js?ver=1.0.0'></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
var TB_pluginPath = 'http://www.welovebug.com/wp-content/items/js-source';
|
||||
var TB_config = {
|
||||
'widget_show_photos': true,
|
||||
'widget_show_source': true,
|
||||
'widget_show_header': true,
|
||||
'general_link_screen_names': true,
|
||||
'general_link_hash_tags': true,
|
||||
'general_link_urls': true,
|
||||
'widget_check_sources': true,
|
||||
'widget_show_user': true
|
||||
}
|
||||
</script>
|
||||
<!-- Items that should be detected -->
|
||||
<link rel='stylesheet' href='http://example.com/wp-content/items/detect-me-1/cache/7f81.css?m=12' type='text/css' media='screen'/>
|
||||
<link rel="stylesheet" href="/wp-content/items/detect-me-2/css/frontend.css?ver=3.9.2"/>
|
||||
|
||||
<style type="text/css">
|
||||
#fancybox-loading.fancybox-ie div {
|
||||
background: transparent;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://example.com/wp-content/items/style-tag/fancybox/fancy_loading.png', sizingMethod='scale');
|
||||
}
|
||||
</style>
|
||||
<script type='text/javascript' src='http://example.com/wp-content/items/detect-me-3/s2member-o.php?ws=1'></script>
|
||||
|
||||
<script type='text/javascript'
|
||||
src='http://example.com/wp-content/items/script-tag/s2member-o.php?ws_plugin__s2member_js_w_globals=1'></script>
|
||||
<script type='text/javascript' src='/wp-content/items/detect-me-4/main.js'></script>
|
||||
<!-- Duplicate, detect-me-4 should only be detected once -->
|
||||
<script type='text/javascript' src='/wp-content/items/detect-me-4/main.js'></script>
|
||||
|
||||
<style type="text/css" media="all">
|
||||
/* <![CDATA[ */
|
||||
@import url("https://example.com/wp-content/items/style-tag-import/css/plugin.css?ver=1.9.4");
|
||||
@import url("https://example.com/wp-content/items/style-tag-import/css/datatables.css?ver=1.9.4");
|
||||
/* ]]> */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="top">
|
||||
<div class="header">
|
||||
<h1 class="logo">
|
||||
Blablabla the following plugin should not match : /wp-content/items/this-plugin-should-not-match/sub.css
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script type='text/javascript' src='//wp-content/items/detect-me-5/main.js'></script>
|
||||
|
||||
<script type='text/javascript'>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://example.com/wp-content/items/detect-me-6/assets/js/vendor/html5shiv.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<style type="text/css">
|
||||
#fancybox-loading.fancybox-ie div {
|
||||
background: transparent;
|
||||
filter: AlphaImageLoader(src='http://example.com/wp-content/items/detect-me-7/fancybox/fancy_loading.png', sizingMethod='scale');
|
||||
}
|
||||
</style>
|
||||
|
||||
<style type="text/css" media="all">
|
||||
/* <![CDATA[ */
|
||||
var pollsL10n = {"ajax_url": "http:\/\/example.com\/wp-content\/items\/escaped-url\/wp-polls.php", "text_wait": "Your last request is still being processed. Please wait a while ...", "text_valid": "Please choose a valid poll answer.", "text_multiple": "Maximum number of choices allowed: ", "show_loading": "1", "show_fading": "1"};
|
||||
@import url("https://example.com/wp-content/items/detect-me-8/css/plugin.css?ver=1.9.4");
|
||||
@import url('/wp-content/items/detect-me-9/css/datatables.css?ver=1.9.4');
|
||||
@import url(/wp-content/items/detect-me-10/css/datatables.css?ver=1.9.4);
|
||||
@import url(//wp-content/items/detect-me-11/css/datatables.css?ver=1.9.4);
|
||||
/* ]]> */
|
||||
</script>
|
||||
<script type='text/javascript' src='http://platform.twitter.com/widgets.js?ver=1.0.0'></script>
|
||||
</style>
|
||||
|
||||
<!-- a duplicate one -->
|
||||
<script type='text/javascript'
|
||||
src='http://example.com/wp-content/items/script-tag/s2member-o.php?ws_plugin__s2member_js_w_globals=1'></script>
|
||||
</html>
|
||||
<script type='text/javascript'>
|
||||
/* <![CDATA[ */
|
||||
var poll1 = {"ajax_url": "http:\/\/example.com\/wp-content\/items\/detect-me-12\/wp-polls.php", "text_wait": "Please wait a while ..."};
|
||||
var poll2 = {"ajax_url": "\/wp-content\/items\/detect-me-13\/wp-polls.php", "text_wait": "Please wait a while ..."};
|
||||
var poll3 = {"ajax_url": "\/\/wp-content\/items\/detect-me-14\/wp-polls.php", "text_wait": "Please wait a while ..."};
|
||||
/* ]]> */
|
||||
</script>
|
||||
|
||||
<!-- Items that should not be detected -->
|
||||
http://example.com/wp-content/items/this-should-not-match/sub.css
|
||||
href="http://example.com/wp-content/items/this-should-not-match/sub.css"
|
||||
/wp-content/items/this-should-not-match/sub.css
|
||||
//wp-content/items/this-should-not-match/sub.css
|
||||
src='/wp-content/items/this-should-not-match/sub.css'
|
||||
|
||||
<script type="text/javascript">
|
||||
var TB_pluginPath = 'http://www.welovebug.com/wp-content/items/js-source';
|
||||
var TB_config = { 'widget_show_photos': true }
|
||||
</script>
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
<link rel="alternate" type="application/atom+xml" title="Example Atom Feed" href="http://example.com/feed/atom"/>
|
||||
<link rel="pingback" href="http://example.com/xmlrpc.php"/>
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="http://example.localhost/wp-content/themes/theme1/style.css"/>
|
||||
<link type="text/css" rel="stylesheet" href="http://example.localhost/wp-content/themes/theme 2/javascript.js"/>
|
||||
<link type="text/css" rel="stylesheet" href="http://example.localhost/wp-content/themes/theme-3/test.png"/>
|
||||
<link type="text/css" rel="stylesheet" href="http://example.com/wp-content/themes/theme1/style.css"/>
|
||||
<link type="text/css" rel="stylesheet" href="http://example.com/wp-content/themes/theme 2/javascript.js"/>
|
||||
<link type="text/css" rel="stylesheet" href="http://example.com/wp-content/themes/theme-3/test.png"/>
|
||||
|
||||
<style type="text/css" media="all">
|
||||
/* <![CDATA[ */
|
||||
|
||||
Reference in New Issue
Block a user