Remember: "Pineapple-mode" is only 1/2 of the functionality of the r00tabaga. This guide shows you how to build that half, by itself.
If you want to re-create a r00tabaga from scratch, you'll need to check out Help! I broke my r00tabaga :(
Inspired by the work of Andy Davies at Pentura Labs with Blue For The Pineapple and Samiux with his TL-MR3020 WiFi Pineapple Made Easy Howto, we set out to do the same thing with a TL-MR3040.
Quick Start
This abbreviated guide is here to centralize support resources, and has been modified only insofar as to remove any unnecessary steps and reference use of the TL-MR3040 throughout the instructions. The full version of this guide can be seen in Pentura Labs' original post, entitled: "Blue For The Pineapple," which uses a TL-WR703N.
To begin, download and flash an appropriate build of OpenWRT for your platform (TL-WR703N, TL-MR11U, TL-MR3040) from here: http://downloads.openwrt.org/attitude_adjustment/12.09/ar71xx/generic/
Preparing USB as / (root)
Format a USB key with two partitions, ext4 and swap, install attitude adjustment squashfs, connect router 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
At this point you can install any additional packages you may want or 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
Use 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, obtainable from http://www.wifipineapple.com/
Below is sample output from 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)
Using Squashfuse (https://github.com/vasi/squashfuse) or OSXFUse, it is easy to mount the pineapple.img extracted earlier:
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 Pineapple Web Interface
Open Source Method
As of the last month, Sebkinne has made the Pineapple's Web Interface available as open source via github:
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.
- Secondly the ps command is slightly different in the version on the TPLink search and replace “ps aux| ps auxww” with ps.
- From simon:
grep -lr -e ‘ps aux’ * | xargs sed -i ‘s/ps aux/ps/g’
grep -lr -e ‘ps -all’ * | xargs sed -i ‘s/ps -all/ps/g’
grep -lr -e ‘ps auxww’ * | xargs sed -i ‘s/ps auxww/ps/g’
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 config files 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=
And that's it! With these configs in place, you're TP-Link TL-MR3040 will now look and taste just like a pineapple!
4 Comments