A bug bounty program, also called a vulnerability rewards program (VRP), is a crowdsourcing initiative that rewards individuals for discovering and reporting software bugs. Bug bounty programs are often initiated to supplement internal code audits and penetration tests as part of an organization's vulnerability management strategy.
Many software vendors and websites run bug bounty programs, paying out cash rewards to software security researchers and white hat hackers who report software vulnerabilities that have the potential to be exploited. Bug reports must document enough information for for the organization offering the bounty to be able to reproduce the vulnerability. Typically, payment amounts are commensurate with the size of the organization, the difficulty in hacking the system and how much impact on users a bug might have.
Mozilla paid out a $3,000 flat rate bounty for bugs that fit its criteria, while Facebook has given out as much as $20,000 for a single bug report. Google paid Chrome operating system bug reporters a combined $700,000 in 2012 and Microsoft paid UK researcher James Forshaw $100,000 for an attack vulnerability in Windows 8.1. In 2016, Apple announced rewards that max out at $200,000 for a flaw in the iOS secure boot firmware components and up to $50,000 for execution of arbitrary code with kernel privileges or unauthorized iCloud access.
While the use of ethical hackers to find bugs can be very effective, such programs can also be controversial. To limit potential risk, some organizations are offering closed bug bounty programs that require an invitation. Apple, for example, has limited bug bounty participation to few dozen researchers.
A step by step lab based mini course on analyzing your car network
I wanted to learn about hacking cars. As usual I searched around the internet and didn't find any comprehensive resources on how to do this, just bits and pieces of the same info over and over which is frustrating. I am not a car hacking expert, I just like to hack stuff. This mini course will run in a fully simulated lab environment available from open garages, which means in 5 minutes from now you can follow along and hack cars without ever bricking your girlfriends car. Since you obviously wouldn't attack your own Lambo, totally use your girlfriends Prius.
Below are the topics covered in this blogseries so you can decide if you want to read further:
Whats covered in this car hacking mini course:
Setting up Virtual Environments for testing
Sniffing CAN Traffic
Parsing CAN Traffic
Reverse Engineering CAN IDs
Denial of service attacks
Replaying/Injecting Traffic
Coding your own CAN Socket Tools in python
Targeted attacks against your cars components
Transitioning this to attacking a real car with hardware
The first thing we are going to do before we get into any car hacking specifics such as "WTF is CAN?", is get your lab up and running. We are going to run a simple simulated CAN Bus network which controls various features of your simulated car. Its better to learn by doing then sit here and recite a bunch of car network lingo at you and hope you remember it.
I also don't want you to buy a bunch of hardware and jack into your real car right away. Instead there are options that can get you started hacking cars RIGHT NOW by following along with this tutorial. This will also serve to take away the fear of hacking your actual car by understanding what your doing first.
Video Playlist:
Setting up your Lab:
First things first, set yourself up with an Ubuntu VMware install, and load it up. Optionally you could use a Kali Iinux VM, however, that thing drives me nuts with copy paste issues and I think Kayak was giving me install problems. So support is on you if you would like to use Kali. However, I do know Kali will work fine with OpenGarages virtual car.. So feel free to use it for that if you have it handy and want to get started right away.
Install PreReq Libraries:
Once you load this up you are going to want to install CAN utilities and pre-requisite libraries. This is really easy to do with the following Apt-get commands:
Once this is done we can startup the simulator by changing directories to the downloaded repo and running the following 2 commands, which will setup a virtual CAN interface and a simulator GUI Cluster:
Run the setup Script to get the vcan0 interface up:
root@kali:~/ICSim# ./setup_vcan.sh
root@kali:~/ICSim# ./icsim vcan0
On a new terminal tab we will open up our simulators controller with the following command,
root@kali:~/ICSim#./controls vcan0
Note: that the controller must be the in-focus GUI screen to send keyboard commands to the simulator.
How to Use the Simulator:
The simulator has a speedometer with Right and Left turn signals, doors etc. Below are the list of commands to control the simulator when the Control panel is in focus. Give them each a try and note the changes to the simulator.
Up and Down keys control the gauges clusters speedometer
Left and Right keys Control the Blinkers
Right Shift + X, A or B open doors
Left Shift + X, A or be Close doors
Try a few of the above commands for example Right Shift +X and you will see the interface change like so, notice the open door graphic:
Awesome, thanks to OpenGarages you now you have your very own car to hack
Notice in the setup commands above we used a VCan0 interface. Run Ifconfig and you will now see that you indeed have a new network interface that speaks to the CAN network over VCan0.
ficti0n@ubuntu:~/Desktop/ICSim$ ifconfig vcan0
vcan0 Link encap:UNSPECHWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
Car networks run on a variety of protocols most prevalent being CAN. You can think of a CAN Bus like an old school networking hub where everyone can see everyone elses traffic. This is true to some extent although you may not see all of the cars traffic if its not connected to that particular bus your plugged into. You can think of CAN traffic kind of like UDP in that its send and forget, the main difference being parts of the CAN bus network don't actually have addresses and everything runs off arbitration IDs and priorities. Thats enough background to get you doing rather then reading.
With a little knowledge out of the way lets check if we can see our CAN traffic from our virtual car via the CanDump utility, which you installed as part of CanUtils package above. Using the following command on the vcan0 interface our simulator uses you can view a stream of traffic:
ficti0n@ubuntu:~/Desktop/ICSim$ candump vcan0
Above we can see a bunch of CAN frames, and if we perform actions on the vehicle we will see changes to data values in the CanDump output.However this may happen very fast, and we may not be able to see if for example we unlocked our simulators door. This is because things are changing constantly in the cars IDLE state. One single value changing may not stand out enough for us to take notice or may scroll so fast we cant see it.
Capture and Replay CAN Actions:
One option would be to perform an action and replay it, we should see the actions happen again in the replay if the traffic for the action we recorded is on the same bus network our device is plugged into. There are loads of networks within a car and its not guaranteed our network tap for example an OBD2 port plugin is connected to the same network as door we opened.Or the door may not be connected to the network at all depending on your car and its age or how its configured.
Replaying dumps with CanPlayer:
Another useful tool included with CanUtils package is CanPlayer for replaying traffic. If the functionality we are trying to capture is on the same Bus as the adaptor plugged into the car, or in this case our Virtual CAN interface, we can use CanDump to save traffic to a file. We then use CanPlayer to replay the traffic on the network. For example lets run CanDump and open a door and then replay the functionality with CanPlayer.
Lab 1 Steps:
Run CanDump
Right Shift + X to open a door
Cancel CanDump (ctrl+c)
Left Shift + X to close the door
Run can player with the saved dump and it will replay the traffic and open the door
Recording the door opening:(-l for logging)
ficti0n@ubuntu:~/Desktop/ICSim$ candump -l vcan0
Replaying the CanDump file:(use the file your can dump created)
Nice, so if all went well you should see that your door is now open again. If this did not happen when attacking a real car, just try to replay it again. CAN networks are not like TCP/IP, they are more like UDP in that you send out your request and its not expecting a response. So if it gets lost then it gets lost and you have to resend. Perhaps something with higher priority on the network was sending at the time of your replay and your traffic was overshadowed by it.
Interacting with the Can Bus and Reversing Traffic:
So thats cool, but what about actually understanding what is going on with this traffic, CanDump is not very useful for this, is scrolls by to quickly for us to learn much from.Instead we can use CanSniffer with colorized output to show us the bytes within packets that change. Below is an example of CanSniffer Traffic:
You will see 3 fields, Time, IDand Data. Its pretty easy to figure out what these are based on thier name. The most important part for our usage in this blog are the ID and the Data fields.
The ID field is the frame ID which is loosely associated with the device on the network which is effected by the frame being sent. The ID to also determines the priority of the frame on the network.The lower the number of the CAN-ID the higher priority it has on the network and more likely it will be handled first.The data field is the data being sent to change some parameter like unlocking a door or updating output. You will notice that some of the bytes are highlighted RED. The values in red are the values that are changing during the idle state you are currently in.
Determine which ID and Byte controls the throttle:
So with the terminal sniffing window open put the simulator and the controller into the foreground, with the controller being the window you have clicked and selected.Pay attention to the CanSniffer output while hitting the UP ARROW and look for a value that was white but is now Red and increasing in value as the throttle goes up.This might take you a few minutes of paying attention to whats going on to see.
The following 2 pictures show ID 244 in the IDLE state followed by pressing the up button to increase the speed. You will notice a byte has turned red and is increasing in value through a range of HEX values 0-F. It will continue to enumerate through values till it reaches its max speed.
The byte in ID 244 which is changing is the value while the throttle is engaged, so 244 associated in some way with the increasing speed. The throttle speed is a good value to start with as it keeps increasing its value when pressed making it easier to spot while viewing the CanSniffer output.
Singling out Values with Filters:
If you would like to single out the throttle value then click the terminal window and press -000000 followed by the Enter key which will clear out all of the values scrolling. Then press +244 followed by the Enter key which will add back the throttle ID. You can now click the controller again and increase the speed with your Up arrow button without all the noise clouding your view.You will instead as shown below only have ID 244 in your output:
To get back all of the IDs again click the terminal window and input +000000 followed by the Enter key. Now you should see all of the output as before.Essentially 000000 means include everything. But when you put a minus in front of it then it negates everything and clears your terminal window filtering out all values.
Determine Blinker ID:
Now lets figure out another ID for the blinkers. If you hit the left or right arrow with the controls window selected you will notice a whole new ID appears in the list, ID 188 shown in the picture below which is associated with the blinker.
This ID was not listed before as it was not in use within the data output until you pressed the blinker control.Lets single this value out by pressing -000000 followed by +188. Just like in the throttle example your terminal should only show ID 188, initially it will show with 00 byte values.
As you press the left and the right blinker you will see the first Byte change from 00 to 01 or 02. If neither is pressed as in the screenshot above it will be 00. Its kind of hard to have the controller in focus and get a screenshot at the same time but the ID will remain visible as 00 until it times out and disappears from the list when not active. However with it filtered out as above you can get a better view of things and it wont disappear.
Time for YOU to do some Protocol Reversing:
This lab will give you a good idea how to reverse all of the functionality of the car and associate each action with the proper ID and BYTE. This way you can create a map of intended functionality changes you wish to make.Above we have done a few walk throughs with you on how to determine which byte and ID is associated with an action. Now its time to map everything out yourself with all the remaining functionality before moving on to attacking individual components.
Lab Work Suggestion:
Take out a piece of paper and a pencil
Try unlocking and locking doors and write down the ID which controls this action (remember your filters)
Try unlocking each door and write down the BYTES needed for each door to open
Try locking each doors and what Bytes change and what are their values, write them down
Do the same thing for the blinkers left and right (Might be different then what I did above)
What ID is the speedometer using?What byte changes the speed?
Attacking Functionality Directly:
With all of the functionality mapped out we can now try to target various devices in the network directly without interacting with the controllers GUI. Maybe we broke into the car via cellular OnStar connectionor the center console units BLE connection which was connected to the CAN network in some way. After an exploit we have direct access to the CAN network and we would like to perform actions. Or maybe you have installed a wireless device into an OBD2 port under the dashboard you have remote access to the automobile.
Using the data from the CAN network reversing lab above we can call these actions directly with the proper CAN-ID and Byte.Since we are remote to the target we can't just reach over and grab the steering wheel or hit the throttle we will instead send your CAN frame to make the change.
One way we can do this is via the CanSend utility. Lets take our information from our lab above and make the left turn signal flash with the following ID 188 for the turn signal by changing the first byte to 01 indicating the left signal is pressed. CanSend uses the format ID#Data. You will see this below when sending the turn signal via CanSend.
You should have noticed that the left signal flashed. If not pay more attention and give it another try or make sure you used the correct ID and changed the correct byte.So lets do the same thing with the throttle and try to set the speed to something with ID 244 that we determined was the throttle.
My guess is that nothing happened because its so fast the needle is not going to jump to that value. So instead lets try repeating this over and over again with a bash loop which simply says that while True keep sending the throttle value of 11 which equates to about 30mph:
ficti0n@ubuntu:~/Desktop/ICSim$ while true; do cansend vcan0 244#00000011F6;done
Yes thats much better, you may notice the needle jumping back and forth a bit. The reason the needle is bouncing back and forth is because the normal CAN traffic is sent telling the car its actually set to 00 in between your frames saying its 30mph.But it worked and you have now changed the speed the car sees and you have flashed the blinker without using the cars normal blinker controls. Pretty cool right?
Monitor the CAN Bus and react to it:
Another way to handle this issue is to monitor the CAN network and when it sees an ID sent it will automatically send the corresponding ID with a different value.. Lets give that a try to modify our speed output by monitoring for changes. Below we are simply running CanDump and parsing for ID 244 in the log output which is the throttle value that tells the car the speed. When a device in the car reports ID 244 and its value we will immediately resend our own value saying the speed is 30mph with the value 11.See below command and try this out.
ficti0n@ubuntu:~/Desktop/ICSim$ candump vcan0 | grep " 244 " | while read line; do cansend vcan0 244#00000011F6; done
With this running after a few seconds you will see the speed adjust to around 30MPH once it captures a legitimate CAN-ID 244 from the network traffic and sends its own value right after.
Ok cool, so now while the above command is still running click the controller window and start holding down the Up arrow with the controller in focus.. After a few seconds or so when the speed gets above 30MPH you will see the needle fighting for the real higher value and adjusting back to 30MPH as your command keeps sending its on value as a replacement to the real speed.
So thats one way of monitoring the network and reacting to what you see in a very crude manner.Maybe someone stole your car and you want to monitor for an open door and if they try to open the door it immediately locks them in.
Conclusion and whats next:
I am not an expert car hacker but I hope you enjoyed this. Thats about as far as I want to go into this subject today, in the next blog we will get into how to code python to perform actions on the CAN network to manipulate things in a similar way.With your own code you are not limited to the functionality of the tools you are provided and can do whatever you want. This is much more powerful then just using the CanUtils pre defined tools. Later on I will also get into the hardware side of things if you would like to try this on a real car where things are more complicated and things can go wrong.
"The only way a domain compromise can be remediated with a high level of certainty is a complete rebuild of the domain."
Personally, I agree with this, but .... But whether this is the real solution, I'm not sure. And the same applies to compromised computers. When it has been identified that malware was able to run on the computer (e.g. scheduled scan found the malware), there is no easy way to determine with 100% certainty that there is no rootkit on the computer. Thus rebuilding the computer might be a good thing to consider. For paranoids, use new hardware ;)
But rebuilding a single workstation and rebuilding a whole domain is not on the same complexity level. Rebuilding a domain can take weeks or months (or years, which will never happen, as the business will close before that).
There are countless documented methods to backdoor a computer, but I have never seen a post where someone collects all the methods to backdoor a domain. In the following, I will refer to domain admin, but in reality, I mean Domain Admins, Enterprise Admins, and Schema Admins.
Ways to backdoor a domain
So here you go, an incomplete list to backdoor a domain:
Create a new domain admin user. Easy to do, easy to detect, easy to remediate
Dump password hashes. The attacker can either crack those or just pass-the-hash. Since KB2871997, pass-the-hash might be trickier (https://technet.microsoft.com/library/security/2871997), but not impossible. Easy to do, hard to detect, hard to remediate - just think about service user passwords. And during remediation, consider all passwords compromised, even strong ones.
Logon scripts - modify the logon scripts and add something malicious in it. Almost anything detailed in this post can be added :D
Use an already available account, and add domain admin privileges to that. Reset its password. Mess with current group memberships - e.g. http://www.exploit-db.com/papers/17167/
Backdoor any workstation where domain admins login. While remediating workstations, don't forget to clean the roaming profile. The type of backdoor can use different forms: malware, local admin, password (hidden admin with 500 RID), sticky keys, etc.
Backdoor any domain controller server. For advanced attacks, see Skeleton keys
Backdoor files on network shares which are commonly used by domain admins by adding malware to commonly used executables - Backdoor factory
Change ownership/permissions on AD partitions - if you have particular details on how to do this specifically, please comment
Create a new domain user. Hide admin privileges with SID history. Easy to do, hard to detect, easy to remediate - check Mimikatz experimental for addsid
Golden tickets - easy to do, hard to detect, medium remediation
Silver tickets - easy to do, hard to detect, medium/hard remediation
The following list does not fit in the previous "instant admin" tips, but still, it can make the attackers life easier if their primary foothold has been disabled:
Backdoor recent backups - and when the backdoor is needed, destroy the files, so the files will be restored from the backdoored backup
Backdoor the Exchange server - get a copy of emails
Backdoor workstation/server golden image
Change permission of logon scripts to allow modification later
Place malicious symlinks to file shares, collect hashes via SMB auth tries on specified IP address, grab password hashes later
Backdoor remote admin management e.g. HP iLO - e.g. create new user or steal current password
Backdoor files e.g. on shares to use in SMB relay
Backdoor source code of in-house-developed software
Use any type of sniffed or reused passwords in new attacks, e.g. network admin, firewall admin, VPN admin, AV admin, etc.
Change the content of the proxy pac file (change browser configuration if necessary), including special exception(s) for a chosen domain(s) to use proxy on malicious IP. Redirect the traffic, enforce authentication, grab password hashes, ???, profit.
Create high privileged users in applications running with high privileges, e.g. MSSQL, Tomcat, and own the machine, impersonate users, grab their credentials, etc. The typical pentest path made easy.
Remove patches from servers, change patch policy not to install those patches.
Steal Windows root/intermediate CA keys
Weaken AD security by changing group policy (e.g. re-enabling LM-hashes)
Update [2015-09-27]: I found this great presentation from Jakob Heidelberg. It mentions (at least) the following techniques, it is worth to check these:
Microsoft Local Administrator Password Solution
Enroll virtual smart card certificates for domain admins
Forensics
If you have been chosen to remediate a network where attackers gained domain admin privileges, well, you have a lot of things to look for :)
I can recommend two tools which can help you during your investigation:
But guess what, not all of these problems are solved by rebuilding the AD. One has to rebuild all the computers from scratch as well. Which seems quite impossible. When someone is creating a new AD, it is impossible not to migrate some configuration/data/files from the old domain. And whenever this happens, there is a risk that the new AD will be backdoored as well.
Ok, we are doomed, but what can we do? I recommend proper log analysis, analyze trends, and detect strange patterns in your network. Better spend money on these, than on the domain rebuild. And when you find something, do a proper incident response. And good luck!
Ps: Thanks to Andrew, EQ, and Tileo for adding new ideas to this post.
All commands (A-Z) for Kali Linux here: A apropos Search Help manual pages (man -k) apt-get Search for and install software packages (Debian/Ubuntu) aptitude Search for and install software packages (Debian/Ubuntu) aspell Spell Checker awk Find and Replace text, database sort/validate/index B basename Strip directory and suffix from filenames bash GNU Bourne-Again SHell bc Arbitrary precision calculator language bg Send to background break Exit from a loop • builtin Run a shell builtin bzip2 Compress or decompress named file(s) C cal Display a calendar case Conditionally perform a command cat Concatenate and print (display) the content of files cd Change Directory cfdisk Partition table manipulator for Linux chgrp Change group ownership chmod Change access permissions chown Change file owner and group chroot Run a command with a different root directory chkconfig System services (runlevel) cksum Print CRC checksum and byte counts clear Clear terminal screen cmp Compare two files comm Compare two sorted files line by line command Run a command – ignoring shell functions • continue Resume the next iteration of a loop • cp Copy one or more files to another location cron Daemon to execute scheduled commands crontab Schedule a command to run at a later time csplit Split a file into context-determined pieces cut Divide a file into several parts D date Display or change the date & time dc Desk Calculator dd Convert and copy a file, write disk headers, boot records ddrescue Data recovery tool declare Declare variables and give them attributes • df Display free disk space diff Display the differences between two files diff3 Show differences among three files dig DNS lookup dir Briefly list directory contents dircolors Colour setup for `ls' dirname Convert a full pathname to just a path dirs Display list of remembered directories dmesg Print kernel & driver messages du Estimate file space usage E echo Display message on screen • egrep Search file(s) for lines that match an extended expression eject Eject removable media enable Enable and disable builtin shell commands • env Environment variables ethtool Ethernet card settings eval Evaluate several commands/arguments exec Execute a command exit Exit the shell expect Automate arbitrary applications accessed over a terminal expand Convert tabs to spaces export Set an environment variable expr Evaluate expressions F false Do nothing, unsuccessfully fdformat Low-level format a floppy disk fdisk Partition table manipulator for Linux fg Send job to foreground fgrep Search file(s) for lines that match a fixed string file Determine file type find Search for files that meet a desired criteria fmt Reformat paragraph text fold Wrap text to fit a specified width. for Expand words, and execute commands format Format disks or tapes free Display memory usage fsck File system consistency check and repair ftp File Transfer Protocol function Define Function Macros fuser Identify/kill the process that is accessing a file G gawk Find and Replace text within file(s) getopts Parse positional parameters grep Search file(s) for lines that match a given pattern groupadd Add a user security group groupdel Delete a group groupmod Modify a group groups Print group names a user is in gzip Compress or decompress named file(s) H hash Remember the full pathname of a name argument head Output the first part of file(s) help Display help for a built-in command • history Command History hostname Print or set system name I iconv Convert the character set of a file id Print user and group id's if Conditionally perform a command ifconfig Configure a network interface ifdown Stop a network interface ifup Start a network interface up import Capture an X server screen and save the image to file install Copy files and set attributes J jobs List active jobs • join Join lines on a common field K kill Stop a process from running killall Kill processes by name L less Display output one screen at a time let Perform arithmetic on shell variables • ln Create a symbolic link to a file local Create variables • locate Find files logname Print current login name logout Exit a login shell • look Display lines beginning with a given string lpc Line printer control program lpr Off line print lprint Print a file lprintd Abort a print job lprintq List the print queue lprm Remove jobs from the print queue ls List information about file(s) lsof List open files M make Recompile a group of programs man Help manual mkdir Create new folder(s) mkfifo Make FIFOs (named pipes) mkisofs Create an hybrid ISO9660/JOLIET/HFS filesystem mknod Make block or character special files more Display output one screen at a time mount Mount a file system mtools Manipulate MS-DOS files mtr Network diagnostics (traceroute/ping) mv Move or rename files or directories mmv Mass Move and rename (files) N netstat Networking information nice Set the priority of a command or job nl Number lines and write files nohup Run a command immune to hangups notify-send Send desktop notifications nslookup Query Internet name servers interactively O open Open a file in its default application op Operator access P passwd Modify a user password paste Merge lines of files pathchk Check file name portability ping Test a network connection pkill Stop processes from running popd Restore the previous value of the current directory pr Prepare files for printing printcap Printer capability database printenv Print environment variables printf Format and print data • ps Process status pushd Save and then change the current directory pwd Print Working Directory Q quota Display disk usage and limits quotacheck Scan a file system for disk usage quotactl Set disk quotas R ram ram disk device rcp Copy files between two machines read Read a line from standard input • readarray Read from stdin into an array variable • readonly Mark variables/functions as readonly reboot Reboot the system rename Rename files renice Alter priority of running processes remsync Synchronize remote files via email return Exit a shell function rev Reverse lines of a file rm Remove files rmdir Remove folder(s) rsync Remote file copy (Synchronize file trees) S screen Multiplex terminal, run remote shells via ssh scp Secure copy (remote file copy) sdiff Merge two files interactively sed Stream Editor select Accept keyboard input seq Print numeric sequences set Manipulate shell variables and functions sftp Secure File Transfer Program shift Shift positional parameters shopt Shell Options shutdown Shutdown or restart linux sleep Delay for a specified time slocate Find files sort Sort text files source Run commands from a file `.' split Split a file into fixed-size pieces ssh Secure Shell client (remote login program) strace Trace system calls and signals su Substitute user identity sudo Execute a command as another user sum Print a checksum for a file suspend Suspend execution of this shell • symlink Make a new name for a file sync Synchronize data on disk with memory T tail Output the last part of file tar Tape ARchiver tee Redirect output to multiple files test Evaluate a conditional expression time Measure Program running time times User and system times touch Change file timestamps top List processes running on the system traceroute Trace Route to Host trap Run a command when a signal is set(bourne) tr Translate, squeeze, and/or delete characters true Do nothing, successfully tsort Topological sort tty Print filename of terminal on stdin type Describe a command • U ulimit Limit user resources • umask Users file creation mask umount Unmount a device unalias Remove an alias • uname Print system information unexpand Convert spaces to tabs uniq Uniquify files units Convert units from one scale to another unset Remove variable or function names unshar Unpack shell archive scripts until Execute commands (until error) uptime Show uptime useradd Create new user account userdel Delete a user account usermod Modify user account users List users currently logged in uuencode Encode a binary file uudecode Decode a file created by uuencode V v Verbosely list directory contents (`ls -l -b') vdir Verbosely list directory contents (`ls -l -b') vi Text Editor vmstat Report virtual memory statistics W wait Wait for a process to complete • watch Execute/display a program periodically wc Print byte, word, and line counts whereis Search the user's $path, man pages and source files for a program which Search the user's $path for a program file while Execute commands who Print all usernames currently logged in whoami Print the current user id and name (`id -un') wget Retrieve web pages or files via HTTP, HTTPS or FTP write Send a message to another user X xargs Execute utility, passing constructed argument list(s) xdg-open Open a file or URL in the user's preferred application. yes Print a string until interrupted . Run a command script in the current shell !! Run the last command again