APP Tracking Cookies Monster using WatchService

Joe

Thành viên VIP
21/1/13
2,951
1,318
113
Hi

You all surely know that every site where you visit will tries to track you with cookies. Cookies are used to tag your computer with an unique ID. When you visit several sites and each site checks your computer for the Cookies ID and if the ID is everywhere the same your "surfing route" (where you were) can be deduced and your surfing behavior (e.g. what item you click at) can be interpreted. It's Your profile and it is assembled together from the surfing route and behavior. That is most universal the tracking technique. The vilest tracking comes from all FREE social networks (e.g. Facebook). To finance themselves all free social networks create therewith the profiles of their users (or clients) and sell them to the advertisers. And Facebook, for example, becomes a billion US$ company. All that comes from the profiles of its users. Your profile.

The way how cookies are implemented is so manifold that I won't go into details about Cookies Implementation. However all most popular browsers (Microsoft Edge, Google Chrome, Firefox and Opera) allow you to manage the cookies. The Cookies are usually saved in a file called Cookies (and Cookies-journal). And its format is usually SQLITE. The question is how trustable the Cookies Management tools are. Trust yourself is the foolproof trust, isn't it? I show you hereunder a JAVA implementation in SWING that runs independently from any browser.

The codes: CookiesMonster.java

Java:
import java.util.concurrent.*;
import java.awt.event.*;
import java.nio.file.*;
import java.util.*;
import java.io.*;
//
import javax.swing.*;
// Joe T. Nartca (C)
public class CookiesMonster extends Thread {
  public static void main(String... a) throws Exception {
    UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
    new CookiesMonster(a.length == 0? "CookiesList.txt":a[0]);
  }
  // Constructor
  public CookiesMonster(String config) throws Exception {
    prop = new Properties();
    prop.load(new FileInputStream(config));
    load( );
    // SWING
    JFrame jf = new JFrame("CookiesMonster");
    JButton but = new JButton("EXIT", new ImageIcon("cookies_monster.png"));
    but.addActionListener(e -> {
      halt( );
      System.exit(0);
    });
    jf.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    JLabel lab = new JLabel("CookiesMonster is");
    JPanel pan = new JPanel();
    pan.add(lab);
    pan.add(but);
    jf.add(pan);
    jf.pack();
    jf.setVisible(true);
  }
  private void load( ) {
    end = false;
    cookies = true;
    pool = Executors.newFixedThreadPool(10);
    //
    fLst = new ArrayList<>();
    String Cookies = prop.getProperty("OPERA");
    if (Cookies != null) { // Opera
      fLst.add(Cookies+"/Cookies");
      fLst.add(Cookies+"/Cookies-journal");
    }
    Cookies = prop.getProperty("CHROME");
    if (Cookies != null) { // Chrome
      fLst.add(Cookies+"/Safe Browsing Cookies-journal");
      fLst.add(Cookies+"/Safe Browsing Cookies");
      fLst.add(Cookies+"/Cookies-journal");
      fLst.add(Cookies+"/Cookies");
    }
    Cookies = prop.getProperty("FIREFOX");
    if (Cookies != null) fLst.add(Cookies+"/cookies.sqlite");
    Cookies = prop.getProperty("EDGE");
    if (Cookies != null) fLst.add(Cookies+"/Cookies");
    start( );
  }
  public void halt( ) {
    try {
      end = true;
      for (String fn : fLst) {
        RandomAccessFile raf = new RandomAccessFile(fn, "rw");
        raf.setLength(0);
        raf.close();
      }
      String Cookies = prop.getProperty("OPERA");
      if (Cookies != null) { // Opera
        FileOutputStream fou = new FileOutputStream(Cookies+"/opera_autoupdate.log", false);
        fou.close();
        File[] files = new File(Cookies).listFiles();
        for (File file : files) if (file.isFile()) {
          String fn = file.getName(); // remove all ssdfp... files
          if (fn.indexOf("ssd") == 0 && fn.indexOf(".lock") < 0 || fn.indexOf(".old") > 0) file.delete();
        }
      }
      Cookies = prop.getProperty("CHROME");
      if (Cookies != null) { // Chrome
        File[] files = new File(Cookies).listFiles();
        for (File file : files) if (file.isFile() && file.getName().indexOf(".old") > 0 ) file.delete();
      }
      Cookies = prop.getProperty("FIREFOX");
      if (Cookies != null) { // FireFox
        FileOutputStream fou = new FileOutputStream(Cookies+"/cookies.sqlite.bak", false);
        fou.close();
      }
    } catch (Exception ex) { }
    pool.shutdownNow();
  }
  //
  @SuppressWarnings("unchecked")
  public void run( ) {
    for (final String fN : fLst) pool.submit(()-> {
      RandomAccessFile raf = null;
      try {
        String fn = fN.replace("/", File.separator);
        raf = new RandomAccessFile(fn, "rw");
        WatchService ws = FileSystems.getDefault().newWatchService();
        String dir = fn.substring(0, fn.lastIndexOf(File.separator)+1);
        WatchKey wk = Paths.get(dir).register(ws,
                                              StandardWatchEventKinds.ENTRY_CREATE,
                                              StandardWatchEventKinds.ENTRY_DELETE,
                                              StandardWatchEventKinds.ENTRY_MODIFY);
        OUT: while (!end) {
          for (WatchEvent<?> event : wk.pollEvents()) {
            if (end) break OUT;
            WatchEvent.Kind<?> kind = event.kind();
            if ((dir+((WatchEvent<Path>)event).context().toFile()).equalsIgnoreCase(fn) &&
                (kind == StandardWatchEventKinds.ENTRY_MODIFY ||  kind == StandardWatchEventKinds.ENTRY_CREATE))
            try {
              raf.setLength(0); // reset Cookies
              break;
            } catch (Exception ex) {
              //ex.printStackTrace();
            }
          }
          wk.reset();
          try { Thread.sleep(500); }
          catch (Exception e) { }
        }    
      } catch (Exception ex) {
        //ex.printStackTrace();
      }
      try {
        if (raf != null) raf.close();
      } catch (Exception ex) { }
    });
  }
  //
  private Properties prop;
  private List<String> fLst;
  private ExecutorService pool;
  private volatile boolean end = false, cookies;
}
How it works? CookieMonster checks every 200 milliseconds for an eventual Cookies Entry and remove it immediately so that any tracking becomes irrelevant. And when the app is terminated it clears all the cookies that still be left..in the Cookies files.

For WINDOWS 10 you have to configure the CookieList.txt that contains the Cookies Directories and is as following:
Code:
#-------------------------------------------------------------------------------
# Cookies directory on WINDOWS 10
#
CHROME=C:/Users/[USER-NAME]/AppData/Local/Google/Chrome/User Data
OPERA=C:/Users/[USER-NAME]/AppData/Roaming/Opera Software/Opera Stable
EDGE=C:/Users/[USER-NAME]/AppData/Local/Microsoft/Edge/User Data/Default
FIREFOX=C:/Users/[USER-NAME]/AppData/Roaming/Mozilla/Firefox/Profiles/usqz5p89.default
Where [USER_NANE] is the Sign-In name of your PC. This list contains the directories of browsers (here: Chrome, Edge, Firefox, Opera). If your PC-OS is
LINUX you have to check for the correct paths of this list.

How to build the CookiesMonster?

  1. Copy the source to any directory and the CookieList.txt
  2. Correct the cookieList.txt according to your environment
  3. Download the CookiesMonster image to the same directory
  4. Compile it
And that's all, folk! The app will appear like this Monster_start.png

An important hint:
If you run this little CookiesMonster app parallelly to Opera Browser (with ad-blocker ON) you could enjoy YouTube almost free of ads.

Have fun!
 

Attachments

Sửa lần cuối:

Joe

Thành viên VIP
21/1/13
2,951
1,318
113
The CookiesMonster app can be modified to an API so that you can invoke it from your own application.

The Parameters file used by Properties
Code:
#-------------------------------------------------------------------------------
# Cookies Management with Cookies directory on WINDOWS 10
# SWEEP=n  where n in milliseconds, sweeping times for cookies (min. 200).
#
SWEEP=500
#
OPERA=C:/Users/[USER-NAME]/AppData/Roaming/Opera Software/Opera Stable
EDGE=C:/Users/[USER-NAME]/AppData/Local/Microsoft/Edge/User Data/Default
CHROME=C:/Users/[USER-NAME]/AppData/Local/Google/Chrome/User Data/Default
FIREFOX=C:/Users/[USER-NAME]/AppData/Roaming/Mozilla/Firefox/Profiles/usqz5p89.default
#-------------------------------------------------------------------------------
The CookiesMonster.java as API
Java:
import java.util.concurrent.*;
import java.nio.file.*;
import java.util.*;
import java.io.*;
// Joe T. Nartca (C)
public class CookiesMonster extends Thread {
  // Constructor
  public CookiesMonster(Properties prop) {
    end = false;
    this.prop = prop;
    pool = Executors.newFixedThreadPool(10);
    // Cookies sweeping time (milliSeconds)
    String cookies = prop.getProperty("SWEEP");
    if (cookies == null) time = 500;
    else {
      time = Integer.parseInt(cookies);
      if (time < 200) time = 200;
    }
    fLst = new ArrayList<>();
    cookies = prop.getProperty("OPERA");
    if (cookies != null) { // Opera
      fLst.add(cookies+"/cookies");
      fLst.add(cookies+"/cookies-journal");
    }
    cookies = prop.getProperty("CHROME");
    if (cookies != null) { // Chrome
      fLst.add(cookies+"/Safe Browsing cookies-journal");
      fLst.add(cookies+"/Safe Browsing cookies");
      fLst.add(cookies+"/cookies-journal");
      fLst.add(cookies+"/cookies");
    }
    cookies = prop.getProperty("FIREFOX");
    if (cookies != null) fLst.add(cookies+"/cookies.sqlite");
    cookies = prop.getProperty("EDGE");
    if (cookies != null) fLst.add(cookies+"/cookies");
    start( );
  }
  public void halt( ) {
    end = true;
    cleanup(prop);
    pool.shutdownNow();
  }
  @SuppressWarnings("unchecked")
  public void run( ) {
    for (final String fN : fLst) pool.submit(()-> {
      RandomAccessFile raf = null;
      try {
        String fn = fN.replace("/", File.separator);
        raf = new RandomAccessFile(fn, "rw");
        WatchService ws = FileSystems.getDefault().newWatchService();
        String dir = fn.substring(0, fn.lastIndexOf(File.separator)+1);
        WatchKey wk = Paths.get(dir).register(ws,
                                              StandardWatchEventKinds.ENTRY_CREATE,
                                              StandardWatchEventKinds.ENTRY_DELETE,
                                              StandardWatchEventKinds.ENTRY_MODIFY);
        OUT: while (!end) {
          for (WatchEvent<?> event : wk.pollEvents()) {
            if (end) break OUT;
            WatchEvent.Kind<?> kind = event.kind();
            if ((dir+((WatchEvent<Path>)event).context().toFile()).equalsIgnoreCase(fn) &&
                (kind == StandardWatchEventKinds.ENTRY_MODIFY ||  kind == StandardWatchEventKinds.ENTRY_CREATE))
            try {
              System.out.println(fn+": "+raf.length());
              raf.setLength(0); // reset Cookies
              break;
            } catch (Exception ex) {
              //ex.printStackTrace();
            }
          }
          wk.reset();
          try { Thread.sleep(time); }
          catch (Exception e) { }
        }
      } catch (Exception ex) {
        //ex.printStackTrace();
      }
      try {
        if (raf != null) raf.close();
      } catch (Exception ex) { }
    });
  }
  //
  public static void cleanup(Properties prop) {
    try {
      String Cookies = prop.getProperty("OPERA");
      if (Cookies != null) { // Opera
        FileOutputStream fou = new FileOutputStream(Cookies+"/opera_autoupdate.log", false);
        fou.close();
        RandomAccessFile raf = new RandomAccessFile(Cookies+"/Cookies", "rw");
        raf.setLength(0);
        raf.close();
        raf = new RandomAccessFile(Cookies+"/Cookies-journal", "rw");
        raf.setLength(0);
        raf.close();
        File[] files = new File(Cookies).listFiles();
        for (File file : files) if (file.isFile()) {
          String fn = file.getName(); // remove all ssdfp... files
          if (fn.indexOf("ssd") == 0 && fn.indexOf(".lock") < 0 || fn.indexOf(".old") > 0) file.delete();
        }
      }
      Cookies = prop.getProperty("CHROME");
      if (Cookies != null) { // Chrome
        RandomAccessFile raf = new RandomAccessFile(Cookies+"/Cookies-journal", "rw");
        raf.setLength(0);
        raf.close();
        raf = new RandomAccessFile(Cookies+"/Safe Browsing Cookies-journal", "rw");
        raf.setLength(0);
        raf.close();
        raf = new RandomAccessFile(Cookies+"/Safe Browsing Cookies", "rw");
        raf.setLength(0);
        raf.close();
        raf = new RandomAccessFile(Cookies+"/Cookies", "rw");
        raf.setLength(0);
        raf.close();
        File[] files = new File(Cookies).listFiles();
        for (File file : files) if (file.isFile() && file.getName().indexOf(".old") > 0 ) file.delete();
      }
      Cookies = prop.getProperty("FIREFOX");
      if (Cookies != null) { // FireFox
        RandomAccessFile raf = new RandomAccessFile(Cookies+"/cookies.sqlite", "rw");
        raf.setLength(0);
        raf.close();
         (new File(cookies+"/Cookies.sqlite.bak")).delete();
      }
      Cookies = prop.getProperty("EDGE");
      if (Cookies != null) { // Edge
        RandomAccessFile raf = new RandomAccessFile(Cookies+"/cookies", "rw");
        raf.setLength(0);
        raf.close();
      }
    } catch (Exception ex) { }
  }
  //
  private int time;
  private Properties prop;
  private List<String> fLst;
  private ExecutorService pool;
  private volatile boolean end = false;
}
And how this CookiesMonster API is used:
Java:
import javax.swing.*;
// Joe Nartca (C)
public class Cookies {
  public static void main(String... a) throws Exception {
    UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
    new Cookies(a.length == 0? "CookiesList.txt":a[0]);
  }
  // 1st Constructor
  public Cookies(String config) throws Exception {
    java.util.Properties prop = new java.util.Properties();
    prop.load(new java.io.FileInputStream(config));
    monster = new CookiesMonster(prop);
    // SWING
    JFrame jf = new JFrame("CookiesMonster");
    JButton but = new JButton("OFF", new ImageIcon("cookies_monster.png"));
    but.addActionListener(e -> {
      if (but.getText().equals("OFF")) {
        but.setText("ON");
        monster.halt( );
        monster = null;
     }  else {
       but.setText("OFF");
       monster = new CookiesMonster(prop);
     }
    });
    JButton exit = new JButton("EXIT");
    exit.addActionListener(e -> {
      if (monster != null) monster.halt( );
      else CookiesMonster.cleanup(prop);
      System.exit(0);
    });
    jf.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    JPanel pan = new JPanel();
    pan.add(but);
    pan.add(exit);
    jf.add(pan);
    jf.setSize(350, 155);
    jf.setVisible(true);
  }
  private CookiesMonster monster;
}
The appearance
Monster.png
 
Sửa lần cuối: