for pos inrange(1, 33): lo, hi = 0, 15 while lo < hi: mid = (lo + hi) // 2 # inject: MID(password,N,1) > HEX[mid] if response_true: lo = mid + 1 else: hi = mid result += alphabet[lo]
Two-factor authentication bypass. A German ordering application
("Gurroga") has login + auth token (2FA). Need to order a "special
article" without valid credentials.
A friend and me have a bet running, that you won't beat his OCR
program in scanning text out of images. His average scan time is 2.5
seconds, can you beat that?
One reason why I wanted the warchall box is to offer more realistic
webhacking challenges. You may now try the Live RFI challenge hosted on
it. Note: There is a harsh firewall that only allows connections to
wechall, warchall and the logserver.
The public WeChall page only gives the description and answer form;
the vulnerable web app itself is hosted on Warchall at
http://rfi.warchall.net/.
Recon
The vulnerable page at http://rfi.warchall.net/ has a
lang parameter in the URL (index.php?lang=en,
index.php?lang=de). Source disclosure via
php://filter confirms the vulnerability:
This reveals DB credentials (RFI/RFI),
domain (rfi.warchall.net), and salt
(schnickschmugg).
Key observations: - require $iso includes whatever the
user passes as lang — classic RFI/LFI. -
open_basedir is set to getcwd() (the www
directory) before the include, then reset to / after. - The
included file must return an array with welcome and
construction keys, because the code indexes into
$lang['welcome'] and $lang['construction']. A
payload that only prints output will cause a type error. -
php://filter works for source disclosure (reading files
within open_basedir). - The data:// wrapper is
not blocked by open_basedir —
allow_url_include is enabled.
Exploit
Since data:// wrappers work and
allow_url_include is On, we can execute arbitrary PHP
without needing an external server (bypassing the firewall restriction
entirely).
The payload needs to: 1. Execute a command (e.g.,
system()) 2. Capture the output via
ob_start()/ob_get_clean() — raw
system() output goes to stdout and won't appear in the
$lang['welcome'] slot 3. Return an array with
welcome and construction keys
The challenge name "Right-FI" is a play on "RFI" (Remote File
Inclusion) and "Residual-current device" (the page subtitle).
open_basedir restricts filesystem path
resolution to the current directory, but does not block
PHP stream wrappers (data://, php://filter)
when allow_url_include is enabled. This is a well-known PHP
misconfiguration pitfall — open_basedir and
allow_url_include are orthogonal controls.
php://input may or may not work depending on PHP
version and open_basedir interaction; data://
is more reliable.
The firewall restriction (only wechall/warchall/logserver) is
irrelevant when using data:// — no outbound connection is
needed.
The en and de language files in the web
directory are simple PHP files returning arrays with
welcome and construction keys, which is why
the exploit payload must also return the same array structure.
A simpler payload like
data://text/plain,<?php print file_get_contents("solution.php"); ?>
does NOT work because the code does $lang = require $iso
and then accesses $lang['welcome'] — a string return is not
an array.
I have created an advanced version of the simple substitution cipher.
It can now use chars in range from 0-255, but that should not stop you.
The ciphertext is in the language of this text, and uses correct
punctuation and case-sensitivity.
Substitution I 的进阶版。每次页面会生成一套新的 0-255
字节替换表,密文是十六进制字节序列,明文语言仍然是英文。
Solution
这题不能复用旧答案:同一个挑战在不同 session 下会给不同密文和不同的
solution 值。但明文模板是固定的,所以可以用 known plaintext
方法解码。
Congratulations! This one was harder, but you got it! Very well done fellow hacker! The problem with this cipher is that the key is pretty long! I will come up with a better encryption sheme any soon! Your solution is: <session-answer>!
注意原文里故意写成了 sheme,不是
scheme。
解码脚本核心逻辑:
1 2 3 4
cipher = [int(x, 16) for x in re.findall(r'\b[0-9A-F]{2}\b', hex_blob)] template = 'Congratulations! This one was harder, but you got it! Very well done fellow hacker! The problem with this cipher is that the key is pretty long! I will come up with a better encryption sheme any soon! Your solution is: ' mapping = {byte: char for byte, char inzip(cipher, template)} plaintext = ''.join(mapping.get(byte, '?') for byte in cipher)
Your mission is to login as Admin. The application is vulnerable to
sql injection, but the signup process seems a bit "weird". 目标是以
admin 身份登录。用户名字段存在 SQL 注入漏洞。