TP-Link’s all-in-one SR20 Smart Home Router allows arbitrary command execution from a local network connection, according to a Google security researcher.
On Wednesday, 90 days after he informed TP-Link of the issue and received no response, Matthew Garrett, a well-known Google security engineer and open-source contributor, disclosed a proof-of-concept exploit to demonstrate a vulnerability affecting TP-Link’s router.
The 38-line script shows that you can execute any command you choose on the device with root privileges, without authentication. The SR20 was announced in 2016.
Via Twitter, Garrett explained that TP-Link hardware often incorporates TDDP, the TP-Link Device Debug Protocol, which has had multiple vulnerabilities in the past. Among them, version 1 did not require a password.
«The SR20 still exposes some version 1 commands, one of which (command 0x1f, request 0x01) appears to be for some sort of configuration validation,» he said. «You send it a filename, a semicolon and then an argument.»
Once it receives the command, says Garrett, the router responds to the requesting machine via TFTP, asks for the filename, imports it to a Lua interpreter, running as root, and sends the argument to the config_test() function within the imported file.
The Lua os.execute() method passes a command to be executed by an operating system shell. And since the interpreter is running as root, Garret explains, you have arbitrary command execution.
However, while TDDP listens on all interfaces, the default firewall prevents network access, says Garrett. This makes the issue less of a concern that remote code execution flaws identified in TP-Link 1GbE VPN routers in November.
Even so, vulnerability to a local attack could be exploited if an attacker manages to get a malicious download onto a machine connected to an SR20 router.
TP-Link did not immediately respond to a request for comment.
Garrett concluded his disclosure by urging TP-Link to provide a way to report security flaws and not to ship debug daemons on production firmware.
Researchers find new Intel VISA (Visualization of Internal Signals Architecture) debugging technology.
At the Black Hat Asia 2019 security conference, security researchers from Positive Technologies disclosed the existence of a previously unknown and undocumented feature in Intel chipsets.
Called Intel Visualization of Internal Signals Architecture (Intel VISA), Positive Technologies researchers Maxim Goryachy and Mark Ermolov said this is a new utility included in modern Intel chipsets to help with testing and debugging on manufacturing lines.
VISA is included with Platform Controller Hub (PCH) chipsets part of modern Intel CPUs and works like a full-fledged logic signal analyzer.
According to the two researchers, VISA intercepts electronic signals sent from internal buses and peripherals (display, keyboard, and webcam) to the PCH —and later the main CPU.
VISA EXPOSES A COMPUTER’S ENTIRE DATA
Unauthorized access to the VISA feature would allow a threat actor to intercept data from the computer memory and create spyware that works at the lowest possible level.
But despite its extremely intrusive nature, very little is known about this new technology. Goryachy and Ermolov said VISA’s documentation is subject to a non-disclosure agreement, and not available to the general public.
Normally, this combination of secrecy and a secure default should keep Intel users safe from possible attacks and abuse.
However, the two researchers said they found several methods of enabling VISA and abusing it to sniff data that passes through the CPU, and even through the secretive Intel Management Engine (ME), which has been housed in the PCH since the release of the Nehalem processors and 5-Series chipsets.
INTEL SAYS IT’S SAFE. RESEARCHERS DISAGREE.
Goryachy and Ermolov said their technique doesn’t require hardware modifications to a computer’s motherboard and no specific equipment to carry out.
The simplest method consists of using the vulnerabilities detailed in Intel’s Intel-SA-00086security advisory to take control of the Intel Management Engine and enable VISA that way.
«The Intel VISA issue, as discussed at BlackHat Asia, relies on physical access and a previously mitigated vulnerability addressed in INTEL-SA-00086 on November 20, 2017,» an Intel spokesperson told ZDNet yesterday.
«Customers who have applied those mitigations are protected from known vectors,» the company said.
However, in an online discussion after his Black Hat talk, Ermolov said the Intel-SA-00086 fixes are not enough, as Intel firmware can be downgraded to vulnerable versions where the attackers can take over Intel ME and later enable VISA.
Furthermore, Ermolov said that there are three other ways to enable Intel VISA, methods that will become public when Black Hat organizers will publish the duo’s presentation slides in the coming days.
As Ermolov said yesterday, VISA is not a vulnerability in Intel chipsets, but just another way in which a useful feature could be abused and turned against users. Chances that VISA will be abused are low. This is because if someone would go through the trouble of exploiting the Intel-SA-00086 vulnerabilities to take over Intel ME, then they’ll likely use that component to carry out their attacks, rather than rely on VISA.
As a side note, this is the second «manufacturing mode» feature Goryachy and Ermolov found in the past year. They also found that Apple accidentally shipped some laptops with Intel CPUs that were left in «manufacturing mode.»
More info : - If the board fails to connect to the cloud, perform a hard reset (ie. disconnect it completely before rebooting it) - The cloud endpoint used to get the flag is /flag, in case you need to guess it
And a .tgz is given, containing the 3 firmwares of the 3 available boards:
$ ls -l total 1376 -rwxrwxrwx 1 root root 287536 mars 27 2019 board-2.bin -rwxrwxrwx 1 root root 287536 mars 27 2019 board-3.bin -rwxrwxrwx 1 root root 287536 mars 27 2019 board-4.bin -rwxrwxrwx 1 root root 545222 mars 22 18:17 firmwares-d1bd1fcbfb1fdef7678608460ed96b16074aae3f43ed052ebcc3e2724d7efc27.tgz $ sha256sum board-* aadc9e62ba75bda60b1412d0514bae00a28f51636c1291590e70c217bcf25a2f board-2.bin 27e7b7d39566bbdbd109a56e50f546681770ef3fad261118d64e1319ff0d53e7 board-3.bin 32682457545043f8611078d43549cf4414f9f0bd29700c1f2c42ad80d5013229 board-4.bin
Understanding what to do
As this challenge looks not trivial at all, I’ve spent 15 minutes on understanding the goal and the path to achieve the job. All the 3 boards are in free access on a desk beside the organisation team.
When you power-up the device using the black USB cable, it start running and show the activity on the network connector. As this device is a development board, the left secable part is a ST-Link V2 ready to handle the right part of the board, composed of the main MCU and a few components. Connecting a PC to the USB port and running it with the official ST-Link utility give you this trace:
19:53:18 : ST-LINK SN : 0669FF494849887767175629 19:53:18 : ST-LINK Firmware version : V2J29M18 19:53:18 : Connected via SWD. 19:53:18 : SWD Frequency = 4,0 MHz. 19:53:18 : Connection mode : Connect Under Reset. 19:53:18 : Debug in Low Power mode enabled. 19:53:18 : Device ID:0x419 19:53:18 : Device family :STM32F42xxx/F43xxx 19:53:18 : Can not read memory! Disable Read Out Protection and retry.
The MCU is protected, but the ST-link is non altered and can be used.
Now let’s see if the virtual COM port (VCP) is mapped by the ST-Link for debug purpose. Just start a terminal and RESET the board to have a look at the boot sequence:
Starting mbed-os-example-tls/tls-client Using Mbed OS 5.11.5 Successfully connected to perfectlyunbreakable-cloud.insomni.hack at port 443 Starting the TLS handshake… Successfully completed the TLS handshake Server certificate: cert. version : 1 serial number : 29:98:FB:FA:5B:65:0A:2D:15:E0:A4:BF:9B:06:6C:0B:1D:72:C8:8A issuer name : C=CH, ST=Geneva, O=Insomni'hack subject name : C=CH, ST=Geneva, O=Insomni'hack, CN=perfectlyunbreakable-cloud.insomni.hack issued on : 2019-03-14 11:00:24 expires on : 2020-07-26 11:00:24 signed using : ECDSA with SHA256 EC key size : 256 bits
Certificate verification passed Established TLS connection to perfectlyunbreakable-cloud.insomni.hack HTTP: Received 175 chars from server HTTP: Received '200 OK' status … OK HTTP: Received message: HTTP/1.1 200 OK Server: nginx Date: Fri, 22 Mar 2019 18:11:52 GMT Content-Type: text/html; charset=utf-8 Content-Length: 20 Connection: keep-alive
Cloud connection OK.
At this point, nothing other is possible over the serial port, impossible to send command to the board.
To summarize: The goal is to connect to the https://perfectlyunbreakable-cloud.insomni.hack/flag URL. I can deduce that only the official boards can do it because they own a client side certificate in their flash. So, the only way to connect to /flag with a regular browser is to steal the private certificate key from the flash of the MCU and import it to the browser.
Let’s start the reverse
Check the difference between all the 3 firmwares
As the authors gives you the 3 binary firmwares from the 3 running board, this looks too simple to spot the certificate by this way, but let’s try it.
The public certificate is the first difference, and the 32 bytes at offset 0x080437B0 is the second one. The second one is the most interesting because it should be the —–BEGIN PRIVATE KEY—– but it was not the case.
Let’s the long reverse start
Now it’s time to reverse the 281KB STM32 firmware file… And guess what, just to be sure to maximise the complexity of the task, let’s use a newcomer: Ghidra!
The tool worth a look and from my previous tests, the ARM-thumb decompiler was fine on all the examples I’ve tried.
LOAD THE FILE
Loading the firmware and giving at this first stage the correct description to Ghidra is mandatory. The STM32 used for the challenge is a STM32F42xxx/F43xxx (according to the previous ST-Link trace). Checking in the reference guide for the ARM level instruction will point you Cortex-M4. And if you dig more, you’ll find it’s an ARMv7E ISA. The mistake I’ve done is to select in Ghidra the ARM v7 little endian target. The correct one is Cortex (thanks Balda for the correction):
And do not forget to set the base address of the firmware:
FINDING INTERESTING STUFF
Now we need to find the public and private key in the firmware. For the pub cert chain, it’s trivial, just need to look for strings « BEGIN CERTIFICATE »:
But now the complex things start: where the f*ck is the private key… At this point you have no choice to understand how the HTTPS connection is done to the server. The first and winning idea is to take back the serial log and try to identify the SDK used. At the beginning « Mbed OS 5.11.5 » explicitly give you the answer. Then, you need to dig more for guessing how the TLS is done.
The interesting part is :
Starting the TLS handshake… Successfully completed the TLS handshake
After a few minutes digging with Google, this PAGE give you nearly the same trace I’ve obtain through the serial interface. From this sample code found in the SDK, you can find your way in the firmware:
As I’ve never pay attention on how to reverse some C++ code in an embedded target, I was stuck by the pointer added to a method without parameter in the original source code. Ghidra is doing a good job, but you need to understand that the pointer renamed here « complexStruct » is the pointer to the current memory segment of the instance of the object.
Then, digging more in the TLS part is needed. According to the SDK, using a client private certificate measn you need to call the function « mbedtls_ssl_conf_own_cert ». By searching in the strings I found « mbedtls_ssl_conf_own_cert() returned -0x%04X » and a XREF. This code is setting up the certificate pub/priv key pair:
Now, it’s time to study the function genPrivateKey() and see how it works:
The funniest part of the challenge is here. This code is nothing more than a bitwise AND with 2 offset in memory. One in flash, OK, but the other one in a non initialized SRAM zone! Now it’s time to have a look at the hint given during the CTF:
Fri Mar 22 2019, 22:20:22 [Perfectly Unbreakable Flag Hint] The title acronym means something else in the hardware community!
« PUF » acronym. What? Google point THIS page. My friend dok tells me, « I know what it is, it’s something you can’t clone because it use some physical unpredictable parameter ». But in the current case the PUF function is the SRAM at boot. 64 bytes are used as the private key. But, as there is some flipping bits in those 64 bytes during the powerup sequence, another 64 bytes table is used as mask for keeping only the stables states bits, and remove the flipping one. This tech needs to boot a huge number of time the board to monitor the states of the 8×64 bits and only keep the stable one. That’s a REALLY GOOD TRIX!
Now I need to dump the content of the SRAM3, forgotten during the first dump . It’s quite easy, even with the protection fuse set. You just need to connect your PC, run the ST-Link utility and press « connect », then on the target hit RESET and at the very first moment of the boot you can dump the whole SRAM zone. Even if the debug port is closed.
With the memory dump and the flash dump, here is the code who compute and display the private key:
import base64 sram = "\x09\xE6\xF1\x20\x32\xE2\x38\xDD\xCF\x29\x27\x7F\x6F\xEB\x76\x34\x40\xC4\x44\xDC\xCA\xCD\x3B\x87\x0B\xAB\xE1\xB8\xE8\x80\x7B\x9B\x3B\xAA\xD5\x04\x61\xCA\xA2\x91\x66\x32\x49\xDF\xE5\x42\x98\xF5\x98\xB2\x37\x7E\x7E\xEB\xFD\x2E\xAB\xC1\x9F\x5A\xC0\xE3\xFF\xD9" flash = "\x59\x3D\x32\xFE\x47\xA5\x4A\x85\x88\x35\x4E\x27\x63\x49\x37\xB6\xFF\x1B\xBE\xC2\xCE\x63\x95\xAB\x30\x3F\x77\x9D\x59\xD3\xE2\x75\xDD\xFF\x1E\x03\x2E\xF1\xEE\xE1\x52\xE8\xAA\x8B\x0E\x9D\xFA\xEA\x4E\x3D\x79\x0C\xD7\xEB\xBD\x7E\x73\x35\x9E\x5B\xBE\x5D\x42\xD7" res =  for x in range(len(sram)) : res.append( ord(sram[x]) & ord(flash[x]) ) print("Private key = ",res)
At this point it was 3H56. My first think was « shit, it miss me 10 minutes to generate the private key and solve the challenge ».
CONTINUE THE REVERSE AT HOME
As it’s always a big deception to not finish a challenge in time, I continue at home to solve it. But I was wrong. It was far more complex to finish the reverse until the flag, and the 10 minutes changed to another 4 hours of job.
After obtaining the bits from SRAM who doesn’t flip, you need to reverse this:
And the funny stuff is for example:
This one doesn’t decompile, and the ASM view is not so clear. My guess is this an interrupt hook to an external crypto-engine who run in a few cycles a cryptographic function.
To help identifying the function, I’ve download an official TLS library from Mbed: mbedtls-2.16.0-apache.tgz. With this reference source code, the unknown function can be commented and is a little bit more readable:
If you think it’s trivial now, your right but with the solution on the eyes it’s more easy, believe me . So the unknown part of the private key become:
import base64 import hashlib from array import array
Now it’s time to start a little bit of crypto. EDIT: no, not a little! I have something looking like the private key and the full chain of certificate. I need to craft a correct certificate, so I can deploy it and visit the /flag URL. If you wonder how I can do that after the CTF you’re right: I have asked to the creators of the challenge the Docker files to run it here and finish the work.
First, craft the private key. For this one you need to generate the ECC correct private + public key file in .pem format. I never found a regular way working because of a lack of knowledge in certificate / keys manipulation. Thanks to Sylvain for correct my silly Python code. The use an enhanced Python crypto lib is needed, I’ve used Pycryptodome.
Now you need to concatenate the 2 public certificates found in the flash of the board in a file called « chain.pem ». And finally generate a single file with all the stuff to import it on a regular browser:
$ openssl pkcs12 -info -in personnal.pfx Enter Import Password: MAC: sha1, Iteration 2048 MAC length: 20, salt length: 8 PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048 Certificate bag Bag Attributes localKeyID: 95 5D 33 B2 38 0B 4C CE FC 46 DD 1C 55 17 63 45 5A 7A 17 82 subject=C = CH, ST = Geneva, O = Insomni'hack, CN = board-2.insomni.hack issuer=C = CH, ST = Geneva, O = Insomni'hack -----BEGIN CERTIFICATE----- MIIBgzCCASoCFCmY+/pbZQotFeCkv5sGbAsdcsiLMAoGCCqGSM49BAMCMDUxCzAJ BgNVBAYTAkNIMQ8wDQYDVQQIDAZHZW5ldmExFTATBgNVBAoMDEluc29tbmknaGFj azAeFw0xOTAzMTQxNjA3NDZaFw0yMDA3MjYxNjA3NDZaMFQxCzAJBgNVBAYTAkNI MQ8wDQYDVQQIDAZHZW5ldmExFTATBgNVBAoMDEluc29tbmknaGFjazEdMBsGA1UE AwwUYm9hcmQtMi5pbnNvbW5pLmhhY2swWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC AAQ6ezsYJBMBjVBhWLjPzcZjSv7/z4WQZI/820/RgryR+phEx6oY8EE8+EVA5+Jg XuhIoTvirMKnhWkHBu+NtNNLMAoGCCqGSM49BAMCA0cAMEQCIDQgEWRfMgl78w68 92AYoRIrkLVMKmXHj6Kibqm0h66PAiAgaJnY8NgDzEXXcgnk7uKSJr5weal9b7mX fTP+lQ8dGw== -----END CERTIFICATE----- Certificate bag Bag Attributes: subject=C = CH, ST = Geneva, O = Insomni'hack issuer=C = CH, ST = Geneva, O = Insomni'hack -----BEGIN CERTIFICATE----- MIIBwDCCAWWgAwIBAgIURc/ib+oKmFi+wE2R8p4frfrjZxowCgYIKoZIzj0EAwIw NTELMAkGA1UEBhMCQ0gxDzANBgNVBAgMBkdlbmV2YTEVMBMGA1UECgwMSW5zb21u aSdoYWNrMB4XDTE5MDMxNDEwNDkwOVoXDTE5MDQxMzEwNDkwOVowNTELMAkGA1UE BhMCQ0gxDzANBgNVBAgMBkdlbmV2YTEVMBMGA1UECgwMSW5zb21uaSdoYWNrMFkw EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEYrOHfsBHEvA71iU0GvRp2MT0XflBCWwh EJ2OkM6uI1C4dg8OfNul7CrqOz3/vxJ/aMWOCcwcfadSkMuXLnWdgaNTMFEwHQYD VR0OBBYEFN4XdSOEDDc8mhd1Z5sJS0iXLaSbMB8GA1UdIwQYMBaAFN4XdSOEDDc8 mhd1Z5sJS0iXLaSbMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIh AOBd8Q53tDEVhQHeZr4vZa7cVZIi0xW3JzT6y1TIOpDjAiEAxvmsQdLwf3SYVzlf OQTTWPLAob+l+gyqt5Cfq5f6j4Y= -----END CERTIFICATE----- PKCS7 Data Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048 Bag Attributes localKeyID: 95 5D 33 B2 38 0B 4C CE FC 46 DD 1C 55 17 63 45 5A 7A 17 82 Key Attributes: Enter PEM pass phrase: Verifying - Enter PEM pass phrase: -----BEGIN ENCRYPTED PRIVATE KEY----- MIHjME4GCSqGSIb3DQEFDTBBMCkGCSqGSIb3DQEFDDAcBAimiYHm+GS83AICCAAw DAYIKoZIhvcNAgkFADAUBggqhkiG9w0DBwQIpZKgXjFIC3IEgZAPX/83qeR2bwPn /HDKhevSpTlqqzvT2NDxMdI907kMggHfVNgCY2rzMP3Bmk9F+CpdgpFPNFSP2gWV iNDxGRusXAIDg3to2ZRCmt31/31idQwFgDqW2LqawXv0TCWit6Y22su7uDKDz0Vw w2FZXeM26zGl+hkL0QJIuSqmyMhrncUzJdGxGWfXENKaee9JsMw= -----END ENCRYPTED PRIVATE KEY-----
One fuckin’ thing to know: if you don’t set a password to your .pfx file, Firefox will fail silently to import it.
Another funny thing: at this point you don’t know if there is more computing on the 32 bytes used for generate the private key. The firmware is so huge, you can’t check all functions between the last key manipulation and the TCP_connect to the HTTPS port. You just need to try and pray…
Now you just need to connect to the super-secure cloud with the fake credz:
And now you just need to grab the flag:
No, not exactly the flag …
I was wondering the needs to this last step, who’ve made lost the flag to Marius (@nSinusR) from Tasteless (@TeamTasteless). Yes, Marius arrived during the CTF at this point at 3h55. It’s the difference between skilled teams and amateurs . As we have access to the boards, we have the firmware, it would have been possible to patch the board to connect directly to the url https://perfectlyunbreakable-cloud.insomni.hack/flag instead of https://perfectlyunbreakable-cloud.insomni.hack/ during the boot sequence. So the last step involve the private key you’ve used for generate the certificate as a proof of work. To remove the AES-CBC I’ve used Openssl:
I personally go to Insomni’Hack CTF for one thing: the hardware challenges. This year 2 challenges were here for our pleasure. The first one from @_noskill of http://fixme.ch/ , intern at SCRT at the moment, were cool and a good warm-up (write-up from Sylvain of DUKS HERE). And this « monster » from Balda & Sylvain.
I must say this challenge occupy me during the whole CTF. I’ve learn a tech’ I’ve never seen before, the PUF concept is really funny and, I guess, used IRL. Solving a task close to a real project is far away more exiting, and it was the case here! Using Ghidra was a good experience, I’ll do it again and hope to forget ASAP IDA-PRO to focus only on this wonderful open-source tool.
A little regret on this one is the missing in the description of the « crypto » categorie. With this more accurate description I would not tried it alone, and I would asked for some helps to other members of the team at the very first moment of the CTF. And the complexity was too much for a 10 hours CTF, so the task wasn’t solved at 4h00 by anyone. To be honest, without the help of the conceptors, I’ll not be able to solve it, even afterwards (I guess I would ragequit() before the flag ).
From the description: « To our surprise, we found out that our challenge from last year has been counterfeited by another CTF. » is well sent . Last year I solved in 3 minutes the hardware challenge, because the flash read protection fuse on the STM32 was forgotten (write-up HERE). In November 2018 Balda got a kind word at GreHack CTF on the first hardware challenge :
"An Insomni'Hack 2018 tribute":
Was a 400 points at Insomni'hack and is only a 50 points at GreHack ... with the good tools ( Hello Baldanos )
This year you win, so 1 – 1. See you the 15th of November for the next edition of GreHack .
Credits & Greetings
Nice challenge by Baldanos (@Baldanos) and Sylvain (@Pelissier_S). Thanks for your time and the technical trix on Ghidra during the CTF. Big up guyz!
Thanks to Azox (@8008135_) for help me at … 3H25! Pretty sure that together we would solve it in time, bourricot !
Majority of the times during a penetration test or bug-bounty engagement, you might encounter customers who limit the scope of testing to non-jailbroken devices running the latest mobile OS. How do you dynamically instrument the application in those cases? How do you trace the various functionalities in the application while trying to attack the actual application logic?
Frida (https://www.frida.re/) is a runtime instrumentation toolkit for developers, reverse-engineers, and security researchers that allows you to inject your own script into the blackbox mobile application. Normally Frida is always installed and run on Jailbroken devices. That process is pretty straight-forward. However, the complexity increases when you want to run it on non-jailbroken devices. In this article I’ll explain in detail the steps to be followed to get Frida running on the latest non-jailbroken version of iOS viz iOS 12.1.4.
The only requirement at this stage is an unencrypted IPA file. This is normally provided by the customer. If not, we can download the IPA file from the AppStore and then use tools like Clutch(https://github.com/KJCracks/Clutch) or bfinject(https://github.com/BishopFox/bfinject) to decrypt it. Alternatively unencrypted versions of the IPA files are also available on https://www.iphonecake.com/. Ensure that you do a checksum check and verify it with the custom before you start testing. Don’t be shocked if you find that the IPA files from the website have been modified to include un-intended code. In our case, lets target the Uber application from the AppStore.
The various steps for setting up Frida to run on non-jailbroken iOS device are:
1) Setting up the Signing Identity
2) Setting up Mobile Provision File
3) Performing the Actual Patching
4) Fixing Codesign issues
5) Performing the required Frida-Fu
I will take you through each of these steps one-by-one.
Setting up the Signing Identity
a) Launch Xcode and navigate to the Accounts section using the Preferences menu item. Make sure you are logged in to Xcode using your Apple account.
b) Select “Agent” and Click Manage Certificates.
c) Click + and select “iOS Development”.
d) To verify that the identity is properly set up, you can use the following command:
security find-identity -p codesigning -v
This command will output all the signing identities for your account.
Setting up Mobile Provision File
a) Next step will be to create a new Xcode project with team as agent and target as your actual test device and click play. Run the application on the device. You have to do this step for every new device that you want to use for testing.
b) Right click the generated .app file and select “Show in Finder”.
c) Right click the .app file from the Finder and select “Show Contents”.
d) Save the embedded.mobileprovision file. You will need this later while signing the IPA file.
Performing the Actual Patching
a) Download the latest version of Frida. This can be done using the following command: