Sunday, March 29, 2020

putty ssh passwordless login

SSH server is already configured with openssh on Linux. From Windows machine Putty application.  Go to 'All Programs' -> Putty -> PuttyGen.  Click Generate.  It will take few seconds to generate a set of private and public keys. Save them individually.


Copy the 'user-public' file to ssh server machine and append the contents to 'authorized_keys' file

1
2
3
4
5
# ssh-keygen -i -f user-public 
ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAnVjU8ymO2p8ZMxjWjiBSDvBLyqENwUQQq4KYotJMUQtSOc08kvGvnuS3Y3ZsJyMJpVcq803v7dPiec0IVqaqo5uLPrpKtLDz5pqHHS3GmQnvkvBoHRxLgR89I0EQWHvJ+cAt1Hfa2GNTSAG3Qc30hRWlkWZrm/Wg5JasvmgBtRsp4WTBwrAH2EkGTC7NL2aoDNZ+IF0zElHGUoSB2a4PU17Tbh2paEIb2+ISCn2Wd0PFJGzFNcgLcO7exNc6OsBZRfz8Iltvt/Hc+64ORDVi1ck23WMI2A/VfePdmq6Yf/iL5c96wPg2vCCjGQghGfytuwPo7BFCOGibwU5yBhuy8Q==

# ssh-keygen -i -f user-public >> ~/.ssh/authorized_keys
#

On the client, machine we have to create a new profile and link 'user-private.ppk' file to the profile.





From Windows machine, you can open the putty application, select the IP address from the 'Saved Sessions', 'Load' and 'Open'.  You will get the prompt in the ssh session.

Thanks

Ssh using Openssh

SSH Secure Shell, whenever we want to execute a shell command on a remote machine, it is used.  The whole idea here is to make sure that eaves drop will not be able to decrypt it, as it is encrypted.

Now, we already have a linux machine(172.16.0.1) that has openssh server running.  I have a client linux machine(172.16.0.20).  For the first time, whenever we issue a command.

1
2
3
4
5
6
7
8
9
# ssh 172.16.0.1 -l root ls

Host '172.16.0.1' is not in the trusted hosts file.
(ssh-rsa fingerprint sha1!! 3f:61:51:b5:00:02:64:f9:c4:c3:dd:a1:e9:eb:ac:9e:1b:aa:ef:68)
Do you want to continue connecting? (y/n) y
root@172.16.0.1's password: 
abc.txt
def.txt
#

Line 5: It asks whether to include public key in the file ~/.ssh/known_hosts
Line 6: Password is needed

1
2
3
# cat .ssh/known_hosts 

172.16.0.1 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC97bEOOLravOBmbx/P+5BXxEEH49N3tdS3PgynAwdma/OY6fGzFrXhGnKZgYKbkKSTldKpXs3xUdRhjR6jU9VN4GcjzmcFfNgniGdq6SntV/U9lrdCGt2V5dLdTAE8I3q2vQL9i/OQ83fcu9CVKN6/O0jToJ65n9lrgrsFfSjkFWlPJLh2l9Syvgl1OReat6iBetcpetUnC0CTG9ORwpDsl+GbQAXc2VSWirafQRDNFNTC1aOwgUa9YMFY+XUqetU/76nYr4MC8JNoWkqvH0O+6UTR5wKhYDMaDIr9PGtTJF+2Hqt97XYAudieIwBogiGNl5/fF2GKW3j7ykibDAxH
#

You can see the entry added in the file.  Now, delete the file.  We can avoid the banner by explicitly adding it by ourselves.  It will be available by two methods:

Using ssh-keyscan command remotely:

1
2
3
4
5
# ssh-keyscan -H 172.16.0.1
# 172.16.0.1 SSH-2.0-OpenSSH_6.2
no hostkey alg
# 172.16.0.1 SSH-2.0-OpenSSH_6.2
|1|Dg0BPDSZVlQ397prZu+fKSB31zM=|Vab1XH6An8aw4QQoR1rln8mvwo0= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC97bEOOLravOBmbx/P+5BXxEEH49N3tdS3PgynAwdma/OY6fGzFrXhGnKZgYKbkKSTldKpXs3xUdRhjR6jU9VN4GcjzmcFfNgniGdq6SntV/U9lrdCGt2V5cLdSAD8I3q2vQL9i/OQ83fcu9CVKN6/O0jToJ65n9lrgrsFfSjkFWlPJLh2l9Syvgl1OReat6iBetcpetUnC0CTG9ORwpDsl+GbQAXc2VSWirafQRDNFNTC1aOwgUa9YMFY+XUqetU/76nYr4MC8JNoWkqvH0O+6UTR5wKhYDMaDIr9PGtTJF+2Hqt97XYAudieIwBogiGNl5/fF2GKW3j7ykibDAxH

On the server machine (172.16.0.1), in the following location

1
2
#cat /etc/ssh/ssh_host_rsa_key.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC97bEOOLravOBmbx/P+5BXxEEH49N3tdS3PgynAwdma/OY6fGzFrXhGnKZgYKbkKSTldKpXs3xUdRhjR6jU9VN4GcjzmcFfNgniGdq6SntV/U9lrdCGt2V5cLdSAD8I3q2vQL9i/OQ83fcu9CVKN6/O0jToJ65n9lrgrsFfSjkFWlPJLh2l9Syvgl1OReat6iBetcpetUnC0CTG9ORwpDsl+GbQAXc2VSWirafQRDNFNTC1aOwgUa9YMFY+XUqetU/76nYr4MC8JNoWkqvH0O+6UTR5wKhYDMaDIr9PGtTJF+2Hqt97XYAudieIwBogiGNl5/fF2GKW3j7ykibDAxH 

Copy and paste the corresponding public key in the known_hosts file of client(172.16.0.20)

1
2
3
4
5
6
7
# vi .ssh/known_hosts 
 
# ssh 172.16.0.1 -l root ls
root@172.16.0.1's password: 
abc.txt
def.txt
#

Passwordless Login for the server

Whenever we issue ssh to the server, it always asks for password.  To avoid this, we have to keep that user's public key in the 'authorized_key' list of server.  Remember, it has to be public key of user@hostname(~/.ssh/id_rsa.pub) and NOT public key of the hostname(/etc/ssh/ssh_host_rsa_key.pub)

Initially 'id_rsa.pub' would not be present.  There will be only 2 files 'known_hosts' and 'authorized hosts'

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# ls ~/.ssh/
authorized_keys  known_hosts
# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
d6:1c:43:59:bc:fe:fa:36:e4:44:0c:12:96:41:2f:f9 root@svtap01end1.bec.broadcom.net
The key's randomart image is:
+--[ RSA 2048]----+
|         .*B.    |
|         o+oo    |
|          =..+   |
|         o =. o  |
|        S o.E.   |
|       .    . o  |
|             =   |
|              =  |
|            .+.. |
+-----------------+
# ls ~/.ssh/
authorized_keys  id_rsa  id_rsa.pub  known_hosts
# cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6gtqYxfBe/dcBtMPh/j1x6eAVOLbn9ooY12ztDs15q4kkjw0YNkHVcw9vX3Ys5eIx2N+5WaFc8uCuZFqK+F3/qybCNkIditLwoC8OOH3zXZeBB+hzkACl1ThEIIHRlqUX79xMokPwOM99OOt6CwKZCl81aRF75+QW6ek8PxMvEm4O9zb22pGU36Qb5PS6IOKfBUbIUi4v7dR5ElBiziPCZqXgFDf5iZAS83hyvSVxl5VG7dhO0GfWGa+KrQ1kwdK5oyIL81PBgkQFrxVzejApSxwBgNs+1B9e8Tq5/FsxcLfUB0w12VQlIedZOeUDhh18+MoUrStdNYrEZqNwt5Ox root@svtap01end1.bec.broadcom.net
#

Copy the output of id_rsa.pub to authorized hosts in the server.  After doing lot of trails of copy paste the contents to the file, in-build command 'ssh-copy-id' worked smoothly.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# ssh-copy-id root@172.16.0.1
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@172.16.0.1's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@172.16.0.1'"
and check to make sure that only the key(s) you wanted were added.

# ssh 172.16.0.1 ls
abc.txt
def.txt
#

Thank you.

Wednesday, September 4, 2019

Nping - ICMP Types

Nping, one of the utility that comes with nmap.  Today, I will give some info on ICMP types that it supports.  It may not be complete list of ICMP types, but a few.

References:
I have a Fedora Linux machine connected to a wireless router through ethernet cable.

Basic Ping

1
2
3
4
5
6
7
8
9
$nping --icmp -c 1 --dest-ip 192.168.1.1

Starting Nping 0.6.45 ( http://nmap.org/nping ) at 2019-09-02 09:23 EDT
SENT (0.0225s) ICMP [192.168.1.10 > 192.168.1.1 Echo request (type=8/code=0) id=13299 seq=1] IP [ttl=64 id=18670 iplen=28 ]
RCVD (0.0232s) ICMP [192.168.1.1 > 192.168.1.10 Echo reply (type=0/code=0) id=13299 seq=1] IP [ttl=64 id=9377 iplen=28 ]
 
Max rtt: 0.651ms | Min rtt: 0.651ms | Avg rtt: 0.651ms
Raw packets sent: 1 (28B) | Rcvd: 1 (46B) | Lost: 0 (0.00%)
Nping done: 1 IP address pinged in 1.04 seconds

'c' refers to number of requests to be sent.


Some other stuff we can do like:


Time Stamp

1
2
3
4
5
6
7
8
9
$nping --icmp -c 1 --icmp-type 13 --dest-ip 192.168.1.1

Starting Nping 0.6.45 ( http://nmap.org/nping ) at 2019-09-02 11:29 EDT
SENT (0.0176s) ICMP [192.168.1.10 > 192.168.1.1 Timestamp request (type=13/code=0) id=24214 seq=1 orig=0 recv=0 trans=0] IP [ttl=64 id=14849 iplen=40 ]
RCVD (0.0183s) ICMP [192.168.1.1 > 192.168.1.10 Timestamp reply (type=14/code=0) id=24214 seq=1 orig=0 recv=3463577600 trans=3463577600] IP [ttl=64 id=65252 iplen=40 ]
 
Max rtt: 0.675ms | Min rtt: 0.675ms | Avg rtt: 0.675ms
Raw packets sent: 1 (40B) | Rcvd: 1 (46B) | Lost: 0 (0.00%)
Nping done: 1 IP address pinged in 1.03 seconds


There are other types of ICMP that are not widely used.  You may try to experiment and end up disappointed because many would not have been configured.  For understanding purpose you can go through wiki. https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol


Sunday, August 25, 2019

Basic Demo of Default Gateway

I got a host having a IP Address 192.168.10.176.  We will see how it reacts when it wants to reach out to different IP Addresses.



IP Addresses within Network

In the above picture, whenever the host wants to reach to any IP Address within the network, it sends out ARP Request to resolve the MAC Address.  To demonstrate, we tried to ping 192.168.10.177, 192.168.10.178 and 192.168.10.190.  As I connect only *.177 PC there was reply from only that machine.  It is not important.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# ping -c 1 192.168.10.177
PING 192.168.10.177 (192.168.10.177): 56 data bytes
64 bytes from 192.168.10.177: seq=0 ttl=64 time=0.724 ms

--- 192.168.10.177 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.724/0.724/0.724 ms
#
# ping -c 1 192.168.10.178
PING 192.168.10.178 (192.168.10.178): 56 data bytes
^C
--- 192.168.10.178 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss

# ping -c 1 192.168.10.190
PING 192.168.10.190 (192.168.10.190): 56 data bytes
^C
--- 192.168.10.190 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss

# 

 Analysing the following sniffer capture.


Note those ARP Requests that our host generates.  It requests MAC only for *.177, *.178 and *.190.  The conclusion is for all the IPs that are within the network host will directly requests for MAC addresses of those machines.

IP Address outside Network

I try to ping some IP Address outside its network that do not exist.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# ping -c 1 192.168.10.200
PING 192.168.10.200 (192.168.10.200): 56 data bytes
^C
--- 192.168.10.200 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss

# ping -c 1 192.168.1.20
PING 192.168.1.20 (192.168.1.20): 56 data bytes
^C
--- 192.168.1.20 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss

# ping -c 1 1.3.2.4
PING 1.3.2.4 (1.3.2.4): 56 data bytes

--- 1.3.2.4 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
#

As there are no hosts with those IPs, all pings fail.  Let us analyze the sniffer capture:

Here the host wanted to reach out to an IP Address that is not in its configured network interface.  The sequence of things that happened here:

  1. Requests for the MAC Address of 'Default Gateway' that is configured(i.e. 192.168.1.177).
  2. Host took note of the MAC address of gateway, say it gw-mac
  3. Following packets destined to that IP address will have destination mac as gw-mac. Other elements like source mac, source IP and destination IP will be as usual 
The aim here is -- Host has to deliver the packet to the gateway that is capable of routing. That is why the destination mac is of the gateway's.  The gateway must be configured such that the packet is routing to its desired network.


Tuesday, August 13, 2019

Proxy ARP in Linux

In my previous post, you have seen how proxy arp was configured on cisco router.  Now, we do a demo on a linux machines FC19.



Briefly,
  • Without proxyarp, Multihost will respond for all configured IPs
  • With proxyarp, Multihost will respond for all connected network IPs(except the interface on which it receives arp request)
Here, I will discuss only about how multicast responds to ARP and not about Ping.  To simplify our explanation we use a tool 'arping'.  It is usually inbuilt in all machines.


Without proxyarp, Multihost will respond for all configured IPs

No proxyarp is enabled in Multihost.  'eth0' on Multihost will arp respond to its configured IP addresses '172.16.0.10' and '192.168.1.8'.  The way I use arping below to direct arp request is self-explanatory.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[root@abc12end1 ~]$arping -I enp0s20u4 -f 172.16.0.10
ARPING 172.16.0.10 from 172.16.0.1 enp0s20u4
Unicast reply from 172.16.0.10 [00:FF:18:B4:CC:6F]  0.811ms
Sent 1 probes (1 broadcast(s))
Received 1 response(s)

[root@abc12end1 ~]$arping -I enp0s20u4 -f 192.168.1.8
ARPING 192.168.1.8 from 172.16.0.1 enp0s20u4
Unicast reply from 192.168.1.8 [00:FF:18:B4:CC:6F]  0.799ms
Sent 1 probes (1 broadcast(s))
Received 1 response(s)

[root@abc12end1 ~]$arping -I enp0s20u4 -f 192.168.1.1
ARPING 192.168.1.1 from 172.16.0.1 enp0s20u4
^CSent 2 probes (2 broadcast(s))
Received 0 response(s)

Observe that I requested for 192.168.1.1 for which Multihost didn't respond.

With proxyarp, Multihost will respond for all connected network IPs


Now, I enable proxyarp using the following commands.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# cat /proc/sys/net/ipv4/conf/all/proxy_arp
0
# cat /proc/sys/net/ipv4/ip_forward
0

# echo 1 > /proc/sys/net/ipv4/conf/all/proxy_arp
# echo 1 > /proc/sys/net/ipv4/ip_forward

# cat /proc/sys/net/ipv4/conf/all/proxy_arp
1
# cat /proc/sys/net/ipv4/ip_forward
1
 

Now issue arp request for any of the IP address in 192.168.1.x network.  Irrespective of whether the host exists or not, eth0 will respond with its MAC address.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
[root@abc12end1 ~]$arping -I enp0s20u4 -f 192.168.1.8
ARPING 192.168.1.8 from 172.16.0.1 enp0s20u4
Unicast reply from 192.168.1.8 [00:FF:18:B4:CC:6F]  0.802ms
Sent 1 probes (1 broadcast(s))
Received 1 response(s)

[root@abc12end1 ~]$arping -I enp0s20u4 -f 192.168.1.1
ARPING 192.168.1.1 from 172.16.0.1 enp0s20u4
Unicast reply from 192.168.1.1 [00:FF:18:B4:CC:6F]  444.585ms
Sent 1 probes (1 broadcast(s))
Received 1 response(s)

[root@abc12end1 ~]$arping -I enp0s20u4 -f 192.168.1.2
ARPING 192.168.1.2 from 172.16.0.1 enp0s20u4
Unicast reply from 192.168.1.2 [00:FF:18:B4:CC:6F]  126.458ms
Sent 1 probes (1 broadcast(s))
Received 1 response(s)

Here 192.168.1.1 and 192.168.1.2 hosts do not exist.  But Multihost's eth0 responded with its MAC Address.

Thursday, August 1, 2019

Proxy ARP in Packet Tracer

I believe the following diagram will give a brief idea about what Proxy ARP does.  By default all cisco routers will have proxy arp enabled over the interfaces.

Description

Typically, any interface having IP address 'IP1' after receiving an arp request(for IP1) it sends arp response with its MAC address.  

Suppose 'proxy arp' is enabled in any interface(say Gi0/1), and the other interfaces(Gi0/2, Gi0/3) of the network device are configured with other networks(IP2, IP3).  If Gi0/1 receives any arp request for any of the IP addresses in IP2 or IP3, Gi0/1 sends out ARP response with its own MAC Address.
'Proxy ARP' configuration gives the authority for that interface.

Demonstration

I picked a router with following interfaces and IP addresses.

Topology

Configurations in the router will be as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Router(config)#
Router(config)#int gigabitEthernet 0/0
Router(config-if)#ip address 192.168.0.1 255.255.255.0
Router(config-if)#no shut
Router(config-if)#exit
Router(config)#int gigabitEthernet 0/1
Router(config-if)#ip address 192.168.1.1 255.255.255.0
Router(config-if)#no shut
Router(config-if)#exit
Router(config)#int gigabitEthernet 0/2
Router(config-if)#ip address 192.168.2.1 255.255.255.0
Router(config-if)#no shut
Router(config-if)#exit

If you observe, Laptop0 has subnet mask 255.0.0.0 while others have 255.255.255.0.   I did it for a reason.  If I ping to 192.168.2.x or 192.168.3.x from Laptop0, it initially generates ARP request for that particular IP address.  If I keep subnet as 255.255.255.0 and issue a ping to 192.168.2.x or 192.168.3.x, it will generate ARP for the default IP address configured.  Explanation of this needs a separate post which I am planning to do later.

For this post, just remember that with this configuration I will be able to generate ARP requests for 192.168.2.x or 192.168.3.x IP addresses.


C:\>arp -a
No ARP Entries Found

C:\>ping -n 1 192.168.0.1
Pinging 192.168.0.1 with 32 bytes of data:
Reply from 192.168.0.1: bytes=32 time<1ms TTL=255
Ping statistics for 192.168.0.1:
    Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),

C:\>ping -n 1 192.168.1.1
Pinging 192.168.1.1 with 32 bytes of data:
Reply from 192.168.1.1: bytes=32 time<1ms TTL=255
Ping statistics for 192.168.1.1:
    Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),

C:\>ping -n 1 192.168.1.100
Pinging 192.168.1.100 with 32 bytes of data:
Request timed out.
Ping statistics for 192.168.1.100:
    Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),

C:\>ping -n 1 192.168.1.101
Pinging 192.168.1.101 with 32 bytes of data:
Request timed out.
Ping statistics for 192.168.1.101:
    Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),

C:\>ping -n 1 192.168.2.1

Pinging 192.168.2.1 with 32 bytes of data:

Request timed out.

Ping statistics for 192.168.2.1:

    Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),

Initially we made sure ARP entries are not present.  We have issued ping to
  • 192.168.0.1 (its own network on Gi 0/0)
  • 192.168.1.1 and 192.168.1.100 (other interface's Gi0/1 network address) (Existing IP address)
  • 192.168.1.101 (other interface's Gi0/1 network address) (This IP address not present)
  • 192.168.2.1 (other interface's Gi0/2 network address) (Existing IP address)
When we look at arp entries:

1
2
3
4
5
6
C:\>arp -a
  Internet Address      Physical Address      Type
  192.168.0.1           0040.0b1a.9a01        dynamic
  192.168.1.1           0040.0b1a.9a01        dynamic
  192.168.1.100         0040.0b1a.9a01        dynamic
  192.168.1.101         0040.0b1a.9a01        dynamic

Line 3, its conventional arp response of Gi0/0 MAC address.
Line 4 and 5, Gi0/0 responded with its own MAC address for the network present in Gi0/1
Line 6, Irrespective whether the IP address exists or not, if it gets arp request for any of the IP address in 192.168.1.x network it responds with its own MAC address.

Bonus Tip

You must have noticed that I issued ping to 192.168.2.1 (Gi0/2), but the arp entry is not present.  This is because that operational status is down.  So, we placed a switch to make it 'up'.  Now proxy-arp works as usual.

Placed a switch to make Gig0/2 operational status 'up'


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
C:\>arp -a
No ARP Entries Found

C:\>ping 192.168.2.1
Pinging 192.168.2.1 with 32 bytes of data:
Reply from 192.168.2.1: bytes=32 time=1ms TTL=255
Reply from 192.168.2.1: bytes=32 time<1ms TTL=255
Ping statistics for 192.168.2.1:
    Packets: Sent = 2, Received = 2, Lost = 0 (0% loss),

C:\>ping 192.168.2.100
Pinging 192.168.2.100 with 32 bytes of data:
Ping statistics for 192.168.2.100:
    Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),

C:\>arp -a
  Internet Address      Physical Address      Type
  192.168.2.1           0040.0b1a.9a01        dynamic
  192.168.2.100         0040.0b1a.9a01        dynamic


Sunday, July 21, 2019

Generate WiFi Beacons

I am going to pump Wifi Beacons in the air.  For this, I use Alfa-AWUS036NHA usb wifi dongle in Fedora.  I googled through some websites to create a virtual interface of usb wifi in monitor mode. Installed Scapy so as to program.

Beacon Frame
The Beacon Frame above is generated using the following python code.  Run the code, and in sniffer the above frame will be seen.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#! /usr/bin/env python
from scapy.all import *
import sys

####### Enter the interface ###########
iface = 'mon0'

####### Initializing the parameters in pairs of SSID and BSSID #########
pairs = [('ACTIVEHUB','00:90:12:34:56:78'),('ACTIVEHUB2','00:90:12:34:56:79')]

for SSID,BSSID in pairs:
        # Create MAC Header
        dot11 = Dot11(type=0, subtype=8, addr1='ff:ff:ff:ff:ff:ff',addr2=BSSID, addr3=BSSID)
        beacon = Dot11Beacon()
        # Create SSID Tag Parameter in Beacon Frame
        essid = Dot11Elt(ID='SSID',info=SSID, len=len(SSID))

        # Combine all objects into a single frame
        frame = RadioTap()/dot11/beacon/essid

        # Send 'count' number of frames with interval 'inter' seconds
        sendp(frame, iface=iface, inter=0.100, count=1)

In line 9, I have included 2 beacons. Each beacon represented as a pair (SSID, BSSID). You can include as many as you like.