|
1 | 1 | #!/usr/bin/env python2
|
2 | 2 | """
|
| 3 | +Pwntools exposes several magic command-line arguments and environment |
| 4 | +variables when operating in `from pwn import *` mode. |
| 5 | +
|
| 6 | +The arguments extracted from the command-line and removed from ``sys.argv``. |
| 7 | +
|
| 8 | +Arguments can be set by appending them to the command-line, or setting |
| 9 | +them in the environment prefixed by ``PWNLIB_``. |
| 10 | +
|
| 11 | +The easiest example is to enable more verbose debugging. Just set ``DEBUG``. |
| 12 | +
|
| 13 | +.. code-block:: bash |
| 14 | +
|
| 15 | + $ PWNLIB_DEBUG=1 python exploit.py |
| 16 | + $ python exploit.py DEBUG |
| 17 | +
|
| 18 | +These arguments are automatically extracted, regardless of their name, and |
| 19 | +exposed via ``pwnlib.args.args``, which is exposed as the global variable |
| 20 | +``args``. Arguments which ``pwntools`` reserves internally are not exposed |
| 21 | +this way. |
| 22 | +
|
| 23 | +.. code-block:: bash |
| 24 | +
|
| 25 | + $ python -c 'from pwn import *; print args' A=1 B=Hello HOST=1.2.3.4 DEBUG |
| 26 | + defaultdict(<type 'str'>, {'A': '1', 'HOST': '1.2.3.4', 'B': 'Hello'}) |
| 27 | +
|
| 28 | +This is very useful for conditional code, for example determining whether to |
| 29 | +run an exploit locally or to connect to a remote server. Arguments which are |
| 30 | +not specified evaluate to an empty string. |
| 31 | +
|
| 32 | +.. code-block:: python |
| 33 | +
|
| 34 | + if args['REMOTE']: |
| 35 | + io = remote('exploitme.com', 4141) |
| 36 | + else: |
| 37 | + io = process('./pwnable') |
| 38 | +
|
| 39 | +The full list of supported "magic arguments" and their effects are listed |
| 40 | +below. |
3 | 41 | """
|
4 | 42 | import collections
|
5 | 43 | import logging
|
@@ -42,46 +80,67 @@ def asbool(s):
|
42 | 80 | else:
|
43 | 81 | raise ValueError('must be integer or boolean: %r' % s)
|
44 | 82 |
|
45 |
| -def set_log_level(x): |
| 83 | +def LOG_LEVEL(x): |
| 84 | + """Sets the logging verbosity used via ``context.log_level``, |
| 85 | + e.g. ``LOG_LEVEL=debug``. |
| 86 | + """ |
46 | 87 | with context.local(log_level=x):
|
47 | 88 | context.defaults['log_level']=context.log_level
|
48 | 89 |
|
49 |
| -def set_log_file(x): |
| 90 | +def LOG_FILE(x): |
| 91 | + """Sets a log file to be used via ``context.log_file``, e.g. |
| 92 | + ``LOG_FILE=./log.txt``""" |
50 | 93 | context.log_file=x
|
51 | 94 |
|
52 |
| -def set_log_level_error(x): |
53 |
| - set_log_level('error') |
| 95 | +def SILENT(x): |
| 96 | + """Sets the logging verbosity to ``error`` which silences most |
| 97 | + output.""" |
| 98 | + LOG_FILE('error') |
54 | 99 |
|
55 |
| -def set_log_level_debug(x): |
56 |
| - set_log_level('debug') |
| 100 | +def DEBUG(x): |
| 101 | + """Sets the logging verbosity to ``debug`` which displays much |
| 102 | + more information, including logging each byte sent by tubes.""" |
| 103 | + LOG_FILE('debug') |
57 | 104 |
|
58 |
| -def set_noterm(v): |
| 105 | +def NOTERM(v): |
| 106 | + """Disables pretty terminal settings and animations.""" |
59 | 107 | if asbool(v):
|
60 | 108 | global term_mode
|
61 | 109 | term_mode = False
|
62 | 110 |
|
63 |
| -def set_timeout(v): |
| 111 | +def TIMEOUT(v): |
| 112 | + """Sets a timeout for tube operations (in seconds) via |
| 113 | + ``context.timeout``, e.g. ``TIMEOUT=30``""" |
64 | 114 | context.defaults['timeout'] = int(v)
|
65 | 115 |
|
66 |
| -def set_randomize(v): |
| 116 | +def RANDOMIZE(v): |
| 117 | + """Enables randomization of various pieces via ``context.randomize``""" |
67 | 118 | context.defaults['randomize'] = asbool(v)
|
68 | 119 |
|
69 |
| -def set_aslr(v): |
| 120 | +def NOASLR(v): |
| 121 | + """Disables ASLR via ``context.aslr``""" |
70 | 122 | context.defaults['aslr'] = not asbool(v)
|
71 | 123 |
|
72 |
| -def set_noptrace(v): |
| 124 | +def NOPTRACE(v): |
| 125 | + """Disables facilities which require ``ptrace`` such as ``gdb.attach()`` |
| 126 | + statements, via ``context.noptrace``.""" |
73 | 127 | context.defaults['noptrace'] = asbool(v)
|
74 | 128 |
|
| 129 | +def STDERR(v): |
| 130 | + """Sends logging to ``stderr`` by default, instead of ``stdout``""" |
| 131 | + context.log_console = sys.stderr |
| 132 | + |
75 | 133 | hooks = {
|
76 |
| - 'LOG_LEVEL': set_log_level, |
77 |
| - 'LOG_FILE': set_log_file, |
78 |
| - 'DEBUG': set_log_level_debug, |
79 |
| - 'NOTERM': set_noterm, |
80 |
| - 'SILENT': set_log_level_error, |
81 |
| - 'RANDOMIZE': set_randomize, |
82 |
| - 'TIMEOUT': set_timeout, |
83 |
| - 'NOASLR': set_aslr, |
84 |
| - 'NOPTRACE': set_noptrace, |
| 134 | + 'LOG_LEVEL': LOG_LEVEL, |
| 135 | + 'LOG_FILE': LOG_FILE, |
| 136 | + 'DEBUG': DEBUG, |
| 137 | + 'NOTERM': NOTERM, |
| 138 | + 'SILENT': SILENT, |
| 139 | + 'RANDOMIZE': RANDOMIZE, |
| 140 | + 'TIMEOUT': TIMEOUT, |
| 141 | + 'NOASLR': NOASLR, |
| 142 | + 'NOPTRACE': NOPTRACE, |
| 143 | + 'STDERR': STDERR, |
85 | 144 | }
|
86 | 145 |
|
87 | 146 | def initialize():
|
|
0 commit comments