RouterOS抓包恢复PPPOE密码
2018.05.01
codewindy
 热度
℃
RouterOS PPPOE(Session) Password Packet Sniffer
背景
过程
考虑到我买的rb750gr3不具有通用性及经济实惠性,我后面都采用虚拟机来实现
先将家里老旧路由器的 WAN口 插上网线连接到电脑的 RJ45网口
打开虚拟机vmware 导入 routeros 镜像, 桥接到物理网卡
下载并打开winbox客户端,并通过winbox 来登录ros,默认帐号是 admin 密码是 空
[admin@fsm] > ip export # may/02/2019 15:45:48 by RouterOS 6.44.2 # software id = ZJ3M-ESHW # /ip pool add name=pool1 ranges=10.16.0.2-10.16.0.254 /ip address add address=192.168.199.22/24 comment=defconf interface=ether1 network=192.168.199.0 add address=192.168.199.122/24 interface=ether1 network=192.168.199.0 /ip cloud set update-time=no /ip dhcp-client add dhcp-options=hostname,clientid disabled=no interface=ether1 /ip dns set allow-remote-requests=yes servers=192.168.199.1 /ip firewall nat add action=masquerade chain=srcnat out-interface-list=WAN /ip route add disabled=yes distance=1 gateway=192.168.199.1 [admin@fsm] > ppp export # may/02/2019 15:45:52 by RouterOS 6.44.2 # software id = ZJ3M-ESHW
/ppp profile add dns-server=223.5.5.5 local-address=10.16.0.1 name=8M remote-address=pool1
|
原理
- chap ** 认证过程是md5加密的,但是pap 是明文认证方式,所以我们通过ros伪造pppoe**服务器来抓包获取
- PPP-PAP认证原理
- PPP-CHAP认证原理
PPP提供了两种可选的身份认证方法:口令验证协议PAP(Password Authentication Protocol,PAP)和质询握手协议(Challenge Handshake Authentication Protocol,CHAP)。如果双方协商达成一致,也可以不使用任何身份认证方法。 CHAP认证比PAP认证更安全,因为CHAP不在线路上发送明文密码,而是发送经过摘要算法加工过的随机序列,也 被称为”挑战字符串”.如图所示。同时,身份认证可以随时进行,包括在双方正常通信过程中。因此,非法用户就算截获并成功破解了一次密码,此密码也将在 一段时间内失效
))
- 使用Java代码来创建和解析出账号密码
- 项目地址
https://github.com/codewindy/JavaTutorials
package com.codewindy.mongodb.service.impl;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.ssh.JschUtil; import cn.hutool.extra.ssh.Sftp; import com.codewindy.mongodb.pojo.ApiResult; import com.codewindy.mongodb.pojo.PppoeDetail; import com.codewindy.mongodb.service.MikrotikService; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import me.legrange.mikrotik.ApiConnection; import me.legrange.mikrotik.MikrotikApiException; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils;
import java.io.File; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors;
@Service @Slf4j public class MikrotikServiceImpl implements MikrotikService {
@Override public ApiResult login(String username, String password) { ApiConnection con = null; try { con = initApiConnection(username, password); List<Map<String, String>> execute = con.execute("/ip/address/print"); con.close(); return new ApiResult(execute);
} catch (MikrotikApiException e) { log.info("登录RouterOS失败 = {}", e.getMessage()); return new ApiResult(e.getMessage()); } }
@Override public ApiResult createPPPOEServer(String ipPoolRange) { ApiConnection con = null; try { con = initApiConnection("admin", ""); con.execute("/ip/pool/print"); con.execute("/ip/pool/add name=pool1 ranges=10.10.10.2-10.10.20.1"); con.execute("/ppp/profile/add name=pppoe_10M remote-address=pool1"); con.execute("/ppp/secret/add name=0327 password=0327Test service=pppoe profile=pppoe_10M"); con.execute("/interface/pppoe-server/server/add authentication=pap service-name=PPPoE_Server interface=ether1 one-session-per-host=yes default-profile=pppoe_10M"); con.execute("/interface/pppoe-server/server/enable numbers=0"); String command4capFileName = "/tool/sniffer/set file-name=%s.cap filter-mac-protocol=pppoe file-limit=10KiB memory-limit=10KiB"; con.execute(String.format(command4capFileName, DateUtil.today())); log.info("开始执行抓包pppoe-session==={}", String.format(command4capFileName, DateUtil.today())); con.execute("/tool/sniffer/start mac-protocol=pppoe interface=ether1 direction=rx"); List<Map<String, String>> resultMapList = con.execute("/file/print"); for (Map<String, String> fileMap : resultMapList) { if ((fileMap.get("type").contains(".cap") || fileMap.get("type").contains(".pcap"))&& Integer.parseInt(fileMap.get("size"))>1000){ con.execute("/tool/sniffer/stop"); } } return new ApiResult("初始化pppoe服务器成功!"); } catch (MikrotikApiException e) { log.info("登录RouterOS失败 = {}", e.getMessage()); return new ApiResult(e.getMessage()); } }
private ApiConnection initApiConnection(String username, String password) throws MikrotikApiException { ApiConnection con; con = ApiConnection.connect("192.168.2.2"); con.setTimeout(5000); con.login(username, password); return con; }
@Override public ApiResult getPcapFileDetail() { ApiConnection con = null; try { con = initApiConnection("admin", ""); List<Map<String, String>> resultMapList = con.execute("/file/print"); resultMapList.stream().filter(s -> s.get("type").contains(".cap") || s.get("type").contains(".pcap")).forEach(s -> System.out.println("pcap报文的size="+s.get("size"))); List<String> contentList = resultMapList.stream().filter(s -> s.get("type").contains(".cap") || s.get("type").contains(".pcap")).map(s -> s.get("contents")).collect(Collectors.toList()); Set<String> pppoeAccountSet = contentList.stream().filter(content -> content.contains("user")&& content.contains("authentication")).map(content -> StrUtil.subBetween(content, "user", "authentication").trim()).collect(Collectors.toSet()); List<PppoeDetail> pppoeDetailList = Lists.newArrayListWithCapacity(pppoeAccountSet.size()); for (String pppoeAccount : pppoeAccountSet) { List<String> passwordlist = contentList.stream().filter(content->content.contains(pppoeAccount)).map(content -> StrUtil.subBetween(content, pppoeAccount, "\u0000").trim()).distinct().collect(Collectors.toList()); PppoeDetail pppoeDetail = new PppoeDetail(); pppoeDetail.setAccount(pppoeAccount); if (!CollectionUtils.isEmpty(passwordlist)) { pppoeDetail.setPassword(StrUtil.subPre(passwordlist.get(0),16)); } pppoeDetailList.add(pppoeDetail); } con.close(); return new ApiResult(pppoeDetailList); } catch (MikrotikApiException e) { log.info("获取PPPOESession详情失败 = {}", e.getMessage()); return new ApiResult(e.getMessage()); } }
@Override public ApiResult downloadPPPOESession() { try { Sftp sftp= JschUtil.createSftp("192.168.2.2", 22, "admin", ""); sftp.cd("/"); log.info("获取sftp文件当前路径",sftp.pwd()); log.info("显示当前目录下的文件",sftp.ls("/")); List<String> fileList = sftp.ls("/"); fileList.stream().filter(s -> s.contains(".cap") || s.contains(".pcap")).forEach(capFile -> sftp.get(capFile, "C:\\WBYF_IDEA\\"));
sftp.close(); return new ApiResult("下载pcap数据文件成功"); } catch (Exception e) { log.info("下载pcap抓包文件失败 = {}", e.getMessage()); return new ApiResult(e.getMessage()); } }
@Override public ApiResult parseLocalPcapFile() {
String path ="C:\\WBYF_IDEA\\JavaTutorials\\mongodb\\src\\main\\resources\\pcap"; List<String> fileList = FileUtil.listFileNames(path); List<String> parsedStringList = Lists.newArrayListWithCapacity(fileList.size()); for (String pcapFileName : fileList) { if (pcapFileName.contains(".cap")||pcapFileName.contains(".pcap")) { System.out.println("pcapFileName = " + path+File.separator+pcapFileName); String parsedString = FileUtil.readString(path+File.separator+pcapFileName, CharsetUtil.UTF_8); parsedStringList.add(parsedString); } }
return new ApiResult(parsedStringList); } }
|
结论
- 使用wireshark 打开抓到的cap 报文即可.
参考