View Javadoc
1   package com.jsql.model.injection.strategy;
2   
3   import com.jsql.model.InjectionModel;
4   import com.jsql.util.LogLevelUtil;
5   import org.apache.logging.log4j.LogManager;
6   import org.apache.logging.log4j.Logger;
7   import org.xbill.DNS.*;
8   import org.xbill.DNS.Record;
9   
10  import java.io.IOException;
11  import java.net.DatagramPacket;
12  import java.net.DatagramSocket;
13  import java.net.SocketException;
14  import java.util.ArrayList;
15  import java.util.List;
16  
17  public class DnsServer {
18  
19      private static final Logger LOGGER = LogManager.getRootLogger();
20  
21      private final InjectionModel injectionModel;
22      private final List<String> results = new ArrayList<>();
23      private DatagramSocket socket;
24      private boolean isStopped = false;
25  
26      public DnsServer(InjectionModel injectionModel) {
27          this.injectionModel = injectionModel;
28          try {
29              this.socket = new DatagramSocket(null);
30          } catch (SocketException e) {
31              LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
32          }
33      }
34  
35      public void listen() {
36          this.socket.close();  // unbind if already connected
37          int port = Integer.parseInt(this.injectionModel.getMediatorUtils().getPreferencesUtil().getDnsPort());
38          var domainName = this.injectionModel.getMediatorUtils().getPreferencesUtil().getDnsDomain();
39          this.results.clear();
40          try (var newSocket = new DatagramSocket(port)) {
41              this.socket = newSocket;
42              LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "DNS listening on port [{}] for [{}]...", port, domainName);
43  
44              byte[] buffer = new byte[512];
45              while (!this.isStopped) {
46                  DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
47                  this.socket.receive(packet);
48  
49                  Message query = new Message(packet.getData());
50                  Record question = query.getQuestion();
51                  Name name = question.getName();
52  
53                  if (name.toString().contains(domainName)) {
54                      this.results.add(name.toString());
55                  }
56  
57                  // Build response
58                  Message response = new Message(query.getHeader().getID());
59                  response.getHeader().setFlag(Flags.QR); // Response
60                  response.addRecord(question, Section.QUESTION);
61  
62                  response.addRecord(
63                      Record.fromString(
64                          Name.fromString(domainName +"."),
65                          Type.A,
66                          DClass.IN,
67                          86400,
68                          "127.0.0.1",
69                          Name.fromString(domainName +".")
70                      ),
71                      Section.ANSWER
72                  );
73  
74                  byte[] responseData = response.toWire();
75                  DatagramPacket responsePacket = new DatagramPacket(
76                      responseData,
77                      responseData.length,
78                      packet.getAddress(),
79                      packet.getPort()
80                  );
81                  this.socket.send(responsePacket);
82              }
83          } catch (SocketException e) {  // expected on receive() when socket is closed
84              LOGGER.log(LogLevelUtil.IGNORE, e, e);
85          } catch (IOException e) {
86              LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
87          } finally {
88              this.isStopped = false;
89          }
90      }
91  
92      public void close() {
93          this.socket.close();
94          this.isStopped = false;
95      }
96  
97      public List<String> getResults() {
98          return this.results;
99      }
100 }