杂谈
之前看到有热心网友分享了一个溯源小技巧,很多热心网友使用代理时,可能都会忽略的问题,那就是没有禁止UDP协议中的STUN,这种情况极大程度上会造成你的真实IP地址泄露
相关阅读
效果演示
你只需要访问上面的页面,就可以获取到自己IP的使用情况了,包括
- 服务器端通过XFF头或者CDN上获取的你的IP地址
- 通过WebRTC获取的你的IP地址
![图片[1]-WebRTC疑似可以获取你的真实IP地址 | 在线检测工具 附源码-FancyPig's blog](https://static.iculture.cc/wp-content/uploads/2023/04/20230419053737760.png?x-oss-process=image/auto-orient,1/format,webp/watermark,image_cHVibGljL2xvZ28ucG5nP3gtb3NzLXByb2Nlc3M9aW1hZ2UvcmVzaXplLFBfMTA,x_10,y_10)
至于第一行为什么会和第三行出现不一致的情况,那就是取决于你使用代理时的模式了
比方说规则模式出现这样的情况是很正常的,如果是全局模式,通常情况下这两者会是一致的
在上面我们分享的文章中,里面有讲解到一些防止WebRTC获取到源IP地址的方式,譬如在IOS的🚀软件中,通常,你需要设置-UDP-禁用STUN,默认情况下,这个选项是不被禁用的,因此,你在手机上浏览一些内容时,恰巧服务端又是使用WebRTC获取的IP地址,那么,你很有可能会被记录到真实的IP地址,导致最终被溯源
![图片[2]-WebRTC疑似可以获取你的真实IP地址 | 在线检测工具 附源码-FancyPig's blog](https://static.iculture.cc/wp-content/uploads/2023/04/20230419053939628.png?x-oss-process=image/auto-orient,1/format,webp/watermark,image_cHVibGljL2xvZ28ucG5nP3gtb3NzLXByb2Nlc3M9aW1hZ2UvcmVzaXplLFBfMTA,x_10,y_10)
让ChatGPT写一个WebRTC的获取代码
- 功能实现
- 页面优化
![图片[3]-WebRTC疑似可以获取你的真实IP地址 | 在线检测工具 附源码-FancyPig's blog](https://static.iculture.cc/wp-content/uploads/2023/04/20230419054827868.png?x-oss-process=image/auto-orient,1/format,webp/watermark,image_cHVibGljL2xvZ28ucG5nP3gtb3NzLXByb2Nlc3M9aW1hZ2UvcmVzaXplLFBfMTA,x_10,y_10)
页面设计优化
![图片[4]-WebRTC疑似可以获取你的真实IP地址 | 在线检测工具 附源码-FancyPig's blog](https://static.iculture.cc/wp-content/uploads/2023/04/20230419055003568.png?x-oss-process=image/auto-orient,1/format,webp/watermark,image_cHVibGljL2xvZ28ucG5nP3gtb3NzLXByb2Nlc3M9aW1hZ2UvcmVzaXplLFBfMTA,x_10,y_10)
代码部署
当然,你如果也想部署一个类似于这样的蜜罐,也可以使用下面的代码
- get_real_ip.php 用于获取XFF、CDN的IP
- index.html 前端界面
get_real_ip.php
<?php
function getUserIP() {
$ip = '';
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
return $ip;
}
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
$ip = getUserIP();
echo json_encode(['ip' => $ip]);
?>
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Get IP Addresses</title>
<link rel="stylesheet" href="https://unpkg.com/element-ui@2.15.6/lib/theme-chalk/index.css">
<script src="https://unpkg.com/vue@2.6.14"></script>
<script src="https://unpkg.com/element-ui@2.15.6/lib/index.js"></script>
</head>
<body>
<div id="app">
<el-container>
<el-header>
<h1>Your IP Addresses:</h1>
</el-header>
<el-main>
<el-table :data="ipAddresses" style="width: 100%" border>
<el-table-column prop="type" label="Type" width="180"></el-table-column>
<el-table-column prop="address" label="IP Address"></el-table-column>
</el-table>
</el-main>
</el-container>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
ipAddresses: [
{ type: 'XFF or CDN IP Address', address: 'Loading...' },
{ type: 'WebRTC Local IP Address', address: 'Loading...' },
{ type: 'WebRTC IPv4 Address', address: 'Loading...' },
{ type: 'WebRTC IPv6 Address', address: 'Loading...' }
]
};
},
mounted() {
// Fetch XFF or CDN IP address
const xhr = new XMLHttpRequest();
xhr.open('GET', 'get_real_ip.php', true);
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
const jsonResponse = JSON.parse(xhr.responseText);
this.ipAddresses[0].address = jsonResponse.ip;
}
};
xhr.send();
// WebRTC IPs
const iceServers = [
{ urls: 'stun:stun.l.google.com:19302' },
{ urls: 'stun:stun1.l.google.com:19302' },
{ urls: 'stun:stun2.l.google.com:19302' },
{ urls: 'stun:stun3.l.google.com:19302' },
{ urls: 'stun:stun4.l.google.com:19302' },
];
// getUserIPs function
function getUserIPs(callback) {
const myPeerConnection = new RTCPeerConnection({ iceServers });
myPeerConnection.createDataChannel("");
myPeerConnection.createOffer().then(offer => myPeerConnection.setLocalDescription(offer));
myPeerConnection.onicecandidate = function(event) {
if (event.candidate) {
const parts = event.candidate.candidate.split(' ');
const ip = parts[4];
callback(ip);
}
};
}
getUserIPs((ip) => {
// ... (same as before)
const ipv4Regex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
const ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}(([0-9a-fA-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]))|([0-9a-fA-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]))$/;
if (ipv4Regex.test(ip)) {
this.ipAddresses[2].address = ip;
} else if (ipv6Regex.test(ip)) {
this.ipAddresses[3].address = ip;
} else {
this.ipAddresses[1].address = ip;
}
});
}
});
</script>
</body>
</html>
© 版权声明
THE END
- 最新
- 最热
只看作者