AR-Framework

Just a quick post to mention I’ve created a site to document (very lightly) some of my MSc research, its available at arf.rootentropy.co.za. The code for the AR-Framework will only released once I’ve submitted my thesis and changed the comments to be suitable for PG13.

Enjoy.

Dionaea can be NOISY

So in my previous post I mentioned how one of my Dionaea honeypots was giving me trouble, the host it was running on was sitting at 20/20Gb used. Before that happened Dionaea was running fine. Anyway I finally had a chance to look at it today and found the problem, well not exactly but I used the lazy mans fix. Just posting it here in case someone else has to go through the same kak.

The Dionaea nfq module was failing hard, this is odd because by default it is not enabled (and I was running default settings). Taken from the official Dionaea site:

nfq can intercept incoming tcp connections during the tcp handshake giving your honeypot the possibility to provide service on ports which are not served by default.

It essentially replays whatever attack is coming in to the source in an attempt to keep the connection open and learn more, even from protocols and services it has no idea how to talk to.

Check diskspace with:

df -Th

in an actual directory you can use:

du -h

So my dionaea.log was just below 20Gb’s in size (the log is normally located in /var/dionaea/logs/dionaea.log)

Inspecting the log I found that dionaea managed to work itself into a endless debugging loop while trying to do something with the nfq module, I don’t know why, I don’t even have it enabled. This was taking up all the space:

nfq_io_cb loop 0xaa5140 w 0x51d0dc revents 1

nfq_io_cb loop 0xaa5140 w 0x51d0dc revents 1

nfq_io_cb loop 0xaa5140 w 0x51d0dc revents 1

To lazy way to fix this is to just turn off debug logging in the “dionaea.conf” file, I believe this is found in:

/etc/dionaea/dionaea.conf

One of the first entries in the config file is logging, by default its set to log “all” just change that to something like “critical” or whatever level of logging is sufficient for you.

The problem with this fix is that dionaea is still stuck in some loop and useing around 38% of the CPU, I’ll follow this a bit more when I have a chance (and manage to track someone down who knows dionaea a bit better).

Papers, Python and Poo

Why is there never enough time? I’m actually wondering if its possible to train oneself to type with 1 hand and then work across two PC’s at the same time? I think my brain would melt. So with time being a sincere douche bag, I thought I’d make a post on what I’ve been busy with the last few months.

Besides paper season now officially concluded (I did not make it to the nac of sac that smelled of poo). I did managed to get 3 papers submitted, all to ISSA. One in the main, another in the Information Warfare stream and a third in the Forensics in the Cloud stream. Big thanks to Mr @kamp_staaldraad as we co-authored all of them. I’ll edit this post with links to the papers once they are up on the ISSA site.

I’ve also managed to finish my AR-Framework, which I use in my research to automate the reconnaissance of malicious hosts on the intertubes. It does a lot, from session handling for various data sources to live fingerprinting. I do however believe that the AR-Framework deserves a separate blog post with lots of juicy details.

Speaking about data sources, I’ve written a little python script called hpclient.py which checks a dionaea (honeypot) database for new connections, creates a JSON encoded object and sends the data along (rather merely) to a RabbitMQ message broker. Its a neat way to get near real-time access to data on your honeypots. Not as neat as writing a custom ihandler, but, by god man! there is no time! This to will get a separate post (coupled with ntclient.py which is similar but slightly more heavy script for use with network telescopes)

I’ve also managed to get a dionaea honeypot up and running on the amazon EC2 cloud using their Free tier, thank you to Andrew for his quick and simple guide. My RabbitMQ broker has in the meantime decided that it does not like my EC2 honeypot and the reverse SSH tunnel I used to get AMQP traffic flowing, which made me sad. Hopefully I can figure it out soon.

In addition to the EC2 honeypot, a local (South African) VPS service has agreed to give me a free vps for September to run another HP. I got that up/running/sending data in 30mins and then another problem arose, disk quota exceeded warnings. Not sure how the hell I’m using 20/20gb but hopefully will get that sorted soon. The company also deserves a big thank you by name, but that will have to wait until my honeypot is no longer running. I don’t want you dirty internet folk messing with it.

Of-course all my code will make its way to my public git (bitbucket) repo in due course, for the moment I need to focus on finishing my thesis before the end of October 2012. That said, its back to writing for me, I have a rather stringent quota of writing for each day if I want to finish in time. I’ve also promised @kamp_staaldraad I post on our shared blog, which should be done before the end of the week.

Metasploit && PostgreSQL

Righto, so the other day I obliterated my postgre install, don’t ask me why or how. It suffice to say it was gone. Add to the fact that metasploit has deprecated the db_driver command, only supporting postgre now, so the sqlite3 instance I had is no more. Oh and if at any point during this post you sit there thing, what the fuck is he on about, I’m writing it as I understand, which might not be correct.

Anyway, I installed postgress and setup a new user. I have constant issues with my Internet connection between home and campus (both going through the university connection, only one requires proxy auth). apt-get was failing and I hate constantly changing settings so I just downloaded and compiled from source.

wget <postgres URL>

tar -xvf postgres-version && cd postgres-version

./configure

make

make install

Made a postgres user for metasploit, created a database and granted permissions to the metasploit user.

sudo -u postgres psql

postgres-# create user msfuser with password 'somepassword';

postgres-# create database msfdb;

postgres=# grant all privileges on database msfdb to msfuser;

I then fired up metasploit, connected to the db and thought everything was fine, but everytime I restarted my msfconsole session it would forget my db settings. mep.

Anyway, so did some digging in /opt/metasploit-X.X.X/config/

found the database.yml configuration and edited it to match the newly made database settings. Now everything is happy again and peace has been restored, no more msfconsole - n to keep it from crying…

How to 0wn conference proceedings

While working on my paper (Remote Fingerprinting and Multisensor Data Fusion) for a certain security conference that for the moment shall not be named,  I was distracted by the lack of security on their paper submission service.

After a tweet or two @RC1140 pointed me to the latest Phrack issue and the captcha owning therein. His efforts at inspiring evil overcame my weak will power towards all forms of malice and I decided that I will in addition to my initial paper, submit a WIP paper entitled How to 0wn conference proceedings and see how it goes. I hope there is enough time to complete it, but judging from past experience and sequential confirmation numbers(subtract number of papers published each year) on the afore mentioned paper submission service I’m pretty sure there will be another extension.

The paper outline and main ideas to follow, for you to see and here to live in-case it gets bounced from the actual proceedings.

No registration required!

Firstly to submit an abstract and paper, you are not required to register and confirm an account through email verification (as one would expect, *Cought* security conference? *Cought*). I have not even looked at their validation of MIME types and for the sake of my arguments this actually falls out of scope, but I’m sure someone can have some fun testing it.

So we are able to submit abstracts and papers without registration or a valid email, check.

Lack of Captcha!

Woe is me, nothing standing in the way of a simple script to generate and submit as many paper submissions as a while True loop and a cheap VPS’s bandwidth will allow. Beautiful soup and Selenium come to mind, but I wont be surprised if generating an HTML page locally and submitting it also works.

So we are able to submit custom abstracts and perhaps upload papers without any validation that we are human and not a script, check.

Malice a minute!

So you might find yourself asking, “What fine evil can we get up to on this fine evening?" Well this is why a special spot in a hot place will be reserved for me one day, for now lets just let the creative juices flow.

Firstly submitting thousands of papers from spoofed email addresses could cause conference organisers a serious headache, obfuscating legitimate submissions by burying them between fake submissions. Sure with some database foo they might be able to delete the fake submissions because they look the same, so lets address this issue.

Create another script to spider google scholar, citeseer or any other archive of papers, grab their abstracts and submit them. Now you have legitimate (if plagiarised) abstracts being submitted, much harder to detect and sort through.

I mentioned spoofing the email addresses, lets take that a step further, create another script to spider the Conference website (perhaps more specifically the past papers section), download the PDF’s and extract all the previous authors email addresses, now you have a nice long list of email addresses to really annoy the organisers and make your fake submissions look even more legit. It goes without saying that you can scrape the email addresses of other authors from citeseer, ect.

Other evil considerations!

Since the Conference in question so graciously sends you (or some other unfortunate soul) an email containing contents of the submission you made, how about using it to spam the masses with your own personal message, packed away in their email template. Perhaps using HTML to obscure some details?

Be naughty and re-use some work, as an added idea to thicken the plot of legitimate looking papers and fuel the ever increasing and annoying pattern of authors re-using their work, lets use a new script… The idea here is to scrape the Conference site for past papers, parse the paper and submit the contents to google translate, translate to language A (lets say German), then translate that to language B (Say Russia) and then finally (unless you want more repetitions) back to English. In so doing you should now have the same paper, but slightly reworded and ready for fresh publishing *ick*.

For the sake of politeness I have now deleted my tweets naming the conference, just seems fair since I’m making this blog post.

Pwnage and Ponies

Recently @barryirwin asked myself and @kamp_staaldraad to give a lecture on metasploit. The audience would be the 4th compsci students who selected to do the 5 week information security module. The lecture would be on the second last day of the course so they already had a feel for info sec, but had no actual hands on experience.

So with that in mind I set out to find some content and ideas for a introductory lecture on metasploit (a 2 hour slot was given to us).

The slides can be found here.

The Content:

I started off by introducing them to the structure of penetration testing, the different kinds web/infrastructure and some of the tools they might encounter (along with a nmap primer).  I then gave them a basic overview of what metasploit is and the various was you can interact with it (msfconsole, msfcli and armatage).

We then jumped into the metasploit database and how to use it, after which I went over the basic commands in msfconsole (use, set, search, back, show) and the directory structure. That covered the really basic and boring but necessary introduction, now it was time to move on to some demos (content still in the slides for later reference).

I showed them how to use msfconsole to bruteforce a mysql server, I started by showing them how to use nmap to find a server and then using auxiliary/scanner/mysql/mysql_login to bruteforce with a custom dictionary.

Next I gave them a quick primer on bind shells, reverse shells and meterpreter. After this was done I jumped into the hello world demo of metasploit => ms08-067. I showed them how to use the nmap scripting engine to check for smb vulns and then finally how to exploit one with metasploit. After the exploit I showed them how to use meterpreter and some of the common commands. I migrated from one process to another to show how you could move to a safer more permanent process and illustrate meterpreters new way of privilege escalation.

After the demo I went into msfpayload and showed them how to use it, I then went into msfencode and talked about why you would want to use an encoder and how to test your payloads with virus vault. The final topic I spoke about was using a custom executable templates and packers to further obfuscate a payload.

The Practical:

They were then given some practical exercises to solve, this they will do in their own time and submit for marking at a later stage. @kamp_staaldraad worked really hard on making fantastic looking simulations. Each of the students received 2 pre-made vm’s with instructions on what their mission was. The practical however deserves a whole post on its own which I will do once they have completed them and the marking has been done.

The Offensive Honeypot

This is a repost of what I sent to to the kippo users group on google.

I’m sure some of you have heard of LaBrea the ‘sticky’ honeypot that created a tarpit to throttle certain tcp based worms and in some cases stop them completely. Well, I thought the notion of using a honeypot for something other than information gathering and analysis was quite interesting. I think my discovery of LaBrea might have been the first steps towards realising an offensive honeypot and now I would like to take things further.

The first time I used a honeypot in an offensive manner was last year (2011) when I combined Dionaea and ettercap to create a service that would detect worm propagating on your local network and isolate/quarantine that host using ARP poisoning. This approach has its limitations but from an academic point of view I thought it was pretty neat, it’s a new way to use honeypots, it might not be the most efficient but it opens up new avenues of research and different ways of solving a problem.

I would now like to propose to you my current project, the offensive honeypot (still lacking a name at this point). I present this hoping to start a discussion; I would appreciate your thoughts on the topic, suggestions, concerns, requests and tips.

The basic idea here is to have an offensive honeypot that is used for username/password dictionary collection and striking back at the attacking hosts. I’m going to break the rest of this post into 4 sections to illustrate the functionality of this honeypot.

Services/Protocols

Initially it will only support ssh, this is just for me to get a feel for how it’s going to work and to sort out logic issues. Then later on I would like to add support for as many services as possible, if it is getting brute forced out there, it should be emulated by this honeypot. The honeypot will be written in python, I am currently busy with the ssh side of things and using twisted.conch. Further services emulation I would like to support include; ftp, mysql, mssql, postgres, vnc, rdp (what else can you think off?).

Dictionary Collection

This is a very important aspect of the honeypot, I would like to collect the actual dictionaries used by attackers and record the popularity/frequency of the use of these dictionaries according to the service being attacked. The honeypot will include logic to check once a new attack session has started, if the first username/password(u/p) matches any previously seen starting u/p combinations.

If there was a match it keeps a record of the u/p’s coming in (as associated with that dictionary) and if they all match the previously seen dictionary then increment the frequency of that dictionary for whichever service was being attacked. If the first u/p combination or subsequent ones don’t match a previously seen dictionary a new dictionary entry is made. There is a bit more to the logic, but this should give you an idea of what I’m after.

Strike Back

This is the actual offensive part of the honeypot, it replays the u/p combination the attacking host used back to that host. There are a couple of reasons for this, firstly from ethical standpoint the honeypot is not actively going out and attacking hosts on the internet, it is merely using a form of offensive self-defence replaying the attack it received to the host who sent it (I consider this reasonable and acceptable force) in reference to laws regarding self-defence in the physical world.

Secondly, this replay attack has a very high probability of working as the host that is attacking you has most likely been a victim to that same attack. Meaning the attacker is simply using a host they have already compromised to pivot attacks from.

Once a legitimate username and password combination has been found it is left to the discretion of the honeypot owner to what they would like to do, by default the honeypot will not store this u/p. The offensive honeypot could however be configured to do so and execute commands on the remote host if so desired.

Something that might be useful is to view currently logged in users, bash history, uptime and the IP address the last ssh connection came from. Once again, the responsibility of ethical and legal behaviour falls on the owner of the honeypot here. Guns don’t kill people, people kill people.

Informant Functionality

With this functionality the honeypot may be configured as a semi-automated warning system to inform compromised hosts of their current state. Using whois information or crawling a webpage for mailto tags to retrieve contact information and then compiling an email that would only require the honeypot owner to verify the details and then send.

I hope to have something out soon for those honeypot owners who want to give a little something back to their attackers.

Detecting W32/SQLSlammer with python

I’m throwing this bit of code out there, just to show how easy it can be to write nifty little scripts in python. Use this script for detecting the SQL slammer worm(or rather the exploit it uses). The SQLSlammer worm is a really neat little creature (if rather archaic). By neat and little, I mean all contained in a single UDP packet and able to make a MSsql server cry.

I had a look at the payload contained in the UDP packet and illustrate how to detect if the buffer overflow exploit for a vulnerable MSsql server is present.

And now I present to you the crude but effective python script I wrote to inspect traffic on a interface and alert you once a MSsql server buffer overflow exploit (the one used by Slammer) has been detected.

from pcapy import open_live
from impacket import ImpactDecoder

class Slammer:
    def __init__(self):
        max_bytes = 1024
        read_timeout = 100 # in milliseconds
        # Open live capture on eth0
        reader = open_live('eth0', max_bytes, True, read_timeout)
        reader.setfilter('udp')
        # Run the packet capture loop
        reader.loop(0, self.callback)
    
    def callback(self, hdr, data):  
        # Parse the Ethernet packet
        decoder = ImpactDecoder.EthDecoder()
        ether = decoder.decode(data)
        # Parse the IP packet inside the Ethernet packet
        iphdr = ether.child()
        # we only ude the udphdr but set the rest if 
        # you might want to use them later
        tcphdr = icmphdr = udphdr = iphdr.child()  
        #if iphdr.get_ip_p() == ImpactPacket.UDP.protocol:
        self.handle_udp(iphdr, udphdr)
        
    def handle_udp(self, iphdr, udphdr):
        try:
            print "[Inspecting UDP]"
            # We dont use most of these, but left them for refrence
            srcp = udphdr.get_uh_sport()
            dstp = udphdr.get_uh_dport()
            ip = iphdr.get_ip_src()
            len = udphdr.get_uh_ulen()
            chksum = udphdr.get_uh_sum()
            data = udphdr.get_data_as_string()
            # MS sql server port
            if dstp == 1434:
                print "srcport: %s | destport: %s | len: %s |"%(srcp, dstp, len)
                self.ident_slammer(data, ip) 
        except:
            failed = "I dont care"

    def ident_slammer(self, payload, ip):
        # set if 0x04 is found, which means its performing
        # a query to find a database on the given host
        query = 0 
        # length of the db name the query is asking for
        # if this is larger than 16 bytes,
        # it triggers the exploit. The name string should be terminated 
        # before the 16th byte with a 0x00
        length = 0
        index = 0
        for b in payload:
            h = ord(b)
            # read these three IF statements from the bottem up to get the logic
            if length > 16 and query == 1:
                print "DB namestring longer than 16 bytes"
                print "[SQL buffer overflow exploit] FOUND, incomming from: %s"%ip
                break;
            if query == 1:
                if h == 0:
                    break;
                else:
                    length += 1 
            if h == 4 and index == 0:
                query = 1
                print "Sql database search query..."
            index += 1
             
def main():
    print "--[Listening on eth0]--"
    slammer = Slammer()

if __name__ == "__main__":
    main()

MS11-083 Traffic Capture

Edit: Added short guide from Ryan Dewhurst (@ethicalhack3r) on how to get it running on Ubuntu [see bottom of post].

MS11-083 has arrived and people are getting both excited and scared, it looks like its going to be the next MS08-067. Which if you remember, Conficker used to bend windows over and have a jol. Time for a honeypot?

Disclaimer: This script is not intended to be a complete, efficient or stable. It’s just quick and dirty.

In anycase I took a moment and decided to write a script that would capture potential MS11-083 traffic in an attempt to capture this exploit in the wild (once its out there, might as well start looking). According to the security bulletin “The vulnerability could allow remote code execution if an attacker sends a continuous flow of specially crafted UDP packets to a closed port on a target system”. So that’s exactly what I looked at, I used netstat -un and -lun to find all open and listening ports and filtered them out. UDP packets to a closed port normally results in a ICMP Port Unreachable response or no response at all, so I’ve ignored them.

The code is commented and you need the little bash script in the same folder to get the ports. Remember to make it executable (sudo chmod +x getports.sh) and run ms11-083_sniffer.py as root. It will create a pcap file named the <current datetime.pcap> and any UDP traffic heading towards a closed port will be logged.

Once you have some pcaps and you think they might contain exploit traffic remember that sharing is caring and karma is a bitch, don’t share if it was just Chuck Testa. My code is dirty and I wrote it quickly so don’t hate, feel free to modify and make it better (in fact, you probably should).

I’ll try and add my nmap enumeration script tomorrow, it does a portscan and OS fingerprint on a given host and inserts that data into a sqlitedb. That way you can check if the traffic was coming from a windows host.

ms11-083_sniffer.py

getports.sh

With the bash script, just remove the .txt file extension (my hosting is being annoying). Below is the code if you want to have a peek.

   

from pcapy import *
from impacket import ImpactDecoder, ImpactPacket
from socket import *
import fcntl
import struct
import os
import time

class Sniffer:    
    def __init__(self):
        self.promiscuous = True
        self.called = 0 #silly habits
        self.interface = 'eth0'
        self.max_bytes = 65535  # Theoretical max size for a UDP packet
        self.read_timeout = 100
        self.ip = self.get_ip_address(self.interface)
        self.bpf = 'ip dst host %s and not src net 192.168.1.0/30'%self.ip
        
        print "\n---------------------------------------------------"
        print "Sniffing for unsolicited UDP packets to closed ports."
        print "      \"Open ports are for losers\" - MS11-083"
        print "Pcap log started, listening from %s"%time.strftime("%d:%m:%Y %H:%M:%S", time.localtime())
        print "---------------------------------------------------"
 
    def get_ip_address(self, ifname):
        s = socket(AF_INET, SOCK_STREAM)
        return inet_ntoa(fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s', ifname[:15]))[20:24])
    
    def start(self):
        self.reader = open_live(self.interface, self.max_bytes, self.promiscuous, self.read_timeout)
        # Pcapy uses BPF to filter packets, not src net 192.168.1.0/30 
        # should be changed, it just filters out 1.0, 1.1, 1.2 and 1.3
        # which I use for diffrent gateways and dont want traffic
        # from the router hitting the logs.
        self.reader.setfilter(self.bpf)
        # Run the packet capture loop
        self.reader.loop(0, self.callback)
          
    def callonce(self):
        self.dumper = self.reader.dump_open(time.strftime("%d-%m-%Y_%H-%M-%S.pcap", time.localtime()))    
        self.called = 1
    
    def callback(self, hdr, data):  
        # Parse the Ethernet packet
        decoder = ImpactDecoder.EthDecoder()
        ether = decoder.decode(data)
        # Parse the IP packet inside the Ethernet packet, typep
        iphdr = ether.child()
        udphdr = iphdr.child()
        
        # First check that the packets are not comming from the local host
        # Then check that it is a UDP packet (incase you changed the BPF) also
        # Check that the destination port for the packet is a closed port on the host
        if (iphdr.get_ip_src() != self.ip):
            self.refresh_portlist()
            if (iphdr.get_ip_p() == ImpactPacket.UDP.protocol and udphdr.get_uh_dport() not in self.portlist):
                if self.called == 0:
                    self.callonce()
                print "Incoming UDP packet from %s"%iphdr.get_ip_src()
                self.dumper.dump(hdr, data)
     
    def refresh_portlist(self):
        # bash script to get all the open and listening UDP ports
        # used in the callback function as criteria for logging traffic  
        output = os.popen("./getports.sh")
        pl = output.readlines()
        self.portlist = []
        for p in pl:
            self.portlist.append(int(p))
                    
def main():
    snf = Sniffer()
    snf.start()

if __name__ == "__main__":
    main()

Getting it up and running:

If anyone is stuck getting this working on ubuntu, Ryan Dewhurst (http://www.ethicalhack3r.co.uk/) made a short guide. Thanks!

Getting ms11-083_sniffer.py running on Ubuntu:

wget http://rootentropy.co.za/honeypot/ms11-083_sniffer.py
wget http://rootentropy.co.za/honeypot/getports.sh.txt
mv getports.sh.txt getports.sh
sudo chmod +x getports.sh
sudo apt-get install g++ python2.7-dev libpcap-dev
get http://oss.coresecurity.com/repo/pcapy-0.10.5.tar.gz
tar -xvf pcapy-0.10.5.tar.gz
cd pcapy-0.10.5/
sudo python setup.py install
cd ..
wget http://oss.coresecurity.com/repo/Impacket-0.9.6.0.tar.gz
tar -xvf Impacket-0.9.6.0.tar.gz
cd Impacket-0.9.6.0/
sudo python setup.py install
cd ..

I had to change line 82 in ms11-083_sniffer.py to include sh:
output = os.popen(sh ./getports.sh)

Then just run:
sudo python ms11-083_sniffer.py

(Update (on the (blog)))

Well since I’m useless at writing/finishing stuff within a linear timeline, I have decided to write a post on what is sitting in my drafts folder, all 7 of them. I guess its not a big issue since no one actually reads these ramblings, they are more of a reminder to myself to get things done.

So here follows the posts I’m busy working on:

Inferring DDoS Part 1: Flow Based Analysis.

I digg network telescopes (also known as blackhole, sinkholes or darknets if it floats your boat), they form a decent proportion of my research (both last year for Honours and this year for my MSc). This post explains how flow based analysis is used to detected DDoS attacks from traffic captured by a network telescope.

Inferring DDoS Part 2: Event Based Analysis.

Same as above but looks at event based analysis, which makes use of some time-domain qualities, which are essentially just a handful of metrics that help to detect and single out DDoS attacks.

Researching potentially malicious IP addresses

This post documents some of the analysis and information gathering scripts I have written over the last while to help me expand on data I collect with network telescopes. These include geoip lookups, projecthoneypot lookups, nmap scans, reverse dns and worm fingerprinting (slammer so far) from live traffic.

Dissecting W32/SQLSlammer.worm

This post is based on the analysis of slammer, a really neat little worm. By neat and little, I mean all contained in a single UDP packet and able to make a MSsql server bend over. I look at the payload, how to read the opcodes, what they do and how the exploit works. I then go through a pythons script I created to inspect traffic on a interface and alert you once sql slammer has been detected.

Penetration Testing Lifecycle

This is my attempt to get more familiar with what happens during a pen test, I’ve got some theoretical knowledge but not nearly enough practical hands covered in shell code, nitty gritty experience. So the post will cover pen testing broadly and also lay the foundation for subsequent posts based on more specific aspects, techniques, tools and considerations.

Pen Testing: Null byte problem

Really old bug that is still very prevalent and has decent coverage since it’s concerned with C string handling and subsequently effects almost everything built on C, which is harsh. The other issue is, its been around for ages but I believe it’s lost on most of us young folk and theses are the people who are building sites that will be vulnerable to the %00.

Defending against Phishing - Thats my image!

Yo phisher, I’m real happy for you and I’mma let you finish but that image your using is the best! Actually that image your using just got pulled from my web server, from a mail client, wtf? Actually its fine, just have this image instead. Encase you don’t have your OCR goggles on it says “This email is a phishing Scam”. The post will outline a defensive technique I haven’t seen anyone else employing and have POC code to boot.