Cisco Stealthwatch Alarm and Graylog

I just love Stealthwatch and Cisco “network a as sensor” concept. If you think traditional SIM/SIEM systems and visibility what is moving in your network L2/L3 level, I claim that the visibility is zero.

You can send switch or router or server syslog data to your SIM/SIEM server and still not get visibility to your network traffic in L2/L3 level. If your router is smart enough it maybe can told some information about connections, but what if there is asymmetric/dynamic routing and different data flows goes to different paths?

SIM/SIEM can see network connection traffic only from Firewalls, because FW can told that.

But what if your network device where your client is connected can told every flow what you send or receive? What if all network switches, routers, firewall and clients can told that where traffic going? If you are lucky and you have also identity based network with pxGrid, then you get real 360 visibility in your traffic.

Think about situation, when you are implementing new DNS server and you want to know what clients are still using old ones or tried to use some public servers. What if you have SCADA network and you want to do segmentation without segmentation? In Stealthwatch you can create rules that SCADA1 can talk to the SCADA2, but not SCADA3 server when those servers are in same network segment or even same switch. If SCADA1 sends any data to SCADA3 Stealthwatch will create alarm and that alarm can be forward to the Graylog server.

How STW (Stealthwatch) and Graylog can be integrate together, so that you can see STW generated alarms in your Graylog server? I assume that you already have Stealthwatch and Graylog up and running. I will use STW version 7.1.1 and Graylog 3.2.3.

Graylog configuration

First we configure Graylog to receive message from STW.

Go System/Inputs and Inputs.
Launch new Raw/Plaintext UDP input.
Create new input at port 1516 and name it.

Now we need to add extractor, which is parse incoming messages.

Click Manage extractors.
Choose Actions and Import extractors.

You can download latest extractor in my github https://github.com/hrleinonen/graylog-stealthwatch paste that json file in your Graylog import extractors.

Extractor brings these new fields in your graylog:

ALARMSEV = Alarm severity
ALARMSTATUS = Alarm current status
CAT = Alarm category
DOMAIN = STW Domain
DST = Destination
DSTPORT = Destination port
FLOWCOLLECTORIP = Flowcollector IP
FLOWCOLLECTORNAME = Flowcollector name
HOSTNAME = SMC hostname
PROTO = IP protocol
SOURCEHG = Source host group
SRC = Source
TARGETHG = Target host group

Stealthwatch configuration

First open Configuration > Response Management.
Choose Syslog Formats.
Give name, description, facility and severity. Copy MSG Part bellow.

Create new syslog format.

LEEF:2.0|Lancope|Stealthwatch|7.1|{alarm_type_id}|0x7C|src={source_ip}|dst={target_ip}|dstPort={port}|proto={protocol}|msg={alarm_type_description}|fullmessage={details}|start={start_active_time}|end={end_active_time}|cat={alarm_category_name}|alarmID={alarm_id}|sourceHG={source_host_group_names}|targetHG={target_host_group_names}|sourceHostSnapshot={source_url}|targetHostSnapshot={target_url}|flowCollectorName={device_name}|flowCollectorIP={device_ip}|domain={domain_name}|exporterName={exporter_hostname}|exporterIPAddress={exporter_ip}|exporterInfo={exporter_label}|targetUser={target_username}|targetHostname={target_hostname}|sourceUser={source_username}|alarmStatus={alarm_status}|alarmSev={alarm_severity_name}

Syslog message format and fields what Stealthwatch is sending to the Graylog.

Choose Actions.

Next we create server where to send alarms.

Give name, description, your Graylog server IP-address, port and choose your new syslog message format.
Choose Rules.

Next we choose what to send.

Give name, description, domain and what should be true. I choose here All, so this will send all STW alarms to Graylog.

And where to send alarms.

Click Add and choose your new

Graylog Stealthwatch Dashboard

I have created also simple example dashboard, which is telling basic information about alarms. You can download json file in my github. You must edit dashboard so that you replace DOMAIN:PUT-MY-OWN-DOMAIN-HERE at you own domain, like DOMAIN:acme.local

STW simple dashboard.

Ubuntu (and maybe others) OpenLDAP 2.4+ and schema extension

I needed to integrate Cisco ISE (Identity Service Engine) and OpenLDAP together. It was easy task, but after couple week I realized that I need more fields. I didn’t find good fields in ISE SGT and some other uses, so I decide to create my own LDAP schema.

There was lot’s off discussion about how to generate your own schema, but only couple which worked for me. Now in this blogpost I parse those information together so you don’t need to do so much googling, ducking, bingin etc.

First install Apache Directory Studio. You can find it here https://directory.apache.org/studio/

After Directory Studio is started, open Apache Directory Studio Schema Editor.

Schema Editor Icon.

Choose File > New.

File > New.

Select Schema Editor > New Schema Project and click Next.

New Schema Project.

Give project name and click Next.

Project name.

Choose Server Type OpenLDAP and click Finish. After this you have created new project where you can add your own OpenLDAP schema.

Server Type.

Choose File > New.

File > New.

Select Schema Editor > New Schema and click Next.

Give schema name and click Finish.

Schema name.

Under Cisco > Object Classes, choose New > New Object Class.

New Object Class.

Give new OID, you can find instruction how get new private OID here https://pen.iana.org/pen/PenApplication.page and current OIDs here https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers also give new unique name for attribute in aliases field and description. After this click Next.

New Object Type OID.

Choose Class type Auxiliary and click Finish.

Class Type.

Under Cisco > Attribute Types, choose New > New Attribute Type.

New Attribute Type.

Give new OID, you can find instruction how get new private OID here https://pen.iana.org/pen/PenApplication.page and current OIDs here https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers also give new unique name for attribute and description. After this click Next.

New attribute type.

Choose Syntaxt, lenght and properties.

Attribute Type Content.

Choose matching rules and click Finish.

Matching Rules.

Choose Object class CiscoSchemaExtension and look Optional attributes. Choose Add…

Optional attributes.

Find your attribute and click Choose.

Object attributes.

Choose File > Save.

You are now create your own OpenLDAP schema extension.

Now choose Cisco > Export > Schemas as OpenLDAP files.

Schema Export.

Choose what to export and click Finish.

Schema export.

Login your linux server and create directory.

mkdir /tmp/ldapschema && cd /tmp/ldapschema

Copy your exported ldap file (cisco.schema) to directory /etc/ldap/schema

Create file called ldap.conf

echo “include /etc/ldap/schema/cisco.schema” > ldap.conf

Now generate ldap files what you import to your OpenLDAP server. Give command slaptest -f ldap.conf -F .

slaptest -f ldap.conf -F .

As you can see there is new directory in /tmp/ldapschema

New file and directory.

Go to directory cn=config/cn=schema

Directory cn=config/cn=schema

Edit file called cn={0}cisco.ldif

Remove bottom lines.

Removed lines in bottom.

Edit top lines

Original lines.
Edited lines.

Now you can add your new schema to your OpenLDAP server. Use command ldapadd -Y EXTERNAL -H ldapi:/// -f cn\=\{0\}cisco.ldif

If everything goes fine you get adding new entry….

Now restart your slapd (service slapd restart) and start using your new schema.

Cisco Meraki MX and Graylog3 Part 4

This parser/content pack are used to log Meraki MX security-events.

First download content pack from my github https://github.com/hrleinonen/graylog-meraki

File called “Cisco_Meraki_MX_Appliance_Security.json” is for MX appliance security events. It brings couple new search fields in Graylog3.

New fields are:

  • DISPOSITION = Disposition (eg. malicious)
  • ACTION = Action (eg. block)
  • SHA256 = SHA256 about file (eg. 2546dcffc5ad854d4d…)
  • NAME = Malware name (eg. Win.Ransomware.Eicar::95.sbx.tg)
  • SRCIP = Source IP-address (eg. 10.10.101.101)
  • SRCPORT = Source port (eg. 23434)
  • DSTIP = Destination IP-address (eg. 193.166.3.7)
  • DSTPORT = Destination port (eg. 443)

Upload file to Graylog3 using instruction from my blog https://www.hacknetwork.org/?p=167

Action report example.

Malware name example.

Now open Meraki dashboard and choose correct network.

Choose Network-wide > Configure > General.

Find part called reporting.

Cisco Meraki Syslog-server configuration.

Add your Graylog-server IP-address, port 5556 and choose Appliance event log role. Click save after this. Now your should see traffic in your graylog input.

Cisco Meraki MX and Graylog3 Part 3

This parser/content pack are used to log Meraki MX URL-events.

First download content pack from my github https://github.com/hrleinonen/graylog-meraki

File called “Cisco_Meraki_MX_Appliance_URLs.json” is for MX appliance events. It brings couple new search fields in Graylog3.

New fields are:

  • AGENT = Browser agent (eg. Mozilla Firefox)
  • REQUEST = Http request (eg. POST)
  • SRCIP = Source IP-address (eg. 10.10.101.101)
  • SRCPORT = Source port (eg. 23434)
  • DSTIP = Destination IP-address (eg. 193.166.3.7)
  • DSTPORT = Destination port (eg. 443)
Map based on destination IP-addresses.
Example fields.

Upload file to Graylog3 using instruction from my blog https://www.hacknetwork.org/?p=167

Now open Meraki dashboard and choose correct network.

Choose Network-wide > Configure > General.

Find part called reporting.

Cisco Meraki Syslog-server configuration.

Add your Graylog-server IP-address, port 5555 and choose Appliance event log role. Click save after this. Now your should see traffic in your graylog input.

Cisco Meraki MX and Graylog3 Part 2

First download content pack from my github https://github.com/hrleinonen/graylog-meraki

File called “Cisco_Meraki_MX_Appliance_Events.json” is for MX appliance events. It brings couple new search fields in Graylog3.

New fields are:

  • EVENT_TYPE = Event type (eg. IDS, content_filtering_block or dhcp)
  • SPI = Security Parameter Index  (eg. 53afbb30231007)
  • URL_CATEGORY = Category where blocked site belongs (eg. Malware)
Top 10 values for event type.
Top 5 blocked URL categories

Upload file to Graylog3 using instruction from my blog https://www.hacknetwork.org/?p=167

Now open Meraki dashboard and choose correct network.

Choose Network-wide > Configure > General.

Find part called reporting.

Cisco Meraki Syslog-server configuration.

Add your Graylog-server IP-address, port 5557 and choose Appliance event log role. Click save after this. Now your should see traffic in your graylog input.

Cisco Meraki MX and Graylog3

I really like Meraki cloud concept. It includes complete network stack Firewalls/SD-WAN, WLAN, Switches and Security Cameras (also MDM). Only problem (if we don’t count missing AnyConnect) is logs and query. Now, because I use Graylog for my other projects, I decide to use Graylog3 to my logstorage. There is no ready parsers or dashboards in Graylog marketplace, so I start to make my own.

Here comes parser (GROK based) for MX flow records, enjoy.

First download content pack from my github https://github.com/hrleinonen/graylog-meraki

There is couple roles in Meraki MX which you use to send syslog. I choose to send every role to different port, so I can choose what extractol to use.

File called “Cisco_Meraki_Flow_Content_Pack.json” is for MX flow events. It brings couple new search fields in Graylog3.

New fields are:

  • DSTIP = Destination IP-address (eg. 208.67.222.222)
  • DSTPORT = Destination port (eg. 53)
  • FLOW_TYPE = Flow start or end (eg. ip_flow_end)
  • PROTOCOL = Protocol (eg. tcp)
  • SRCIP = Source IP-address (eg. 172.16.0.10)
  • SRCPORT = Source port (eg. 1007)
  • TRANSLATED_DST_IP = Translated destination IP-address (eg. 1.2.3.4)
  • TRANSLATED_PORT = Translated port (eg. 55)
  • TRANSLATED_SRC_IP = Translated source IP-address (eg. 81.3.4.1)

Example for new search fields (btw. this is demo generated data not my inside net).

Now, when you are downloaded json file you must to upload it to the Graylog3. Choose System > Content Packs, Content Packs site opens. Click Upload (green box) upper left corner. Choose content pack file and upload.

There is now new content pack called Cisco Meraki Flow, now click Install. After this you have new input and dashboard.

Go to the input site System > Inputs. There is input called MERAKI_LOGS_FLOWS. Input listens RAW/plaintext udp port 5558 (there is some problems in standard Syslog udp). If input is not started, you must start it.

Now open Meraki dashboard and choose correct network.

Choose Network-wide > Configure > General.

Find part called reporting.

Cisco Meraki Syslog-server configuration.

Add your Graylog-server IP-address, port 5558 and choose Flows role. Click save after this. Now your should see traffic in your graylog input.

Click System > Inputs find MERAKI_LOGS_FLOWS and choose Show Received Messages.

There is also new dashboard called “Meraki MX Flow Records”. Go Dashboards > Meraki MX Flows Records.

Example flow dashboard.

TLS1.3 – End of the NGFW as we know it?

Update 08/12/2017:

It seems that corporate interest and concern about frauds drives over privacy. There is IETF draft which explains methods how MITM can be done also in future:

https://tools.ietf.org/html/draft-green-tls-static-dh-in-tls13-01?lipi=urn%3Ali%3Apage%3Ad_flagship3_detail_base%3BXwPTluc4SkCHhmc0hYE3Vg%3D%3D (Data Center use of Static Diffie-Hellman in TLS 1.3 draft-green-tls-static-dh-in-tls13-01)


In this post I will be focused in TLS version 1.3 and specially those parts what I think that will change the mature of the NGFW as we know it.

TLS as you maybe know it’s cornerstone of the encryption in modern Internet world. If you take browser session to your bank it is TLS protected and probably it is protected by TLS version 1.2. So why we need new TLS version? Answer can be that we need more privacy and faster response time, but the obverse for this is that it is more difficult to see where the client is going and what is the data inside encrypted HTTPS session.

Let’s first look what we can see in TLS 1.2 protected traffic without TLS decryption. TLS session start with client hello and after this comes server hello and client key exchange etc (picture 1).

Picture 1. TLS 1.2 RSA handshake (2 round).

After handshake is finished, then application data is encrypted. If we look this traffic in the Wireshark we can see that even we don’t decrypt it there is lot’s of metadata information what can be used in NGFW. NGFW can do filter based on certificate information what server sends to client. If you take www-session to youtube.com, server certificate tells quite much.

There is fields what we can see like SubjectAltName, issuer, country, state, validity etc information (Picture 2).

Picture 3. Server hello.

If we tie up this information about that information what our client tells we can be quite sure where the client is going and if it’s safe site based eg. reputation information.

When client sends hello message, it adds field called “Server Name Indication” SNI in the request (picture 3).

Picture 3. SNI field in client hello.

Now we have handled basic filtering options based on that information what certificate and client can tell in TLS1.2 world.

If your NGFW is capable to make SSL-interception (like Cisco NGFW and some others), in other words doing man-in-the-middle function. Then you can decrypt HTTPS traffic and do some more filtering (and eg. malware scanning and sandbox) based on that data what NGFW can now see in plain text. Basic function SSL interception is that NGFW signs certificates for it’s own corporate trusted root certificate (picture 4).

Picture 4. Basic SSL interception (2 round).

Because TLS 1.2 can use static RSA keys in the encrypt/decrypt session it’s quite easy and “light” to do SSL-interception, you can try it yourself using tools like Burp Suite. There is also possibility to use Elliptic Curve instead of RSA, key exchange is quite similar in ECDSA. Main difference is that after server sends certificate it also sends ServerKeyExchange message. Decrypting Elliptical Curve Digital Signature Algorithm (ECDSA) protected traffic will use more processing power that RSA based, because proxy process needs to calculate more keys.

All the methods what I have described above can be used to see inside SSL-protected traffic or can be used filtering traffic based on certificate information. SSL-interception feature has also one drawback, browsers can detect that eg. https://www.google.com is not signed in valid root CA and can gives warning.

So how the TLS version 1.3 change the game field?

First the good news, there is no RSA anymore. Then the bad news visibility to the traffic is terrible if we think security and filtering.

TLS 1.3 handshake is totally different (picture 5). There is only 2 phases. First Client sends information and server responds.

Picture 5. TLS 1.3 handshake.

After this all data is encrypted. If we first look client hello, we can see that there is only SNI field (picture 6), just like TLS version 1.2 was.

Picture 6. Client hello.

SNI based filter is working for the standard user, but it can be manipulate for certain tricks. Now see what’s server hello can tell us (picture 7).

Picture 7. Server hello.

Nothing, in TLS version 1.3 we cannot see anything and this is the reason why NGFW will change. We cannot anymore use metadata for server certificates. In transparent proxy/firewall mode we cannot see anything what is inside SSL session. Also decrypting TLS 1.3 is verry difficult, because in every new session will generate new keys (picture 8) so that SSL-interception should be done in every session. There is also some other features which make interception even more difficult.

Picture 8. TLS1.3 sessions.

If the hacker breaks one session there is no effect for other sessions, because those are using different keys.

So what we can do if script kiddie can manipulate SNI field and we cannot use SSL-interception? Is the NGFW URL-filtering story ended? Well we can ease our pain to use good old proxy pac feature (and maybe opendns plus AMP4Endpoints also). Proxy pac implementations has one good feature. Browser send (CONNECT request) target where it try to go in plain text and we can use this feature in URL-filtering (picture 9).

Picture 9. HTTP connect request and TLS 1.3.

This means that company firewall needs to block http(s) access from other sources than proxy address.

There is also effect for application intelligence, if browser based applications start using TLS 1.3 we lost view for data.

So what I think is that vendors will implement some lightweight proxy function in their devices, so they can see more information where client is going in TLS 1.3 world. They will also use more and more reputation based solution where site is pre-checked before client is allowed to make connections. This is only my guesses, but let’s see.

Facedancer21 – Test your USB interface against unwanted devices.

USB interface, that small, useful, hard to protect multifunctional port in your PC, phone, digibox etc. device.

In this article I don’t try to crash my system or get inside to the OS, I just want to protect my Linux devices against unwanted USB devices. This blog post can be divined in the three part.

  1. Limit type of devices what can be connected in the box.
  2. Remove all devices which are not connected in the box during boot time.
  3. Combination of both.

This method is tested in Debian and RedHat/CentOS setup. There is a little difference between those two distributions.

First what you need is Facedancer21 USB device emulator hardware (you can order it here: https://store.hackaday.com/products/facedancer21)

 

Facedancer21 board.

Second you need Linux (or Mac OS X, I use both) and python version 3 installed on it.

Third you need to download NCC Groups USB host security assessment tool. I recommended that you use both tool:

Original umap: https://github.com/nccgroup/umap

Version 2 umap: https://github.com/nccgroup/umap2

What I have noticed that they works with different scenarios and version 2 is still limited (eg. missing printer and OS detection support), but version 2 is more accurate when you are testing audio based usb devices. In version 1 is feature called “Start network server”, but it’s not working for me.

Fourth you need target. In this picture it’s raspberry pi and raspbian (ok I had too much time in the hotel room).

Facedancer21 setup. Laptop, facedancer21 and target.

Scenario 1.

You can use -h option when you start your umap.py python script. It shows umap help options.

NCC umap.py options.

As you can see there is lot’s of options also in fuzzing, but that’s another story.

Connect your facedancer21 to the victims usb-port and run command “sudo python3 umap -P /dev/tty.usbserial-AH039TWN -O”. Check your logs what is correct device, my was tty.usbserial-AH039TWN. Option -O scans your target and gives best gues for operating system.

It maybe won’t recognise all embedded TV’s etc. but it is still quite good feature, if you don’t know what OS your target is running.

Next we need to figure out what USB-devices your target support. Run command“sudo python3 umap -P /dev/tty.usbserial-AH039TWN -i”. Option -i scans your target and lists all supported USB-devices. You should do this also in umap2, run command “umap2scan -P fd:/dev/ttyUSB0”, in my Kali FD2 is ttyUSB0.

Scan made by umap.

As you can see there is lot’s of supported USB devices in the default settings.

Scan made by umap2.

NCC umap2 version looks more beautiful, but seems to find also same devices.

Next we try to make some hardening, so that we can limit number of device types what we can connect to USB port. Try to run command “lsmod” and see what kernel modules are installed after first scan.

Output for lsmod.

As you can see there is lot’s of stuff loaded.

Go to /etc/modprobe.d directory and create new file. Now, in debian based you must put values this way:

blacklist snd_usb_audio
...
...

And in RedHat/CentOS in this way

install usb-storage /bin/true
...
...

in that file. You can use also command “lsusb -t” to find loaded drivers. After this reboot your system and run umap scan again.

Scan for original umap.

Scan for umap2.

As you can see original umap gives that audio is still supported, but version 2 tells that it is not supported. Actually OS cannot load correct drivers, but detects that some one is trying to connect headset in the USB port.

Scenario 2.

Now we know how-to filter USB devices. What if we need to filter all devices off. This is quite easy, but there is downside. When you need to connect devices in the USB port, you need boot the device every time.

In debian based distributions open file /etc/rc.local and put line echo 0 > /sys/bus/usb/devices/usb1/authorized_default” before line exit 0. You can check how many USB HUB is in your system to make “ls -l” in /sys/bus/usb/devices/ directory.

In RedHat/CentOS based system create file called eg. lockusb.sh and put it in the /etc directory. Edit file and put this information on it:

#!/bin/bash
# USB lock
# Ville Leinonen/Atea Finland
echo 0 > /sys/bus/usb/devices/usb1/authorized_default
echo 0 > /sys/bus/usb/devices/usb2/authorized_default
echo 0 > /sys/bus/usb/devices/usb3/authorized_default
echo 0 > /sys/bus/usb/devices/usb4/authorized_default

Remeber check the directory. Now create systemd file called eg. lockusb.service and put it in /etc/systemd/system/ directory. Chmod +x it and edit file:

# Location /etc/systemd/system/lockusb.service
# Ville Leinonen/Atea Finland Oy
[Unit]
Description=Lock USB in the boot
After=sshd.service

[Service]
Type=simple
ExecStart=/etc/lockusb.sh

[Install]
WantedBy=multi-user.target

Remember to enable script in the when system starts.

Now remove all the devices and reboot the system and scan it again.

Original umap scan.

Original umap2 scan.

Now you see that there is any supported USB devices anymore.

Scenario 3.

Now you need to connect eg. memory stick on the device. Insert USB-memory stick in the port and run command “lsusb -t”.

Command lsusb -t output.

As you can see there is no mass-storage device in the list. Now reboot the device.

Command lsusb -t output.

After boot you see that usb-storage driver is loaded. Now if you run umap scan, you can see that mass-storage is not supported again.

Scan after mass-storage instert and boot.

Now if you remove mass-storage and insert it again, it wont work. So you are still protected against unwanted USB-devices.

If you need to scan some specific USB-class then you can use -c option eg. sudo python3 umap.py -P /dev/tty.usbserial-AH039TWN -c 08:06:50″, this will scan only mass-storage class.

That’s all for this time. C’ya in next month.

How-to generate traffic in your network for just one Raspberry Pi

We had a problem how-to  generate real life network traffic for our network, so that our sensor will react? One solution can be punch of virtual machines, but we needed WiFi and I did not want to invest adapters. Then Raspberry Pi 3 comes out. I get idea, what if we use RPi3 for our traffic generator?

MAC-address list example.

URL-category example.

Ok, how all this is done? Quite simple actually. We need one Raspberry Pi3 (or model B /w WiFi dongle). I assume that your RPi is installed /w basic image, so I don’t give instructions for that.

First install wget and macchanger (apt-get install wget, macchanger).

Second download majestic and modify (or OpenDNS) top one million websites.

  1. # wget http://downloads.majestic.com/majestic_million.csv
  2. (Linux)# sed -i ‘1d’ majestic_million.txt (mac)# sed -i.bak ‘1d’ majestic_million.txt
  3. # awk -F ‘,’ {‘print $3’} majestic_million.csv > majestic_million.txt

Third create file called mac-host.txt and add MAC-address and hostname information for it.

# MAC-address Vendor
# 00CDFE Apple Inc.
# 38F23E Microsoft Mobile Oy
# 3C5AB4 Google Inc.
# 18AF61 Apple Inc.
# 001175 Intel Corporate
# E4F89C Intel Corporate
# 24DBAC HUAWEI TECHNOLOGIES CO. LTD
# 745F00 Samsung Semiconductor Inc.
# 0023C2 SAMSUNG Electronics. Co. LTD
# 00E003 NOKIA WIRELESS BUSINESS COMMUN
# 006094 IBM Corp
# 00A027 FIREPOWER SYSTEMS, INC.
# 000903 Panasas, Inc
# 000EC0 Nortel Networks
# 0080C7 XIRCOM
# CC78AB Texas Instruments
# 84C7EA Sony Mobile Communications AB
# 90842B LEGO System A/S
# A8A795 Hon Hai Precision Ind. Co.,Ltd.
# D067E5 Dell Inc.
# B02628 Broadcom Limited
00:cd:fe:aa:bb:cc FakeClient1
38:f2:3e:aa:bb:cc FakeClient2
3c:5a:b4:aa:bb:cc FakeClient3
18:af:61:aa:bb:cc FakeClient4
00:11:75:bb:cc:aa FakeClient5
e4:f8:9c:bb:cc:aa FakeClient6
24:db:ac:bb:cc:aa FakeClient7
74:5f:00:bb:cc:aa FakeClient8
00:23:c2:cc:bb:aa FakeClient9
00:e0:03:cc:bb:aa FakeClient10
00:60:94:cc:bb:aa FakeClient11
00:a0:27:cc:bb:aa FakeClient12
00:09:03:ff:dd:aa FakeClient13
00:0e:c0:fa:da:ca FakeClient14
00:80:c7:fa:dd:cc FakeClient15
cc:78:ab:aa:aa:ba FakeClient16
84:c7:ea:ab:ba:cc FakeClient17
90:84:2b:ca:ca:aa FakeClient18
a8:a7:95:0c:ec:c1 FakeClient19
d0:67:e5:00:01:02 FakeClient20
b0:26:28:23:21:23 FakeClient21

After this you can create script generate_web.sh which randomly creates new entry in your firewall/wlan-ap/switch etc device.

#!/bin/bash
# Shell script that randomly draws user-agent, web-site and mac-address
# after that it will make wget for that site.
# Sorry folks, if you looks your logs and see Amiga user-agent :)
#
# Under GPL. Ville Leinonen/2017/09/19
#
while [ : ]
do
   URL="$(shuf -n 1 majestic_million.txt)"
   UA="$(shuf -n 1 user-agents.txt)"
   SP="$(shuf -i 120-900 -n 1)"

   wget --user-agent="$UA" -O /dev/null $URL > /dev/null 2>&1
   sleep 2
   wget --user-agent="$UA" -O /dev/null www.internetbadguys.com > /dev/null 2>&1
   sleep $SP

   MAC=$(cat mac-host.txt | grep -v '#' | awk -F ' ' '{ print $1 }' | shuf -n 1)
   HOST=$(grep -i $MAC mac-host.txt | awk -F ' ' '{ print $2 }')

   macchanger -m $MAC wlan0
   hostname $HOST
   echo $HOST
   ifdown wlan0
   ifup wlan0
   service dhcpcd restart
done

Script makes new connection somewhere between 120 and 900 second. Site called www.internetbadguys.com is used by testing OpenDNS.

There is still missing for part that get bad files for AMP analysis, but I have ideas for that too. Maybe I will tell it later.

I suggest that you run this script inside screen or make it daemon.

File user-agents.txt can be like this:

Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36
Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/7.0)
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0
Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36
Mozilla/5.0 (iPhone; CPU iPhone OS 8_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12D508 Safari/600.1.4
Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36
Mozilla/5.0 (iPad; CPU OS 8_4_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) CriOS/44.0.2403.67 Mobile/12H321 Safari/600.1.4
Mozilla/5.0 (Windows NT 6.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/7.0; .NET4.0E; .NET4.0C)
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36
Amiga-AWeb/3.4.167SE
Amiga-AWeb/3.5.07 beta
AmigaVoyager/3.4.4 (MorphOS/PPC native)
AmigaVoyager/2.95 (compatible; MC680x0; AmigaOS)
AmigaVoyager/3.2 (AmigaOS/MC680x0)
Links (0.98; Win32; 80×25)
Links (2.1; Linux 2.6.18-gentoo-r6 x86_64; 80×24)
Links (0.96; Linux 2.4.20-18.7 i586)
Links (2.1pre18; Linux 2.4.31 i686; 100×37)
Links (2.2; Linux 2.6.25-gentoo-r9 sparc64; 166×52)
Links (2.3pre1; Linux 2.6.35-22-generic i686; 177×51)
Links (2.8; CYGWIN_NT-6.2-WOW64 1.7.25(0.270/5/3) i686; GNU C 4.7.3; windows)

Meraki Social Login with Linkedin

How to use Linkedin account to login company guest network?

That’s the question.

Most commonly companies use static passwords or pre/self registration in guest networks. Cisco Meraki guest access can give you much more information about your guests (eg. name, email, photo and current position). In this article I tell you how-to use Cisco Meraki’s social login feature. I’d like to thank phpgang for basic idea for oAuth2 authentication.

I did some search in Google and I did not find good examples how-to use Cisco Meraki and php together with social login. Here is one example how-to use those.

What if you guest-network login layout looks something like this instead of username/password fields? What if you can advertise your products in guest access page?

First you need to development account in Linkedin and give some permission to your php-code.

https://www.linkedin.com/developer/apps/

You need to get Client Id, Client Secret and you must to know your server dns name. Remember use SSL secured site, with real certificates.

You must also need to configure Meraki walled garden to allow access to certain sites (Linkedin and your www-server) without authentication.

After this is done you can put your php-code together. This code is still under dev and contains some bugs, idiotism etc, but it works.

Create config.php file. This file include your Linkedin app client id and client secret, so keep it private.

<?php
    $client_id = "client_id_here"; // enter your client id
    $client_secret = "client_secret_here"; // enter your client secret
    $redirect_uri = "https://acme_jetlag_url_here/callback.php"; // enter your redirect url
?>

Next you need to create index.php file. Your client will first see this page.

<!DOCTYPE html>
<html>
<head>
<style>

div.container {
    width: 100%;
    border: 1px solid gray;
}

div {
    background-color: white;
}

header, footer {
    padding: 1em;
    color: white;
    background-color: #3A454A;
    clear: left;
    text-align: center;
}

nav {
    float: left;
    max-width: 160px;
    margin: 0;
    padding: 1em;
}

nav ul {
    list-style-type: none;
    padding: 0;
}

nav ul a {
    text-decoration: none;
}

article {
    margin-left: 270px;
    border-left: 1px solid gray;
    padding: 1em;
    overflow: hidden;
}

body  {
    background-image: url("showroom.jpg");
    background-color: #ffffff;
}

img {
    width:100%;
}

</style>
</head>

<body>
<div class="container">
<header>
   <h1>Social Login</h1>
</header>

<nav>
    <p>Sign in using your Linkedin account.</p>

<?php
   session_start();
   $base_grant_url = urldecode($_GET['base_grant_url']);
   $user_continue_url = urldecode($_GET['user_continue_url']);
   $override_continue_url = 'https://www.hacknetwork.org';
   $override_the_users_request = false;

   echo '<a href="login.php"><img src="Linkedin_login.png" alt="Linkedin login button" style="width:200px;"></a>';
      if ($override_the_users_request) {
        $grant_url = $base_grant_url . "?continue_url=" . urlencode($override_continue_url) ."&duration=28800";
      } else {
        $grant_url = $base_grant_url . "?continue_url=" . urlencode($user_continue_url) ."&duration=28800";
      }

      $_SESSION['grant_url'] = $grant_url;
      $_SESSION['user_continue_url'] = $user_continue_url;
      $_SESSION['base_grant_url'] = $base_grant_url;
?>

</nav>
<article>
  <h1>Guest Network</h1>
  <p>Lorium ipslum, blah, blah. Session timeout is 8 hour.</p>
  <br><p>Guest network is using Meraki techology and custom social login functions.</p>
</article>
<footer>Under GPL. Ville Leinonen/Atea Finland</footer>
</div>
</body>
</html>

When guest clicks Linkedin image, user will redirected to Linkedin authentication page. This page is provided by Linkedin, so we don’t see guest passwords.

After successfully login Linkedin will send data back to callback.php page.

<?php
// Replace this in next version -->
function post_curl($url,$param="")
{
    $ch = curl_init();
    curl_setopt($ch,CURLOPT_URL,$url);
    if($param!="")
        curl_setopt($ch,CURLOPT_POSTFIELDS,$param);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}
// <---

    session_start();
    if( isset($_SESSION['user_info']) or !isset($_SESSION['login']) ){ // if user is logged in
        header("location: index.php"); // redirect user to index page
        return false;
    }
    include 'config.php'; // include app data
if(isset($_GET['code'])) // get code after authorization
{
    $url = 'https://www.linkedin.com/uas/oauth2/accessToken';
    $param = 'grant_type=authorization_code&code='.$_GET['code'].'&redirect_uri='.$redirect_uri.'&client_id='.$client_id.'&client_secret='.$client_secret;
    $return = (json_decode(post_curl($url,$param),true));
       $url = 'https://api.linkedin.com/v1/people/~:(id,firstName,lastName,pictureUrls::(original),headline,publicProfileUrl,location,industry,positions,email-address)?format=json&oauth2_access_token='.$return['access_token'];
       $obj = json_decode(file_get_contents($url), true);
}
    $_SESSION['user_info'] = $obj;
      $grant_url = $_SESSION['grant_url'];
      $user_continue_url = $_SESSION['user_continue_url'];
      $base_grant_url = $_SESSION['base_grant_url'];
      $_SESSION['grant_url'] = $grant_url;
      $_SESSION['user_continue_url'] = $user_continue_url;
      $_SESSION['base_grant_url'] = $base_grant_url;

    header("location: afterlogin.php");
?>

Site callback.php will redirect client to afterlogin.php page. Guest still need to click link to get access.

<!DOCTYPE html>
<html>
<head>
<style>

div.container {
    width: 100%;
    border: 1px solid gray;
}

div {
    background-color: white;
}

header, footer {
    padding: 1em;
    color: white;
    background-color: #3A454A;
    clear: left;
    text-align: center;
}

nav {
    float: left;
    max-width: 260px;
    margin: 0;
    padding: 1em;
}

nav ul {
    list-style-type: none;
    padding: 0;
}

nav ul a {
    text-decoration: none;
}

article {
    margin-left: 270px;
    border-left: 1px solid gray;
    padding: 1em;
    overflow: hidden;
}

body  {
    background-image: url("showroom.jpg");
    background-color: #ffffff;
}

img {
    width:100%;
}

</style>
</head>
<body>
<div class="container">
<header>
   <h1>Login Success</h1>
</header>
<nav>
<?php
    session_start();
    if( isset($_SESSION['user_info']) ){ // if user is logged in
        $user_info = $_SESSION['user_info'];
        $grant_url = $_SESSION['grant_url'];
        $user_continue_url = $_SESSION['user_continue_url'];

        $override_continue_url = 'https://www.hacknetwork.org';
        $base_grant_url = $_SESSION['base_grant_url'];
?>
        <p>Continue to Internet <a href="<?php print $grant_url ?>">Click here</a>.</p>
        <?php
    }

    else{ // if user is not logged in
       header("location: index.php");
    }
?>

</nav>
<article>
    <h1>Welcome <?php echo $user_info["firstName"]; ?> <?php echo $user_info["lastName"]; ?></h1>
    <p>Click left side link continue to the Internet.</p>
    <p>Use your daily ACME coupon code for get free cup of coffee: <b>Free4Cf33</b></p>
    <p>Get our latest offers from Atea eSHOP (eshop.atea.fi)</p>
</article>
<footer>Under GPL. Ville Leinonen/Atea Finland</footer>
</div>
</body>
</html>

If everything goes fine you get information for your guest users.