Skip to content
This repository has been archived by the owner on Aug 4, 2021. It is now read-only.

Commit

Permalink
Merge pull request #15 from sergejmueller/0.5.2
Browse files Browse the repository at this point in the history
v0.5.2
  • Loading branch information
sergejmueller authored Jul 22, 2016
2 parents b3a3ead + 6f9c2aa commit 346ba1d
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 70 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
### v0.5.2 (2016-07-22)

##### Changes
* Core: Add new library [finder.js](lib/finder.js) with file system functions
* Core: Refactor [app.js](lib/app.js) in association with [finder.js](lib/finder.js)
* Core: Remove `makeAbsolute` function from [helpers.js](lib/helpers.js)
* package.json: Add `npm outdated` to `npm test`
* Readme: Add *Features* part
* Readme: More text changes


### v0.5.1 (2016-07-21)

##### Changes
Expand Down
42 changes: 29 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
wpscan
============

`wpscan` [Node.js module](https://www.npmjs.com/package/wpscan) allows you to quickly scan a WordPress site looking for known vulnerabilities, security issues and misconfigurations. `wpscan` helps you secure and maintain your WordPress against hackers.
`wpscan` [Node.js module](https://www.npmjs.com/package/wpscan) allows you to quickly scan WordPress sites looking for known vulnerabilities, security issues and misconfigurations. `wpscan` helps you secure and maintain your WordPress against hackers.

Beginner friendly. Easy to install. Supports custom rules. **Work in progress**, see [todos](TODO.md) and [changelog](CHANGELOG.md).

Expand All @@ -11,13 +11,29 @@ Beginner friendly. Easy to install. Supports custom rules. **Work in progress**,
[![Known Vulnerabilities](https://snyk.io/test/github/sergejmueller/wpscan/badge.svg)](https://snyk.io/test/github/sergejmueller/wpscan)


Install
Features
-----
- [Preinstalled rules](#default-rules) for a quick start.
- [Custom rules](#custom-rules) increases the functionality.
- [Selective ignoring](#ignore-rules) default and custom rules.
- Multiple WordPress scans from a [bulk file](#bulk-scan).
- Detection for
- WordPress directories (`wp-content`, ...).
- WordPress installed in a subdirectory.
- Changeable User-Agent string.
- Silent mode displays warnings only.
- Beginner friendly, easy to install.
- Lightweight, cross plattform framework.


Install
-----
```
[sudo] npm install --global wpscan
```

`wpscan` requires `Node.js >= 4` and [npm](http://blog.npmjs.org/post/85484771375/how-to-install-npm).


Usage
-----
Expand All @@ -37,10 +53,10 @@ Option | Shortcut | Description
------ | -------- | -----------
`--help` | `-h` | Outputs supplied help text.
`--silent` | `-s` | Disables success and info messages. Displays warnings only.
`--rules-dir` | `-r` | Loads additional rules from a directory (see below).
`--bulk-file` | `-b` | Reads additional WordPress site URLs from a text file (see below).
`--rules-dir` | `-r` | Loads additional rules from a directory (see [Custom rules](#custom-rules)).
`--bulk-file` | `-b` | Reads additional WordPress site URLs from a text file (see [Bulk scan](#bulk-scan)).
`--ignore-rule` | `-i` | Skips loading and execution of a specific rule (see [Ignore rules](#ignore-rules)).
`--user-agent` | `-u` | Defines a custom `User-Agent` string. Default is `wpscan`.
`--ignore-rule` | `-i` | Skips loading and execution of a specific rule (see below).


Quick examples
Expand Down Expand Up @@ -101,23 +117,23 @@ exports.fire = function( data ) {
- [wpscan default rules](lib/rules)


Bulk scan
Ignore rule(s)
-----
Multiple WordPress site URLs can be imported from a single file. This is a simple text file with one URL per line.
`wpscan` can skip certain [default](lib/rules) and custom rules. The CLI option `--ignore-rule` takes a rule name, the rule name is the JavaScript file name of the rule without path. Multiple rule filtering is possible by a multiple use of the CLI option.

```bash
wpscan -b ~/path/to/sources.txt
wpscan ma.tt --ignore-rule wp-login.js
wpscan ma.tt --ignore-rule wp-login.js --ignore-rule files-exists.js
wpscan ma.tt --rules-dir ./example/rules --ignore-rule custom-rule.js
```


Ignore rule(s)
Bulk scan
-----
`wpscan` can skip certain [default](lib/rules) and custom rules. The CLI option `--ignore-rule` takes a rule name, the rule name is the JavaScript file name of the rule without path. Multiple rule filtering is possible by a multiple use of the CLI option.
Multiple WordPress site URLs can be imported from a single file. This is a simple text file with one URL per line.

```bash
wpscan ma.tt --ignore-rule wp-login.js
wpscan ma.tt --ignore-rule wp-login.js --ignore-rule files-exists.js
wpscan ma.tt --rules-dir ./example/rules --ignore-rule custom-rule.js
wpscan -b ~/path/to/sources.txt
```


Expand Down
56 changes: 20 additions & 36 deletions lib/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ require( 'helpers' );

const
// npm modules
fs = require( 'fs' ),
path = require( 'path' ),
request = require( 'request' ).defaults( { timeout: 9999 } ),

// app modules
log = require( 'log' ),
finder = require( 'finder' ),

// app config
config = require( '../config/app.json' );
Expand All @@ -30,25 +29,21 @@ module.exports.wpscan = function( data ) {

// Sources from bulk file
if ( data['bulk-file'] ) {
data['bulk-file'] = data['bulk-file'].makeAbsolute();

try {
if ( fs.statSync( data['bulk-file'] ).isFile() ) {
sources = sources.concat(
fs.readFileSync( data['bulk-file'] ).toString().split("\n").filter(Boolean)
);
}
sources = sources.concat(
finder.readFileLines( data['bulk-file'] )
);
} catch( error ) {
log.warn( error );
}
}

// Loop sources
sources.forEach( function( siteURL ) {
sources.forEach( function( url ) {

fire( {
'wpURL': siteURL,
'siteURL': siteURL,
'wpURL': url,
'siteURL': url,
'rulesDir': data['rules-dir'],
'userAgent': data['user-agent'],
'ignoreRule': data['ignore-rule'],
Expand Down Expand Up @@ -255,46 +250,35 @@ function extractWpURL( data ) {

function loadRules( data ) {

// Init rules dirs
var dirs = [ config.rulesDir.makeAbsolute() ];
// Default rules dir
var dirPaths = [ config.rulesDir ];

// Handle custom rules dir
// Custom rules dir
if ( data.rulesDir ) {
data.rulesDir = data.rulesDir.makeAbsolute();

try {
if ( fs.statSync( data.rulesDir ).isDirectory() ) {
dirs.push( data.rulesDir );
}
} catch( error ) {
log.warn( error );
}
dirPaths.push( data.rulesDir );
}

// Loop available paths
dirs.forEach( function( dir ) {
// Loop available dirs
dirPaths.forEach( function( dirPath ) {

fs.readdir( dir, function( error, files ) {
finder.readDir( dirPath, function( error, filePaths ) {

if ( error ) {
return log.warn( error );
}

files.map( function( file ) {
filePaths.map( function( filePath ) {

return path.join( dir, file );
return finder.joinPaths( dirPath, filePath );

} ).filter( function( file ) {
} ).filter( function( filePath ) {

return fs.statSync( file ).isFile() &&
( path.extname( file ) === '.js' ) &&
( ! data.ignoreRule.includes( path.basename( file ) ) );
return finder.isFile( filePath, '.js' ) && ! finder.isBlacklistedFile( filePath, data.ignoreRule );

} ).forEach( function( file ) {
} ).forEach( function( filePath ) {

// Require & start rule
try {
require( file ).fire( data );
finder.requireFile( filePath ).fire( data );
} catch( error ) {
return log.warn( error );
}
Expand Down
149 changes: 149 additions & 0 deletions lib/finder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
'use strict';


const finder = {}
const fs = require( 'fs' )
const path = require('path')


/**
* Checks whether the file path is a regular file
*
* @param {String} filePath File name
* @param {String} fileExt File extension
* @return {Boolean} True if a valid file
*/

finder.isFile = ( filePath, fileExt ) => {

if ( ! fs.statSync( finder.absolutePath( filePath ) ).isFile() ) {
return false;
}

if ( fileExt ) {
return path.extname( filePath ) === fileExt;
}

return true;

}


/**
* Checks whether the dirpath is a regular directory
*
* @param {String} dirPath Directory name
* @return {Boolean} True if a valid directory
*/

finder.isDir = ( dirPath ) => {

return fs.statSync( finder.absolutePath( dirPath ) ).isDirectory();

}


/**
* Reads and returns the content of a file
*
* @param {String} filePath File name
* @return {Mixed} File content
*/

finder.readFile = ( filePath ) => {

return fs.readFileSync( finder.absolutePath( filePath ) );

}


/**
* Reads the content of a directory
*
* @param {String} dirPath Directory name
* @param {String} callback Callback function
* @return {Object} Content object
*/

finder.readDir = ( dirPath, callback ) => {

fs.readdir( finder.absolutePath( dirPath ), callback );

}


/**
* Reads and returns content lines of a file
*
* @param {String} filePath File name
* @return {Array} Content lines
*/

finder.readFileLines = ( filePath ) => {
return finder.readFile( filePath ).toString().split( "\n" ).filter( Boolean )
}


/**
* Loads a module from a JavaScript file
*
* @param {String} filePath File name
* @return {Object} module.exports from the resolved module
*/

finder.requireFile = ( filePath ) => {

return require( finder.absolutePath( filePath ) );

}


/**
* Checks if a file is blacklisted
*
* @param {String} filePath File name
* @param {Array} blacklist Blacklisted items
* @return {Boolean} True if the file is blacklisted
*/

finder.isBlacklistedFile = ( filePath, blacklist ) => {

return blacklist.includes( path.basename( filePath ) );

}


/**
* Makes a path absolute
*
* @param {String} objPath Object path
* @return {String} Absolute path
*/

finder.absolutePath = ( objPath ) => {

if ( path.isAbsolute( objPath ) ) {
return objPath;
}

return path.join( __dirname, '..', objPath );

}


/**
* Join two paths
*
* @param {String} path1 First path
* @param {String} path2 Second path
* @return {String} Joined paths
*/

finder.joinPaths = ( path1, path2 ) => {

return path.join( path1, path2 );

}


module.exports = finder;
19 changes: 0 additions & 19 deletions lib/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

const
// npm modules
path = require('path'),
rtrim = require( 'rtrim' ),
prependHttp = require( 'prepend-http' ),
validUrl = require( 'valid-url' ).isWebUri;
Expand Down Expand Up @@ -69,21 +68,3 @@ Object.prototype.normalizeURL = function() {
return false;

};


/**
* Return absolute path
*
* @param void
* @return {String} Absolute path
*/

String.prototype.makeAbsolute = function() {

if ( path.isAbsolute( this ) ) {
return this;
}

return path.join( __dirname, '..', this );

};
Loading

0 comments on commit 346ba1d

Please sign in to comment.