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 static void main(String[] args) {
36          new Thread(new DnsServer(new InjectionModel())::listen).start();
37      }
38  
39      public void listen() {
40          this.socket.close();  // unbind if already connected
41          int port = Integer.parseInt(this.injectionModel.getMediatorUtils().preferencesUtil().getDnsPort());
42          var domainName = this.injectionModel.getMediatorUtils().preferencesUtil().getDnsDomain();
43          this.results.clear();
44          try (var newSocket = new DatagramSocket(port)) {
45              this.socket = newSocket;
46              LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "DNS listening on port [{}] for [{}]...", port, domainName);
47  
48              byte[] buffer = new byte[512];
49              while (!this.isStopped) {
50                  DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
51                  this.socket.receive(packet);
52  
53                  Message query = new Message(packet.getData());
54                  Record question = query.getQuestion();
55                  Name name = question.getName();
56  
57                  if (name.toString().contains(domainName)) {
58                      // can println name on local
59                      this.results.add(name.toString());
60                  }
61  
62                  // Build response
63                  Message response = new Message(query.getHeader().getID());
64                  response.getHeader().setFlag(Flags.QR); // Response
65                  response.addRecord(question, Section.QUESTION);
66  
67                  response.addRecord(
68                      Record.fromString(
69                          Name.fromString(domainName +"."),
70                          Type.A,
71                          DClass.IN,
72                          86400,
73                          "127.0.0.1",
74                          Name.fromString(domainName +".")
75                      ),
76                      Section.ANSWER
77                  );
78  
79                  byte[] responseData = response.toWire();
80                  DatagramPacket responsePacket = new DatagramPacket(
81                      responseData,
82                      responseData.length,
83                      packet.getAddress(),
84                      packet.getPort()
85                  );
86                  this.socket.send(responsePacket);
87              }
88          } catch (SocketException e) {  // expected on receive() when socket is closed
89              LOGGER.log(LogLevelUtil.IGNORE, e, e);
90          } catch (IOException e) {
91              LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
92          } finally {
93              this.isStopped = false;
94          }
95      }
96  
97      public void close() {
98          this.socket.close();
99          this.isStopped = false;
100     }
101 
102     public List<String> getResults() {
103         return this.results;
104     }
105 }