發表文章

目前顯示的是有「CPlus」標籤的文章

[C++] 優雅玩耍函數指標呼叫,把你同事玩弄得嫑嫑的。(離職前記得回顧這篇文)

圖片
前言 最近正好寫一些玩具想模組化,以前在處理 Function Pointer 都是強轉型 + typedef 然後 ^C^V 瘋狂複製貼上函數型別來做到 C/C++ 內對指標函數呼叫。最近正好摸到一些 C++11 有支援到的正規轉型別方式,發現乾...XD 不用在手殘複製貼上啦,原來 C++11 一堆關鍵字已經可以讓你快速定義型別 + 把函數模組化放到自己的樣板內了超ㄎㄧㄤ btw 這篇只是筆記文,最一開始我只是想查 C/C++ 內到底能不能編譯時期就取得函數的型別XDDDD (結果是:幹,居然真的可以咧XDDDDD) #murmur 如果看完這篇文還是不懂怎麼做,那就算惹,我也沒很認真想解釋細節,不要太認真XD(只是覺得分頁欄有點滿,寫到部落格來不要佔 Chrome 的分頁,反正我看了哪些參考文獻都附在底下了) 另外,這篇都在講 Windows 上的做法,不過理論上把 LoadLibrary 跟 GetProcAddress 替換為對應 macOS/Linux 的函數應該都可以 work(N 年前好像有玩一下 macOS 上是可以跑的) 考.考.考.考考古學家  可以先參考這篇  [C++] How to GetProcAddress() like a boss   裡面純 C 寫法的強轉型函數指標做法,這相信常玩函數指標的人都有用過這樣玩法: 原理就只是: 宣告一個新的函數型別 ShellAboutProc,型別、呼叫約制跟你想呼叫的系統函數必須一致(對啦,不然等等堆疊爛掉你就知道惹) 接著透過 LoadLibrary() 載入系統函數模組取得模組地址、透過 GetProcAddress() 取得該函數位於該函數庫上真正地址 以 ShellAboutProc 函數型別宣告一個變數 shellAbout 最後將該函數地址強轉型為我們定義好的 ShellAboutProc 型別覆寫入 shellAbout 變數內,大功告成 la,shellAbout 變數就可以被當原生函數呼叫了 這做法超簡單、也實用,不過看也知道一堆地方可以省略XD,比方說根本不需要額外開一個變數來暫存函數指標,可以直接用內聯函數型態的方式、取代宣告函數型別與變數(離題惹)

HITCON ENT 惡意軟體新型API呼叫行為實作(Patten式GetProcAddress找碴呼叫API)

圖片
動機 這次HITCON Enterprise正好坐在R0場有幸聽到PK大神講的議程XD。不過本來想聽這場是想知道實際Google Drive C2 API呼叫過程的Olly分析,不過似乎整場議程重點不放在那Otz... 但正好聽到一件有趣的事情,議程內提到新型惡意軟體呼叫不再像以前是用GetProcAddress,而是自幹了一個叫做GetProcAddressEx呼叫方式會像是: GetProcAddressEx( ModuleBase, "0=L;3=d;4=L;11=A"); //找尋一個API根據函數名,第0個為L、第3個為d、第4個為L、第11個為A 這手法聽起來像是在逃避正常靜態分析軟體(如IDA Pro)可以很容易根據Import Address Table得知呼叫過程或者透過對GetProcessAddress下斷點動態反查API過程,所以我想這個GetProcAddressEx內部應該: 不該使用到任何API來增加分析難度 暴力分析DLL模組結構體找碴外導函數 暴力列舉API過程中根據Pattern(也就是0=L;3=d...)找到第一筆合適的API名 根據這個原則,於是我開始實做惹XD Visual C++實作 關於這種奇怪的要求,想到之前有研究過類似的發文 [Windows][PE][ASM]純組語手幹Dll Header解析外導函數表撈出函數地址(如LoadLibraryA動態地址) 索性我就拿這個的部分Code來改成VC++函數版本了XD 首先Pattern檢測部份,我寫了一支簡單的函數 int StrVal(std::string Data) { return std::stoi(Data); } bool ChkPatten(char* Str, char* Patten) { bool retn = true; std::string n = ""; for (int i = 0; Patten[i]; i++) { if (*(char*)(Patten + i) == '=') { int LPos = StrVal(n); char RChar = *(char*)(Patten + i + 1);...

HITCONxTDOH 闖關活動逆向題目Source開源啦

圖片
當初會寫這個有趣的題目裡面是正好想提到IDA Pro的一些小小手花技巧,正好可以接上 HITCON CMT 2015 手花詐欺IDA Pro的一些小手段 (IDA ProHex-Rays DecompilerSimple Tricks) 的議程XD Source Code連結:https://github.com/aaaddress1/HITCONxTDoH-2015-Crypto-Game

淺談Windows上Buffer Overflow中SEH異常處理機制攻擊手法&Shellcode插入手法

圖片
此篇內容接續著前幾篇Blog文: 從PE架構淺談純組語撈出當前進程的映像路徑  從PE架構到模組架構到暴力列舉模組找模組位置(如Kernel32.dll)  純組語手幹Dll Header解析外導函數表撈出函數地址(如LoadLibraryA動態地址)  你知道聽歌也會中毒嗎?初探BOF攻擊、KMPlayer MP3漏洞利用 參考文獻 緩衝區溢位攻擊:第四章 - 真槍實彈  緩衝區溢位攻擊:第五章 - 攻擊的變化 最近時間很緊湊啊...還是慢慢看這本電子書內容,挑出一點細節還有大概的精華整理成自己的筆記了XD,因為這部分技術很繁瑣又很多細項,所以筆記都是整理給自己看怕自己老人癡呆忘記用的(?),如果是大牛們請飄過吧(´・_・`) *PS:此篇文章實做測試於Windows XP SP3版本上,若使用Vista或者更高版本將可能遇到DEP防護導致Shellcode屬性不可被執行而無法成功攻擊唷XD 首先,SEH是什麼? SEH全名為Structured Exception Handling,在MSDN上可以查到微軟官方提供的資訊在此: Structured Exception Handling (Windows) - MSDN - Microsoft ,當你正在使用的程式遇到異外情形是不合乎邏輯或者違法處置的時候,程式無法自己處理,一般來說會先給try處理(而try的註冊資訊也會註冊於SEH鏈結內)當try內也無法處理掉時會交由Debugger處理,若Debugger也無法處理時(或者當下沒有被Debugger Attach時),最後就會把處理權交由系統來做處理(如下圖所示) 系統就會根據當下環境整理出記憶體傾印資訊,然後問你要不要回傳給開發者,或者要選擇手動處理這個問題(不過我沒用過上面任何一個功能就是了XD) 那麼SEH在Windows上是怎麼運作的呢? 可以之前我寫的本系列文章的第一篇 從PE架構淺談純組語撈出當前進程的映像路徑  ,當初在介紹每個線程中都有個TEB結構體(Thread Environment Block),而線程會根據被分配的ASM Script一直做一個個Opcode解析並且執行的動作。 但如果哪天解析Opcod...

你知道聽歌也會中毒嗎?初探BOF攻擊、KMPlayer MP3漏洞利用(附贈ADR的歌聲、Source Code)

圖片
此篇內容接續著前幾篇Blog文: 從PE架構淺談純組語撈出當前進程的映像路徑  從PE架構到模組架構到暴力列舉模組找模組位置(如Kernel32.dll)  純組語手幹Dll Header解析外導函數表撈出函數地址(如LoadLibraryA動態地址) 參考文獻 緩衝區溢位攻擊:第四章 - 真槍實彈  我知道這個標題有點聳動,其實沒到那麼可怕啦XD 呼...我終於看到第四章節了T^T,一樣是雷雷的筆記文章,另外,這篇文章特別感謝Orange大神在我找不到BUG在哪的時候伸出援手替我解圍啊啊啊啊啊 這邊要寫的筆記是 緩衝區溢位攻擊:第四章 - 真槍實彈 文中提及的KMPlayer 1440版中關於MP3的漏洞,在KMPlayer 1440版中針對MP3音樂檔案文件做解析時會有存在Buffer Overflow(BOF)的問題,以下紀錄我自己在探究這個漏洞利用、練習時的逐步思路跟概念,到最後寫出一個可以利用漏洞來引發攻擊者想做的惡意事情,卻是透過MP3音樂文件做觸發。 如果正在看文章的你還沒有下載KMPlayer 1440有漏洞的版本,可以在這裡下載: KMPlayer 3.0.0.1440 萬能影音播放器 綠色免安裝 中文版&110套面板 (我是下載免安裝版,我也是在這裡下載的XD) 首先,得知MP3文件在解析時會有存在BOF問題,可以先用mona引擎替我們生產一組Pattern來做測試,看看實際在哪個點引發出錯進而分析如何做攻擊,開啟Immunity Debugger下命令:!mona pattern_create 10000 它會替我們生產一個10000個字長度的Pattern,另外, 特別記得在VISTA、WIN7除錯器記得要以工作管理員運行...XD,剛剛被雷過  接著可以在Immunity Debugger底下發現一個Pattern.txt文件:  接著可以看到mona替我們生產出一組Pattern長度為10000長度的文字,將ASCII段內的文字複製起來,另外以記事本開新檔案將ASCII段內的所有文字複製後保存進去新的文字檔,命名為adr.mp3  接著如果你把adr.mp3丟給KMPlayer.exe執行,會發現狀況如下: ...

[C++Builder]解決Firemonkey跨平台專案無法實機發佈軟體到iPhone設備上DEBUG

圖片
原先一開始我的專案需求 只專門測試了軟體可以跑在Android、Windows、OSX上面 所以PAServer什麼的都已經弄好了 因為ADR很窮...只有Android手機,後來跟朋友借到一隻iPhone5(有JB),發現選到iOS Device並且Macbook Pro已經正確跟iPhone連線上,PAServer也正確啟動服務可以遠端聯繫了,卻出現: 這問題很雷,特雷 因為這個問題去查Google有九成以上的台灣Blog介紹C++ Builder開發iOS App是沒有介紹這個問題該怎麼解決的...(應該直接了當的說台灣沒幾隻貓在寫C++ Builder開發的iOS App部落格的感覺...) 仔細看了一下編譯噴錯的原因: iphone developer no identity found(blablabla以下省略超多字)大略意思是在遠端調試的時候,一個叫做iPhoneDeveloper的程式無法正確被傳遞參數並且把App傳入iOS設備導致的 翻了一下PAServer目錄底下: 其實App還有簽章之類的內容PAServer早就幫你弄好了...只是app沒辦法放進去 這時候有兩種做法: 1.有JB狀況下 可選擇再新增一個"payload"的資料夾並且把.app放進去裡面,最後把payload資料夾與另外兩個檔案用壓縮的方式壓縮成一個解壓縮包,並且把副檔名改為.ipa 2.修正iPhonedeveloper無法被喚起的問題 後來爬了大概快四十幾篇文,後來在對岸論壇爬到問題應該出在權限不足沒有簽章權限問題,解決方法如下 首先開啟你的Laucher找到系統程式的“鑰匙圈存取” 在鑰匙圈存取》憑證輔助程式 找到“製作憑證”開啟它 接著名稱寫:iPhone Developer,身份類型:自簽根,憑證類型:代碼簽名 然後其他就預設值,一路按繼續繼續繼續繼續繼續繼續繼續繼續繼續繼續繼續 最後看到完成,再回你的C++ Builder做一次編譯就可以解決這個問題了 (參考: 盒子論壇 )

[ASM][IDA][C++]爆破也能很優雅!純靜態爆破文件關鍵點+純靜態打Patch(IDA反組譯﹢打Patch)

圖片
在打Patch方面,Windows上分析 一直都有著優異分析能力的Ring3工具有三套 Cheat Engine、OllyICE、IDA 大家比較熟的可能是OllyICE可以直接分析PE Header、分析.text段 然後直接對Patch的資料保存回執行檔文件 或者不少人也知道Cheat Engine有提供一個噁爛等級的Lua腳本 讓你直接用ASM+Lua,不會主流程式語言也能輕鬆製作出補釘工具 有些人乾脆就自己寫一個KeyGen or Patch文件了. 不過今天要介紹的不是這些, 而是大多數人知道IDA可以分析程式靜態邏輯,輕鬆得知內容 而不知道其實IDA也有Patch文件的功能XD (知道的就別看這篇文啦~很雷很雷~~大牛請飄過) 是說本來這篇文想用純英文耍屌寫文章 後來想想...算惹 幹嘛這樣吃力不討好呢(尻杯XD)

[C++]DLL遠程注入(LoadLibraryA)

國中寫的東西現在翻一翻 然後整理一下XD 丟上來Blog當廢文發XD [VB.NET]DLL跨進程遠程注入(LoadLibraryA) C++ Source Code在GitHub: https://github.com/aaaddress1/Dll-Injector-In-CB bool EnablePrivilege() { //提權模組 //這個其實你用不用都沒差(在Win7以上) //不過這個模組如果不用,在XP之下會沒辦法正常寫入記憶體/跨進程存取 HANDLE hToken=NULL; //用OpenProcessToken確認自己的進程等級(非NULL則有權限) if (OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken)) return true; LPCTSTR szPrivName = SE_DEBUG_NAME;//調整到DEBUG BOOL fEnable = true; TOKEN_PRIVILEGES tp; tp.PrivilegeCount = 1; LookupPrivilegeValue(NULL,szPrivName,&tp.Privileges[0].Luid); tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED:0; AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),NULL,NULL); return((GetLastError() == ERROR_SUCCESS)); } bool RemoteInject(String DLLPath,DWORD process_id) { EnablePrivilege();//提權 //接著用OpenProcess取得遠端進程控制句柄 void* ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS,false,process_id); if(!ProcessHandle) return false; //接著把String轉Char Arra...

[VB.NET]DLL跨進程遠程注入(LoadLibraryA)

這份Code在我高二的時候好像就丟在某論壇惹吧 不過既然現在有Blog就一併更新發上來了 [C++]DLL遠程注入(LoadLibraryA) Source Code在GitHub: https://github.com/aaaddress1/DLL-Injector-In-VB.NET 核心Code: Dim DllPath As String = Application.StartupPath + "/MyDll.dll" '先宣告變數來存放你要注入的DLL Dim TargetHandle As IntPtr = Process.GetProcessesByName("ProcessName")(0).Handle '然後透過Process類別去取得Handle '特別注意一下這個Handle取到了就同等於用OpenProcess得到控制句柄了喔 If (TargetHandle.Equals(IntPtr.Zero)) Then MsgBox("對進程 " + ComboBox1.Text + " 進行打開進程行為失敗.") Exit Sub End If '獲取LoadLibraryA的地址(PS:不同進程但同API,地址相同). Dim GetAdrOfLLBA As IntPtr = GetProcAddress(GetModuleHandle("Kernel32"), "LoadLibraryA") If (GetAdrOfLLBA.Equals(IntPtr.Zero)) Then MsgBox("取得LoadLibraryA API函數基址失敗.") Exit Sub End If '將DLL路徑轉為Char()陣列. Dim OperaChar As Byte() = System.Text.Encoding.Default.GetBytes(DllPath) '在目標進程申請一塊空間存放路徑字串. Dim DllMemPathAdr = VirtualAllocEx(TargetHandle, 0...

[C++][PEB][ASM]硬幹取得指定函數的內存地址、透過PEB枚舉獲取指定內存地址之函數名稱

這篇是個人筆記啦XD 基本上就是因為網路上要找到寫這種奇怪的東西,實在找不到 所以就去網路上東抓西抓然後改一改弄出來的東西了 首先是 透過指定模組取得函數名稱的地址(其實就是GetProcAddress API的功能啦) DWORD GetFuncAddr(HMODULE hModule,char* FuncName) { PIMAGE_DOS_HEADER pDosHeader; PIMAGE_NT_HEADERS pNtHeader; PIMAGE_EXPORT_DIRECTORY pExportDirectory; HMODULE hModuleBase = hModule; pDosHeader = (PIMAGE_DOS_HEADER)hModuleBase; pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)hModuleBase + pDosHeader->e_lfanew); pExportDirectory = PIMAGE_EXPORT_DIRECTORY(pNtHeader->OptionalHeader.DataDirectory[0].VirtualAddress + (PBYTE)hModuleBase); PDWORD pAddressName = PDWORD((PBYTE)hModuleBase+pExportDirectory->AddressOfNames); //函数名称表指针 PWORD pAddressOfNameOrdinals = (PWORD)((PBYTE)hModuleBase+pExportDirectory->AddressOfNameOrdinals); //函数名称序号表指针 PDWORD pAddresOfFunction = (PDWORD)((PBYTE)hModuleBase+pExportDirectory->AddressOfFunctions); //函数地址表指针 for (int index = 0; index < (pExportDirectory->NumberOfNames); index++) { PCHAR pFunc = (PCHAR)((long)hModuleBase + *pA...

[C++][ASM]免API撈模組基址(asm從PEB硬幹)

這是從對岸忘記從哪裡撈來的... 不過看了一下手法很漂亮就記錄下來惹XD 原理是用asm從PEB去指向模組的List去找這樣 底下稍微改過原本寫法然後補上註解 DWORD GetSelfModule()//等同GetModuleHanle(NULL) { DWORD dRetn = 0; asm {    push eax //保護堆疊    MOV eax,dword ptr fs:[0x30] // pointer to PEB    MOV eax,dword ptr [eax+0x8] //eax = Current Module Base    MOV [dRetn],eax    pop eax //恢復堆疊 } return dRetn; } 另個是如果想搜索 DWORD GetKernelModule()//獲取Kernel32 DLL Base { DWORD dRetn = 0; asm {    push eax    mov eax,dword ptr fs:[0x30]   //pointer to PEB    mov eax,dword ptr [eax+0x0c]   //pointer to loader data    mov eax,dword ptr [eax+0x1c]   //first entry in initialization order list (ntdll.dll)    mov eax,dword ptr [eax]    //second entry int initialization order list (kernel32.dll)    mov eax,dword ptr [eax+0x08]   //base addr of kernel32.dll    mov [dRetn],eax    po...

[很雷][C++][OllyICE][ASM]摸摸摸、初探Buffer Overflow攻擊

圖片
一直覺得Buffer Overflow的算法很神奇 一定要算到很精確才能讓Shellcode溢位到準確的EIP上做return 不過最近某某大神的這篇 緩衝區溢位攻擊:第二章 - 改變程式執行的流程 <(_ _)> 看完之後自己的心得吧(?) 不過因為使用上原版的好麻煩...(各種懶惰) 所以改寫了一下 在中間因為x恆等於1所以永遠都會printf出"x is 1"這句話 用跟蹤了一下Dev C++編譯出來的結果 先對strcpy下breakpoint然後跟蹤回去可以看到整支code在哪 接著可以跟蹤一下記憶體 在func函數跑到申請區域變數記憶體完後的stack資料 在func函數跑到尾巴時候的stack資料 可以試著把Dev C內的Code文字改成24個點去占用buffer變數的24個Byte看看 占用後的結果: 會發現還有兩組LONG大小的空間,才會占用到EIP返回點 後來跟了一下22FEC0中記錄的777B8CD5的這個位置,是strcpy的API地址 至於22FEC4的這個就不知道是啥了...看不太懂到底這個位置是? 總之可以得知我們需要占用24個字節+2個LONG的長度+一個LONG(EBP記錄的變數) 最後才能占用到22FECC的EIP返回點 可以發現那個永遠不會被執行到的位置地址為0x0040170C 轉成BYTE Array得寫:0C 17 40 00 所以最後文字的Shellcode可以寫成: 「 ........................xxxxyyyyzzzz\x0C\x17\x40\x00 」 24個「.」負責占用buffer的內容 四個x負責占用strcpy的地址 四個y負責占用不知道是啥的空間 四個z負責占用占存的EBP值 接著就是補上四個BYTE的返回點 最後把文字換為shellcode,就成功控制了底下的邏輯流程惹

[C][ASM]微軟的函數頭定義要mov edi,edi的原因

在C的規範下的組語,函數頭形式會做 push ebp mov ebp,esp sup esp, n//stack資料轉區域變數空間 /*...接著就可以存取[ebp+4*k]的參數...*/ add esp, n ( or ret n)//平衡堆疊 pop ebp ret 幾個比較神奇的事情: 1. MASM為啥頭函數要多一個mov edi,edi 該不會是為了湊足五個字節方便我們破解者Hook吧XD? 2. 為啥wsprintf要使用者自己平衡堆疊? 3. 有些函數明明就不需要參數 為啥還是需要做enter跟leave?

[C++Builder][VC++][DevC++]逆向分析for迴圈能否使用多重條件句

圖片
for迴圈標準寫法: for(int i = 0 ; (i < 10); i++); 或者可以用建構式初始化起始值 for(int i(0) ; (i < 10) ; i++); for迴圈在編譯器解釋上是把;;前中後三個拆解成三個block來處理 所以可以寫: for(int i(0),t(0),k(0), (i<10); i++); 這樣for迴圈"內"就可以一次使用三個變數 所以當然也可以在最後一個尾巴的block加上額外的運算方法: for(int i(0),t(0),k(0), (i<10); t = i+1, k = t*2; i++); 理論上既然for迴圈內以逗號隔開應該是會被解析的, 那麼for(; 條件句1,條件句2,條件句3;); 應該這麼寫編譯器應該也是會過的 編譯一下,過了 來分析一下記憶體上是怎麼跑的 用Cheat Engine動態跟蹤一下很快就能找到存取點了(那個k值的地址) :P 跟蹤回去,可以找到int main()架構在這裡 看來Dev C++ 在組合語言上只保留了k == 99這個條件句了 (對於 i < 10這個條件句已經被無視了Otz) 為了避免是Dev C++對於for迴圈解析的問題 另外拿了Visual C++做了測試: 用Cheat Engine跟蹤一下int main()的結果: VC++的解析狀況也是選擇只保留最後一個條件句,把 i < 10條件句給遺忘了T__T 不信邪的再拿CBuilder測一下 用Cheat Engine跟蹤: C++Builder編譯後的結果也是選擇把條件句 i < 10做遺忘,只取最後一個 看起來各個版本的C++IDE做解析都會把 for (int i = 0 ; i < 10 , i < 9, i < 8; i++); 只解析最後一個條件句(意思是如這個for迴圈i只會跑0~7) 查了一下國外討論串 Are multiple conditions allowed in a for loop? 結論也是這樣Otz.