ブログ移転
(今更...)
nfqueue+scapyで偽の応答を返す
PythonライブラリであるNetfilterQueueを使うことでiptablesのnfqueueルールにマッチしたパケットを扱うことができる。
NetfilterQueue 0.3 : Python Package Index
ここではNetfilterQueueとScapyを使用して偽のDNS応答パケットを返してみる。
ICMP Echo Requestをフックしてみる
まずはICMP Echo RequestパケットをフックしてReplyを返すfake_icmp.pyを作ってみる。
import os import sys from scapy.all import * from netfilterqueue import NetfilterQueue def fake_echo_reply(pkt): """ 偽のICMP Echo Replyパケットを作成する """ ip = IP() icmp = ICMP() ip.src = pkt[IP].dst ip.dst = pkt[IP].src icmp.type = 0 icmp.code = 0 icmp.id = pkt[ICMP].id icmp.seq = pkt[ICMP].seq print("\t%s => %s" % (ip.src, ip.dst)) data = pkt[ICMP].payload send(ip/icmp/data) def process(pkt): """ NFQUEUEから受け取ったパケットを処理する関数 """ packet = IP(pkt.get_payload()) proto = packet.proto # 0x01 = ICMP if proto is 0x01: print("[*] ICMP Packet Detected") if packet[ICMP].type is 8: print("[*] ICMP Echo Request Packet Detected") fake_echo_reply(packet) def main(): nfqueue = NetfilterQueue() # キューID = 1 nfqueue.bind(1, process) try: nfqueue.run() except: print("Exiting...") sys.exit(1) main()
iptablesにてecho-requestなICMPパケットをNFQUEUEターゲットでキューに入れる。
iptables -A OUTPUT -p icmp --icmp-type echo-request -j NFQUEUE --queue-num 1
この状態でfake_icmp.pyを起動して、pingを打ってみる。
# ping -c 3 8.8.8.8 PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. 64 bytes from 8.8.8.8: icmp_seq=1 ttl=64 time=4.91 ms 64 bytes from 8.8.8.8: icmp_seq=2 ttl=64 time=5.17 ms 64 bytes from 8.8.8.8: icmp_seq=3 ttl=64 time=4.93 ms --- 8.8.8.8 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 4.916/5.008/5.174/0.142 ms
実際には8.8.8.8にパケットは送信されず、iptablesのNFQUEUEターゲットによってフックされ、fake_icmp.pyへ渡される。
fake_icmp.pyでは受け取ったパケットに基づいて生成されたICMP echo replyが送信される。
# python fake_icmp.py WARNING: No route found for IPv6 destination :: (no default route?) [*] ICMP Packet Detected [*] ICMP Echo Request Packet Detected 8.8.8.8 => 192.168.1.210 [*] ICMP Packet Detected [*] ICMP Echo Request Packet Detected 8.8.8.8 => 192.168.1.210 [*] ICMP Packet Detected [*] ICMP Echo Request Packet Detected 8.8.8.8 => 192.168.1.210
偽のDNS応答を返す
同様にDNSの問い合わせパケットをフックし、実際とは異なるIPアドレスを返すようにしてみる。
iptablesでポート53番へ送信されるパケットをNFQUEUEに渡す。
ここではキューIDを2にしている。
iptables -A OUTPUT -p udp --dport 53 -j NFQUEUE --queue-num 2
fake_dns.pyは以下のようになる。
先ほどのICMPと同様、受け取ったパケットに基づいてDNS応答パケットを作成する。
import os import sys from scapy.all import * from netfilterqueue import NetfilterQueue def fake_dns_reply(pkt, qname): """ 偽のDNS応答パケットを作成する """ ip = IP() udp = UDP() ip.src = pkt[IP].dst ip.dst = pkt[IP].src udp.sport = pkt[UDP].dport udp.dport = pkt[UDP].sport solved_ip = sys.argv[1] # 偽のIPアドレス qd = pkt[UDP].payload dns = DNS(id = qd.id, qr = 1, qdcount = 1, ancount = 1, arcount = 1, nscount = 1, rcode = 0) dns.qd = qd[DNSQR] dns.an = DNSRR(rrname = qname, ttl = 3600, rdlen = 4, rdata = solved_ip) dns.ns = DNSRR(rrname = qname, ttl = 3600, rdlen = 4, rdata = solved_ip) dns.ar = DNSRR(rrname = qname, ttl = 3600, rdlen = 4, rdata = solved_ip) print("\t%s:%s" % (ip.dst, udp.dport)) send(ip/udp/dns) def process(pkt): """ NFQUEUEから受け取ったパケットを処理する関数 """ packet = IP(pkt.get_payload()) proto = packet.proto # 0x11 = UDP if proto is 0x11: if packet[UDP].dport is 53: print("[*] DNS request") dns = packet[UDP].payload qname = dns[DNSQR].qname print("[*] Requesting for %s" % qname) fake_dns_reply(packet, qname) def main(): nfqueue = NetfilterQueue() # キューID = 2 nfqueue.bind(2, process) try: nfqueue.run() except: print("Exiting...") # iptables reset sys.exit(1) main()
引数に返したいIPアドレスを渡して起動する。
ここでは153.120.0.175(mrtc0.com)を渡す。
# python fake_dns.py 153.120.0.175
digの結果は以下のようになる。
# dig www.google.com ; <<>> DiG 9.9.5-9+deb8u6-Debian <<>> www.google.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21188 ;; flags: qr; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1 ;; QUESTION SECTION: ;www.google.com. IN A ;; ANSWER SECTION: www.google.com. 3600 IN A 153.120.0.175 ;; AUTHORITY SECTION: www.google.com. 3600 IN A 153.120.0.175 ;; ADDITIONAL SECTION: www.google.com. 3600 IN A 153.120.0.175 ;; Query time: 15 msec ;; SERVER: 192.168.1.1#53(192.168.1.1) ;; WHEN: Mon Mar 28 01:30:43 JST 2016 ;; MSG SIZE rcvd: 122
偽の応答を返していることが確認できた。
参考
gopacketでpcapを読み込む
Goでパケットを扱うライブラリにgopacketがある。
ここではgopacketでpcapを読み込んでパケットの内容を表示してみる。
単純に読み込んで表示する
読み込むpcapはhttp.capを使っている。
package main import ( "fmt" "io" "github.com/google/gopacket" "github.com/google/gopacket/pcap" "log" ) var ( pcapFile string = "http.cap" handle *pcap.Handle err error ) func main() { handle, err = pcap.OpenOffline(pcapFile) if err != nil { log.Fatal(err) } defer handle.Close() packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for { packet, err := packetSource.NextPacket() if err == io.EOF { break } else if err != nil { log.Println("Error:", err) continue } fmt.Println(packet) } }
読み込み箇所は以下の部分。
handle, err = pcap.OpenOffline(pcapFile)
でpcapを読み込み、
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
でpcapからパケットを取得できる。
https://godoc.org/github.com/google/gopacket#PacketSource
ちなみに、もっと簡単に読み込む方法としてPackets()を使う方法もある。
for packet := range packetSource.Packets() { fmt.Println(packet) }
実行結果
PACKET: 62 bytes, wire length 62 cap length 62 @ 2004-05-13 19:17:07.311224 +0900 JST - Layer 1 (14 bytes) = Ethernet {Contents=[..14..] Payload=[..48..] SrcMAC=00:00:01:00:00:00 DstMAC=fe:ff:20:00:01:00 EthernetType=IPv4 Length=0} - Layer 2 (20 bytes) = IPv4 {Contents=[..20..] Payload=[..28..] Version=4 IHL=5 TOS=0 Length=48 Id=3905 Flags=DF FragOffset=0 TTL=128 Protocol=TCP Checksum=37355 SrcIP=145.254.160.237 DstIP= 65.208.228.223 Options=[] Padding=[]} - Layer 3 (28 bytes) = TCP {Contents=[..28..] Payload=[] SrcPort=3372(tip2) DstPort=80(http) Seq=951057939 Ack=0 DataOffset=7 FIN=false SYN=true RST=false PSH=false ACK=false URG=false ECE= false CWR=false NS=false Window=8760 Checksum=49932 Urgent=0 Options=[TCPOption(2:[5 180]), NOP, NOP, TCPOption(4:[])] Padding=[]} PACKET: 62 bytes, wire length 62 cap length 62 @ 2004-05-13 19:17:08.222534 +0900 JST - Layer 1 (14 bytes) = Ethernet {Contents=[..14..] Payload=[..48..] SrcMAC=fe:ff:20:00:01:00 DstMAC=00:00:01:00:00:00 EthernetType=IPv4 Length=0} - Layer 2 (20 bytes) = IPv4 {Contents=[..20..] Payload=[..28..] Version=4 IHL=5 TOS=0 Length=48 Id=0 Flags=DF FragOffset=0 TTL=47 Protocol=TCP Checksum=61996 SrcIP=65.208.228.223 DstIP=145.2 54.160.237 Options=[] Padding=[]} - Layer 3 (28 bytes) = TCP {Contents=[..28..] Payload=[] SrcPort=80(http) DstPort=3372(tip2) Seq=290218379 Ack=951057940 DataOffset=7 FIN=false SYN=true RST=false PSH=false ACK=true URG=fal se ECE=false CWR=false NS=false Window=5840 Checksum=23516 Urgent=0 Options=[TCPOption(2:[5 100]), NOP, NOP, TCPOption(4:[])] Padding=[]} ...
パケットが持つレイヤを表示する
package main import ( "fmt" "io" "github.com/google/gopacket" "github.com/google/gopacket/layers" "github.com/google/gopacket/pcap" "log" ) var ( pcapFile string = "http.cap" handle *pcap.Handle err error ) func printPacketInfo(packet gopacket.Packet) { for _, layer := range packet.Layers() { fmt.Println(layer.LayerType()) } } func main() { handle, err = pcap.OpenOffline(pcapFile) if err != nil { log.Fatal(err) } defer handle.Close() packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for { packet, err := packetSource.NextPacket() if err == io.EOF { break } else if err != nil { log.Println("Error:", err) continue } printPacketInfo(packet) } }
Ethernet IPv4 TCP Ethernet IPv4 TCP Ethernet IPv4 TCP Ethernet IPv4 TCP Payload
Ethernet
func printPacketInfo(packet gopacket.Packet) { ethernetLayer := packet.Layer(layers.LayerTypeEthernet) if ethernetLayer != nil { fmt.Println("[*] Ethernet Layer") ethernetPacket, _ := ethernetLayer.(*layers.Ethernet) fmt.Printf("\tSource MAC: %s\n", ethernetPacket.SrcMAC) fmt.Printf("\tDestination MAC: %s\n", ethernetPacket.DstMAC) fmt.Printf("\tEthernet type: %s\n", ethernetPacket.EthernetType) } }
[*] Ethernet Layer Source MAC: 00:00:01:00:00:00 Destination MAC: fe:ff:20:00:01:00 Ethernet type: IPv4 [*] Ethernet Layer Source MAC: 00:00:01:00:00:00 Destination MAC: fe:ff:20:00:01:00 Ethernet type: IPv4 [*] Ethernet Layer Source MAC: fe:ff:20:00:01:00 Destination MAC: 00:00:01:00:00:00 Ethernet type: IPv4
IP
func printPacketInfo(packet gopacket.Packet) { ipLayer := packet.Layer(layers.LayerTypeIPv4) if ipLayer != nil { fmt.Println("[*] IPv4 layer") ip, _ := ipLayer.(*layers.IPv4) fmt.Printf("\t%s -> %s\n", ip.SrcIP, ip.DstIP) fmt.Printf("\tProtocol: %s\n", ip.Protocol) fmt.Printf("\tIHL: %d\n", ip.IHL) fmt.Printf("\tTOS: %d\n", ip.TOS) fmt.Printf("\tLength: %d\n", ip.Length) fmt.Printf("\tId: %d\n", ip.Id) fmt.Printf("\tFlags: %s\n", ip.Flags) fmt.Printf("\tFragOffset: %d\n", ip.FragOffset) fmt.Printf("\tTTL: %d\n", ip.TTL) } }
[*] IPv4 layer 65.208.228.223 -> 145.254.160.237 Protocol: TCP IHL: 5 TOS: 0 Length: 40 Id: 0 Flags: DF FragOffset: 0 TTL: 47 ...
TCP
func printPacketInfo(packet gopacket.Packet) { ipLayer := packet.Layer(layers.LayerTypeIPv4) tcpLayer := packet.Layer(layers.LayerTypeTCP) if tcpLayer != nil { ip, _ := ipLayer.(*layers.IPv4) tcp, _ := tcpLayer.(*layers.TCP) // Bool flags: FIN, SYN, RST, PSH, ACK, URG, ECE, CWR, NS if tcp.SYN { fmt.Println("[*] TCP Layer") fmt.Printf("\t%s:%d -> %s:%d\n", ip.SrcIP, tcp.SrcPort, ip.DstIP, tcp.DstPort) fmt.Printf("\tSeq: %d\n", tcp.Seq) fmt.Printf("\tAck: %d\n", tcp.Ack) fmt.Printf("\tDataOffset: %d\n", tcp.DataOffset) fmt.Printf("\tWindow: %d\n", tcp.Window) fmt.Printf("\tChecksum: %d\n", tcp.Checksum) fmt.Printf("\tUrgent: %d\n", tcp.Urgent) } } }
[*] TCP Layer 145.254.160.237:3372 -> 65.208.228.223:80 Seq: 951057939 Ack: 0 DataOffset: 7 Window: 8760 Checksum: 49932 Urgent: 0 [*] TCP Layer 65.208.228.223:80 -> 145.254.160.237:3372 Seq: 290218379 Ack: 951057940 DataOffset: 7 Window: 5840 Checksum: 23516 Urgent: 0
Application層
func printPacketInfo(packet gopacket.Packet) { applicationLayer := packet.ApplicationLayer() if applicationLayer != nil { fmt.Println("[*] Application Layer") fmt.Printf("\t%s\n", applicationLayer.Payload()) } }
[*] Application Layer GET /download.html HTTP/1.1 Host: www.ethereal.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113 Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Referer: http://www.ethereal.com/development.html
UDP
func printPacketInfo(packet gopacket.Packet) { ipLayer := packet.Layer(layers.LayerTypeIPv4) udpLayer := packet.Layer(layers.LayerTypeUDP) if udpLayer != nil { fmt.Println("[*] UDP Layer") ip, _ := ipLayer.(*layers.IPv4) udp, _ := udpLayer.(*layers.UDP) fmt.Printf("\t%s:%d -> %s:%d\n", ip.SrcIP, udp.SrcPort, ip.DstIP, udp.DstPort) fmt.Printf("\tChecksum: %d\n", udp.Checksum) fmt.Printf("\tLength: %d\n", udp.Length) } }
[*] UDP Layer 145.254.160.237:3009 -> 145.253.2.203:53 Checksum: 4271 Length: 55 [*] UDP Layer 145.253.2.203:53 -> 145.254.160.237:3009 Checksum: 12290 Length: 154
参考
Scapyで大きいpcapを読み込む
パケットを作成したりpcapをいじったりして遊ぶPythonライブラリにscapyがある。
pcapを扱う際、rdpcapで読み込むことができるが、一度に全て読み込んでしまうため、大きいpcapを操作するときには厳しいことがある。
そんなときはPcapReaderを使えばいいらしい。
with PcapReader('huge.pcap') as pr: for p in pr: ...
参考
chrootとxinetdで脆弱なプログラムを動かす
CTFなどで脆弱なアプリケーションを動かしてそれをpwnする問題がある。 DockerとかJailとか使う方法もあるだろうけど簡単に手っ取り早くできるのはchroot+xinetdだと思う。
まずは脆弱なプログラム(vuln.c)を用意する。
#include <stdio.h> #include <unistd.h> #include <fcntl.h> int main(){ char file_name[100]; char buf[1025] = {"¥0"}; int fd; printf("Input file name > "); scanf("%s", file_name); fflush(stdout); fd = open(file_name, O_RDONLY); if(fd == -1){ return -1; } if(read(fd, buf, sizeof(buf))<0){ close(fd); return -1; } printf("%s\n", buf); close(fd); return 0; }
$ gcc vuln.c -o vuln
chroot環境を構築するためにlddで依存環境を確認して適当に配置。
$ ldd vuln linux-gate.so.1 (0xb76ee000) libc.so.6 => /lib/i386-linux-gnu/i686/cmov/libc.so.6 (0xb751f000) /lib/ld-linux.so.2 (0xb76ef000) $ ldd /bin/bash linux-gate.so.1 (0xb77d8000) libncurses.so.5 => /lib/i386-linux-gnu/libncurses.so.5 (0xb778c000) libtinfo.so.5 => /lib/i386-linux-gnu/libtinfo.so.5 (0xb7769000) libdl.so.2 => /lib/i386-linux-gnu/i686/cmov/libdl.so.2 (0xb7763000) libc.so.6 => /lib/i386-linux-gnu/i686/cmov/libc.so.6 (0xb75b9000) /lib/ld-linux.so.2 (0xb77d9000)
最終的にこのようなディレクトリ構造になる。
$ tree . ├── bin │ └── bash ├── lib │ ├── i386-linux-gnu │ │ ├── i686 │ │ │ └── cmov │ │ │ ├── libc.so.6 │ │ │ └── libdl.so.2 │ │ ├── libncurses.so.5 │ │ └── libtinfo.so.5 │ └── ld-linux.so.2 ├── vuln ├── vuln.c └── secret.txt
続いてxinetdの設定。
/etc/xinetd.d/vuln.confを以下の内容で作成する。
service buln { type = UNLISTED protocol = tcp socket_type = stream port = 12345 wait = no server = /usr/sbin/chroot server_args = /usr/chroot/ ./vuln user = root }
serverにはchrootコマンドのバイナリを指定する。 which chroot
とかで調べればいい。
server_argsにchrootの引数を指定する。chroot環境である/usr/chroot/のvulnを動かすという意。
chrootを実行するにはroot権限が必要なのでuserにrootを指定する。
最後に/etc/xinetd.confに
includedir /etc/xinetd.d
が記述されていることを確認する。
そして
service xinetd start
でxinetdを起動すると指定したポート(ここでは12345)でvulnが待ち受けている。
nc host 12345
みたいな形でアクセスして
cat /etc/passwd
のようにchroot環境にないファイルを参照することができないことが確認できる。
参考
Heroku Buttonを試す
Chatworkの期限切れタスクを毎朝通知するためにHerokuアプリを書いた。
AkkaどころかScalaも全然知らなかったし、Herokuも使ったことなかったけどとりあえず最低限動いてる。
mrt-k/akka-cwnotifier · GitHub
で、Heroku Buttonってのがあるらしい。
README.mdなどのドキュメントに設置すると、クリック1つでHerokuにデプロイできるらしい。すごい。
Creating a 'Deploy to Heroku' Button | Heroku Dev Center
設置するまでのメモを残しておく。
app.jsonを書く
リポジトリにapp.jsonが必要。
app.jsonの形式は app.json Schema | Heroku Dev Center に書いてある。
必須項目はないらしいけど、 name
description
logo
ぐらいは書いたほうがいいらしい。
{ "name": "akka-cwnotifier", "description": "The notice task of Chatwork", "repository": "https://github.com/mrt-k/akka-cwnotifier", "logo": "https://pbs.twimg.com/profile_images/673806204599054337/ANb_c1Yj.png", "keywords": ["scala", "akka", "chatwork"] }
logoはないので私のTwitterアイコンにした。
README.mdにHeroku Buttonを設置する
[![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy?template=https://github.com/mrt-k/akka-cwnotifier)
また、GitHubのREADME.mdに設置するのであれば以下のようにtemplate=を指定しなくてもRefererから勝手にリポジトリ特定してやってくれるらしい。
[![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy)
これだけで以下のように Deploy to Heroku ボタンができる。便利。
環境変数
今回Heroku Buttonを試したアプリにはChatworkのAPIキーなどを環境変数として設定する必要がある。
これもapp.jsonで設定する。
{ "name": "akka-cwnotifier", "description": "The notice task of Chatwork", "repository": "https://github.com/mrt-k/akka-cwnotifier", "logo": "https://pbs.twimg.com/profile_images/673806204599054337/ANb_c1Yj.png", "keywords": ["scala", "akka", "chatwork"], "env": { "API_KEY": { "description": "Chatwork API KEY" }, "ROOM_ID": { "description": "Destination room" } } }
descriptionに説明を書ける。
他にも "generator": "secret"
でランダムな文字列を自動生成できたり、 value
で初期値を設定できる。
デフォルトで全て必須扱いとなるが、 "required" : false
で任意扱いにできる。
app.json Schema | Heroku Dev Center
するとデプロイ画面で環境変数を設定できるようになる。
まとめ
リポジトリ直下にapp.jsonを配置するだけで簡単にデプロイできるようになって便利。
参考
広島市内のAPをマッピングしてみた
この記事は 「ふつうの広島 Advent Calendar 2015」 の19日目の記事です.
曰く,
「ふつう」ってのは普通よりすごかったり、普通よりおしかったり、普通よりゆるかったり」
らしいので, 普通よりゆるいことを書きます.
広島市内のAPをマッピングしてみた
当日の昼過ぎまで寝ていた上にアドベントカレンダーの存在を忘れていました.
特にネタもなかったので, 以前, 学内のAPをマッピングしたのを広島市内でやってみました.
背景
唐突な思いつきなので, 現在の公衆無線LANの数とか位置を知れたら面白いかもなぁと漠然と思っていただけで特に目的もなくやりました.
パークマップ広島という駐車場情報を確認できるサービスもありますし, アクセスポイント広島というのもおもしろいかもなぁと思ったり.
ちなみに僕は宗教上の理由で公衆無線LANサービスは使いません.
実施
本通りのロッテリアで遅めの昼食を摂りつつ, 前回と同じ手順で準備.
公衆無線LANを使う場面といえば, 待ち時間に使う場合が多いのでは?と思い, バス停や駅, 飲食店街などを独断と偏見で適当に歩きました.
総務省が出している公衆無線LAN利用に関する情報セキュリティ意識調査結果によると,
観光地で利用するインターネット接続手段として、訪日外国人は半分近く、日本人は8割近くが無料公衆無線LANを選択しており、公衆無線LANは携帯電話回線と並ぶ主要な利用手段となっている
とあるので, 近くの観光スポットである原爆ドーム周辺も歩きました.
無料公衆無線LANを利用している方はVPNも一緒に利用しているんでしょうか. 心配です.
結果
1時間ほど歩いた結果として2000個以上のAPを収集できました.
kmlにエクスポートしてGoogle Mapにインポートしようとしたところ, 上限数を超えていたため, いくつか登録できませんでした.
本通りから原爆ドームをぐるっと回る形で歩いた通りに, 様々なAPが乱立しています.
本当は三越(画像でいうところのもう少し右)あたりまで歩いたのですが, この時点でインポートできる上限数を超えてたみたいですね.
結果として, softbankやau, docomoなどのキャリアが提供しているAPが想像以上に多い印象を受けました.
あと, 未だにWEPなAPがいくつかありました. 大体全体の1/10程度. うーん...
SSIDが0001docomoのような形式ってどうなんですかね.
僕が悪意ある無線LAN APを立てるとしたらSSIDを0002docomoとかに...と思ったけど, 攻撃者は素直に同一名のSSIDにしますね, はい.
ちなみに今回のkmlは無断で公開してはいけないような気がしたので公開していません.
各キャリアなどが提供しているAPなどは公開しても問題ないような気がするので気が向いたら編集して公開してもいいかなと思います.
ただ, 公開のためにもっと歩かなければならないということを考えると気が引けますが...
感想
無料で使える公衆無線LANサービスは便利ではありますが, セキュリティ的には問題視されています.
先ほど紹介した総務省の公衆無線LAN利用に関する情報セキュリティ意識調査結果にもある通り, 公衆無線LAN利用時の意識, 知識が低いように思えます.
もちろんコンピュータやその他テクノロジーに疎い方々にVPNを使って〜などと言うのは難しいですし, そもそもSSIDやTLSといった言葉もわからないでしょう.
このあたりの知識は学校では教わらないだろうし, 地道に警鐘を鳴らしていくしかないのかなぁと思います.
と, 素人ながら沸々と感じました.
できるだけ利用者に負担をかけずに, かつ, 安全に利用できるインターネット/ネットワーク社会を築いていきたいですね.