From ed9268ca19d7454bf8c86b8c63bb823f0fb1bb1e Mon Sep 17 00:00:00 2001 From: Philip OKeefe Date: Sun, 17 Jul 2016 00:48:28 -0400 Subject: [PATCH] Adding the Laposte module --- README.md | 23 ++++++---- .../scala/fish/philwants/ModuleFactory.scala | 3 +- src/main/scala/fish/philwants/Runner.scala | 2 +- .../philwants/modules/LaposteModule.scala | 46 +++++++++++++++++++ .../fish/philwants/AmazonModuleTest.scala | 2 +- .../fish/philwants/LaposteModuleTest.scala | 19 ++++++++ .../fish/philwants/TestCredentials.scala | 4 ++ 7 files changed, 87 insertions(+), 12 deletions(-) create mode 100644 src/main/scala/fish/philwants/modules/LaposteModule.scala create mode 100644 src/test/scala/fish/philwants/LaposteModuleTest.scala diff --git a/README.md b/README.md index 6e19df2..8e34dbd 100644 --- a/README.md +++ b/README.md @@ -9,24 +9,26 @@ A command line tool to detect shared passwords List options: ``` -$ java -jar shard-1.3.jar --help -Shard 1.3 -Usage: java -jar shard-1.3.jar [options] +$ java -jar shard.jar --help +Shard 1.4 +Usage: java -jar shard-1.4.jar [options] -u, --username Username to test -p, --password Password to test -f, --file File containing a set of credentials --format The format of the credentials. Must be a regular expression with 2 capture groups. The first capture group for the username and the second capture group for the password. Defaults to a regex that will match: - "username":"password" + "username":"password" -l, --list List available modules - -v, --version Print the version + -v, --version Print the version + --modules Only run specific modules. A comma separated list --help prints this usage text + ``` List available modules: ``` bash -$ java -jar shard-1.3.jar -l +$ java -jar shard.jar -l Available modules: Facebook LinkedIn @@ -38,6 +40,7 @@ Available modules: Kijiji DigitalOcean Vimeo + Laposte ``` @@ -46,14 +49,14 @@ Available modules: Given a username and password shard will attempt to authenticate with multiple sites: ``` bash -$ java -jar shard-1.3.jar -u username-here -p password-here +$ java -jar shard-1.4.jar -u username-here -p password-here 21:16:25.950 [+] Running in single credential mode 21:16:30.302 [+] username-here:password-here - Reddit, Instagram ``` To test multiple credentials supply a filename. By default this expects one credential per line in the format `"username":"password"`. Custom formats can be supplied with the `--format` option ``` -$ java -jar shard-1.3.jar -f /tmp/creds.txt +$ java -jar shard.jar -f /tmp/creds.txt 21:16:39.501 [+] Running in multi-credential mode 21:16:39.516 [+] Parsed 2 credentials 21:16:42.794 [+] username1:password1 - Reddit, Instagram @@ -84,9 +87,11 @@ Dependencies: - JSoup is used for HTTP communication and HTML parsing - spray-json is used for handling json +If Scala is not your thing check out the secondary_implementations, these are rewrites of shard in other languages. If you add a module to one of these implementations I will rewrite in Scala and add it to the main project as well. + ## Bugs, Requests, and Feedback -Contact me or use this GitHub project +Contact me, join the [Gitter](https://gitter.im/philwantsfish/shard) room, or use this GitHub project diff --git a/src/main/scala/fish/philwants/ModuleFactory.scala b/src/main/scala/fish/philwants/ModuleFactory.scala index 8031e6c..8bff5da 100644 --- a/src/main/scala/fish/philwants/ModuleFactory.scala +++ b/src/main/scala/fish/philwants/ModuleFactory.scala @@ -13,6 +13,7 @@ object ModuleFactory { BitBucketModule, KijijiModule, DigitalOceanModule, - VimeoModule + VimeoModule, + LaposteModule ) } diff --git a/src/main/scala/fish/philwants/Runner.scala b/src/main/scala/fish/philwants/Runner.scala index 85b3248..2cb96e6 100644 --- a/src/main/scala/fish/philwants/Runner.scala +++ b/src/main/scala/fish/philwants/Runner.scala @@ -13,7 +13,7 @@ case class ValidCredentials(creds: Credentials, modules: Seq[AbstractModule]) object Runner extends LazyLogging { val defaultCredentialRegex = """"((?:\"|[^"])+)":"((?:\"|[^"])+)"""" - val versionNumber = "1.2" + val versionNumber = "1.4" def singleCredentialMode(username: String, password: String, moduleFilter: Seq[String]): Unit = { logger.info("Running in single credential mode") diff --git a/src/main/scala/fish/philwants/modules/LaposteModule.scala b/src/main/scala/fish/philwants/modules/LaposteModule.scala new file mode 100644 index 0000000..4eac363 --- /dev/null +++ b/src/main/scala/fish/philwants/modules/LaposteModule.scala @@ -0,0 +1,46 @@ +package fish.philwants.modules + +import fish.philwants.Credentials +import scala.collection.JavaConversions._ +import org.jsoup.nodes.FormElement + +object LaposteModule extends AbstractModule { + val uri = "https://laposte.net/" + val moduleName = "Laposte" + + def tryLogin(creds: Credentials): Boolean = { + val loginUri = "https://www.laposte.net/accueil" + val resp = get(loginUri) + .validateTLSCertificates(false) + .execute() + + // Parse the form the response + val form: FormElement = resp + .parse() + .select("form") + .first() + .asInstanceOf[FormElement] + + // Update the form data to include username and password + val usernameKey = "login" + val passwordKey = "password" + val formdata: Map[String, String] = form + .formData() + .map { e => e.key() -> e.value() } + .toMap + val updatedFormData = formdata + (usernameKey -> creds.username) + (passwordKey -> creds.password) + + // Send login request + val loginUri2 = "https://compte.laposte.net/login.do" + val loginResp = post(loginUri2) + .header("Content-Type", "application/x-www-form-urlencoded") + .data(updatedFormData) + .cookies(resp.cookies()) + .followRedirects(false) + .validateTLSCertificates(false) + .execute() + + // Check login result + loginResp.statusCode() == 302 + } +} diff --git a/src/test/scala/fish/philwants/AmazonModuleTest.scala b/src/test/scala/fish/philwants/AmazonModuleTest.scala index 0fae82b..f03213c 100644 --- a/src/test/scala/fish/philwants/AmazonModuleTest.scala +++ b/src/test/scala/fish/philwants/AmazonModuleTest.scala @@ -5,7 +5,7 @@ import org.scalatest.{FlatSpec, Matchers} import TestCredentials._ class AmazonModuleTest extends FlatSpec with Matchers { - "Amazon module" should "detect a successful login" in { + "Amazon module" should "detect a successful login" ignore { val creds = Credentials(AMAZON_USERNAME, AMAZON_PASSWORD) val mod = AmazonModule mod.tryLogin(creds) shouldBe true diff --git a/src/test/scala/fish/philwants/LaposteModuleTest.scala b/src/test/scala/fish/philwants/LaposteModuleTest.scala new file mode 100644 index 0000000..f1a5d64 --- /dev/null +++ b/src/test/scala/fish/philwants/LaposteModuleTest.scala @@ -0,0 +1,19 @@ +package fish.philwants + +import fish.philwants.modules.LaposteModule +import org.scalatest.{FlatSpec, Matchers} +import TestCredentials._ + +class LaposteModuleTest extends FlatSpec with Matchers { + "Laposte module" should "detect a successful login" in { + val creds = Credentials(LAPOSTE_USERNAME, LAPOSTE_PASSWORD) + val mod = LaposteModule + mod.tryLogin(creds) shouldBe true + } + + it should "detect a failed login" in { + val creds = Credentials(BAD_USERNAME_EMAIL, BAD_PASSWORD) + val mod = LaposteModule + mod.tryLogin(creds) shouldBe false + } +} diff --git a/src/test/scala/fish/philwants/TestCredentials.scala b/src/test/scala/fish/philwants/TestCredentials.scala index cc977e8..efbd18c 100644 --- a/src/test/scala/fish/philwants/TestCredentials.scala +++ b/src/test/scala/fish/philwants/TestCredentials.scala @@ -6,6 +6,7 @@ object TestCredentials { val GENERIC_USERNAME_EMAIL = ??? val GENERIC_USERNAME = ??? val GENERIC_PASSWORD = ??? + val GENERIC_PASSWORD_WITH_CAPITAL = ??? val FACEBOOK_USERNAME = GENERIC_USERNAME_EMAIL val FACEBOOK_PASSWORD = GENERIC_PASSWORD @@ -40,6 +41,9 @@ object TestCredentials { val VIMEO_USERNAME = GENERIC_USERNAME_EMAIL val VIMEO_PASSWORD = GENERIC_PASSWORD + val LAPOSTE_USERNAME = "shard.shardtesting@laposte.net" + val LAPOSTE_PASSWORD = GENERIC_PASSWORD_WITH_CAPITAL + val BAD_USERNAME_EMAIL = "shardtesting-bademail@gmail.com" val BAD_USERNAME = "shardtesting-badusername" val BAD_PASSWORD = "badpassword"