字典破解密码:
- 设计一个信息系统,该系统可为学籍管理系统、订餐系统、票务管理系统不限, 系统必须通过客户端录入账号口令远程登录;
- 系统内至少包含三个以上账号,密码为 6 位以上任意字符组成;
- 设计程序设计程序在该系统所在服务器端进行字典密码破解,破解后将账号密码通过套 接字发送出去;
字典举例:
当前账号信息:
user:1234567
字典:
00000000
111111111
1234567
6666666666
Aaaaaaaa
1234567
为了破解用户名 user 的密码,将字典文件和密码进行依次比对,比对成功即破解。 - 在客户端用破解得到的账号口令进行登录,验证破解成功。
1.服务器(Server)
ServerMain:服务器启动入口
public class ServerMain {
public static void main(String[] args) {
try {
new Server().start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server:负责为所有客户端启动都启动一个线程去处理
public class Server {
private static String name = Server.class.getName();
private static Logger log = Logger.getLogger(name);
public void start() throws IOException {
ServerSocket server = new ServerSocket(8080);
log.info("服务器在8080端口启动。。。");
while (true) {
Socket conn = server.accept();
String reqAddr = conn.getInetAddress().getHostAddress();
log.info(reqAddr + "尝试连接...");
new ServerThead(conn).start();
}
}
}
ServerThread:具体的服务端线程
public class ServerThead extends Thread {
private Socket conn;
private Integer code;
private Integer clientCount = 1;
private static final Integer ERROR_USER = -1;
private static final Integer ERROR_PWD = 0;
private static final Integer SUCCESS = 1;
private static String name = Server.class.getName();
private static Logger log = Logger.getLogger(name);
public ServerThead(Socket conn) {
this.conn = conn;
}
@Override
public void run() {
try {
while (this.code != ERROR_USER || this.code != SUCCESS) {
read();
write();
}
conn.close();
} catch (IOException e) {
}
}
public void read() throws IOException {
InputStream inputStream = conn.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String msg = bufferedReader.readLine();
check(msg);
}
private void check(String msg) throws IOException {
File file = new File("server02/user.txt");
Reader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String info = bufferedReader.readLine();
String[] InfoSplit = info.split(":");
String[] msgSplit = msg.split(":");
String reqAddr = conn.getInetAddress().getHostAddress();
if (! InfoSplit[0].equals(msgSplit[0])) {
this.code = ERROR_USER;
log.info(reqAddr + " 账号错误,拒绝连接!");
} else if (! InfoSplit[1].equals(msgSplit[1])) {
this.code = ERROR_PWD;
log.info(reqAddr + " 密码错误。。。");
} else {
this.code = SUCCESS;
log.info("客户端" + clientCount + "(" + reqAddr + " )连接成功!!!");
clientCount++;
}
}
public void write() throws IOException {
OutputStream outputStream = conn.getOutputStream();
PrintWriter printWriter = new PrintWriter(outputStream);
printWriter.println(this.code);
printWriter.flush();
}
}
2.破解工具(Tool)
ToolMain:启动该破解工具
public class ToolMain {
public static void main(String[] args) {
try {
new Tool().start();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
ToolUtils:工具类,提供以下辅助方法
- 读取客户端信息(ip,port,username),udp模式
- 获取密码字典(pwdLib.txt)
- 将密码字典中的密码与username组装成访问服务器的token
- 将破解出的密码发送回客户端,udp模式
public class ToolUtils {
public static List<String> generateInfo(String username) throws IOException {
List<String> pwdList = getPwdListByDFS();
List<String> infoList = new ArrayList<>();
for (int i = 0; i < pwdList.size(); i++) {
String info = username + ":"+ pwdList.get(i);
infoList.add(info);
}
return infoList;
}
private static List<String> getPwdListByFile() throws IOException {
File file = new File("client02/src/tool/pwdLib.txt");
Reader reader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(reader);
ArrayList<String> pwdList = new ArrayList<>();
String pwd;
while ((pwd = bufferedReader.readLine()) != null) {
pwdList.add(pwd);
}
bufferedReader.close();
reader.close();
return pwdList;
}
// 暴力枚举
private static List<String> getPwdListByDFS() {
List<String> pwdList = new ArrayList<>();
generate(0, "", 6, pwdList);
return pwdList;
}
private static void generate(int level, String s, int n, List<String> res) {
if (level == n) {
res.add(s);
return;
}
for (int i = 0; i <= 9; i++) {
generate(level + 1, s + i, n, res);
}
}
public static Map<String,Object> recvServerInfo() throws IOException {
DatagramSocket socket = new DatagramSocket(1234);
DatagramPacket packet = new DatagramPacket(new byte[256], 256);
System.out.println("等待客户端请求...");
socket.receive(packet);
String serverInfo = new String(packet.getData());
String[] split = serverInfo.split(":");
HashMap<String, Object> infoMap = new HashMap<>();
infoMap.put("ip",split[0]);
infoMap.put("port",Integer.valueOf(split[1]));
infoMap.put("username",split[2].trim());
socket.close();
return infoMap;
}
public static void sendPwd(String pwd) throws IOException {
DatagramSocket socket = new DatagramSocket(1234);
DatagramPacket packet = new DatagramPacket(pwd.getBytes(), pwd.length(), InetAddress.getByName("localhost"), 6666);
socket.send(packet);
System.out.println("密码已向客户端发送!");
socket.close();
}
}
Tool:执行破解,依次将组装好的token发向服务端;若成功或账号错误则直接停止破解,返回错误;否则继续破解,直到找到或字典库用完;tcp模式
public class Tool {
private Socket client;
private static final Integer ERROR_USER = -1;
private static final Integer ERROR_PWD = 0;
private static final Integer SUCCESS = 1;
public void start() throws IOException, InterruptedException {
Map<String, Object> serverInfoMap = ToolUtils.recvServerInfo();
client = new Socket((String)serverInfoMap.get("ip"), (Integer)serverInfoMap.get("port"));
blast(ToolUtils.generateInfo((String) serverInfoMap.get("username")));
}
public boolean blast(List<String> infoList) throws IOException, InterruptedException {
OutputStream outputStream = client.getOutputStream();
PrintWriter printWriter = new PrintWriter(outputStream);
InputStream inputStream = client.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
for (String info : infoList) {
printWriter.println(info);
printWriter.flush();
Integer code = Integer.valueOf(reader.readLine());
if (code == ERROR_USER) {
System.out.println("账号错误");
ToolUtils.sendPwd("");
return false;
} else if (code == ERROR_PWD) {
// System.out.println("破解中..." + info.split(":")[1] + " 错误");
} else if (code == SUCCESS) {
System.out.println("破解成功!密码:" + info.split(":")[1]);
ToolUtils.sendPwd(info.split(":")[1]);
return true;
} else {
System.out.println("未知异常");
return false;
}
}
ToolUtils.sendPwd("");
System.out.println("字典中无匹配密码。。。");
return false;
}
}
3.客户端(Client)
ClientMain:启动客户端
public class ClientMain {
public static void main(String[] args) {
try {
new Client().start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client
- 读取用户输入(IP,port,username)
- 将请求信息发送给Tool进行破解,udp模式
- 接收破解后的密码,udp模式
- 若破解成功则用该密码尝试登陆,失败则结束程序,tcp模式
public class Client {
public void start() throws IOException {
String serverInfo = input();
useTool(serverInfo);
String pwd = serverInfo.split(":")[2] + ":" + recvPwd();
login(pwd);
}
public String input() {
String serverInfo = "";
System.out.print("服务器IP:");
Scanner in = new Scanner(System.in);
serverInfo = serverInfo + in.nextLine() + ":";
System.out.print("端口:");
serverInfo = serverInfo + in.nextLine() + ":";
System.out.print("账号:");
serverInfo = serverInfo + in.next();
return serverInfo;
}
public void useTool(String serverInfo) throws IOException {
DatagramSocket socket = new DatagramSocket(6666);
DatagramPacket packet = new DatagramPacket(serverInfo.getBytes(), serverInfo.length(),
InetAddress.getByName("localhost"), 1234);
socket.send(packet);
System.out.println("等待破解密码中...");
socket.close();
}
public String recvPwd () throws IOException {
DatagramSocket socket = new DatagramSocket(6666);
DatagramPacket packet = new DatagramPacket(new byte[32], 32);
socket.receive(packet);
if (new String(packet.getData()).trim().isEmpty()) {
System.out.println("破解失败。。。");
System.exit(0);
}
String pwd = new String(packet.getData());
System.out.println("获取到破解密码:" + pwd);
return pwd;
}
public void login(String pwd) throws IOException {
Socket client = new Socket("127.0.0.1", 8080);
System.out.println("尝试连接...");
OutputStream outputStream = client.getOutputStream();
PrintWriter printWriter = new PrintWriter(outputStream);
printWriter.println(pwd.trim());
printWriter.flush();
InputStream inputStream = client.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
if (Integer.valueOf(bufferedReader.readLine()) == 1 ) {
System.out.println("连接成功!");
} else {
System.out.println("连接失败!");
}
printWriter.close();
outputStream.close();
bufferedReader.close();
inputStream.close();
client.close();
}
}
结果分析
首先,启动服务器
然后,启动破解工具
下面演示三种情况:成功、失败、账号错误。
1)情况一:可以破解成功,账户是user(存在这个账户,且密码在字典库中)
2)情况二:登陆失败(字典用尽)
3)情况三:账号错误,输入一个服务器user.txt没有的账号


其余题目及代码
1)暴力破解密码
- 设计一个信息系统,该系统可为学籍管理系统、订餐系统、票务管理系统不限, 系统必须通过客户端录入账号口令远程登录;
- 系统内至少包含三个以上账号,密码为 6 位以上数字组成;
- 设计程序在该系统所在服务器端进行暴力密码破解,破解后将账号密码通过套接字发送出去;
- 在客户端用破解得到的账号口令进行登录,验证破解成功。
3)认证审计系统
- 设计一个信息系统,系统必须通过客户端录入账号口令远程登录;
- 系统内至少包含三个以上账号;
- 某账号登录后服务器端可实时显示该账号登录的时间及 IP 信息;
- 服务器端可查询账号的历史登录信息。
4)数据嗅探系统
-
设计一个信息系统,系统必须通过客户端录入账号口令远程登录;
-
登录后客户端可通过键盘输入向服务器发送数据;
-
服务器端设置嗅探关键字,如果客户端发送的数据包含该关键字,即将该数据显示出来。
举例:
服务器设置关键字:密码
客户端从键盘输入的数据 1:你好,我是张三
客户端从键盘输入的数据 2:我的密码是 password
服务器端显示:我的密码是 password
5)防火墙系统
- 设计一个信息系统,系统必须通过客户端录入账号口令远程登录;
- 系统内至少包含三个以上账号;
- 系统服务器端可设定禁止登录的 IP 地址和账号信息;
- 如果客户端从禁止的 IP 地址登录或使用禁止的账号登录则显示不允许登录,并断开连 接。
7)图形验证模拟
- 开发一个手机锁屏的图形验证程序,以字符命令行形式来实现要求完成的功能有:
- 登录时输入用户名;
- 输入 4*4 坐标下的图形点位置,用字符方式输入;
- 输入完成后实现在服务器端对图形进行验证;
- 至少有三个以上的用户验证。
举例:
显示:请输入用户名
输入:user
显示:请输入验证图形
输入:verify
显示:登录成功
这五个题目的代码我就不列出来了,有需要的同学可以到我的 GitHub 中 clone,点击这里跳转…另外,其中还有包括我当时结果截图的实验报告。在下载前请先看清 readme.md!
最后,如果觉得有帮助的同学,可以给我的博客点个赞,当然,再能关注一下是极好的~






















还没有评论,来说两句吧...