1595 lines
120 KiB
HTML
1595 lines
120 KiB
HTML
<!DOCTYPE html>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<html class="theme-next gemini use-motion" lang="zh-Hans">
|
||
<head><meta name="generator" content="Hexo 3.8.0">
|
||
<meta charset="UTF-8">
|
||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||
<meta name="theme-color" content="#222">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<meta http-equiv="Cache-Control" content="no-transform">
|
||
<meta http-equiv="Cache-Control" content="no-siteapp">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css">
|
||
|
||
<link href="/css/main.css?v=5.1.4" rel="stylesheet" type="text/css">
|
||
|
||
|
||
<link rel="apple-touch-icon" sizes="180x180" href="/images/hackerrank.png?v=5.1.4">
|
||
|
||
|
||
<link rel="icon" type="image/png" sizes="32x32" href="/images/hackerrank.png?v=5.1.4">
|
||
|
||
|
||
<link rel="icon" type="image/png" sizes="16x16" href="/images/hackerrank.png?v=5.1.4">
|
||
|
||
|
||
<link rel="mask-icon" href="/images/logo.svg?v=5.1.4" color="#222">
|
||
|
||
|
||
|
||
|
||
|
||
<meta name="keywords" content="小米,路由器,MiniUPnP,">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<meta name="description" content="概述HomePageOpenWRT与miniUPnP MiniUPnP项目提供了支持UPnP IGD(互联网网关设备)规范的软件。在MiniUPnPd中添加了NAT-PMP和PCP支持。 对于客户端(MiniUPnPc)使用libnatpmp来支持NAT-PMP。MiniUPnP守护程序(MiniUPnPd)支持OpenBSD,FreeBSD,NetBSD,DragonFly BSD(Open)">
|
||
<meta name="keywords" content="小米,路由器,MiniUPnP">
|
||
<meta property="og:type" content="article">
|
||
<meta property="og:title" content="小米路由器_MiniUPnP协议">
|
||
<meta property="og:url" content="https://cool-y.github.io/2019/04/21/XIAOMI-UPnP/index.html">
|
||
<meta property="og:site_name" content="混元霹雳手">
|
||
<meta property="og:description" content="概述HomePageOpenWRT与miniUPnP MiniUPnP项目提供了支持UPnP IGD(互联网网关设备)规范的软件。在MiniUPnPd中添加了NAT-PMP和PCP支持。 对于客户端(MiniUPnPc)使用libnatpmp来支持NAT-PMP。MiniUPnP守护程序(MiniUPnPd)支持OpenBSD,FreeBSD,NetBSD,DragonFly BSD(Open)">
|
||
<meta property="og:locale" content="zh-Hans">
|
||
<meta property="og:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555830377/paper/111.png">
|
||
<meta property="og:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555830425/paper/112.png">
|
||
<meta property="og:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555830465/paper/113.png">
|
||
<meta property="og:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555830499/paper/114.png">
|
||
<meta property="og:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555830533/paper/1133.png">
|
||
<meta property="og:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555830573/paper/115.png">
|
||
<meta property="og:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555830618/paper/1111.png">
|
||
<meta property="og:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555576753/paper/1.png">
|
||
<meta property="og:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555576810/paper/2.png">
|
||
<meta property="og:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555577220/paper/3.png">
|
||
<meta property="og:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555577719/paper/4.png">
|
||
<meta property="og:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555577820/paper/5.png">
|
||
<meta property="og:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555580242/paper/6.png">
|
||
<meta property="og:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555580904/paper/7.png">
|
||
<meta property="og:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555581152/paper/8.png">
|
||
<meta property="og:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555581385/paper/9.png">
|
||
<meta property="og:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555581672/paper/10.png">
|
||
<meta property="og:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555581840/paper/11.png">
|
||
<meta property="og:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555918880/paper/2231.png">
|
||
<meta property="og:updated_time" content="2019-07-11T01:51:28.743Z">
|
||
<meta name="twitter:card" content="summary">
|
||
<meta name="twitter:title" content="小米路由器_MiniUPnP协议">
|
||
<meta name="twitter:description" content="概述HomePageOpenWRT与miniUPnP MiniUPnP项目提供了支持UPnP IGD(互联网网关设备)规范的软件。在MiniUPnPd中添加了NAT-PMP和PCP支持。 对于客户端(MiniUPnPc)使用libnatpmp来支持NAT-PMP。MiniUPnP守护程序(MiniUPnPd)支持OpenBSD,FreeBSD,NetBSD,DragonFly BSD(Open)">
|
||
<meta name="twitter:image" content="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555830377/paper/111.png">
|
||
|
||
|
||
|
||
<script type="text/javascript" id="hexo.configurations">
|
||
var NexT = window.NexT || {};
|
||
var CONFIG = {
|
||
root: '/',
|
||
scheme: 'Gemini',
|
||
version: '5.1.4',
|
||
sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
|
||
fancybox: true,
|
||
tabs: true,
|
||
motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
|
||
duoshuo: {
|
||
userId: '0',
|
||
author: '博主'
|
||
},
|
||
algolia: {
|
||
applicationID: '',
|
||
apiKey: '',
|
||
indexName: '',
|
||
hits: {"per_page":10},
|
||
labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
|
||
|
||
<link rel="canonical" href="https://cool-y.github.io/2019/04/21/XIAOMI-UPnP/">
|
||
|
||
|
||
|
||
|
||
|
||
<title>小米路由器_MiniUPnP协议 | 混元霹雳手</title>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</head>
|
||
|
||
<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<div class="container sidebar-position-left page-post-detail">
|
||
<div class="headband"></div>
|
||
|
||
<header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
|
||
<div class="header-inner"><div class="site-brand-wrapper">
|
||
<div class="site-meta ">
|
||
|
||
|
||
<div class="custom-logo-site-title">
|
||
<a href="/" class="brand" rel="start">
|
||
<span class="logo-line-before"><i></i></span>
|
||
<span class="site-title">混元霹雳手</span>
|
||
<span class="logo-line-after"><i></i></span>
|
||
</a>
|
||
</div>
|
||
|
||
<p class="site-subtitle"></p>
|
||
|
||
</div>
|
||
|
||
<div class="site-nav-toggle">
|
||
<button>
|
||
<span class="btn-bar"></span>
|
||
<span class="btn-bar"></span>
|
||
<span class="btn-bar"></span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<nav class="site-nav">
|
||
|
||
|
||
|
||
<ul id="menu" class="menu">
|
||
|
||
|
||
<li class="menu-item menu-item-home">
|
||
<a href="/" rel="section">
|
||
|
||
<i class="menu-item-icon fa fa-fw fa-home"></i> <br>
|
||
|
||
首页
|
||
</a>
|
||
</li>
|
||
|
||
|
||
<li class="menu-item menu-item-about">
|
||
<a href="/about/" rel="section">
|
||
|
||
<i class="menu-item-icon fa fa-fw fa-user"></i> <br>
|
||
|
||
关于
|
||
</a>
|
||
</li>
|
||
|
||
|
||
<li class="menu-item menu-item-tags">
|
||
<a href="/tags/" rel="section">
|
||
|
||
<i class="menu-item-icon fa fa-fw fa-tags"></i> <br>
|
||
|
||
标签
|
||
</a>
|
||
</li>
|
||
|
||
|
||
<li class="menu-item menu-item-categories">
|
||
<a href="/categories/" rel="section">
|
||
|
||
<i class="menu-item-icon fa fa-fw fa-th"></i> <br>
|
||
|
||
分类
|
||
</a>
|
||
</li>
|
||
|
||
|
||
<li class="menu-item menu-item-archives">
|
||
<a href="/archives/" rel="section">
|
||
|
||
<i class="menu-item-icon fa fa-fw fa-archive"></i> <br>
|
||
|
||
归档
|
||
</a>
|
||
</li>
|
||
|
||
|
||
<li class="menu-item menu-item-bookmarks">
|
||
<a href="/bookmarks/" rel="section">
|
||
|
||
<i class="menu-item-icon fa fa-fw fa-map"></i> <br>
|
||
|
||
书签
|
||
</a>
|
||
</li>
|
||
|
||
|
||
<li class="menu-item menu-item-hack之外">
|
||
<a href="/hack之外/" rel="section">
|
||
|
||
<i class="menu-item-icon fa fa-fw fa-heartbeat"></i> <br>
|
||
|
||
HACK之外
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
<li class="menu-item menu-item-search">
|
||
|
||
<a href="javascript:;" class="popup-trigger">
|
||
|
||
|
||
<i class="menu-item-icon fa fa-search fa-fw"></i> <br>
|
||
|
||
搜索
|
||
</a>
|
||
</li>
|
||
|
||
</ul>
|
||
|
||
|
||
|
||
<div class="site-search">
|
||
|
||
<div class="popup search-popup local-search-popup">
|
||
<div class="local-search-header clearfix">
|
||
<span class="search-icon">
|
||
<i class="fa fa-search"></i>
|
||
</span>
|
||
<span class="popup-btn-close">
|
||
<i class="fa fa-times-circle"></i>
|
||
</span>
|
||
<div class="local-search-input-wrapper">
|
||
<input autocomplete="off" placeholder="搜索..." spellcheck="false" type="text" id="local-search-input">
|
||
</div>
|
||
</div>
|
||
<div id="local-search-result"></div>
|
||
</div>
|
||
|
||
|
||
|
||
</div>
|
||
|
||
</nav>
|
||
|
||
|
||
|
||
</div>
|
||
</header>
|
||
|
||
<main id="main" class="main">
|
||
<div class="main-inner">
|
||
<div class="content-wrap">
|
||
<div id="content" class="content">
|
||
|
||
|
||
<div id="posts" class="posts-expand">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
|
||
|
||
|
||
|
||
<div class="post-block">
|
||
<link itemprop="mainEntityOfPage" href="https://cool-y.github.io/2019/04/21/XIAOMI-UPnP/">
|
||
|
||
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
|
||
<meta itemprop="name" content="Cool-Y">
|
||
<meta itemprop="description" content>
|
||
<meta itemprop="image" content="/images/avatar.png">
|
||
</span>
|
||
|
||
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
|
||
<meta itemprop="name" content="混元霹雳手">
|
||
</span>
|
||
|
||
|
||
<header class="post-header">
|
||
|
||
|
||
|
||
<h1 class="post-title" itemprop="name headline">小米路由器_MiniUPnP协议</h1>
|
||
|
||
|
||
<div class="post-meta">
|
||
<span class="post-time">
|
||
|
||
<span class="post-meta-item-icon">
|
||
<i class="fa fa-calendar-o"></i>
|
||
</span>
|
||
|
||
<span class="post-meta-item-text">发表于</span>
|
||
|
||
<time title="创建于" itemprop="dateCreated datePublished" datetime="2019-04-21T14:51:45+08:00">
|
||
2019-04-21
|
||
</time>
|
||
|
||
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
<span class="post-category">
|
||
|
||
<span class="post-meta-divider">|</span>
|
||
|
||
<span class="post-meta-item-icon">
|
||
<i class="fa fa-folder-o"></i>
|
||
</span>
|
||
|
||
<span class="post-meta-item-text">分类于</span>
|
||
|
||
|
||
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
|
||
<a href="/categories/IOT/" itemprop="url" rel="index">
|
||
<span itemprop="name">IOT</span>
|
||
</a>
|
||
</span>
|
||
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<span id="/2019/04/21/XIAOMI-UPnP/" class="leancloud_visitors" data-flag-title="小米路由器_MiniUPnP协议">
|
||
<span class="post-meta-divider">|</span>
|
||
<span class="post-meta-item-icon">
|
||
<i class="fa fa-eye"></i>
|
||
</span>
|
||
|
||
<span class="post-meta-item-text">阅读次数:</span>
|
||
|
||
<span class="leancloud-visitors-count"></span>
|
||
</span>
|
||
|
||
|
||
|
||
|
||
|
||
<div class="post-wordcount">
|
||
|
||
|
||
<span class="post-meta-item-icon">
|
||
<i class="fa fa-file-word-o"></i>
|
||
</span>
|
||
|
||
<span title="字数统计">
|
||
6k 字
|
||
</span>
|
||
|
||
|
||
|
||
<span class="post-meta-divider">|</span>
|
||
|
||
|
||
|
||
<span class="post-meta-item-icon">
|
||
<i class="fa fa-clock-o"></i>
|
||
</span>
|
||
|
||
<span title="阅读时长">
|
||
27 分钟
|
||
</span>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
</div>
|
||
</header>
|
||
|
||
|
||
|
||
|
||
|
||
<div class="post-body" itemprop="articleBody">
|
||
|
||
|
||
|
||
|
||
|
||
<h1 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h1><p><a href="http://miniupnp.free.fr/" target="_blank" rel="noopener">HomePage</a><br><a href="https://openwrt.org/docs/guide-user/firewall/upnp/miniupnpd" target="_blank" rel="noopener">OpenWRT与miniUPnP</a></p>
|
||
<blockquote>
|
||
<p>MiniUPnP项目提供了支持UPnP IGD(互联网网关设备)规范的软件。<br>在MiniUPnPd中添加了NAT-PMP和PCP支持。 对于客户端(MiniUPnPc)使用libnatpmp来支持NAT-PMP。<br>MiniUPnP守护程序(MiniUPnPd)支持OpenBSD,FreeBSD,NetBSD,DragonFly BSD(Open)Solaris和Mac OS X以及pf或ipfw(ipfirewall)或ipf和Linux with netfilter。 MiniUPnP客户端(MiniUPnPc)和MiniSSDPd是便携式的,可以在任何POSIX系统上运行。 MiniUPnPc也适用于MS Windows和AmigaOS(版本3和4)。</p>
|
||
</blockquote>
|
||
<p><a href="https://2014.ruxcon.org.au/assets/2014/slides/rux-soap_upnp_ruxcon2014.pptx" target="_blank" rel="noopener">https://2014.ruxcon.org.au/assets/2014/slides/rux-soap_upnp_ruxcon2014.pptx</a><br><a href="https://www.akamai.com/us/en/multimedia/documents/white-paper/upnproxy-blackhat-proxies-via-nat-injections-white-paper.pdf" target="_blank" rel="noopener">https://www.akamai.com/us/en/multimedia/documents/white-paper/upnproxy-blackhat-proxies-via-nat-injections-white-paper.pdf</a><br><a href="https://www.defcon.org/images/defcon-19/dc-19-presentations/Garcia/DEFCON-19-Garcia-UPnP-Mapping.pdf" target="_blank" rel="noopener">https://www.defcon.org/images/defcon-19/dc-19-presentations/Garcia/DEFCON-19-Garcia-UPnP-Mapping.pdf</a></p>
|
||
<h2 id="UPnP-IGD客户端轻量级库和UPnP-IGD守护进程"><a href="#UPnP-IGD客户端轻量级库和UPnP-IGD守护进程" class="headerlink" title="UPnP IGD客户端轻量级库和UPnP IGD守护进程"></a>UPnP IGD客户端轻量级库和UPnP IGD守护进程</h2><p>大多数家庭adsl /有线路由器和Microsoft Windows 2K/XP都支持UPnP协议。 MiniUPnP项目的目标是提供一个免费的软件解决方案来支持协议的“Internet网关设备”部分。</p>
|
||
<blockquote>
|
||
<p>用于UPnP设备的Linux SDK(libupnp)对我来说似乎太沉重了。 我想要最简单的库,占用空间最小,并且不依赖于其他库,例如XML解析器或HTTP实现。 所有代码都是纯ANSI C.</p>
|
||
</blockquote>
|
||
<p>miniupnp客户端库在x86 PC上编译,代码大小不到50KB。<br>miniUPnP守护程序比任何其他IGD守护程序小得多,因此非常适合在低内存设备上使用。 它也只使用一个进程而没有其他线程,不使用任何system()或exec()调用,因此保持系统资源使用率非常低。<br>该项目分为两个主要部分:</p>
|
||
<ul>
|
||
<li>MiniUPnPc,客户端库,使应用程序能够访问网络上存在的UPnP“Internet网关设备”提供的服务。 在UPnP术语中,MiniUPnPc是UPnP控制点。</li>
|
||
<li>MiniUPnPd,一个守护进程,通过作为网关的linux或BSD(甚至Solaris)为您的网络提供这些服务。 遵循UPnP术语,MiniUPnPd是UPnP设备。<br>开发MiniSSDPd与MiniUPnPc,MiniUPnPd和其他协作软件一起工作:1. MiniSSDPd监听网络上的SSDP流量,因此MiniUPnPc或其他UPnP控制点不需要执行发现过程,并且可以更快地设置重定向; 2. MiniSSDPd还能够代表MiniUPnPd或其他UPnP服务器软件回复M-SEARCH SSDP请求。 这对于在同一台机器上托管多个UPnP服务很有用。<br>守护进程现在也可以使用netfilter用于linux 2.4.x和2.6.x. 可以使它在运行OpenWRT的路由器设备上运行。<br>由于某些原因,直接使用MiniUPnP项目中的代码可能不是一个好的解决方案。<br>由于代码很小且易于理解,因此为您自己的UPnP实现提供灵感是一个很好的基础。 C ++中的<a href="http://ktorrent.org/" target="_blank" rel="noopener">KTorrent</a> UPnP插件就是一个很好的例子。</li>
|
||
</ul>
|
||
<h2 id="MiniUPnP客户端库的实用性"><a href="#MiniUPnP客户端库的实用性" class="headerlink" title="MiniUPnP客户端库的实用性"></a>MiniUPnP客户端库的实用性</h2><p>只要应用程序需要侦听传入的连接,MiniUPnP客户端库的使用就很有用。例如:P2P应用程序,活动模式的FTP客户端,IRC(用于DCC)或IM应用程序,网络游戏,任何服务器软件。</p>
|
||
<ul>
|
||
<li>路由器的UPnP IGD功能的典型用法是使用MSN Messenger的文件传输。 MSN Messenger软件使用Windows XP的UPnP API打开传入连接的端口。 为了模仿MS软件,最好也使用UPnP。</li>
|
||
<li>已经为XChat做了一个补丁,以展示应用程序如何使用miniupnp客户端库。</li>
|
||
<li>传输,一个免费的软件BitTorrent客户端正在使用miniupnpc和libnatpmp。</li>
|
||
</ul>
|
||
<h2 id="MiniUPnP守护进程的实用性"><a href="#MiniUPnP守护进程的实用性" class="headerlink" title="MiniUPnP守护进程的实用性"></a>MiniUPnP守护进程的实用性</h2><p>UPnP和NAT-PMP用于改善NAT路由器后面的设备的互联网连接。 诸如游戏,IM等的任何对等网络应用可受益于支持UPnP和/或NAT-PMP的NAT路由器。最新一代的Microsoft XBOX 360和Sony Playstation 3游戏机使用UPnP命令来启用XBOX Live服务和Playstation Network的在线游戏。 据报道,MiniUPnPd正在与两个控制台正常工作。 它可能需要一个精细的配置调整。</p>
|
||
<h2 id="安全"><a href="#安全" class="headerlink" title="安全"></a>安全</h2><p>UPnP实施可能会受到安全漏洞的影响。 错误执行或配置的UPnP IGD易受攻击。 安全研究员HD Moore做了很好的工作来揭示现有实施中的漏洞:<a href="http://hdm.io/writing/originals/SecurityFlawsUPnP.pdf" target="_blank" rel="noopener">通用即插即用(PDF)中的安全漏洞</a>。 一个常见的问题是让SSDP或HTTP/SOAP端口对互联网开放:它们应该只能从LAN访问。</p>
|
||
<h1 id="协议栈"><a href="#协议栈" class="headerlink" title="协议栈"></a>协议栈</h1><p>工作流程<br><img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555830377/paper/111.png" alt></p>
|
||
<p>Linux体系结构<br><img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555830425/paper/112.png" alt></p>
|
||
<h2 id="发现"><a href="#发现" class="headerlink" title="发现"></a>发现</h2><p><img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555830465/paper/113.png" alt><br>给定一个IP地址(通过DHCP获得),UPnP网络中的第一步是发现。<br>当一个设备被加入到网络中并想知道网络上可用的UPnP服务时,UPnP检测协议允许该设备向控制点广播自己的服务。通过UDP协议向端口1900上的多播地址239.255.255.250发送发现消息。此消息包含标头,类似于HTTP请求。此协议有时称为HTTPU(HTTP over UDP):<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">M-SEARCH * HTTP / 1.1</span><br><span class="line">主机:239.255.255.250 :1900</span><br><span class="line">MAN:ssdp:discover</span><br><span class="line">MX:10</span><br><span class="line">ST:ssdp:all</span><br></pre></td></tr></table></figure></p>
|
||
<p>所有其他UPnP设备或程序都需要通过使用UDP单播将类似的消息发送回设备来响应此消息,并宣布设备或程序实现哪些UPnP配置文件。对于每个配置文件,它实现一条消息发送:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">HTTP / 1.1 200 OK</span><br><span class="line">CACHE-CONTROL:max-age = 1800</span><br><span class="line">EXT:</span><br><span class="line">LOCATION:http://10.0.0.138:80 / IGD.xml</span><br><span class="line">SERVER:SpeedTouch 510 4.0.0.9.0 UPnP / 1.0(DG233B00011961)</span><br><span class="line">ST:urn:schemas-upnp-org:service:WANPPPConnection:1</span><br><span class="line">USN:uuid:UPnP-SpeedTouch510 :: urn:schemas-upnp-org:service:WANPPPConnection:1</span><br></pre></td></tr></table></figure></p>
|
||
<p>类似地,当一个控制点加入到网络中的时候,它也能够搜索到网络中存在的、感兴趣的设备相关信息。这两种类型的基础交互是一种仅包含少量、重要相关设备信息或者它的某个服务。比如,类型、标识和指向更详细信息的链接。<br>UPnP检测协议是 <strong><em>基于简单服务发现协议(SSDP)</em></strong> 的。</p>
|
||
<h2 id="描述"><a href="#描述" class="headerlink" title="描述"></a>描述</h2><p>UPnP网络的下一步是描述。当一个控制点检测到一个设备时,它对该设备仍然知之甚少。为了使控制点了解更多关于该设备的信息或者和设备进行交互,控制点必须从设备发出的检测信息中包含的URL获取更多的信息。<br><img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555830499/paper/114.png" alt><br>某个设备的UPnP描述是 <strong>XML</strong> 的方式,通过http协议,包括品牌、厂商相关信息,如型号名和编号、序列号、厂商名、品牌相关URL等。描述还包括一个嵌入式设备和服务列表,以及控制、事件传递和存在相关的URL。对于每种设备,描述还包括一个命令或动作列表,包括响应何种服务,针对各种动作的参数;这些变量描述出运行时设备的状态信息,并通过它们的数据类型、范围和事件来进行描述。</p>
|
||
<h2 id="控制"><a href="#控制" class="headerlink" title="控制"></a>控制</h2><p><img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555830533/paper/1133.png" alt><br>UPnP网络的下一步是控制。当一个控制点获取到设备描述信息之后,它就可以向该设备发送指令了。为了实现此,控制点发送一个合适的控制消息至服务相关控制URL(包含在设备描述中)。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><service></span><br><span class="line"> <serviceType> urn:schemas-upnp-org:service:WANPPPConnection:1 </ serviceType></span><br><span class="line"> <serviceId> urn:upnp-org: serviceId:wanpppc:pppoa </ serviceId></span><br><span class="line"> <controlURL> / upnp / control / wanpppcpppoa </ controlURL></span><br><span class="line"> <eventSubURL> / upnp / event / wanpppcpppoa </ eventSubURL></span><br><span class="line"> <SCPDURL> /WANPPPConnection.xml </ SCPDURL></span><br><span class="line"></ service></span><br></pre></td></tr></table></figure></p>
|
||
<p>要发送SOAP请求,只需要controlURL标记内的URL。控制消息也是通过 <strong><em>简单对象访问协议(SOAP)</em></strong> 用XML来描述的。类似函数调用,服务通过返回动作相关的值来回应控制消息。动作的效果,如果有的话,会反应在用于刻画运行中服务的相关变量。</p>
|
||
<h2 id="事件通知"><a href="#事件通知" class="headerlink" title="事件通知"></a>事件通知</h2><p>下一步是事件通知。UPnP中的事件 <strong><em>协议基于GENA</em></strong> 。一个UPnP描述包括一组命令列表和刻画运行时状态信息的变量。服务在这些变量改变的时候进行更新,控制点可以进行订阅以获取相关改变。<br><img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555830573/paper/115.png" alt><br>服务通过发送事件消息来发布更新。事件消息包括一个或多个状态信息变量以及它们的当前数值。这些消息也是采用XML的格式,用通用事件通知体系进行格式化。一个特殊的初始化消息会在控制点第一次订阅的时候发送,它包括服务相关的变量名及值。为了支持多个控制点并存的情形,事件通知被设计成对于所有的控制点都平行通知。因此,所有的订阅者同等地收到所有事件通知。<br>当状态变量更改时,新状态将发送到已订阅该事件的所有程序/设备。程序/设备可以通过eventSubURL来订阅服务的状态变量,该URL可以在LOCATION指向的URL中找到。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><service></span><br><span class="line"> <serviceType> urn:schemas-upnp-org:service:WANPPPConnection:1 </ serviceType></span><br><span class="line"> <serviceId> urn:upnp-org:serviceId:wanpppc:pppoa </ serviceId></span><br><span class="line"> <controlURL> / upnp / control / wanpppcpppoa </ controlURL></span><br><span class="line"> <eventSubURL> / upnp / event / wanpppcpppoa <</span><br><span class="line"> <SCPDURL> /WANPPPConnection.xml </ SCPDURL></span><br><span class="line"></ service></span><br></pre></td></tr></table></figure></p>
|
||
<h2 id="展示"><a href="#展示" class="headerlink" title="展示"></a>展示</h2><p>最后一步是展示。如果设备带有存在URL,那么控制点可以通过它来获取设备存在信息,即在浏览器中加载URL,并允许用户来进行相关控制或查看操作。具体支持哪些操作则是由存在页面和设备完成的。<br><img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555830618/paper/1111.png" alt></p>
|
||
<h2 id="NAT穿透"><a href="#NAT穿透" class="headerlink" title="NAT穿透"></a>NAT穿透</h2><p>UPnP为NAT(网络地址转换)穿透带来了一个解决方案:<strong>互联网网关设备协议(IGD)</strong>。NAT穿透允许UPnP数据包在没有用户交互的情况下,无障碍的通过路由器或者防火墙(假如那个路由器或者防火墙支持NAT)。</p>
|
||
<h1 id="SOAP和UPnP"><a href="#SOAP和UPnP" class="headerlink" title="SOAP和UPnP"></a>SOAP和UPnP</h1><table>
|
||
<thead>
|
||
<tr>
|
||
<th>协议</th>
|
||
<th>全称</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>UPnP</td>
|
||
<td>Universal Plug and Play</td>
|
||
</tr>
|
||
<tr>
|
||
<td>SSDP</td>
|
||
<td>Simple Service Discovery Protocol</td>
|
||
</tr>
|
||
<tr>
|
||
<td>SCPD</td>
|
||
<td>Service Control Protocol Definition</td>
|
||
</tr>
|
||
<tr>
|
||
<td>SOAP</td>
|
||
<td>Simple Object Access Protocol</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<h2 id="UPnP-Discovery"><a href="#UPnP-Discovery" class="headerlink" title="UPnP - Discovery"></a>UPnP - Discovery</h2><p><img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555576753/paper/1.png" alt></p>
|
||
<h2 id="UPnP-–-Description"><a href="#UPnP-–-Description" class="headerlink" title="UPnP – Description"></a>UPnP – Description</h2><ul>
|
||
<li>XML文件通常托管在高位的TCP端口</li>
|
||
<li>版本信息<br>upnp.org spec<br>通常为1.0</li>
|
||
<li>设备定义<br>型号名和编号、序列号、厂商名、品牌相关URL<br>服务列表:服务类型;SCPD URL;Control URL;Event URL<br><img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555576810/paper/2.png" alt><h2 id="UPnP-–-SCPD"><a href="#UPnP-–-SCPD" class="headerlink" title="UPnP – SCPD"></a>UPnP – SCPD</h2></li>
|
||
<li>定义服务动作和参数的XML文件</li>
|
||
<li>版本信息<br>和描述一致</li>
|
||
<li>动作列表<br>动作名<br>参数:参数名、方向(输入输出)、变量名</li>
|
||
<li>变量列表<br>变量名、数据类型<br><img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555577220/paper/3.png" alt><h2 id="UPnP-–-Control"><a href="#UPnP-–-Control" class="headerlink" title="UPnP – Control"></a>UPnP – Control</h2></li>
|
||
<li>这里用到了SOAP</li>
|
||
<li>主要是RPC服务或CGI脚本的前端</li>
|
||
<li>SOAP封装<br>• XML格式的API调用<br>• 描述XML中的服务类型<br>• 来自SCPD XML的动作名称和参数</li>
|
||
<li>POST封装到control URL<br><img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555577719/paper/4.png" alt><h2 id="TL-DR"><a href="#TL-DR" class="headerlink" title="TL;DR"></a>TL;DR</h2><img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555577820/paper/5.png" alt><h2 id="好的一面"><a href="#好的一面" class="headerlink" title="好的一面"></a>好的一面</h2></li>
|
||
<li>Control AV equipment</li>
|
||
<li>Home automation</li>
|
||
<li>Network administration</li>
|
||
<li>Physical security systems (ok, easy there buddy)</li>
|
||
<li>Industrial monitoring and control (uh…what?)</li>
|
||
<li>And this is just the official specs<br>All our devices can talk to each other! Brave new worlds of remote control and automation! Have your toaster turn on the lights, set the TV to the news channel, and send you a text message when breakfast is ready! The future is now! Nothing could possibly go wrong!<h2 id="关于安全"><a href="#关于安全" class="headerlink" title="关于安全"></a>关于安全</h2></li>
|
||
</ul>
|
||
<ol>
|
||
<li>嵌入式设备</li>
|
||
</ol>
|
||
<ul>
|
||
<li>有限的内存和处理能力</li>
|
||
<li>硬件和软件开发人员通常是完全不同的公司</li>
|
||
<li>复制和粘贴开发</li>
|
||
<li>保持低成本</li>
|
||
<li>不完全关心/懂行</li>
|
||
</ul>
|
||
<ol start="2">
|
||
<li>部署</li>
|
||
</ol>
|
||
<ul>
|
||
<li>数以百万计的面向互联网的UPnP设备</li>
|
||
<li>要计算的供应商太多</li>
|
||
<li>前端是标准化的,后端甚至在同一供应商内也有所不同</li>
|
||
<li>难以修补/更新固件</li>
|
||
<li>仅仅因为你可以,并不意味着你应该</li>
|
||
</ul>
|
||
<ol start="3">
|
||
<li>XML解析很难</li>
|
||
</ol>
|
||
<ul>
|
||
<li>需要大量系统资源</li>
|
||
<li>自由格式的用户提供的数据</li>
|
||
<li>2013年,2.5%的CVE与XML相关[2],其中,近36%的患者CVSS严重程度为7或以上</li>
|
||
<li>随着XML的用例增长,版本也越来越多:递归错误,XXE,命令注入等……</li>
|
||
</ul>
|
||
<h1 id="攻击面"><a href="#攻击面" class="headerlink" title="攻击面"></a>攻击面</h1><ul>
|
||
<li>UPnP服务<br>• HTTP头解析<br>• SSDP解析<br>• OS命令注入<br>• 信息披露</li>
|
||
<li>SOAP服务<br>• HTTP头解析<br>• XML解析<br>• 注射用品<br>• OS命令<br>• SQL注入<br>• SOAP注入<br>• 信息披露<br>• 可疑级别的未经身份验证的设备控制<h2 id="Attack-surface-–-UPnP"><a href="#Attack-surface-–-UPnP" class="headerlink" title="Attack surface – UPnP"></a>Attack surface – UPnP</h2></li>
|
||
<li><p><a href="https://community.rapid7.com/docs/DOC-2150" target="_blank" rel="noopener">CVE-2012-5958</a><br>去年由HD Moore(众多之一)披露;调用strncpy将ST头中的字符串复制到TempBuf[COMMAND_LEN];strncpy的长度参数基于冒号之间的字符数<br><img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555580242/paper/6.png" alt></p>
|
||
</li>
|
||
<li><p>D-Link DIR-815 <a href="http://shadow-file.blogspot.com/2013/02/dlink-dir-815-upnp-command-injection.html" target="_blank" rel="noopener">UPnP命令注入</a><br>去年由Zach Cutlip披露;ST头的内容作为参数传递给M-SEARCH.sh;无需验证<br><img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555580904/paper/7.png" alt></p>
|
||
</li>
|
||
</ul>
|
||
<h2 id="Attack-surface-–-SOAP"><a href="#Attack-surface-–-SOAP" class="headerlink" title="Attack surface – SOAP"></a>Attack surface – SOAP</h2><ul>
|
||
<li><p>XBMC soap_action_name<a href="http://www.exploit-db.com/exploits/15347/" target="_blank" rel="noopener">缓冲区溢出</a><br>由n00b于2010年10月公布;ProcessHttpPostRequest函数分配静态大小的缓冲区;调用sscanf将SOAPAction标头的值复制到其中,没有边界检查<br><img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555581152/paper/8.png" alt></p>
|
||
</li>
|
||
<li><p>博通SetConnectionType<a href="http://sebug.net/paper/Exploits-Archives/2013-exploits/1301-exploits/DC-2013-01-003.txt" target="_blank" rel="noopener">格式字符串漏洞</a><br>去年Leon Juranic和Vedran Kajic透露;SetConnectionType操作将NewConnectionType参数的值提供给snprintf;不对用户控制的值进行检查<br><img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555581385/paper/9.png" alt></p>
|
||
</li>
|
||
<li><p><a href="http://www.pnigos.com/?p=260" target="_blank" rel="noopener">CVE-2014-3242</a><br>今年早些时候由pnig0s披露;SOAPpy允许在SOAP请求中声明用户定义的XML外部实体;不对用户控制的值进行检查<br><img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555581672/paper/10.png" alt></p>
|
||
</li>
|
||
<li><p><a href="http://seclists.org/fulldisclosure/2014/May/32" target="_blank" rel="noopener">CVE-2014-2928</a><br>Brandon Perry今年早些时候公布了(PBerry Crunch!);F5 iControl API set_hostname操作将hostname参数的值传递给shell;再一次,不对用户控制的值进行消毒<br><img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555581840/paper/11.png" alt></p>
|
||
</li>
|
||
<li><p><a href="http://toor.do/DEFCON-19-Garcia-UPnP-Mapping-WP.pdf" target="_blank" rel="noopener">CVE-2011-4499,CVE-2011-4500,CVE-2011-4501,CVE-2011-4503,CVE-2011-4504,CVE-2011-4505,CVE-2011-4506,更多?</a><br>Daniel Garcia在Defcon 19上披露; UPnP IGD 使用AddPortMapping和DeletePortMapping等操作来允许远程管理路由规则;缺乏身份验证,可在WAN接口上使用; 使攻击者能够执行:•NAT遍历 •外部/内部主机端口映射 •内部LAN的外部网络扫描</p>
|
||
</li>
|
||
</ul>
|
||
<h2 id="如何测试"><a href="#如何测试" class="headerlink" title="如何测试"></a>如何测试</h2><ul>
|
||
<li>了解您的网络<br>M-SEARCH你连接的每个网络以监听新的NOTIFY消息</li>
|
||
<li>如果您不需要UPnP,请将其禁用<br>如果不在设备上,则在路由器上</li>
|
||
<li>随时掌握固件更新<br>并非总是自动的</li>
|
||
<li>模糊测试<br>Burp – <a href="http://portswigger.net/burp/" target="_blank" rel="noopener">http://portswigger.net/burp/</a><br>WSFuzzer – <a href="https://www.owasp.org/index.php/Category:OWASP_WSFuzzer_Project" target="_blank" rel="noopener">https://www.owasp.org/index.php/Category:OWASP_WSFuzzer_Project</a><br>Miranda – <a href="http://code.google.com/p/miranda-upnp/" target="_blank" rel="noopener">http://code.google.com/p/miranda-upnp/</a></li>
|
||
</ul>
|
||
<h1 id="对小米WIFI路由器的UPnP分析"><a href="#对小米WIFI路由器的UPnP分析" class="headerlink" title="对小米WIFI路由器的UPnP分析"></a>对小米WIFI路由器的UPnP分析</h1><h2 id="使用工具扫描"><a href="#使用工具扫描" class="headerlink" title="使用工具扫描"></a>使用工具扫描</h2><h3 id="使用Metasploit检查"><a href="#使用Metasploit检查" class="headerlink" title="使用Metasploit检查"></a>使用Metasploit检查</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">msfconsole</span><br><span class="line">msf5 > use auxiliary/scanner/upnp/ssdp_msearch</span><br><span class="line">msf5 auxiliary(scanner/upnp/ssdp_msearch) > set RHOSTS 192.168.31.0/24</span><br><span class="line">RHOSTS => 192.168.31.0/24</span><br><span class="line">msf5 auxiliary(scanner/upnp/ssdp_msearch) > run</span><br><span class="line"></span><br><span class="line">[*] Sending UPnP SSDP probes to 192.168.31.0->192.168.31.255 (256 hosts)</span><br><span class="line">[*] 192.168.31.1:1900 SSDP MiWiFi/x UPnP/1.1 MiniUPnPd/2.0 | http://192.168.31.1:5351/rootDesc.xml | uuid:f3539dd5-8dc5-420c-9070-c6f66d27fc8c::upnp:rootdevice</span><br><span class="line">[*] Scanned 256 of 256 hosts (100% complete)</span><br><span class="line">[*] Auxiliary module execution completed</span><br></pre></td></tr></table></figure>
|
||
<p>从中可以得到这些信息:</p>
|
||
<ul>
|
||
<li>UPnP/1.1</li>
|
||
<li>MiniUPnPd/2.0</li>
|
||
</ul>
|
||
<h3 id="使用nmap进行扫描"><a href="#使用nmap进行扫描" class="headerlink" title="使用nmap进行扫描"></a>使用nmap进行扫描</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">nmap -p1900,5351 192.168.31.1</span><br><span class="line"></span><br><span class="line">PORT STATE SERVICE</span><br><span class="line">1900/tcp filtered upnp</span><br><span class="line">5351/tcp open nat-pmp</span><br></pre></td></tr></table></figure>
|
||
<p><strong><em>nat-pmp</em></strong><br>NAT端口映射协议(英语:NAT Port Mapping Protocol,缩写NAT-PMP)是一个能自动创建网络地址转换(NAT)设置和端口映射配置而无需用户介入的网络协议。该协议能自动测定NAT网关的外部IPv4地址,并为应用程序提供与对等端交流通信的方法。NAT-PMP于2005年由苹果公司推出,为更常见的ISO标准互联网网关设备协议(被许多NAT路由器实现)的一个替代品。该协议由互联网工程任务组(IETF)在RFC 6886中发布。<br>NAT-PMP使用用户数据报协议(UDP),在5351端口运行。该协议没有内置的身份验证机制,因为转发一个端口通常不允许任何活动,也不能用STUN方法实现。NAT-PMP相比STUN的好处是它不需要STUN服务器,并且NAT-PMP映射有一个已知的过期时间,应用可以避免低效地发送保活数据包。<br>NAT-PMP是端口控制协议(PCP)的前身。<br><a href="https://laucyun.com/25118b151a3386b7beff250835fe7e98.html" target="_blank" rel="noopener">https://laucyun.com/25118b151a3386b7beff250835fe7e98.html</a><br>2014年10月,Rapid7安全研究员Jon Hart公布,因厂商对NAT-PMP协议设计不当,估计公网上有1200万台网络设备受到NAT-PMP漏洞的影响。NAT-PMP协议的规范中特别指明,NAT网关不能接受来自外网的地址映射请求,但一些厂商的设计并未遵守此规定。黑客可能对这些设备进行恶意的端口映射,进行流量反弹、代理等攻击。</p>
|
||
<h3 id="netstat扫描"><a href="#netstat扫描" class="headerlink" title="netstat扫描"></a>netstat扫描</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Proto Recv-Q Send-Q Local Address Foreign Address State in out PID/Program name</span><br><span class="line">tcp 0 0 :::5351 :::* LISTEN 0 0 18068/miniupnpd</span><br><span class="line">udp 0 0 192.168.31.1:5351 0.0.0.0:* 0 0 18068/miniupnpd</span><br><span class="line">udp 0 0 0.0.0.0:1900 0.0.0.0:* 1414113 1827652 18068/miniupnpd</span><br></pre></td></tr></table></figure>
|
||
<p>端口1900在UPnP发现的过程中使用,5351通常为端口映射协议NAT-PMP运行的端口</p>
|
||
<h3 id="miranda"><a href="#miranda" class="headerlink" title="miranda"></a><a href="https://www.ethicalhacker.net/columns/heffner/plug-n-play-network-hacking/" target="_blank" rel="noopener">miranda</a></h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br></pre></td><td class="code"><pre><span class="line">sudo python2 miranda.py -i wlx44334c388fbd -v</span><br><span class="line"></span><br><span class="line">Miranda v1.3</span><br><span class="line">The interactive UPnP client</span><br><span class="line">Craig Heffner, http://www.devttys0.com</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Binding to interface wlx44334c388fbd ...</span><br><span class="line"></span><br><span class="line">Verbose mode enabled!</span><br><span class="line">upnp> msearch</span><br><span class="line"></span><br><span class="line">Entering discovery mode for 'upnp:rootdevice', Ctl+C to stop...</span><br><span class="line"></span><br><span class="line">****************************************************************</span><br><span class="line">SSDP reply message from 192.168.31.1:5351</span><br><span class="line">XML file is located at http://192.168.31.1:5351/rootDesc.xml</span><br><span class="line">Device is running MiWiFi/x UPnP/1.1 MiniUPnPd/2.0</span><br><span class="line">****************************************************************</span><br><span class="line"></span><br><span class="line">upnp> host get 0</span><br><span class="line"></span><br><span class="line">Requesting device and service info for 192.168.31.1:5351 (this could take a few seconds)...</span><br><span class="line"></span><br><span class="line">Device urn:schemas-upnp-org:device:WANDevice:1 does not have a presentationURL</span><br><span class="line">Device urn:schemas-upnp-org:device:WANConnectionDevice:1 does not have a presentationURL</span><br><span class="line">Host data enumeration complete!</span><br><span class="line"></span><br><span class="line">upnp> host list</span><br><span class="line"></span><br><span class="line"> [0] 192.168.31.1:5351</span><br><span class="line"></span><br><span class="line">upnp> host info 0</span><br><span class="line"></span><br><span class="line">xmlFile : http://192.168.31.1:5351/rootDesc.xml</span><br><span class="line">name : 192.168.31.1:5351</span><br><span class="line">proto : http://</span><br><span class="line">serverType : MiWiFi/x UPnP/1.1 MiniUPnPd/2.0</span><br><span class="line">upnpServer : MiWiFi/x UPnP/1.1 MiniUPnPd/2.0</span><br><span class="line">dataComplete : True</span><br><span class="line">deviceList : {}</span><br><span class="line"></span><br><span class="line">upnp> host info 0 deviceList</span><br><span class="line"></span><br><span class="line">InternetGatewayDevice : {}</span><br><span class="line">WANDevice : {}</span><br><span class="line">WANConnectionDevice : {}</span><br><span class="line"></span><br><span class="line">upnp> host info 0 deviceList WANConnectionDevice</span><br><span class="line"></span><br><span class="line"> manufacturerURL : http://miniupnp.free.fr/</span><br><span class="line"> modelName : MiniUPnPd</span><br><span class="line"> UPC : 000000000000</span><br><span class="line"> modelNumber : 20180830</span><br><span class="line"> friendlyName : WANConnectionDevice</span><br><span class="line"> fullName : urn:schemas-upnp-org:device:WANConnectionDevice:1</span><br><span class="line"> modelDescription : MiniUPnP daemon</span><br><span class="line"> UDN : uuid:f3539dd5-8dc5-420c-9070-c6f66d27fc8e</span><br><span class="line"> modelURL : http://miniupnp.free.fr/</span><br><span class="line"> manufacturer : MiniUPnP</span><br><span class="line"> services : {}</span><br><span class="line"></span><br><span class="line">upnp> host info 0 deviceList WANConnectionDevice services WANIPConnection</span><br><span class="line"></span><br><span class="line"> eventSubURL : /evt/IPConn</span><br><span class="line"> controlURL : /ctl/IPConn</span><br><span class="line"> serviceId : urn:upnp-org:serviceId:WANIPConn1</span><br><span class="line"> SCPDURL : /WANIPCn.xml</span><br><span class="line"> fullName : urn:schemas-upnp-org:service:WANIPConnection:1</span><br><span class="line"> actions : {}</span><br><span class="line"> serviceStateVariables : {}</span><br><span class="line"></span><br><span class="line">upnp> host info 0 deviceList WANConnectionDevice services WANIPConnection actions</span><br><span class="line"></span><br><span class="line"> AddPortMapping : {}</span><br><span class="line"> GetNATRSIPStatus : {}</span><br><span class="line"> GetGenericPortMappingEntry : {}</span><br><span class="line"> GetSpecificPortMappingEntry : {}</span><br><span class="line"> ForceTermination : {}</span><br><span class="line"> GetExternalIPAddress : {}</span><br><span class="line"> GetConnectionTypeInfo : {}</span><br><span class="line"> GetStatusInfo : {}</span><br><span class="line"> SetConnectionType : {}</span><br><span class="line"> DeletePortMapping : {}</span><br><span class="line"> RequestConnection : {}</span><br><span class="line"></span><br><span class="line">upnp> host info 0 deviceList WANConnectionDevice services WANIPConnection serviceStateVariables</span><br><span class="line"></span><br><span class="line"> InternalClient : {}</span><br><span class="line"> Uptime : {}</span><br><span class="line"> PortMappingLeaseDuration : {}</span><br><span class="line"> PortMappingDescription : {}</span><br><span class="line"> RemoteHost : {}</span><br><span class="line"> PossibleConnectionTypes : {}</span><br><span class="line"> ExternalPort : {}</span><br><span class="line"> RSIPAvailable : {}</span><br><span class="line"> ConnectionStatus : {}</span><br><span class="line"> PortMappingNumberOfEntries : {}</span><br><span class="line"> ExternalIPAddress : {}</span><br><span class="line"> ConnectionType : {}</span><br><span class="line"> NATEnabled : {}</span><br><span class="line"> LastConnectionError : {}</span><br><span class="line"> InternalPort : {}</span><br><span class="line"> PortMappingProtocol : {}</span><br><span class="line"> PortMappingEnabled : {}</span><br><span class="line"></span><br><span class="line">upnp> host summary 0</span><br><span class="line"></span><br><span class="line"> Host: 192.168.31.1:5351</span><br><span class="line"> XML File: http://192.168.31.1:5351/rootDesc.xml</span><br><span class="line"> InternetGatewayDevice</span><br><span class="line"> manufacturerURL: http://www.mi.com</span><br><span class="line"> modelName: MiWiFi Router</span><br><span class="line"> UPC: 000000000000</span><br><span class="line"> modelNumber: 20180830</span><br><span class="line"> presentationURL: http://miwifi.com/</span><br><span class="line"> friendlyName: MiWiFi router</span><br><span class="line"> fullName: urn:schemas-upnp-org:device:InternetGatewayDevice:1</span><br><span class="line"> modelDescription: MiWiFi Router</span><br><span class="line"> UDN: uuid:f3539dd5-8dc5-420c-9070-c6f66d27fc8c</span><br><span class="line"> modelURL: http://www1.miwifi.com</span><br><span class="line"> manufacturer: Xiaomi</span><br><span class="line"> WANDevice</span><br><span class="line"> manufacturerURL: http://miniupnp.free.fr/</span><br><span class="line"> modelName: WAN Device</span><br><span class="line"> UPC: 000000000000</span><br><span class="line"> modelNumber: 20180830</span><br><span class="line"> friendlyName: WANDevice</span><br><span class="line"> fullName: urn:schemas-upnp-org:device:WANDevice:1</span><br><span class="line"> modelDescription: WAN Device</span><br><span class="line"> UDN: uuid:f3539dd5-8dc5-420c-9070-c6f66d27fc8d</span><br><span class="line"> modelURL: http://miniupnp.free.fr/</span><br><span class="line"> manufacturer: MiniUPnP</span><br><span class="line"> WANConnectionDevice</span><br><span class="line"> manufacturerURL: http://miniupnp.free.fr/</span><br><span class="line"> modelName: MiniUPnPd</span><br><span class="line"> UPC: 000000000000</span><br><span class="line"> modelNumber: 20180830</span><br><span class="line"> friendlyName: WANConnectionDevice</span><br><span class="line"> fullName: urn:schemas-upnp-org:device:WANConnectionDevice:1</span><br><span class="line"> modelDescription: MiniUPnP daemon</span><br><span class="line"> UDN: uuid:f3539dd5-8dc5-420c-9070-c6f66d27fc8e</span><br><span class="line"> modelURL: http://miniupnp.free.fr/</span><br><span class="line"> manufacturer: MiniUPnP</span><br></pre></td></tr></table></figure>
|
||
<ul>
|
||
<li>使用miranda发送UPnP命令<br><strong>获取外部IP地址</strong></li>
|
||
</ul>
|
||
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">upnp> host send 0 WANConnectionDevice WANIPConnection GetExternalIPAddress</span><br><span class="line"></span><br><span class="line">NewExternalIPAddress : 172.16.173.231</span><br></pre></td></tr></table></figure>
|
||
<p><strong>增加一个端口映射,将路由器上端口为1900的服务映射到外网端口8080</strong></p>
|
||
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line">upnp> host send 0 WANConnectionDevice WANIPConnection AddPortMapping</span><br><span class="line"></span><br><span class="line">Required argument:</span><br><span class="line"> Argument Name: NewPortMappingDescription</span><br><span class="line"> Data Type: string</span><br><span class="line"> Allowed Values: []</span><br><span class="line"> Set NewPortMappingDescription value to: HACK</span><br><span class="line"></span><br><span class="line">Required argument:</span><br><span class="line"> Argument Name: NewLeaseDuration</span><br><span class="line"> Data Type: ui4</span><br><span class="line"> Allowed Values: []</span><br><span class="line"> Value Min: 0</span><br><span class="line"> Value Max: 604800</span><br><span class="line"> Set NewLeaseDuration value to: 0</span><br><span class="line"></span><br><span class="line">Required argument:</span><br><span class="line"> Argument Name: NewInternalClient</span><br><span class="line"> Data Type: string</span><br><span class="line"> Allowed Values: []</span><br><span class="line"> Set NewInternalClient value to: 192.168.31.1</span><br><span class="line"></span><br><span class="line">Required argument:</span><br><span class="line"> Argument Name: NewEnabled</span><br><span class="line"> Data Type: boolean</span><br><span class="line"> Allowed Values: []</span><br><span class="line"> Set NewEnabled value to: 1</span><br><span class="line"></span><br><span class="line">Required argument:</span><br><span class="line"> Argument Name: NewExternalPort</span><br><span class="line"> Data Type: ui2</span><br><span class="line"> Allowed Values: []</span><br><span class="line"> Set NewExternalPort value to: 8080</span><br><span class="line"></span><br><span class="line">Required argument:</span><br><span class="line"> Argument Name: NewRemoteHost</span><br><span class="line"> Data Type: string</span><br><span class="line"> Allowed Values: []</span><br><span class="line"> Set NewRemoteHost value to:</span><br><span class="line"></span><br><span class="line">Required argument:</span><br><span class="line"> Argument Name: NewProtocol</span><br><span class="line"> Data Type: string</span><br><span class="line"> Allowed Values: ['TCP', 'UDP']</span><br><span class="line"> Set NewProtocol value to: TCP</span><br><span class="line"></span><br><span class="line">Required argument:</span><br><span class="line"> Argument Name: NewInternalPort</span><br><span class="line"> Data Type: ui2</span><br><span class="line"> Allowed Values: []</span><br><span class="line"> Value Min: 1</span><br><span class="line"> Value Max: 65535</span><br><span class="line"> Set NewInternalPort value to: 1900</span><br></pre></td></tr></table></figure>
|
||
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">upnp> host send 0 WANConnectionDevice WANIPConnection GetSpecificPortMappingEntry</span><br><span class="line"></span><br><span class="line"> Required argument:</span><br><span class="line"> Argument Name: NewExternalPort</span><br><span class="line"> Data Type: ui2</span><br><span class="line"> Allowed Values: []</span><br><span class="line"> Set NewExternalPort value to: 8080</span><br><span class="line"></span><br><span class="line"> Required argument:</span><br><span class="line"> Argument Name: NewRemoteHost</span><br><span class="line"> Data Type: string</span><br><span class="line"> Allowed Values: []</span><br><span class="line"> Set NewRemoteHost value to:</span><br><span class="line"></span><br><span class="line"> Required argument:</span><br><span class="line"> Argument Name: NewProtocol</span><br><span class="line"> Data Type: string</span><br><span class="line"> Allowed Values: ['TCP', 'UDP']</span><br><span class="line"> Set NewProtocol value to: TCP</span><br><span class="line"></span><br><span class="line"> NewPortMappingDescription : HACK</span><br><span class="line"> NewLeaseDuration : 0</span><br><span class="line"> NewInternalClient : 192.168.31.1</span><br><span class="line"> NewEnabled : 1</span><br><span class="line"> NewInternalPort : 1900</span><br></pre></td></tr></table></figure>
|
||
<p><strong>可以无需验证地删除映射</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">upnp> host send 0 WANConnectionDevice WANIPConnection DeletePortMapping</span><br></pre></td></tr></table></figure></p>
|
||
<p><img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1555918880/paper/2231.png" alt><br>虽然UPnP是一种很少理解的协议,但它在绝大多数家庭网络上都很活跃,甚至在某些公司网络上也是如此。许多设备支持UPnP以便于消费者使用,但是,它们通常支持不允许任何服务自动执行的操作,尤其是未经授权的情况下。更糟糕的是,协议实现本身很少以安全思维构建,使其可以进一步利用。<br>防止本地/远程利用UPnP的最佳方法是在任何/所有网络设备上禁用该功能。然而,考虑到这个协议和其他“自动魔术”协议旨在帮助懒惰的用户,他们可能不知道这些协议的危险,唯一真正的解决方案是让供应商更加关注他们的设计和实施,并且更加安全。</p>
|
||
<h2 id="浏览配置文件"><a href="#浏览配置文件" class="headerlink" title="浏览配置文件"></a>浏览配置文件</h2><h3 id="通过find命令搜索"><a href="#通过find命令搜索" class="headerlink" title="通过find命令搜索"></a>通过find命令搜索</h3><pre>root@XiaoQiang:/# find -name *upnp*
|
||
./etc/rc.d/S95miniupnpd
|
||
./etc/init.d/miniupnpd
|
||
./etc/hotplug.d/iface/50-miniupnpd
|
||
./etc/config/upnpd
|
||
./tmp/upnp.leases
|
||
./tmp/etc/miniupnpd.conf
|
||
./tmp/run/miniupnpd.pid
|
||
./usr/lib/lua/luci/view/web/setting/upnp.htm
|
||
./usr/sbin/miniupnpd
|
||
./usr/share/miniupnpd
|
||
./www/xiaoqiang/web/css/upnp.css
|
||
./data/etc/rc.d/S95miniupnpd
|
||
./data/etc/init.d/miniupnpd
|
||
./data/etc/hotplug.d/iface/50-miniupnpd
|
||
./data/etc/config/upnpd</pre>
|
||
|
||
<ul>
|
||
<li>/etc/rc.d 启动的配置文件和脚本</li>
|
||
</ul>
|
||
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br></pre></td><td class="code"><pre><span class="line">!/bin/sh /etc/rc.common</span><br><span class="line"># Copyright (C) 2006-2011 OpenWrt.org</span><br><span class="line"></span><br><span class="line">START=95</span><br><span class="line">SERVICE_USE_PID=1</span><br><span class="line">upnpd_get_port_range() {</span><br><span class="line"> local _var="$1"; shift</span><br><span class="line"> local _val</span><br><span class="line"> config_get _val "$@"</span><br><span class="line"> case "$_val" in</span><br><span class="line"> [0-9]*[:-][0-9]*)</span><br><span class="line"> export -n -- "${_var}_start=${_val%%[:-]*}"</span><br><span class="line"> export -n -- "${_var}_end=${_val##*[:-]}"</span><br><span class="line"> ;;</span><br><span class="line"> [0-9]*)</span><br><span class="line"> export -n -- "${_var}_start=$_val"</span><br><span class="line"> export -n -- "${_var}_end="</span><br><span class="line"> ;;</span><br><span class="line"> esac</span><br><span class="line">}</span><br><span class="line">conf_rule_add() {</span><br><span class="line"> local cfg="$1"</span><br><span class="line"> local tmpconf="$2"</span><br><span class="line"> local action external_port_start external_port_end int_addr</span><br><span class="line"> local internal_port_start internal_port_end</span><br><span class="line"></span><br><span class="line"> config_get action "$cfg" action "deny" # allow or deny</span><br><span class="line"> upnpd_get_port_range "ext" "$cfg" ext_ports "0-65535" # external ports: x, x-y, x:y</span><br><span class="line"> config_get int_addr "$cfg" int_addr "0.0.0.0/0" # ip or network and subnet mask (internal)</span><br><span class="line"> upnpd_get_port_range "int" "$cfg" int_ports "0-65535" # internal ports: x, x-y, x:y or range</span><br><span class="line"></span><br><span class="line"> # Make a single IP IP/32 so that miniupnpd.conf can use it.</span><br><span class="line"> case "$int_addr" in</span><br><span class="line"> */*) ;;</span><br><span class="line"> *) int_addr="$int_addr/32" ;;</span><br><span class="line"> esac</span><br><span class="line"></span><br><span class="line"> echo "${action} ${ext_start}${ext_end:+-}${ext_end} ${int_addr} ${int_start}${int_end:+-}${int_end}" >>$tmpconf</span><br><span class="line">}</span><br><span class="line">upnpd_write_bool() { </span><br><span class="line"> local opt="$1" </span><br><span class="line"> local def="${2:-0}" </span><br><span class="line"> local alt="$3" </span><br><span class="line"> local val </span><br><span class="line"></span><br><span class="line"> config_get_bool val config "$opt" "$def" </span><br><span class="line"> if [ "$val" -eq 0 ]; then </span><br><span class="line"> echo "${alt:-$opt}=no" >> $tmpconf </span><br><span class="line"> else </span><br><span class="line"> echo "${alt:-$opt}=yes" >> $tmpconf </span><br><span class="line"> fi </span><br><span class="line">} </span><br><span class="line"></span><br><span class="line">boot() { </span><br><span class="line"> return 0 </span><br><span class="line">} </span><br><span class="line"></span><br><span class="line">start() { </span><br><span class="line"> config_load "upnpd" </span><br><span class="line"> local extiface intiface upload download logging secure enabled natpmp </span><br><span class="line"> local extip port usesysuptime conffile serial_number model_number </span><br><span class="line"> local uuid notify_interval presentation_url enable_upnp </span><br><span class="line"> local upnp_lease_file clean_ruleset_threshold clean_ruleset_interval </span><br><span class="line"></span><br><span class="line"> config_get extiface config external_iface </span><br><span class="line"> config_get intiface config internal_iface </span><br><span class="line"> config_get extip config external_ip </span><br><span class="line"> config_get port config port 5000 </span><br><span class="line"> config_get upload config upload </span><br><span class="line"> config_get download config download </span><br><span class="line"> config_get_bool logging config log_output 0 </span><br><span class="line"> config_get conffile config config_file </span><br><span class="line"> config_get serial_number config serial_number </span><br><span class="line"> config_get model_number config model_number </span><br><span class="line"> config_get uuid config uuid </span><br><span class="line"> config_get notify_interval config notify_interval </span><br><span class="line"> config_get presentation_url config presentation_url </span><br><span class="line"> config_get upnp_lease_file config upnp_lease_file </span><br><span class="line"> config_get clean_ruleset_threshold config clean_ruleset_threshold </span><br><span class="line"> config_get clean_ruleset_interval config clean_ruleset_interval </span><br><span class="line"></span><br><span class="line"> local args </span><br><span class="line"></span><br><span class="line"> . /lib/functions/network.sh </span><br><span class="line"> local ifname </span><br><span class="line"> network_get_device ifname ${extiface:-wan} </span><br><span class="line"></span><br><span class="line"> if [ -n "$conffile" ]; then </span><br><span class="line"> args="-f $conffile" </span><br><span class="line"> else </span><br><span class="line"> local tmpconf="/var/etc/miniupnpd.conf" </span><br><span class="line"> args="-f $tmpconf" </span><br><span class="line"> mkdir -p /var/etc </span><br><span class="line"></span><br><span class="line"> echo "ext_ifname=$ifname" >$tmpconf </span><br><span class="line"></span><br><span class="line"> [ -n "$extip" ] && \ </span><br><span class="line"> echo "ext_ip=$extip" >>$tmpconf </span><br><span class="line"></span><br><span class="line"> local iface </span><br><span class="line"> for iface in ${intiface:-lan}; do </span><br><span class="line"> local device </span><br><span class="line"> network_get_device device "$iface" && { </span><br><span class="line"> echo "listening_ip=$device" >>$tmpconf </span><br><span class="line"> } </span><br><span class="line"> done </span><br><span class="line"></span><br><span class="line"> [ "$port" != "auto" ] && \ </span><br><span class="line"> echo "port=$port" >>$tmpconf </span><br><span class="line"></span><br><span class="line"> config_load "upnpd" </span><br><span class="line"> upnpd_write_bool enable_natpmp 1 </span><br><span class="line"> upnpd_write_bool enable_upnp 1 </span><br><span class="line"> upnpd_write_bool secure_mode 1 </span><br><span class="line"> upnpd_write_bool system_uptime 1 </span><br><span class="line"> [ -n "$upnp_lease_file" ] && { </span><br><span class="line"> touch $upnp_lease_file </span><br><span class="line"> echo "lease_file=$upnp_lease_file" >>$tmpconf </span><br><span class="line"> } </span><br><span class="line"></span><br><span class="line"> [ -n "$upload" -a -n "$download" ] && { </span><br><span class="line"> echo "bitrate_down=$(($download * 1024 * 8))" >>$tmpconf </span><br><span class="line"> echo "bitrate_up=$(($upload * 1024 * 8))" >>$tmpconf </span><br><span class="line"> } </span><br><span class="line"></span><br><span class="line"> [ -n "${presentation_url}" ] && \ </span><br><span class="line"> echo "presentation_url=${presentation_url}" >>$tmpconf </span><br><span class="line"></span><br><span class="line"> [ -n "${notify_interval}" ] && \ </span><br><span class="line"> echo "notify_interval=${notify_interval}" >>$tmpconf </span><br><span class="line"></span><br><span class="line"> [ -n "${clean_ruleset_threshold}" ] && \ </span><br><span class="line"> echo "clean_ruleset_threshold=${clean_ruleset_threshold}" >>$tmpconf </span><br><span class="line"></span><br><span class="line"> [ -n "${clean_ruleset_interval}" ] && \ </span><br><span class="line"> echo "clean_ruleset_interval=${clean_ruleset_interval}" >>$tmpconf </span><br><span class="line"></span><br><span class="line"> [ -z "$uuid" ] && { </span><br><span class="line"> uuid="$(cat /proc/sys/kernel/random/uuid)" </span><br><span class="line"> uci set upnpd.config.uuid=$uuid </span><br><span class="line"> uci commit upnpd </span><br><span class="line"> } </span><br><span class="line"></span><br><span class="line"> [ "$uuid" = "nocli" ] || \ </span><br><span class="line"> echo "uuid=$uuid" >>$tmpconf </span><br><span class="line"></span><br><span class="line"> [ -n "${serial_number}" ] && \ </span><br><span class="line"> echo "serial=${serial_number}" >>$tmpconf </span><br><span class="line"></span><br><span class="line"> [ -n "${model_number}" ] && \ </span><br><span class="line"> echo "model_number=${model_number}" >>$tmpconf </span><br><span class="line"> config_foreach conf_rule_add perm_rule "$tmpconf" </span><br><span class="line"> fi </span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> if [ -n "$ifname" ]; then </span><br><span class="line"> # start firewall </span><br><span class="line"> iptables -L MINIUPNPD >/dev/null 2>/dev/null || fw3 reload </span><br><span class="line"></span><br><span class="line"> if [ "$logging" = "1" ]; then </span><br><span class="line"> SERVICE_DAEMONIZE=1 \ </span><br><span class="line"> service_start /usr/sbin/miniupnpd $args -d </span><br><span class="line"> else </span><br><span class="line"> SERVICE_DAEMONIZE= \ </span><br><span class="line"> service_start /usr/sbin/miniupnpd $args </span><br><span class="line"> fi </span><br><span class="line"> else </span><br><span class="line"> logger -t "upnp daemon" "external interface not found, not starting" </span><br><span class="line"> fi </span><br><span class="line"> return 0 </span><br><span class="line"> } </span><br><span class="line"></span><br><span class="line"> stop() { </span><br><span class="line"> service_stop /usr/sbin/miniupnpd </span><br><span class="line"></span><br><span class="line"> iptables -t nat -F MINIUPNPD 2>/dev/null </span><br><span class="line"> iptables -t filter -F MINIUPNPD 2>/dev/null </span><br><span class="line"> return 0 </span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
|
||
<p>SmartController<br>messagingagent</p>
|
||
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<div>
|
||
<div style="padding: 10px 0; margin: 20px auto; width: 90%; text-align: center;">
|
||
<div>您的支持将鼓励我继续创作!</div>
|
||
<button id="rewardButton" disable="enable" onclick="var qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}">
|
||
<span>打赏</span>
|
||
</button>
|
||
<div id="QR" style="display: none;">
|
||
|
||
|
||
<div id="wechat" style="display: inline-block">
|
||
<img id="wechat_qr" src="/images/Wechatpay.png" alt="Cool-Y 微信支付">
|
||
<p>微信支付</p>
|
||
</div>
|
||
|
||
|
||
|
||
<div id="alipay" style="display: inline-block">
|
||
<img id="alipay_qr" src="/images/Alipay.png" alt="Cool-Y 支付宝">
|
||
<p>支付宝</p>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<footer class="post-footer">
|
||
|
||
<div class="post-tags">
|
||
|
||
<a href="/tags/小米/" rel="tag"># 小米</a>
|
||
|
||
<a href="/tags/路由器/" rel="tag"># 路由器</a>
|
||
|
||
<a href="/tags/MiniUPnP/" rel="tag"># MiniUPnP</a>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<div class="post-nav">
|
||
<div class="post-nav-next post-nav-item">
|
||
|
||
<a href="/2019/04/15/Caving-db-storage/" rel="next" title="复原数据库存储以检测和跟踪安全漏洞">
|
||
<i class="fa fa-chevron-left"></i> 复原数据库存储以检测和跟踪安全漏洞
|
||
</a>
|
||
|
||
</div>
|
||
|
||
<span class="post-nav-divider"></span>
|
||
|
||
<div class="post-nav-prev post-nav-item">
|
||
|
||
<a href="/2019/05/13/PE-file/" rel="prev" title="PE文件格式学习">
|
||
PE文件格式学习 <i class="fa fa-chevron-right"></i>
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
</footer>
|
||
</div>
|
||
|
||
|
||
|
||
</article>
|
||
|
||
|
||
|
||
<div class="post-spread">
|
||
|
||
</div>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<div class="comments" id="comments">
|
||
|
||
<div id="gitment-container"></div>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<div class="sidebar-toggle">
|
||
<div class="sidebar-toggle-line-wrap">
|
||
<span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
|
||
<span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
|
||
<span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
|
||
</div>
|
||
</div>
|
||
|
||
<aside id="sidebar" class="sidebar">
|
||
|
||
<div class="sidebar-inner">
|
||
|
||
|
||
|
||
|
||
<ul class="sidebar-nav motion-element">
|
||
<li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
|
||
文章目录
|
||
</li>
|
||
<li class="sidebar-nav-overview" data-target="site-overview-wrap">
|
||
站点概览
|
||
</li>
|
||
</ul>
|
||
|
||
|
||
<section class="site-overview-wrap sidebar-panel">
|
||
<div class="site-overview">
|
||
<div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
|
||
|
||
<img class="site-author-image" itemprop="image" src="/images/avatar.png" alt="Cool-Y">
|
||
|
||
<p class="site-author-name" itemprop="name">Cool-Y</p>
|
||
<p class="site-description motion-element" itemprop="description">没人比我更懂中医#MAGA</p>
|
||
</div>
|
||
|
||
<nav class="site-state motion-element">
|
||
|
||
|
||
<div class="site-state-item site-state-posts">
|
||
|
||
<a href="/archives/">
|
||
|
||
<span class="site-state-item-count">21</span>
|
||
<span class="site-state-item-name">日志</span>
|
||
</a>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
<div class="site-state-item site-state-categories">
|
||
<a href="/categories/index.html">
|
||
<span class="site-state-item-count">7</span>
|
||
<span class="site-state-item-name">分类</span>
|
||
</a>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
<div class="site-state-item site-state-tags">
|
||
<a href="/tags/index.html">
|
||
<span class="site-state-item-count">41</span>
|
||
<span class="site-state-item-name">标签</span>
|
||
</a>
|
||
</div>
|
||
|
||
|
||
</nav>
|
||
|
||
|
||
|
||
|
||
<div class="links-of-author motion-element">
|
||
|
||
<span class="links-of-author-item">
|
||
<a href="https://github.com/Cool-Y" target="_blank" title="GitHub">
|
||
|
||
<i class="fa fa-fw fa-github"></i>GitHub</a>
|
||
</span>
|
||
|
||
<span class="links-of-author-item">
|
||
<a href="mailto:cool.yim@whu.edu.cn" target="_blank" title="E-Mail">
|
||
|
||
<i class="fa fa-fw fa-envelope"></i>E-Mail</a>
|
||
</span>
|
||
|
||
<span class="links-of-author-item">
|
||
<a href="https://www.instagram.com/yan__han/" target="_blank" title="Instagram">
|
||
|
||
<i class="fa fa-fw fa-instagram"></i>Instagram</a>
|
||
</span>
|
||
|
||
</div>
|
||
|
||
|
||
<div id="music163player">
|
||
<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width="330" height="450" src="//music.163.com/outchain/player?type=4&id=334277093&auto=1&height=430"></iframe>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</div>
|
||
</section>
|
||
|
||
|
||
<!--noindex-->
|
||
<section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
|
||
<div class="post-toc">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#概述"><span class="nav-text">概述</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#UPnP-IGD客户端轻量级库和UPnP-IGD守护进程"><span class="nav-text">UPnP IGD客户端轻量级库和UPnP IGD守护进程</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#MiniUPnP客户端库的实用性"><span class="nav-text">MiniUPnP客户端库的实用性</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#MiniUPnP守护进程的实用性"><span class="nav-text">MiniUPnP守护进程的实用性</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#安全"><span class="nav-text">安全</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#协议栈"><span class="nav-text">协议栈</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#发现"><span class="nav-text">发现</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#描述"><span class="nav-text">描述</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#控制"><span class="nav-text">控制</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#事件通知"><span class="nav-text">事件通知</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#展示"><span class="nav-text">展示</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#NAT穿透"><span class="nav-text">NAT穿透</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#SOAP和UPnP"><span class="nav-text">SOAP和UPnP</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#UPnP-Discovery"><span class="nav-text">UPnP - Discovery</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#UPnP-–-Description"><span class="nav-text">UPnP – Description</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#UPnP-–-SCPD"><span class="nav-text">UPnP – SCPD</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#UPnP-–-Control"><span class="nav-text">UPnP – Control</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#TL-DR"><span class="nav-text">TL;DR</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#好的一面"><span class="nav-text">好的一面</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#关于安全"><span class="nav-text">关于安全</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#攻击面"><span class="nav-text">攻击面</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#Attack-surface-–-UPnP"><span class="nav-text">Attack surface – UPnP</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Attack-surface-–-SOAP"><span class="nav-text">Attack surface – SOAP</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#如何测试"><span class="nav-text">如何测试</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#对小米WIFI路由器的UPnP分析"><span class="nav-text">对小米WIFI路由器的UPnP分析</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#使用工具扫描"><span class="nav-text">使用工具扫描</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#使用Metasploit检查"><span class="nav-text">使用Metasploit检查</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#使用nmap进行扫描"><span class="nav-text">使用nmap进行扫描</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#netstat扫描"><span class="nav-text">netstat扫描</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#miranda"><span class="nav-text">miranda</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#浏览配置文件"><span class="nav-text">浏览配置文件</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#通过find命令搜索"><span class="nav-text">通过find命令搜索</span></a></li></ol></li></ol></li></ol></div>
|
||
|
||
|
||
</div>
|
||
</section>
|
||
<!--/noindex-->
|
||
|
||
|
||
|
||
|
||
</div>
|
||
</aside>
|
||
|
||
|
||
|
||
</div>
|
||
</main>
|
||
|
||
<footer id="footer" class="footer">
|
||
<div class="footer-inner">
|
||
<div class="copyright">© <span itemprop="copyrightYear">2019</span>
|
||
<span class="with-love">
|
||
<i class="fa fa-user"></i>
|
||
</span>
|
||
<span class="author" itemprop="copyrightHolder">Cool-Y</span>
|
||
|
||
|
||
<span class="post-meta-divider">|</span>
|
||
<span class="post-meta-item-icon">
|
||
<i class="fa fa-area-chart"></i>
|
||
</span>
|
||
|
||
<span title="Site words total count">65.9k</span>
|
||
|
||
</div>
|
||
|
||
|
||
<div class="powered-by">由 <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<div class="busuanzi-count">
|
||
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
|
||
|
||
|
||
<span class="site-uv">
|
||
<i class="fa fa-user"></i>
|
||
<span class="busuanzi-value" id="busuanzi_value_site_uv"></span>
|
||
|
||
</span>
|
||
|
||
|
||
|
||
<span class="site-pv">
|
||
<i class="fa fa-eye"></i>
|
||
<span class="busuanzi-value" id="busuanzi_value_site_pv"></span>
|
||
|
||
</span>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</div>
|
||
</footer>
|
||
|
||
|
||
<div class="back-to-top">
|
||
<i class="fa fa-arrow-up"></i>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<script type="text/javascript">
|
||
if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
|
||
window.Promise = null;
|
||
}
|
||
</script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/js/src/utils.js?v=5.1.4"></script>
|
||
|
||
<script type="text/javascript" src="/js/src/motion.js?v=5.1.4"></script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/js/src/affix.js?v=5.1.4"></script>
|
||
|
||
<script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.4"></script>
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.4"></script>
|
||
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.4"></script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.4"></script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<!-- LOCAL: You can save these files to your site and update links -->
|
||
|
||
|
||
<link rel="stylesheet" href="https://jjeejj.github.io/css/gitment.css">
|
||
<script src="https://jjeejj.github.io/js/gitment.js"></script>
|
||
|
||
<!-- END LOCAL -->
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript">
|
||
function renderGitment(){
|
||
var gitment = new Gitment({
|
||
id: window.location.pathname,
|
||
owner: 'Cool-Y',
|
||
repo: 'gitment-comments',
|
||
|
||
oauth: {
|
||
|
||
|
||
client_secret: '1c5db4da72df5e6fc318d12afe5f4406f7c54343',
|
||
|
||
client_id: '180955a2c3ae3d966d9a'
|
||
}});
|
||
gitment.render('gitment-container');
|
||
}
|
||
|
||
|
||
renderGitment();
|
||
|
||
</script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript">
|
||
// Popup Window;
|
||
var isfetched = false;
|
||
var isXml = true;
|
||
// Search DB path;
|
||
var search_path = "search.xml";
|
||
if (search_path.length === 0) {
|
||
search_path = "search.xml";
|
||
} else if (/json$/i.test(search_path)) {
|
||
isXml = false;
|
||
}
|
||
var path = "/" + search_path;
|
||
// monitor main search box;
|
||
|
||
var onPopupClose = function (e) {
|
||
$('.popup').hide();
|
||
$('#local-search-input').val('');
|
||
$('.search-result-list').remove();
|
||
$('#no-result').remove();
|
||
$(".local-search-pop-overlay").remove();
|
||
$('body').css('overflow', '');
|
||
}
|
||
|
||
function proceedsearch() {
|
||
$("body")
|
||
.append('<div class="search-popup-overlay local-search-pop-overlay"></div>')
|
||
.css('overflow', 'hidden');
|
||
$('.search-popup-overlay').click(onPopupClose);
|
||
$('.popup').toggle();
|
||
var $localSearchInput = $('#local-search-input');
|
||
$localSearchInput.attr("autocapitalize", "none");
|
||
$localSearchInput.attr("autocorrect", "off");
|
||
$localSearchInput.focus();
|
||
}
|
||
|
||
// search function;
|
||
var searchFunc = function(path, search_id, content_id) {
|
||
'use strict';
|
||
|
||
// start loading animation
|
||
$("body")
|
||
.append('<div class="search-popup-overlay local-search-pop-overlay">' +
|
||
'<div id="search-loading-icon">' +
|
||
'<i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>' +
|
||
'</div>' +
|
||
'</div>')
|
||
.css('overflow', 'hidden');
|
||
$("#search-loading-icon").css('margin', '20% auto 0 auto').css('text-align', 'center');
|
||
|
||
$.ajax({
|
||
url: path,
|
||
dataType: isXml ? "xml" : "json",
|
||
async: true,
|
||
success: function(res) {
|
||
// get the contents from search data
|
||
isfetched = true;
|
||
$('.popup').detach().appendTo('.header-inner');
|
||
var datas = isXml ? $("entry", res).map(function() {
|
||
return {
|
||
title: $("title", this).text(),
|
||
content: $("content",this).text(),
|
||
url: $("url" , this).text()
|
||
};
|
||
}).get() : res;
|
||
var input = document.getElementById(search_id);
|
||
var resultContent = document.getElementById(content_id);
|
||
var inputEventFunction = function() {
|
||
var searchText = input.value.trim().toLowerCase();
|
||
var keywords = searchText.split(/[\s\-]+/);
|
||
if (keywords.length > 1) {
|
||
keywords.push(searchText);
|
||
}
|
||
var resultItems = [];
|
||
if (searchText.length > 0) {
|
||
// perform local searching
|
||
datas.forEach(function(data) {
|
||
var isMatch = false;
|
||
var hitCount = 0;
|
||
var searchTextCount = 0;
|
||
var title = data.title.trim();
|
||
var titleInLowerCase = title.toLowerCase();
|
||
var content = data.content.trim().replace(/<[^>]+>/g,"");
|
||
var contentInLowerCase = content.toLowerCase();
|
||
var articleUrl = decodeURIComponent(data.url);
|
||
var indexOfTitle = [];
|
||
var indexOfContent = [];
|
||
// only match articles with not empty titles
|
||
if(title != '') {
|
||
keywords.forEach(function(keyword) {
|
||
function getIndexByWord(word, text, caseSensitive) {
|
||
var wordLen = word.length;
|
||
if (wordLen === 0) {
|
||
return [];
|
||
}
|
||
var startPosition = 0, position = [], index = [];
|
||
if (!caseSensitive) {
|
||
text = text.toLowerCase();
|
||
word = word.toLowerCase();
|
||
}
|
||
while ((position = text.indexOf(word, startPosition)) > -1) {
|
||
index.push({position: position, word: word});
|
||
startPosition = position + wordLen;
|
||
}
|
||
return index;
|
||
}
|
||
|
||
indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false));
|
||
indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false));
|
||
});
|
||
if (indexOfTitle.length > 0 || indexOfContent.length > 0) {
|
||
isMatch = true;
|
||
hitCount = indexOfTitle.length + indexOfContent.length;
|
||
}
|
||
}
|
||
|
||
// show search results
|
||
|
||
if (isMatch) {
|
||
// sort index by position of keyword
|
||
|
||
[indexOfTitle, indexOfContent].forEach(function (index) {
|
||
index.sort(function (itemLeft, itemRight) {
|
||
if (itemRight.position !== itemLeft.position) {
|
||
return itemRight.position - itemLeft.position;
|
||
} else {
|
||
return itemLeft.word.length - itemRight.word.length;
|
||
}
|
||
});
|
||
});
|
||
|
||
// merge hits into slices
|
||
|
||
function mergeIntoSlice(text, start, end, index) {
|
||
var item = index[index.length - 1];
|
||
var position = item.position;
|
||
var word = item.word;
|
||
var hits = [];
|
||
var searchTextCountInSlice = 0;
|
||
while (position + word.length <= end && index.length != 0) {
|
||
if (word === searchText) {
|
||
searchTextCountInSlice++;
|
||
}
|
||
hits.push({position: position, length: word.length});
|
||
var wordEnd = position + word.length;
|
||
|
||
// move to next position of hit
|
||
|
||
index.pop();
|
||
while (index.length != 0) {
|
||
item = index[index.length - 1];
|
||
position = item.position;
|
||
word = item.word;
|
||
if (wordEnd > position) {
|
||
index.pop();
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
searchTextCount += searchTextCountInSlice;
|
||
return {
|
||
hits: hits,
|
||
start: start,
|
||
end: end,
|
||
searchTextCount: searchTextCountInSlice
|
||
};
|
||
}
|
||
|
||
var slicesOfTitle = [];
|
||
if (indexOfTitle.length != 0) {
|
||
slicesOfTitle.push(mergeIntoSlice(title, 0, title.length, indexOfTitle));
|
||
}
|
||
|
||
var slicesOfContent = [];
|
||
while (indexOfContent.length != 0) {
|
||
var item = indexOfContent[indexOfContent.length - 1];
|
||
var position = item.position;
|
||
var word = item.word;
|
||
// cut out 100 characters
|
||
var start = position - 20;
|
||
var end = position + 80;
|
||
if(start < 0){
|
||
start = 0;
|
||
}
|
||
if (end < position + word.length) {
|
||
end = position + word.length;
|
||
}
|
||
if(end > content.length){
|
||
end = content.length;
|
||
}
|
||
slicesOfContent.push(mergeIntoSlice(content, start, end, indexOfContent));
|
||
}
|
||
|
||
// sort slices in content by search text's count and hits' count
|
||
|
||
slicesOfContent.sort(function (sliceLeft, sliceRight) {
|
||
if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) {
|
||
return sliceRight.searchTextCount - sliceLeft.searchTextCount;
|
||
} else if (sliceLeft.hits.length !== sliceRight.hits.length) {
|
||
return sliceRight.hits.length - sliceLeft.hits.length;
|
||
} else {
|
||
return sliceLeft.start - sliceRight.start;
|
||
}
|
||
});
|
||
|
||
// select top N slices in content
|
||
|
||
var upperBound = parseInt('1');
|
||
if (upperBound >= 0) {
|
||
slicesOfContent = slicesOfContent.slice(0, upperBound);
|
||
}
|
||
|
||
// highlight title and content
|
||
|
||
function highlightKeyword(text, slice) {
|
||
var result = '';
|
||
var prevEnd = slice.start;
|
||
slice.hits.forEach(function (hit) {
|
||
result += text.substring(prevEnd, hit.position);
|
||
var end = hit.position + hit.length;
|
||
result += '<b class="search-keyword">' + text.substring(hit.position, end) + '</b>';
|
||
prevEnd = end;
|
||
});
|
||
result += text.substring(prevEnd, slice.end);
|
||
return result;
|
||
}
|
||
|
||
var resultItem = '';
|
||
|
||
if (slicesOfTitle.length != 0) {
|
||
resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + highlightKeyword(title, slicesOfTitle[0]) + "</a>";
|
||
} else {
|
||
resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + title + "</a>";
|
||
}
|
||
|
||
slicesOfContent.forEach(function (slice) {
|
||
resultItem += "<a href='" + articleUrl + "'>" +
|
||
"<p class=\"search-result\">" + highlightKeyword(content, slice) +
|
||
"...</p>" + "</a>";
|
||
});
|
||
|
||
resultItem += "</li>";
|
||
resultItems.push({
|
||
item: resultItem,
|
||
searchTextCount: searchTextCount,
|
||
hitCount: hitCount,
|
||
id: resultItems.length
|
||
});
|
||
}
|
||
})
|
||
};
|
||
if (keywords.length === 1 && keywords[0] === "") {
|
||
resultContent.innerHTML = '<div id="no-result"><i class="fa fa-search fa-5x" /></div>'
|
||
} else if (resultItems.length === 0) {
|
||
resultContent.innerHTML = '<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>'
|
||
} else {
|
||
resultItems.sort(function (resultLeft, resultRight) {
|
||
if (resultLeft.searchTextCount !== resultRight.searchTextCount) {
|
||
return resultRight.searchTextCount - resultLeft.searchTextCount;
|
||
} else if (resultLeft.hitCount !== resultRight.hitCount) {
|
||
return resultRight.hitCount - resultLeft.hitCount;
|
||
} else {
|
||
return resultRight.id - resultLeft.id;
|
||
}
|
||
});
|
||
var searchResultList = '<ul class=\"search-result-list\">';
|
||
resultItems.forEach(function (result) {
|
||
searchResultList += result.item;
|
||
})
|
||
searchResultList += "</ul>";
|
||
resultContent.innerHTML = searchResultList;
|
||
}
|
||
}
|
||
|
||
if ('auto' === 'auto') {
|
||
input.addEventListener('input', inputEventFunction);
|
||
} else {
|
||
$('.search-icon').click(inputEventFunction);
|
||
input.addEventListener('keypress', function (event) {
|
||
if (event.keyCode === 13) {
|
||
inputEventFunction();
|
||
}
|
||
});
|
||
}
|
||
|
||
// remove loading animation
|
||
$(".local-search-pop-overlay").remove();
|
||
$('body').css('overflow', '');
|
||
|
||
proceedsearch();
|
||
}
|
||
});
|
||
}
|
||
|
||
// handle and trigger popup window;
|
||
$('.popup-trigger').click(function(e) {
|
||
e.stopPropagation();
|
||
if (isfetched === false) {
|
||
searchFunc(path, 'local-search-input', 'local-search-result');
|
||
} else {
|
||
proceedsearch();
|
||
};
|
||
});
|
||
|
||
$('.popup-btn-close').click(onPopupClose);
|
||
$('.popup').click(function(e){
|
||
e.stopPropagation();
|
||
});
|
||
$(document).on('keyup', function (event) {
|
||
var shouldDismissSearchPopup = event.which === 27 &&
|
||
$('.search-popup').is(':visible');
|
||
if (shouldDismissSearchPopup) {
|
||
onPopupClose();
|
||
}
|
||
});
|
||
</script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.4.js"></script>
|
||
<script>AV.initialize("EWwoJgHNdlj6iBjiFlMcabUO-gzGzoHsz", "x8FxDrYG79C8YFrTww9ljo8K");</script>
|
||
<script>
|
||
function showTime(Counter) {
|
||
var query = new AV.Query(Counter);
|
||
var entries = [];
|
||
var $visitors = $(".leancloud_visitors");
|
||
|
||
$visitors.each(function () {
|
||
entries.push( $(this).attr("id").trim() );
|
||
});
|
||
|
||
query.containedIn('url', entries);
|
||
query.find()
|
||
.done(function (results) {
|
||
var COUNT_CONTAINER_REF = '.leancloud-visitors-count';
|
||
|
||
if (results.length === 0) {
|
||
$visitors.find(COUNT_CONTAINER_REF).text(0);
|
||
return;
|
||
}
|
||
|
||
for (var i = 0; i < results.length; i++) {
|
||
var item = results[i];
|
||
var url = item.get('url');
|
||
var time = item.get('time');
|
||
var element = document.getElementById(url);
|
||
|
||
$(element).find(COUNT_CONTAINER_REF).text(time);
|
||
}
|
||
for(var i = 0; i < entries.length; i++) {
|
||
var url = entries[i];
|
||
var element = document.getElementById(url);
|
||
var countSpan = $(element).find(COUNT_CONTAINER_REF);
|
||
if( countSpan.text() == '') {
|
||
countSpan.text(0);
|
||
}
|
||
}
|
||
})
|
||
.fail(function (object, error) {
|
||
console.log("Error: " + error.code + " " + error.message);
|
||
});
|
||
}
|
||
|
||
function addCount(Counter) {
|
||
var $visitors = $(".leancloud_visitors");
|
||
var url = $visitors.attr('id').trim();
|
||
var title = $visitors.attr('data-flag-title').trim();
|
||
var query = new AV.Query(Counter);
|
||
|
||
query.equalTo("url", url);
|
||
query.find({
|
||
success: function(results) {
|
||
if (results.length > 0) {
|
||
var counter = results[0];
|
||
counter.fetchWhenSave(true);
|
||
counter.increment("time");
|
||
counter.save(null, {
|
||
success: function(counter) {
|
||
var $element = $(document.getElementById(url));
|
||
$element.find('.leancloud-visitors-count').text(counter.get('time'));
|
||
},
|
||
error: function(counter, error) {
|
||
console.log('Failed to save Visitor num, with error message: ' + error.message);
|
||
}
|
||
});
|
||
} else {
|
||
var newcounter = new Counter();
|
||
/* Set ACL */
|
||
var acl = new AV.ACL();
|
||
acl.setPublicReadAccess(true);
|
||
acl.setPublicWriteAccess(true);
|
||
newcounter.setACL(acl);
|
||
/* End Set ACL */
|
||
newcounter.set("title", title);
|
||
newcounter.set("url", url);
|
||
newcounter.set("time", 1);
|
||
newcounter.save(null, {
|
||
success: function(newcounter) {
|
||
var $element = $(document.getElementById(url));
|
||
$element.find('.leancloud-visitors-count').text(newcounter.get('time'));
|
||
},
|
||
error: function(newcounter, error) {
|
||
console.log('Failed to create');
|
||
}
|
||
});
|
||
}
|
||
},
|
||
error: function(error) {
|
||
console.log('Error:' + error.code + " " + error.message);
|
||
}
|
||
});
|
||
}
|
||
|
||
$(function() {
|
||
var Counter = AV.Object.extend("Counter");
|
||
if ($('.leancloud_visitors').length == 1) {
|
||
addCount(Counter);
|
||
} else if ($('.post-title-link').length > 1) {
|
||
showTime(Counter);
|
||
}
|
||
});
|
||
</script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script>
|
||
(function(){
|
||
var bp = document.createElement('script');
|
||
var curProtocol = window.location.protocol.split(':')[0];
|
||
if (curProtocol === 'https') {
|
||
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
|
||
}
|
||
else {
|
||
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
|
||
}
|
||
var s = document.getElementsByTagName("script")[0];
|
||
s.parentNode.insertBefore(bp, s);
|
||
})();
|
||
</script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</body>
|
||
</html>
|