0

So I just recently started having interest and playing CTF's on OverTheWire website and I am still in the first challenge called the bandit Lvl5 if you'll consider looking at it. So it teaches the use of linux command line etc

So here on this challenge I am tasked that there are hidden files in home directory I have to find them and in one of those files I will find a password to go to the next level taking note the are over 20 hidden files that come up.

So I then thought no man yes I can go through this manually but it will take forever so I tried making a script that I thought would work to get the hidden files and open one by one. But it does not work as I wanted.

I wanted to append those hidden files into a list and then run a for loop that will open each one of them and then I will be able to see results and spot password

Code Below

import os

a = []
for i in os.system('find .inhere/'):
    a.append(i)
for j in a:
    print("\n\n cat j ")

So it my first time messing code of such manner trying to interact with the command line using python can you please help on how I can go about it or if my code can be fixed

3
  • 2
    os.system() doesn't return the output of the command. Use subprocess.Popen() for this. And you need to split the output into lines, it's not done automatically for you. Commented Jun 19, 2020 at 22:06
  • 1
    Did you read the documentation? os.system() returns the exit status of the command. Commented Jun 19, 2020 at 22:06
  • 1
    Honestly never did read documentation on it came across this challenge few minutes back and os.system() came to mind, so I guess my mistake also could have be there on not reading the documentation Commented Jun 19, 2020 at 22:19

1 Answer 1

-1

os.system() only returns the exit status of the command (Not the STDOUT). You should use the subprocess module especially the subprocess.Popen. I have added several comments for my code for the better understanding.

Code:

import subprocess
import sys


def call_command(command):
    """
    Call a command the STDOUT
    :param command: The related command
    :return: STDOUT as string
    """

    result1 = subprocess.Popen(
        command.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True
    )

    #  Get the STDOUT and STDERR descriptors of the command.
    std_out, std_err = result1.communicate()

    return std_out


# Find files in test1 folder.
find_result = call_command("find test1/ -type f")
for one_find in find_result.split("\n"):
    if one_find:
        # The result of cat command will be in "cat_result" variable.
        cat_result = call_command("cat {}".format(one_find))
        print(cat_result)

        # You can write the result directly to STDOUT with the following line.
        # sys.stdout.write("\n".join(call_command("cat {}".format(one_find))))

Content of test1 folder:

>>> ll test1/
total 8
drwxrwxr-x  2 user grp 4096 Jul  8 14:18 ./
drwxrwxr-x 18 user grp 4096 Jul  8 14:33 ../
-rw-rw-r--  1 user grp 29 Jul  8 14:18 test_file.txt

Content of test_file.txt:

>>> cat test1/test_file.txt 
Contents of test_file.txt file

Output of the code:

>>> python3 test.py
Contents of test_file.txt file.
Sign up to request clarification or add additional context in comments.

2 Comments

Actually you should prefer subprocess.run() over Popen if you can; this is clearly spelled out in the documentation. It basically saves you from having to reinvent call_command (which of course also duplicates the legacy check_output without the check_ part which you should probably add anyway).
command.split() is also buggy; you should use shlex.split(command) instead, or simply pass in a list of strings. Perhaps see also Actual meaning of shell=True in subprocess