内网中利用UPNP进行端口映射

1 概述

在典型的IPv4网络下,由于NAT技术的广泛使用,端口映射是一种刚需。(下文所涉及“端口转发”、“端口映射”均指同一种技术。)

经典的端口映射方法例如iptables端口转发、SSH端口转发、webshell流量转发(regeorg)、socks代理等技术,是比较常见的用于建立内网通道的技术。本文分享一种利用内网网关设备开放的upnp协议进行端口映射的方法。

关于upnp协议的解释,参考百度百科-UPNP
upnp协议的使用场景很多,端口转发是upnp其中一个功能,但是想要使用该功能,需要网关设备的支持。

2 场景

使用upnp进行端口转发的场景,以下图网络拓扑为例:

内网服务器Server:内网地址192.168.1.2,开放端口1234
网关设备Gateway:内网地址192.168.1.1,公网地址x.x.x.x

常规情况下,如果需要通过公网地址x.x.x.x访问192.168.1.2中的开放端口1234,则可以在Gateway中配置端口转发,但此时至少要有192.168.1.1的(部分)权限。

如果Gateway具备unpn功能,并且启用了unpn服务,则可以在Gateway外部通过upnp指令,打开Gateway上的转发通道,从而完成端口转发。

Gateway开启upnp示例(一般位于路由等设备的配置界面中):

3.利用

metasploit

Metasplioit中有upnp相关的插件,但是不太好用,姿势问题?
插件是:

  • auxiliary/scanner/upnp/ssdp_msearch
  • auxiliary/admin/upnp/soap_portmapping

可以自行探索之

miranda-upnp

miranda-upnp是之前在Github上找到的一个工具,基于python2编写,可以用于内网upnp端口转发通道的建立。

miranda-upnp(github)

upnp协议

也可以根据upnp协议自行实现相关工具,协议使用可以参考这篇文章

4. 演示

以第2节中的拓扑为例,在内网IP为192.168.1.2的Server中运行miranda-upnp,打开转发通道,在Gateway的x.x.x.x:1234与Server 192.168.1.2:1234之间建立映射。

运行miranda-upnp后,首先执行msearch

1
2
3
4
5
6
7
8
9
10
11
12
upnp> msearch

Entering discovery mode for 'upnp:rootdevice', Ctl+C to stop...

****************************************************************
SSDP reply message from 192.168.1.1:49652
XML file is located at http://192.168.1.1:49652/49652gatedesc.xml
Device is running Linux/3.10.53-HULK2, UPnP/1.0, Portable SDK for UPnP devices/1.6.25
****************************************************************

^C
Discover mode halted...

此时已经获得Gateway中的SSDP描述文件,Ctrl-C停止SSDP搜寻。

执行host list,列出扫描到的主机,并执行host get 0选中主机0(Gateway):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
upnp> host list

[0] 192.168.1.1:49652

upnp> host get 0

Requesting device and service info for 192.168.1.1:49652 (this could take a few seconds)...

Host data enumeration complete!

upnp> host info 0 deviceList

InternetGatewayDevice : {}
WANDevice : {}
WANConnectionDevice : {}

执行deviceListservices命令分别查看设备列表和设备中的服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
upnp> host info 0 deviceList InternetGatewayDevice services

Layer3Forwarding : {}

upnp> host info 0 deviceList WANDevice services

WANCommonInterfaceConfig : {}

upnp> host info 0 deviceList WANConnectionDevice services

WANIPConnection : {}

upnp> host info 0 deviceList WANConnectionDevice services

WANIPConnection : {}

upnp>

常规的端口转发功能我们要使用的是WANConnectionDevice设备的WANIPConnection服务,执行actions查看其动作,这里可以看到存在一个名为AddPortMapping的action,我们只要调用这个action,并填写相应参数,即可完成端口转发。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
upnp> host info 0 deviceList WANConnectionDevice services WANIPConnection actions

AddPortMapping : {}
GetNATRSIPStatus : {}
GetGenericPortMappingEntry : {}
GetSpecificPortMappingEntry : {}
ForceTermination : {}
GetExternalIPAddress : {}
GetConnectionTypeInfo : {}
GetStatusInfo : {}
SetConnectionType : {}
DeletePortMapping : {}
RequestConnection : {}

upnp> host send 0 WANConnectionDevice WANIPConnection AddPortMapping

Required argument:
Argument Name: NewPortMappingDescription
Data Type: string
Allowed Values: []
Set NewPortMappingDescription value to: XXXXX

Required argument:
Argument Name: NewLeaseDuration
Data Type: ui4
Allowed Values: []
Set NewLeaseDuration value to: 36000

Required argument:
Argument Name: NewInternalClient
Data Type: string
Allowed Values: []
Set NewInternalClient value to: 192.168.1.2

Required argument:
Argument Name: NewEnabled
Data Type: boolean
Allowed Values: []
Set NewEnabled value to: 1

Required argument:
Argument Name: NewExternalPort
Data Type: ui2
Allowed Values: []
Set NewExternalPort value to: 1234

Required argument:
Argument Name: NewRemoteHost
Data Type: string
Allowed Values: []
Set NewRemoteHost value to: 0.0.0.0

Required argument:
Argument Name: NewProtocol
Data Type: string
Allowed Values: ['TCP', 'UDP']
Set NewProtocol value to: TCP

Required argument:
Argument Name: NewInternalPort
Data Type: ui2
Allowed Values: []
Set NewInternalPort value to: 1234

可以看到此时Gateway中已经激活了相应的转发通道:

GO语言使用自定义包 第十七夜:编写一个Windows的服务
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×