WiFi Pineapple | Blue For The Pineapple | InteliSecure

admin

04.25.2013

WiFi Pineapple | Blue For The Pineapple | InteliSecure

The WiFi Pineapple, was a device coined by the Hak5 (www.hak5.org) Team back in 2008. Originally it was a hacked Fon/Fonera AccessPoint (AP) with Karma patches applied to hostapd. Back then Digninja (Robin wood) called it Jasager (http://www.digininja.org/jasager/), it was called this because the AP software answered “Yes” to all WiFi Beacon Frames; if a WiFi client was looking for the SSID BTOpenzone the Pineapple(or Jasager) would reply “That’s Me!”, if a second WiFi client was looking for an SSID of Starbucks, again the Pineapple would reply “Thats Me!” – Thus tricking unsuspecting users/devices into associating with its private network. From this stage you could attack WiFi clients, and perfrom Man-in-The-Middle(MiTM) attacks on their interenet traffic!.

As the device was small, it was a running joke to hide it within an actual pineapple. Then the Hak5 Team discovered some novelty pineapple cocktail-cups which could house the AP board and a small battery pack (Hence the name Pineapple). Nowadays, its a chunky black Alfa AP121U with a nice sticker of an armed pineapple that looks a bit like a viking, slapped on  its front cover.

The original Fon device only had a finite amount of processing power and memory, and attacks were limited, any extensive process and the watchdog process would trigger and reset the device (assuming a DoS condition was occurring). The Hak5 development Team moved onto other devices as sourcing Fon/Foneras became difficult, and eventually onto slightly more powerful APs; which brings us to the current module Mk IV. The community has since added they’re own modules, improved the interface and added extra functionality like 3G tethering and 3G USB Modem support.

Blue for the Pineapple…

So back to the main topic. We missed the small unobtrusive AP, so conducted some research on porting the Pineapple build onto a cheap small TPLink WiFi AP that costs approximately $20USD.

Our walkthrough is below, but here is the part list:

  • TPLink WR703N – $20(USD)
  • 4GB San Cruiser FIT USB Drive – $8(USD)

As the parts are from China/Thailand they can be cheaply acquired anywhere in the world!

Install Openwrt

This blog post is centered around version 1.5 of the TPLink WR703N.  People are reporting recieving different versions upto v1.7.  For version 1.6, the image below seems to corrupt or brick the device, general consensus from the comments are to use the later 12.09-rc2. Version 1.7 Attitutude adjustment is confirmed as working, however the trunk is broken… so watch this space…

The default web interface language is all in Chinese, so follow these simple instructions to flash a copy of OpenWRT (http://openwrt.org/)

  1. Configure your computer with a static IP address of 192.168.1.111
  2. Connect your computer to the TPLink with an ethernet cable and power on the TPLink through a USB cable (or USB battery)
  3. Browse to 192.168.1.1. Login admin:admin.
  4. Mouseover the left hand links to find the DateTimeCfgRpm.htm link and click
  5. Mouseover the expanded menu to find SoftwareUpgradeRpm.htm link and click
  6. Use the dialog to upload the new flash (link below) to the TPLink. It will go through a 100% status bar twice then reboot.

Openwrt attitude adjustment on squashfs root can mount an external drive as root with overlayfs.

I used the following Firmware for  Version 1.5 (found on the back next to the Serial Number):

  • http://downloads.openwrt.org/attitude_adjustment/12.09-rc1/ar71xx/generic/openwrt-ar71xx-generic-tl-wr703n-v1-squashfs-factory.bin

For version 1.6, the image above seems to corrupt or brick the device, general consensus from the comments are to use the later 12.09-rc2.

  • http://downloads.openwrt.org/attitude_adjustment/12.09-rc2/ar71xx/generic/openwrt-ar71xx-generic-tl-wr703n-v1-squashfs-factory.bin

For version 1.7….. TBA

Preparing The USB as / (root)

Format a usb key with two partitions, ext4 and swap, install attitude adjustment squashfs, connect it to the internet (wifi client/eth0), update package lists.

Install:

  • kmod-usb-core
  • kmod-usb-storage
  • kmod-fs-ext4
  • block-mount

Duplicate data

Copy necessary files from flash to the new root partition:
For pivot overlay you can either use an empty new rootfs OR copy the contents of the current overlay (JFFS2) to the new rootfs (assuming the filesystem for the new external rootfs is mounted on /mnt/sda2 (swap=/dev/sda1)):

tar -C /overlay -cvf - . | tar -C /mnt/sda2 -xf -

For pivot root (”only possible as of r26109!”) you must make sure to have a complete root filesystem on the external rootfs device. One possible way to get such a system (assuming the filesystem for the new external rootfs is mounted on /mnt/sda1) is to issue

mkdir -p /tmp/cproot
mount --bind / /tmp/cproot
tar -C /tmp/cproot -cvf - . | tar -C /mnt/sda2 -xf -
sync ; umount /mnt
umount /tmp/cproot

Whole external root (pivot root)

After r26109 you can configure a non-overlay rootfs (called a whole_root extroot because the entire filesystem must be present on device, not only the changes from the SquashFS) using option target / in the config mount section for the rootfs device.

In order to set up such a whole root overlay, refer to the example below.

While option is_rootfs will still work after r25787, the preferred method of configuring the extroot is option target /overlay in the config mount section for the rootfs device in the /etc/config/fstab file.

config mount
option target /
option device /dev/sda2
option fstype ext4
option options rw,sync
option enabled 1
option enabled_fsck 0

Reboot & Install Packages

Reboot.

You can now install whatever you want from opkg, and it all goes on the USB Drive.

For some Wifi Cracking, here’s a bunch of useful package names:

opkg install htop bash nano netcat tar openssh-sftp-client nmap tcpdump aircrack-ng kismet-client kismet-server nbtscan snort karma samba36-client elinks yafc python php5-cgi uhttpd zoneinfo-core procps

At this point you can install any additional packages you may want/need!

Installing the Hak5 Pineapple Code

The following series of instructions were performed from both a Linux and Mac OSX operating system.

Hacking the Upgrade Image

We used binwalk (https://code.google.com/p/binwalk/) to extract information about the FileSystem boundaries contained within the Hak5 Pineapples upgrade binary firmware image upgrade.bin which is obtainable from http://www.wifipineapple.com/ Direct Link to Image:Firmware-2.8.0

Below is the output of binary-walking the image file:

$ binwalk upgrade.bin
DECIMAL HEX DESCRIPTION
-------------------------------------------------------------------------------------------------------
0 0x0 Squashfs filesystem, little endian, version 4.0, compression: size: 5342622 bytes, 1410 inodes, blocksize: 262144 bytes, created: Thu Jul 12 02:09:55 2012
6291456 0x600000 uImage header, header size: 64 bytes, header CRC: 0x6B09056F, created: Thu Jul 12 02:10:00 2012, image size: 890595 bytes, Data Address: 0x80060000, Entry Point: 0x80060000, data CRC: 0xF9DC8F7E, OS: Linux, CPU: MIPS, image type: OS Kernel Image, compression type: lzma, image name: MIPS OpenWrt Linux-3.2.14
6291520 0x600040 LZMA compressed data (sig 3), properties: 0x6D, dictionary size: 8388608 bytes, uncompressed size: 2690180 bytes

Use dd to extract the image:

Next we use the native unix tool dd, to carve out the squashFS partition:

$dd if=upgrade.bin of=pineapple.img bs=1 count=5342622
5342622+0 records in
5342622+0 records out
5342622 bytes transferred in 12.967170 secs (412011 bytes/sec)

Linux and Mac OSX have a neat program called FUSE (Filesystem in UserSpacE), which allows users to mount/edit filesystems outside of standard kernel code.
Using Squashfuse(https://github.com/vasi/squashfuse) it is incredibly easy to mount the pineapple.img, we extracted earlier. This part of the walkthrough was conducted on OSX (but can easily be replicated in Linux):

mkdir -p /Volumnes/pineapple
squashfuse pineapple.img /Volumes/pineapple/

Extract the (MIPS) karma patched binaries (to save on compliation, and from having to build & patch our own binaries)

$ find /Volumes/pineapple/ -name hostapd
/Volumes/pineapple//lib/wifi/hostapd.sh
/Volumes/pineapple//usr/sbin/hostapd
$ find /Volumes/pineapple/ -name hostapd_cli
/Volumes/pineapple//usr/sbin/hostapd_cli

The copy/ssh these binaries onto the TPLink Openwrt installation.

The Pineapples Web Interface

If you followed the firmware & squashFS extraction you may continue with the following steps, or skip to the next New Opensource section….

Old Method

This stage involves copying all the PHP code for the Pineapples Web interface; earlier versions were stored at /www/pineapple later versions not store the code within the images’ root /pineappple

New Opensource Method

As of the last month Sebkinne, has made the Pineapples Web Interface available as Opensource, use git to download the repository.

git clone https://github.com/WiFiPineapple/web-interface.git /pineapple

Notes

  • Disable all update modules – as this will break the build, the upgrades/updates are all geared for Alfa AccessPoints so you should go through all the code removing the update/upgrade routines to avoid accidentally bricking the TPLink in the future.
  • Simple disable method: remove the ‘upgrade’ folder within the ‘/pineapple’ folder.

Configuration Files

To make this build compatible with the existing Pineapple Scripts (eg. http://wifipineapple.com/wp4.sh). You need to replace the exisitng Openwrt configurations with the ones listed below.

/etc/config/dhcp

config dnsmasq
option domainneeded 1
option boguspriv 1
option filterwin2k 0 # enable for dial on demand
option localise_queries 1
option rebind_protection 1 # disable if upstream must serve RFC1918 addresses
option rebind_localhost 1 # enable for RBL checking and similar services
#list rebind_domain example.lan # whitelist RFC1918 responses for domains
option local '/lan/'
option domain 'lan'
option expandhosts 1
option nonegcache 0
option authoritative 1
option readethers 1
option leasefile '/tmp/dhcp.leases'
option resolvfile '/tmp/resolv.conf.auto'

config dhcp lan
option interface lan
option start 100
option limit 150
option leasetime 12h
option 'ignore' '0'
list 'dhcp_option' '3,172.16.42.42'
list 'dhcp_option' '3,172.16.42.1'
list 'dhcp_option' '6,172.16.42.1,8.8.8.8'
list 'dhcp_option' '6,172.16.42.1,208.67.222.222'

/etc/config/firewall

config defaults
option syn_flood 1
option input ACCEPT
option output ACCEPT
option forward REJECT
# Uncomment this line to disable ipv6 rules
# option disable_ipv6 1

config zone
option name lan
option network 'lan'
option input ACCEPT
option output ACCEPT
option forward REJECT

config zone
option name wan
option network 'wan'
option input REJECT
option output ACCEPT
option forward REJECT
option masq 1
option mtu_fix 1

config forwarding
option src lan
option dest wan

# We need to accept udp packets on port 68,
# see https://dev.openwrt.org/ticket/4108
config rule
option src wan
option proto udp
option dest_port 68
option target ACCEPT
option family ipv4

# Allow IPv4 ping
config rule
option src wan
option proto icmp
option icmp_type echo-request
option family ipv4
option target ACCEPT

# Allow essential incoming IPv6 ICMP traffic
config rule
option src wan
option dest *
option proto icmp
list icmp_type echo-request
list icmp_type destination-unreachable
list icmp_type packet-too-big
list icmp_type time-exceeded
list icmp_type bad-header
list icmp_type unknown-header-type
option limit 1000/sec
option family ipv6
option target ACCEPT

# include a file with users custom iptables rules
config include
option path /etc/firewall.user

/etc/config/network

config interface 'loopback'
option ifname 'lo'
option proto 'static'
option ipaddr '127.0.0.1'
option netmask '255.0.0.0'

config interface 'lan'
option ifname 'eth0'
option type 'bridge'
option proto 'static'
option ipaddr '172.16.42.1'
option netmask '255.255.255.0'
option gateway '172.16.42.42'
option dns '8.8.8.8'

config interface 'wan'
option ifname 'wlan0'
option proto 'dhcp'

/etc/config/uhttpd

# Server configuration
config uhttpd main

option 'index_page' 'index.php'
option 'error_page' '/index.php'
# HTTP listen addresses, multiple allowed
list listen_http 0.0.0.0:80
# list listen_http [::]:80

# HTTPS listen addresses, multiple allowed
list listen_https 0.0.0.0:443
# list listen_https [::]:443

# Server document root
option home /www

# Reject requests from RFC1918 IP addresses
# directed to the servers public IP(s).
# This is a DNS rebinding countermeasure.
option rfc1918_filter 1

# Certificate and private key for HTTPS.
# If no listen_https addresses are given,
# the key options are ignored.
option cert /etc/uhttpd.crt
option key /etc/uhttpd.key

# CGI url prefix, will be searched in docroot.
# Default is /cgi-bin
option cgi_prefix /cgi-bin

# List of extension->interpreter mappings.
# Files with an associated interpreter can
# be called outside of the CGI prefix and do
# not need to be executable.
list interpreter ".php=/usr/bin/php-cgi"
# list interpreter ".cgi=/usr/bin/perl"
# Lua url prefix and handler script.
# Lua support is disabled if no prefix given.
# option lua_prefix /luci
# option lua_handler /usr/lib/lua/luci/sgi/uhttpd.lua

# CGI/Lua timeout, if the called script does not
# write data within the given amount of seconds,
# the server will terminate the request with
# 504 Gateway Timeout response.
option script_timeout 60

# Network timeout, if the current connection is
# blocked for the specified amount of seconds,
# the server will terminate the associated
# request process.
option network_timeout 30

# TCP Keep-Alive, send periodic keep-alive probes
# over established connections to detect dead peers.
# The value is given in seconds to specify the
# interval between subsequent probes.
# Setting this to 0 will disable TCP keep-alive.
option tcp_keepalive 1

# Basic auth realm, defaults to local hostname
# option realm OpenWrt

# Certificate defaults for px5g key generator
config cert px5g

# Validity time
option days 730

# RSA key size
option bits 1024

# Location
option country DE
option state Berlin
option location Berlin

# Common name
option commonname OpenWrt

config uhttpd pineapple
list listen_http 0.0.0.0:1471
option home /pineapple
option index_page index.php
option 'error_page' '/index.php'

# Configuration file in busybox httpd format
option config /etc/config/httpd.conf
option rfc1918_filter 1

# Certificate and private key for HTTPS.
# If no listen_https addresses are given,
# the key options are ignored.
option cert /etc/uhttpd.crt
option key /etc/uhttpd.key

# CGI url prefix, will be searched in docroot.
# Default is /cgi-bin
option cgi_prefix /cgi-bin

# List of extension->interpreter mappings.
# Files with an associated interpreter can
# be called outside of the CGI prefix and do
# not need to be executable.
list interpreter ".php=/usr/bin/php-cgi"

# CGI/Lua timeout, if the called script does not
# write data within the given amount of seconds,
# the server will terminate the request with
# 504 Gateway Timeout response.
option script_timeout 60

# Network timeout, if the current connection is
# blocked for the specified amount of seconds,
# the server will terminate the associated
# request process.
option network_timeout 30# TCP Keep-Alive, send periodic keep-alive probes
# over established connections to detect dead peers.
# The value is given in seconds to specify the
# interval between subsequent probes.
# Setting this to 0 will disable TCP keep-alive.
option tcp_keepalive 1

/etc/php.ini

[PHP]

zend.ze1_compatibility_mode = Off

; Language Options

engine = On
short_open_tag = On
precision    =  12
y2k_compliance = On
output_buffering = Off
;output_handler =
zlib.output_compression = Off
;zlib.output_compression_level = -1
;zlib.output_handler =
implicit_flush = Off
unserialize_callback_func =
serialize_precision = 100

;open_basedir =
disable_functions =
disable_classes =

; Colors for Syntax Highlighting mode.  Anything that's acceptable in
;  would work.
;highlight.string  = #DD0000
;highlight.comment = #FF9900
;highlight.keyword = #007700
;highlight.bg      = #FFFFFF
;highlight.default = #0000BB
;highlight.html    = #000000

;ignore_user_abort = On
;realpath_cache_size = 16k
;realpath_cache_ttl = 120

; Miscellaneous

expose_php = On

; Resource Limits

max_execution_time = 30	; Maximum execution time of each script, in seconds.
max_input_time = 60	; Maximum amount of time each script may spend parsing request data.
;max_input_nesting_level = 64
memory_limit = 8M	; Maximum amount of memory a script may consume.

; Error handling and logging

; Error Level Constants:
; E_ALL             - All errors and warnings (includes E_STRICT as of PHP 6.0.0)
; E_ERROR           - fatal run-time errors
; E_RECOVERABLE_ERROR  - almost fatal run-time errors
; E_WARNING         - run-time warnings (non-fatal errors)
; E_PARSE           - compile-time parse errors
; E_NOTICE          - run-time notices (these are warnings which often result
;                     from a bug in your code, but it's possible that it was
;                     intentional (e.g., using an uninitialized variable and
;                     relying on the fact it's automatically initialized to an
;                     empty string)
; E_STRICT			- run-time notices, enable to have PHP suggest changes
;                     to your code which will ensure the best interoperability
;                     and forward compatibility of your code
; E_CORE_ERROR      - fatal errors that occur during PHP's initial startup
; E_CORE_WARNING    - warnings (non-fatal errors) that occur during PHP's
;                     initial startup
; E_COMPILE_ERROR   - fatal compile-time errors
; E_COMPILE_WARNING - compile-time warnings (non-fatal errors)
; E_USER_ERROR      - user-generated error message
; E_USER_WARNING    - user-generated warning message
; E_USER_NOTICE     - user-generated notice message
; E_DEPRECATED      - warn about code that will not work in future versions
;                     of PHP
; E_USER_DEPRECATED - user-generated deprecation warnings
;
; Common Values:
;   E_ALL & ~E_NOTICE  (Show all errors, except for notices and coding standards warnings.)
;   E_ALL & ~E_NOTICE | E_STRICT  (Show all errors, except for notices)
;   E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR  (Show only errors)
;   E_ALL | E_STRICT  (Show all errors, warnings and notices including coding standards.)
; Default Value: E_ALL & ~E_NOTICE
error_reporting  =  E_ALL & ~E_NOTICE & ~E_STRICT

display_errors = On
display_startup_errors = Off
log_errors = Off
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
;report_zend_debug = 0
track_errors = Off
;html_errors = Off
;docref_root = "/phpmanual/"
;docref_ext = .html
;error_prepend_string = ""
;error_append_string = ""
; Log errors to specified file.
;error_log = /var/log/php_errors.log
; Log errors to syslog.
;error_log = syslog

; Data Handling

;arg_separator.output = "&"
;arg_separator.input = ";&"
variables_order = "EGPCS"
request_order = "GP"
register_globals = Off
register_long_arrays = Off
register_argc_argv = On
auto_globals_jit = On
post_max_size = 8M
;magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off
auto_prepend_file =
auto_append_file =
default_mimetype = "text/html"
;default_charset = "iso-8859-1"
;always_populate_raw_post_data = On

; Paths and Directories

; UNIX: "/path1:/path2"
;include_path = ".:/php/includes"
doc_root = ""
user_dir =
extension_dir = "/usr/lib/php"
enable_dl = On
;cgi.force_redirect = 1
;cgi.nph = 1
;cgi.redirect_status_env = ;
cgi.fix_pathinfo=1
;fastcgi.impersonate = 1;
;fastcgi.logging = 0
;cgi.rfc2616_headers = 0

; File Uploads

file_uploads = On
upload_tmp_dir = "/tmp"
upload_max_filesize = 2M
max_file_uploads = 20

; Fopen wrappers

allow_url_fopen = On
allow_url_include = Off
;from="john@doe.com"
;user_agent="PHP"
default_socket_timeout = 60
;auto_detect_line_endings = Off

; Dynamic Extensions

;extension=ctype.so
;extension=curl.so
;extension=dom.so
;extension=exif.so
;extension=ftp.so
;extension=gd.so
;extension=gmp.so
;extension=hash.so
;extension=iconv.so
;extension=json.so
;extension=ldap.so
;extension=mbstring.so
;extension=mcrypt.so
;extension=mysql.so
;extension=openssl.so
;extension=pcre.so
;extension=pdo.so
;extension=pdo-mysql.so
;extension=pdo-pgsql.so
;extension=pdo_sqlite.so
;extension=pgsql.so
;extension=session.so
;extension=soap.so
;extension=sockets.so
;extension=sqlite.so
;extension=sqlite3.so
;extension=tokenizer.so
;extension=xml.so
;extension=xmlreader.so
;extension=xmlwriter.so

; Module Settings

[APC]
apc.enabled = 1
apc.shm_segments = 1	;The number of shared memory segments to allocate for the compiler cache.
apc.shm_size = 4M	;The size of each shared memory segment.

[Date]
;date.timezone =
;date.default_latitude = 31.7667
;date.default_longitude = 35.2333
;date.sunrise_zenith = 90.583333
;date.sunset_zenith = 90.583333

[filter]

;filter.default = unsafe_raw ;filter.default_flags =

[iconv]

;iconv.input_encoding = ISO-8859-1 ;iconv.internal_encoding = ISO-8859-1 ;iconv.output_encoding = ISO-8859-1

[sqlite]

;sqlite.assoc_case = 0

[sqlite3]

;sqlite3.extension_dir = [Pdo_mysql] pdo_mysql.cache_size = 2000 pdo_mysql.default_socket= [MySQL] mysql.allow_local_infile = On mysql.allow_persistent = On mysql.cache_size = 2000 mysql.max_persistent = -1 mysql.max_links = -1 mysql.default_port = mysql.default_socket = mysql.default_host = mysql.default_user = mysql.default_password = mysql.connect_timeout = 60 mysql.trace_mode = Off [PostgresSQL] pgsql.allow_persistent = On pgsql.auto_reset_persistent = Off pgsql.max_persistent = -1 pgsql.max_links = -1 pgsql.ignore_notice = 0 pgsql.log_notice = 0 [Session] session.save_handler = files session.save_path = “/tmp” session.use_cookies = 1 ;session.cookie_secure = session.use_only_cookies = 1 session.name = PHPSESSID session.auto_start = 0 session.cookie_lifetime = 0 session.cookie_path = / session.cookie_domain = session.cookie_httponly = session.serialize_handler = php session.gc_probability = 1 session.gc_divisor = 100 session.gc_maxlifetime = 1440 session.bug_compat_42 = On session.bug_compat_warn = On session.referer_check = session.entropy_length = 0 ;session.entropy_file = /dev/urandom session.entropy_file = ;session.entropy_length = 16 session.cache_limiter = nocache session.cache_expire = 180 session.use_trans_sid = 0 session.hash_function = 0 session.hash_bits_per_character = 4 url_rewriter.tags = “a=href,area=href,frame=src,input=src,form=,fieldset=”

[mbstring]

;mbstring.language = Japanese ;mbstring.internal_encoding = EUC-JP ;mbstring.http_input = auto ;mbstring.http_output = SJIS ;mbstring.encoding_translation = Off ;mbstring.detect_order = auto ;mbstring.substitute_character = none; ;mbstring.func_overload = 0 ;mbstring.strict_detection = Off ;mbstring.http_output_conv_mimetype= ;mbstring.script_encoding=

[gd]

;gd.jpeg_ignore_warning = 0

[exif]

;exif.encode_unicode = ISO-8859-15 ;exif.decode_unicode_motorola = UCS-2BE ;exif.decode_unicode_intel = UCS-2LE ;exif.encode_jis = ;exif.decode_jis_motorola = JIS ;exif.decode_jis_intel = JIS

[soap]

soap.wsdl_cache_enabled=1 soap.wsdl_cache_dir=”/tmp” soap.wsdl_cache_ttl=86400 soap.wsdl_cache_limit = 5

[sysvshm]

;sysvshm.init_mem = 10000

[ldap]

ldap.max_links = -1

[mcrypt]

;mcrypt.algorithms_dir= ;mcrypt.modes_dir=

New – GitHub Repo

To make code sharing easier, we have created the following Github reposotories:

  • https://github.com/PenturaLabs/web-interface With some infusions included: nmap,rickroll,dnssnarf,urlsnarf,sitesurvey,stats
  • https://github.com/PenturaLabs/Pineapple-Confs