Directing Python output into Batch file giving error

73 Views Asked by At

So I have two files: a python file that basically brute forces every combination in the list of characters, and a batch file that is used as a lock to see "is the python file will brute force it". When running in CMD

python "C:\Users\alexe\OneDrive\Documents\test file\brute_forcer.py" | cmd /C "C:\Users\alexe\OneDrive\Documents\test file\lock1.bat"

, it returns the error

Traceback (most recent call last):
  File "C:\Users\alexe\OneDrive\Documents\test file\brute_forcer.py", line 10, in <module>
    print(x)
BrokenPipeError: [Errno 32] Broken pipe
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='cp1252'>
OSError: [Errno 22] Invalid argument

The file brute_forcer:

import itertools
def foo(l):
  for i in range(1, 101):
    yield from itertools.product(*([l] * i)) 


for x in foo('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()[]{},.<>?|;:`~'):
  #print("y")  
  x = ''.join(x)   
  print(x)

and the lock1.bat file:

@echo off
setlocal enabledelayedexpansion

set "correct_password=HEL"

:INPUT
set /p "user_input=Enter the password: "
if "%user_input%"=="%correct_password%" (
    echo Correct password entered. Access granted.
    goto :EOF
) else (
    echo Incorrect password. Try again.
    goto INPUT
)

I tried asking AI to see what it would do but that wasn't helpful at all and didn't solve my problem.

1

There are 1 best solutions below

0
reedaccess_ On

This one is more complicated than simply piping the output of the python script into the batch file, since we need continuous interaction between the two files. Whenever two programs need to run in parallel and interact with each other, we will need multiple threads or processes.

If you try to run something like python3 brute_forcer.py | lock1.bat, I believe it would redirect all the output of the python script to the batch file at once after the python is done. Regardless, the timing won't work.

However what we need is to continuously feed input to, and read output from the batch file during the execution of the python. For this we need the subprocess module.

What we are doing is running the batch file as another process within our python script. We then pipe the stdin and stdout streams of the python and batch files together such that we can read and write between them.

Here is the updated version of your code that will work.

brute_forcer.py (I left the debugging print statements as comments if you want to output everything the python script is doing):

import itertools
from subprocess import Popen, PIPE, STDOUT

def foo(l):
  for i in range(1, 101):
    yield from itertools.product(*([l] * i)) 
    
p = Popen(['l.bat'], stdout=PIPE, stdin=PIPE, stderr=STDOUT, text=True)
result = p.stdout.readline()
# print(result)
print("Brute forcing...")
for x in foo('#ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()[]{},.<>?|;:`~'):
  guess = ''.join(x).strip()
  # print("trying: %s " %(guess))
  p.stdin.write(guess)
  p.stdin.flush()
  result = p.stdout.readline()
  # print(result)
  if ("Correct" in result):
    print("Password found: %s " %(guess))
    break
  if ("Incorrect" in result):
    result = p.stdout.readline()
    # print(result)

I also have changed the batch file to print a newline when prompting for input, otherwise the readline() function in python will not work, and it is a bit more complicated to read arbitrarily long input that doesn't end with a newline.

lock1.bat:

@echo off
setlocal enabledelayedexpansion
set "correct_password=HEL"

:INPUT
echo Enter the password:
set /p user_input=
if "%user_input%"=="%correct_password%" (
    echo Correct password entered. Access granted.
    goto :EOF
) else (
    echo Incorrect password. Try again.
    goto INPUT
)

Also, you don't need to write the full filepath in your original command. Simply cd your way to the test_file directory, and then you can run python3 brute_forcer.py. Note that I am using python3.