/usr/share/fusil/fusil-php is in fusil 1.5-1.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 | #! /usr/bin/python
"""
Generate PHP source code using random functions with random arguments.
Use "php" command line program.
"""
from fusil.application import Application
from fusil.process.create import CreateProcess
from fusil.process.stdout import WatchStdout
from fusil.process.tools import locateProgram
from fusil.process.watch import WatchProcess
from fusil.project_agent import ProjectAgent
from fusil.bytes_generator import (
BytesGenerator, LengthGenerator,
ASCII8, PRINTABLE_ASCII)
from fusil.write_code import WriteCode
from optparse import OptionGroup
from ptrace.six import unichr, PY2
from random import choice, randint
from weakref import ref
import re
DEBUG_PROJECT = True
VARIABLES = 'abcde'
class Fuzzer(Application):
NAME = "php"
def createFuzzerOptions(self, parser):
options = OptionGroup(parser, "Python fuzzer")
options.add_option("--php", help="PHP program path (default: php)",
type="str", default="php")
return options
def setupProject(self):
php_program = locateProgram(self.options.php)
self.error("Use PHP interpreter: %s" % php_program)
project = self.project
php = PhpSource(project)
# Don't kill any process!
php.ignore_functions.add('posix_kill')
# Avoid timeout
php.ignore_functions.add('ftp_connect')
php.ignore_functions.add('mysql_connect')
php.ignore_functions.add('mysql_pconnect')
php.ignore_functions.add('dns_get_mx')
php.ignore_functions.add('getmxrr')
php.ignore_functions.add('dns_check_record')
php.ignore_functions.add('pfsockopen')
php.ignore_functions.add('dns_get_record')
php.ignore_functions.add('gethostbyname')
php.ignore_functions.add('gethostbynamel')
php.ignore_functions.add('ftp_ssl_connect')
process = PhpProcess(project, [php_program, '<source.php>'], timeout=10.0)
watch = WatchProcess(process, exitcode_score=0.10)
if watch.cpu:
watch.cpu.score_weight = 0.3
stdout = WatchPhpStdout(process, php)
stdout.max_nb_line = (10000, 1.0)
del stdout.words['memory']
del stdout.words['exception']
stdout.addRegex('Call to undefined function', -1.0)
if DEBUG_PROJECT:
stdout.words['warning'] = 0.01
stdout.words['error'] = 0.01
stdout.words['fatal'] = 0.10
stdout.words['assert'] = 0.01
stdout.words['assertion'] = 0.01
stdout.ignoreRegex("Only variables can be passed by reference")
stdout.ignoreRegex("^Fatal error: Can't use function return value in ")
stdout.ignoreRegex("^Fatal error: Class .* not found")
stdout.ignoreRegex("^Parse error:")
stdout.ignoreRegex("sem_get.*Permission denied")
else:
stdout.score_weight = 0.3
def escapeCharacter(character):
if PY2:
code = ord(character)
else:
code = character
if code == ord(b'\\'):
# \ => \\
return u'\\\\'
elif code == ord(b"'"):
# ' => \'
return u'\\"'
elif 32 <= code <= 126:
return unichr(code)
else:
return u'\\x%02X' % code
def quoteString(text):
escaped = u''
for code in text:
escaped += escapeCharacter(code)
return u"'%s'" % escaped
class StringGenerator(BytesGenerator):
def __init__(self, min_length, max_length, bytes_set):
BytesGenerator.__init__(self, min_length, max_length, bytes_set)
def _createValue(self, length):
text = BytesGenerator._createValue(self, length)
return quoteString(text)
class WatchPhpStdout(WatchStdout):
def __init__(self, process, php_source):
WatchStdout.__init__(self, process)
self.php_source = ref(php_source)
self.regex = re.compile('Call to undefined function ([a-z0-9_]+)')
def processLine(self, line):
match = self.regex.search(line)
if match:
name = match.group(1)
functions = self.php_source().functions
if name in functions:
functions.remove(name)
self.error("Remove undefined function: %s (new function list length: %s)" % (
name, len(functions)))
else:
WatchStdout.processLine(self, line)
class NullGenerator:
def createValue(self):
return u'null'
class ReferenceGenerator:
def createValue(self):
return u"&$%s" % choice(VARIABLES)
class BufferOverflow(LengthGenerator):
def __init__(self, min, max):
LengthGenerator.__init__(self, min, max)
def _createValue(self, length):
return u'str_repeat("a", %s)' % length
class VariableGenerator:
def createValue(self):
return u"$%s" % choice(VARIABLES)
class PhpSource(ProjectAgent, WriteCode):
def __init__(self, project):
ProjectAgent.__init__(self, project, "php_source")
WriteCode.__init__(self)
self.generators = [
StringGenerator(0, 10, ASCII8),
StringGenerator(1, 40, PRINTABLE_ASCII),
BufferOverflow(4*1024, 64*1024),
NullGenerator(),
ReferenceGenerator(),
VariableGenerator(),
]
self.min_arguments = 0
self.max_arguments = 10
self.min_instr = 1
self.max_instr = 10
self.ignore_functions = set()
self.functions = set(PHP_FUNCTIONS)
def createArgument(self, func_name, arg_index):
while True:
if func_name == 'sleep' and arg_index == 1:
return '0'
generator = choice(self.generators)
value = generator.createValue()
if func_name == 'isset' and (value == 'null' or value.startswith('&')):
continue
return value
def writeFunction(self, name):
if name not in ('print', 'die', 'eval', 'exit', 'isset', 'empty'):
nb_argument = randint(self.min_arguments, self.max_arguments)
else:
nb_argument = 1
self.write(0, u'echo "%s();\\n";' % name)
self.write(0, u'echo "Result: ";')
self.write(0, u'var_dump(')
self.write(1, name + u'(')
for index in range(1, nb_argument+1):
value = self.createArgument(name, index)
text = u'/* %s */ ' % index + value
if index < nb_argument:
text += u','
self.write(2, text)
self.write(1, u')')
self.write(0, u');')
def writeCode(self, filename, functions):
self.createFile(filename)
self.write(0, u'<?php')
self.write(0, u'echo "error_reporting(E_ALL);\\n\\n";')
self.write(0, u'error_reporting(E_ALL);')
self.write(0, u"$a = 42;")
self.write(0, u"$b = Array('hello', 10, 3);")
self.write(0, u"$c = 'Hello World!';")
self.write(0, u"$d = null;")
self.write(0, u"$e = 3.14;")
self.emptyLine()
nb_instr = randint(self.min_instr, self.max_instr)
for index in range(1, nb_instr+1):
function = choice(functions)
self.write(0, u'echo "--- Instruction %s/%s ---\\n";' % (index, nb_instr))
self.writeFunction(function)
self.write(0, u'echo "\\n";')
self.emptyLine()
self.write(0, u'?>')
self.close()
def on_session_start(self):
functions = list(self.functions - self.ignore_functions)
filename = self.session().createFilename('source.php')
self.writeCode(filename, functions)
self.send('php_source', filename)
class PhpProcess(CreateProcess):
def on_php_source(self, filename):
self.cmdline.arguments[1] = filename
self.createProcess()
# From "/usr/share/vim/vim71/syntax/php.vim" (vim 7.1)
# From "Function and Methods ripped from php_manual_de.tar.gz Jan 2003"
#
# Skip many PHP extensions
# Skip get_defined_functions, get_defined_vars, get_defined_constants
PHP_FUNCTIONS = """array_change_key_case array_chunk array_combine
array_count_values array_diff_assoc array_diff_uassoc array_diff array_fill
array_filter array_flip array_intersect_assoc array_intersect array_key_exists
array_keys array_map array_merge_recursive array_merge array_multisort
array_pad array_pop array_push array_rand array_reduce array_reverse
array_search array_shift array_slice array_splice array_sum array_udiff_assoc
array_udiff_uassoc array_udiff array_unique array_unshift array_values
array_walk array arsort asort compact count current each end extract in_array
key krsort ksort list natcasesort natsort next pos prev range reset rsort
shuffle sizeof sort uasort uksort usort bcadd bccomp bcdiv bcmod bcmul bcpow
bcpowmod bcscale bcsqrt bcsub bzclose bzcompress bzdecompress bzerrno bzerror
bzerrstr bzflush bzopen bzread bzwrite cal_days_in_month cal_from_jd cal_info
cal_to_jd easter_date easter_days exit frenchtojd gregoriantojd jddayofweek
jdmonthname jdtofrench jdtogregorian jdtojewish jdtojulian jdtounix jewishtojd
juliantojd unixtojd call_user_method_array call_user_method class_exists
get_class_methods get_class_vars get_class get_declared_classes
get_object_vars get_parent_class is_a is_subclass_of method_exists ctype_alnum
ctype_alpha ctype_cntrl ctype_digit ctype_graph ctype_lower ctype_print
ctype_punct ctype_space ctype_upper ctype_xdigit checkdate date getdate
gettimeofday gmdate gmmktime gmstrftime localtime microtime mktime strftime
strtotime time dba_close dba_delete dba_exists dba_fetch dba_firstkey
dba_handlers dba_insert dba_key_split dba_list dba_nextkey dba_open
dba_optimize dba_popen dba_replace dba_sync chdir chroot dir closedir getcwd
opendir readdir rewinddir scandir debug_backtrace debug_print_backtrace
error_log error_reporting restore_error_handler set_error_handler
trigger_error user_error escapeshellarg escapeshellcmd exec passthru
proc_close proc_get_status proc_nice proc_open proc_terminate shell_exec
system basename chgrp chmod chown clearstatcache copy dirname disk_free_space
disk_total_space diskfreespace fclose feof fflush fgetc fgetcsv fgets fgetss
file_exists file_get_contents file_put_contents file fileatime filectime
filegroup fileinode filemtime fileowner fileperms filesize filetype flock
fnmatch fopen fpassthru fputs fread fscanf fseek fstat ftell ftruncate fwrite
glob is_dir is_executable is_file is_link is_readable is_uploaded_file
is_writable is_writeable link linkinfo lstat mkdir move_uploaded_file
parse_ini_file pathinfo pclose popen readfile readlink realpath rename rewind
rmdir set_file_buffer stat symlink tempnam tmpfile touch umask unlink
ftp_alloc ftp_cdup ftp_chdir ftp_chmod ftp_close ftp_connect ftp_delete
ftp_exec ftp_fget ftp_fput ftp_get_option ftp_get ftp_login ftp_mdtm ftp_mkdir
ftp_nb_continue ftp_nb_fget ftp_nb_fput ftp_nb_get ftp_nb_put ftp_nlist
ftp_pasv ftp_put ftp_pwd ftp_quit ftp_raw ftp_rawlist ftp_rename ftp_rmdir
ftp_set_option ftp_site ftp_size ftp_ssl_connect ftp_systype
call_user_func_array call_user_func create_function func_get_arg func_get_args
func_num_args function_exists register_shutdown_function
register_tick_function unregister_tick_function bind_textdomain_codeset
bindtextdomain dcgettext dcngettext dgettext dngettext gettext ngettext
textdomain header headers_list headers_sent setcookie iconv_get_encoding
iconv_mime_decode_headers iconv_mime_decode iconv_mime_encode
iconv_set_encoding iconv_strlen iconv_strpos iconv_strrpos iconv_substr iconv
ob_iconv_handler assert_options assert dl extension_loaded get_cfg_var
get_current_user get_extension_funcs get_include_path
get_included_files get_loaded_extensions get_magic_quotes_gpc
get_magic_quotes_runtime get_required_files getenv getlastmod getmygid
getmyinode getmypid getmyuid getopt getrusage ini_alter ini_get_all ini_get
ini_restore ini_set memory_get_usage php_ini_scanned_files php_logo_guid
php_sapi_name php_uname phpinfo phpversion putenv
restore_include_path set_include_path set_magic_quotes_runtime set_time_limit
version_compare zend_logo_guid zend_version ezmlm_hash mail abs acos acosh
asin asinh atan2 atan atanh base_convert bindec ceil cos cosh decbin dechex
decoct deg2rad exp expm1 floor fmod getrandmax hexdec hypot is_finite
is_infinite is_nan lcg_value log10 log1p log max min mt_getrandmax mt_rand
mt_srand octdec pi pow rad2deg rand round sin sinh sqrt srand tan tanh
mb_convert_case mb_convert_encoding mb_convert_kana mb_convert_variables
mb_decode_mimeheader mb_decode_numericentity mb_detect_encoding
mb_detect_order mb_encode_mimeheader mb_encode_numericentity mb_ereg_match
mb_ereg_replace mb_ereg_search_getpos mb_ereg_search_getregs
mb_ereg_search_init mb_ereg_search_pos mb_ereg_search_regs
mb_ereg_search_setpos mb_ereg_search mb_ereg mb_eregi_replace mb_eregi
mb_get_info mb_http_input mb_http_output mb_internal_encoding mb_language
mb_output_handler mb_parse_str mb_preferred_mime_name mb_regex_encoding
mb_regex_set_options mb_send_mail mb_split mb_strcut mb_strimwidth mb_strlen
mb_strpos mb_strrpos mb_strtolower mb_strtoupper mb_strwidth
mb_substitute_character mb_substr_count mb_substr mime_content_type
mysql_affected_rows mysql_client_encoding mysql_close mysql_connect
mysql_data_seek mysql_db_name mysql_db_query mysql_errno
mysql_error mysql_escape_string mysql_fetch_array mysql_fetch_assoc
mysql_fetch_field mysql_fetch_lengths mysql_fetch_object mysql_fetch_row
mysql_field_flags mysql_field_len mysql_field_name mysql_field_seek
mysql_field_table mysql_field_type mysql_free_result mysql_get_client_info
mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info
mysql_insert_id mysql_list_dbs mysql_list_fields mysql_list_processes
mysql_list_tables mysql_num_fields mysql_num_rows mysql_pconnect mysql_ping
mysql_query mysql_real_escape_string mysql_result mysql_select_db mysql_stat
mysql_tablename mysql_thread_id mysql_unbuffered_query connection_aborted
connection_status constant define defined die eval get_browser
highlight_file highlight_string ignore_user_abort pack show_source sleep
uniqid unpack usleep checkdnsrr closelog define_syslog_variables
dns_check_record dns_get_mx dns_get_record fsockopen gethostbyaddr
gethostbyname gethostbynamel getmxrr getprotobyname getprotobynumber
getservbyname getservbyport ip2long long2ip openlog pfsockopen
socket_get_status socket_set_blocking socket_set_timeout syslog flush ob_clean
ob_end_clean ob_end_flush ob_flush ob_get_clean ob_get_contents ob_get_flush
ob_get_length ob_get_level ob_get_status ob_gzhandler ob_implicit_flush
ob_list_handlers ob_start output_add_rewrite_var output_reset_rewrite_vars
pcntl_exec pcntl_fork pcntl_signal pcntl_waitpid pcntl_wexitstatus
pcntl_wifexited pcntl_wifsignaled pcntl_wifstopped pcntl_wstopsig
pcntl_wtermsig preg_grep preg_match_all preg_match preg_quote
preg_replace_callback preg_replace preg_split posix_ctermid
posix_get_last_error posix_getcwd posix_getegid posix_geteuid posix_getgid
posix_getgrgid posix_getgrnam posix_getgroups posix_getlogin posix_getpgid
posix_getpgrp posix_getpid posix_getppid posix_getpwnam posix_getpwuid
posix_getrlimit posix_getsid posix_getuid posix_isatty posix_kill posix_mkfifo
posix_setegid posix_seteuid posix_setgid posix_setpgid posix_setsid
posix_setuid posix_strerror posix_times posix_ttyname posix_uname ereg_replace
ereg eregi_replace eregi split spliti sql_regcase ftok msg_get_queue
msg_receive msg_remove_queue msg_send msg_set_queue msg_stat_queue sem_acquire
sem_get sem_release sem_remove shm_attach shm_detach shm_get_var shm_put_var
shm_remove_var shm_remove session_cache_expire session_cache_limiter
session_decode session_destroy session_encode session_get_cookie_params
session_id session_is_registered session_module_name session_name
session_regenerate_id session_register session_save_path
session_set_cookie_params session_set_save_handler session_start
session_unregister session_unset session_write_close shmop_close shmop_delete
shmop_open shmop_read shmop_size shmop_write socket_accept socket_bind
socket_clear_error socket_close socket_connect socket_create_listen
socket_create_pair socket_create socket_get_option socket_getpeername
socket_getsockname socket_last_error socket_listen socket_read socket_recv
socket_recvfrom socket_select socket_send socket_sendto socket_set_block
socket_set_nonblock socket_set_option socket_shutdown socket_strerror
socket_write stream_context_create stream_context_get_options
stream_context_set_option stream_context_set_params stream_copy_to_stream
stream_filter_append stream_filter_prepend stream_filter_register
stream_get_contents stream_get_filters stream_get_line stream_get_meta_data
stream_get_transports stream_get_wrappers stream_register_wrapper
stream_select stream_set_blocking stream_set_timeout stream_set_write_buffer
stream_socket_accept stream_socket_client stream_socket_get_name
stream_socket_recvfrom stream_socket_sendto stream_socket_server
stream_wrapper_register addcslashes addslashes bin2hex chop chr chunk_split
convert_cyr_string count_chars crc32 crypt explode fprintf
get_html_translation_table hebrev hebrevc html_entity_decode htmlentities
htmlspecialchars implode join levenshtein localeconv ltrim md5_file md5
metaphone money_format nl_langinfo nl2br number_format ord parse_str print
printf quoted_printable_decode quotemeta rtrim setlocale sha1_file sha1
similar_text soundex sprintf sscanf str_ireplace str_pad str_repeat
str_replace str_rot13 str_shuffle str_split str_word_count strcasecmp strchr
strcmp strcoll strcspn strip_tags stripcslashes stripos stripslashes stristr
strlen strnatcasecmp strnatcmp strncasecmp strncmp strpos strrchr strrev
strripos strrpos strspn strstr strtok strtolower strtoupper strtr
substr_compare substr_count substr_replace substr trim ucfirst ucwords vprintf
vsprintf wordwrap token_get_all token_name base64_decode base64_encode
get_meta_tags http_build_query parse_url rawurldecode rawurlencode urldecode
urlencode doubleval empty floatval get_resource_type gettype
import_request_variables intval is_array is_bool is_callable is_double
is_float is_int is_integer is_long is_null is_numeric is_object is_real
is_resource is_scalar is_string isset print_r serialize settype strval
unserialize unset var_dump var_export wddx_add_vars wddx_deserialize
wddx_packet_end wddx_packet_start wddx_serialize_value wddx_serialize_vars
utf8_decode utf8_encode xml_error_string xml_get_current_byte_index
xml_get_current_column_number xml_get_current_line_number xml_get_error_code
xml_parse_into_struct xml_parse xml_parser_create_ns xml_parser_create
xml_parser_free xml_parser_get_option xml_parser_set_option
xml_set_character_data_handler xml_set_default_handler xml_set_element_handler
xml_set_end_namespace_decl_handler xml_set_external_entity_ref_handler
xml_set_notation_decl_handler xml_set_object
xml_set_processing_instruction_handler xml_set_start_namespace_decl_handler
xml_set_unparsed_entity_decl_handler xmlrpc_decode_request xmlrpc_decode
xmlrpc_encode_request xmlrpc_encode xmlrpc_get_type
xmlrpc_parse_method_descriptions xmlrpc_server_add_introspection_data
xmlrpc_server_call_method xmlrpc_server_create xmlrpc_server_destroy
xmlrpc_server_register_introspection_callback xmlrpc_server_register_method
xmlrpc_set_type zip_close zip_entry_close zip_entry_compressedsize
zip_entry_compressionmethod zip_entry_filesize zip_entry_name zip_entry_open
zip_entry_read zip_open zip_read gzclose gzcompress gzdeflate gzencode gzeof
gzfile gzgetc gzgets gzgetss gzinflate gzopen gzpassthru gzputs gzread
gzrewind gzseek gztell gzuncompress gzwrite readgzfile
zlib_get_coding_type""".split()
if __name__ == "__main__":
Fuzzer().main()
|