最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

軟件破解-crackeme04

2020-12-26 23:16 作者:無(wú)情劍客Burning  | 我要投稿

在黑客攻擊-軟件破解(2)?中通過(guò)Radare2的靜態(tài)分析實(shí)現(xiàn)了破解。本文使用frida和radare2進(jìn)行動(dòng)態(tài)分析來(lái)對(duì)crackerMe系列中后面的例子進(jìn)行破解。

crackme0x04

流程圖

首先通過(guò)agf查看流程圖。

[0x080484fb]> agf
[0x08048484]> ?# sym.check (char *s);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ┌─────────────────────────────────────┐
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ ?0x8048484 ? ? ? ? ? ? ? ? ? ? ? ? ?│
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ ? ; CALL XREF from main @ 0x8048559 │
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ 133: sym.check (char *s); ? ? ? ? ? │
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ ; var char *var_dh @ ebp-0xd ? ? ? ?│
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ ; var uint32_t var_ch @ ebp-0xc ? ? │
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ ; var uint32_t var_8h @ ebp-0x8 ? ? │
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ ; var int32_t var_4h @ ebp-0x4 ? ? ?│
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ ; arg char *s @ ebp+0x8 ? ? ? ? ? ? │
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ ; var char *format @ esp+0x4 ? ? ? ?│
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ ; var int32_t var_sp_8h @ esp+0x8 ? │
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ push ebp ? ? ? ? ? ? ? ? ? ? ? ? ? ?│
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ mov ebp, esp ? ? ? ? ? ? ? ? ? ? ? ?│
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ sub esp, 0x28 ? ? ? ? ? ? ? ? ? ? ? │
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ mov dword [var_8h], 0 ? ? ? ? ? ? ? │
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ mov dword [var_ch], 0 ? ? ? ? ? ? ? │
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? └─────────────────────────────────────┘
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? v
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │
┌────────────────────────────────────────────────────────┐
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│ │
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?┌────────────────────────────────────────┐
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│ ?0x8048498 ? ? ? ? ? ? ? ? ? ? ? ? ? ? │
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│ ; CODE XREF from sym.check @ 0x80484f9 │
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│ mov eax, dword [s] ? ? ? ? ? ? ? ? ? ? │
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│ ; const char *s ? ? ? ? ? ? ? ? ? ? ? ?│
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│ mov dword [esp], eax ? ? ? ? ? ? ? ? ? │
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│ ; size_t strlen(const char *s) ? ? ? ? │
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│ call sym.imp.strlen;[oa] ? ? ? ? ? ? ? │
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│ cmp dword [var_ch], eax ? ? ? ? ? ? ? ?│
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│ jae 0x80484fb ? ? ? ? ? ? ? ? ? ? ? ? ?│
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?└────────────────────────────────────────┘
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?f t
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│ │
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│ └───────────────────┐
│ ? ? ? ? ? ? ? ?┌───────────────────────────────────────┘ ? ? ? ? ? ? ? ? ? ? │
│ ? ? ? ? ? ? ? ?│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │
│ ? ? ? ? ? ?┌────────────────────────────────────────────────────────┐ ? ?┌────────────────────────────────────────────┐
│ ? ? ? ? ? ?│ ?0x80484a8 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ ? ?│ ?0x80484fb ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │
│ ? ? ? ? ? ?│ mov eax, dword [var_ch] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│ ? ?│ ; const char *format ? ? ? ? ? ? ? ? ? ? ? │
│ ? ? ? ? ? ?│ add eax, dword [s] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ ? ?│ ; CODE XREF from sym.check @ 0x80484a6 ? ? │
│ ? ? ? ? ? ?│ movzx eax, byte [eax] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│ ? ?│ ; [0x8048649:4]=0x73736150 ? ? ? ? ? ? ? ? │
│ ? ? ? ? ? ?│ mov byte [var_dh], al ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│ ? ?│ ; "Password Incorrect!\n" ? ? ? ? ? ? ? ? ?│
│ ? ? ? ? ? ?│ lea eax, [var_4h] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│ ? ?│ mov dword [esp], str.Password_Incorrect ? ?│
│ ? ? ? ? ? ?│ ; ? ... ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│ ? ?│ ; int printf(const char *format) ? ? ? ? ? │
│ ? ? ? ? ? ?│ mov dword [var_sp_8h], eax ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ ? ?│ call sym.imp.printf;[oc] ? ? ? ? ? ? ? ? ? │
│ ? ? ? ? ? ?│ ; const char *format ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ ? ?│ leave ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│
│ ? ? ? ? ? ?│ ; [0x8048638:4]=0x50006425 ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ ? ?│ ret ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│
│ ? ? ? ? ? ?│ mov dword [format], 0x8048638 ? ? ? ? ? ? ? ? ? ? ? ? ?│ ? ?└────────────────────────────────────────────┘
│ ? ? ? ? ? ?│ lea eax, [var_dh] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│
│ ? ? ? ? ? ?│ ; const char *s ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│
│ ? ? ? ? ? ?│ mov dword [esp], eax ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │
│ ? ? ? ? ? ?│ ; int sscanf(const char *s, const char *format, ? ...) │
│ ? ? ? ? ? ?│ call sym.imp.sscanf;[ob] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │
│ ? ? ? ? ? ?│ mov edx, dword [var_4h] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│
│ ? ? ? ? ? ?│ lea eax, [var_8h] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│
│ ? ? ? ? ? ?│ add dword [eax], edx ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │
│ ? ? ? ? ? ?│ cmp dword [var_8h], 0xf ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│
│ ? ? ? ? ? ?│ jne 0x80484f4 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│
│ ? ? ? ? ? ?└────────────────────────────────────────────────────────┘
│ ? ? ? ? ? ? ? ? ? ?f t
│ ? ? ? ? ? ? ? ? ? ?│ │
│ ? ? ? ? ? ? ? ? ? ?│ └───────────────────────┐
│ ? ?┌───────────────┘ ? ? ? ? ? ? ? ? ? ? ? ? │
│ ? ?│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │
│┌─────────────────────────────────────┐ ? ┌────────────────────────────────────────┐
││ ?0x80484dc ? ? ? ? ? ? ? ? ? ? ? ? ?│ ? │ ?0x80484f4 ? ? ? ? ? ? ? ? ? ? ? ? ? ? │
││ ; const char *format ? ? ? ? ? ? ? ?│ ? │ ; CODE XREF from sym.check @ 0x80484da │
││ ; [0x804863b:4]=0x73736150 ? ? ? ? ?│ ? │ lea eax, [var_ch] ? ? ? ? ? ? ? ? ? ? ?│
││ ; "Password OK!\n" ? ? ? ? ? ? ? ? ?│ ? │ inc dword [eax] ? ? ? ? ? ? ? ? ? ? ? ?│
││ mov dword [esp], str.Password_OK ? ?│ ? │ jmp 0x8048498 ? ? ? ? ? ? ? ? ? ? ? ? ?│
││ ; int printf(const char *format) ? ?│ ? └────────────────────────────────────────┘
││ call sym.imp.printf;[oc] ? ? ? ? ? ?│ ? ? ? v
││ ; int status ? ? ? ? ? ? ? ? ? ? ? ?│ ? ? ? │
││ mov dword [esp], 0 ? ? ? ? ? ? ? ? ?│ ? ? ? │
││ ; void exit(int status) ? ? ? ? ? ? │ ? ? ? │
││ call sym.imp.exit;[od] ? ? ? ? ? ? ?│ ? ? ? │
│└─────────────────────────────────────┘ ? ? ? │
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│
└──────────────────────────────────────────────┘

指令和函數(shù)

sscanf() 函數(shù)的聲明。

int sscanf(const char *str, const char *format, ...)

作用是從字符串讀取格式化輸入。

cmp指令: 該指令與SUB指令一樣執(zhí)行減法的操作,但它并不保存運(yùn)算結(jié)果,只是根據(jù)結(jié)果設(shè)置相關(guān)的條件標(biāo)志位(SF、ZF、CF、OF)。CMP指令后往往跟著條件轉(zhuǎn)移指令,實(shí)現(xiàn)根據(jù)比較的結(jié)果產(chǎn)生不同的程序分支的功能。 inc是增量指令。 inc指令: 該指令對(duì)操作數(shù)oprd加1(增量),它是一個(gè)單操作數(shù)指令。操作數(shù)可以是寄存器或存儲(chǔ)器。由于增量指令主要用于對(duì)計(jì)數(shù)器和地址指針的調(diào)整,所以它不影響進(jìn)位標(biāo)志CF,對(duì)其他狀態(tài)標(biāo)志位的影響與add指令一樣。

偽代碼

通過(guò)pdg查看以下decompiler的代碼

[0x080484fb]> pdg

// WARNING: [r2ghidra] Detected overlap for variable var_dh

void sym.check(char *s)
{
? ?uint32_t uVar1;
? ?char var_dh;
? ?uint32_t var_ch;
? ?uint32_t var_8h;
? ?int32_t var_4h;

? ?var_8h = 0;
? ?var_ch = 0;
? ?while( true ) {
? ? ? ?uVar1 = sym.imp.strlen(s);
? ? ? ?if (uVar1 <= var_ch) break;
? ? ? ?var_dh = s[var_ch];
? ? ? ?sym.imp.sscanf(&var_dh, 0x8048638, &var_4h);
? ? ? ?var_8h = var_8h + var_4h;
? ? ? ?if (var_8h == 0xf) {
? ? ? ? ? ?sym.imp.printf("Password OK!\n");
? ? ? ? ? ?sym.imp.exit(0);
? ? ? ?}
? ? ? ?var_ch = var_ch + 1;
? ?}
? ?sym.imp.printf("Password Incorrect!\n");
? ?return;
}

邏輯分析

通過(guò)流程圖可知核心算法在中間部分,并且可以看出存在循環(huán)。

第一次循環(huán):

1.把var_ch內(nèi)存中的值賦值給eax?mov eax, dword [var_ch]2.把a(bǔ)rg_8h(check函數(shù)參數(shù),也就是輸入的字符串)中的值和eax相加?add eax, dword [arg_8h]3.將eax取byte擴(kuò)充(相當(dāng)于取低8位)?movzx eax, byte [eax]?mov byte [var_dh], al4.將var_4h賦值給eax,注意這里是lea指令lea eax, [var_4h]5.將eax的值賦給var_sp_8h指向的內(nèi)存(為sscanf傳遞參數(shù),從右向左入棧)?mov dword [var_sp_8h], eax6.將0x8048638("%d")賦給var_sp_4h指向的內(nèi)存?mov dword [var_sp_4h], 0x80486387.eax入棧(eax和var_dh的值是一樣的)?lea eax, [var_dh]?mov dword [esp], eax8.調(diào)用用sscanf函數(shù)?call sym.imp.sscanf9.將var_4h指向的值賦給edx?mov edx, dword [var_4h]10.將var_8h的值賦給eax?lea eax, [var_8h]11.edx和eax指向的值相加?add dword [eax], edx12.比較var_8h內(nèi)存中的值和0xf?cmp dword [var_8h], 0xf13.如果相等,則出現(xiàn)成功的提示,如果不相等,則跳轉(zhuǎn)到0x80484f4?cmp dword [var_8h], 0xf?jne 0x80484f4?假設(shè)不相等,開(kāi)始第二輪的循環(huán)。

通過(guò)上面的分析,可知check函數(shù)的功能:對(duì)字符串中的每個(gè)字符取整(類似atoi),然后對(duì)每個(gè)字符相加,和0xf進(jìn)行比較,只有相等的情況,才能Pass.

破解

下面通過(guò)多種方式來(lái)破解這個(gè)程序。

輸入正確的值

知道邏輯,很容易破解這個(gè)程序。輸入12345(和是0xf),Pass.

frida修改邏輯

修改參數(shù)

修改參數(shù)為96(和是0xf),則無(wú)論輸入什么都可以使程序Pass. 32位的函數(shù)參數(shù)傳遞方式在strcpy為何不安全?中有所介紹。

"use strict"

var targetModule = Process.findModuleByName("crackme0x04");
var symbols = targetModule.enumerateSymbols();
var targetFun = null;
for(var i = 0; i < symbols.length; i++) {
? ?targetFun = ?ptr(symbols[i].address);
? ?if (symbols[i].name == "check" && symbols[i].type == "function"){
? ? ? ?Interceptor.attach(targetFun,{
? ? ? ? ? ?onEnter:function(args){
? ? ? ? ? ? ? ?this.tmp = ptr(args[0]);
? ? ? ? ? ? ? ?this.tmp.writeByteArray([0x39,0x36]);
? ? ? ? ? ? ? ?console.log("success");
? ? ? ? ? ? ? ?console.log(hexdump(this.tmp, {
? ? ? ? ? ? ? ? ? ?offset: 0,
? ? ? ? ? ? ? ? ? ?length: 64,
? ? ? ? ? ? ? ? ? ?header: true,
? ? ? ? ? ? ? ? ? ?ansi: true
? ? ? ? ? ? ? ?}));
? ? ? ? ? ? ? Thread.sleep(6);//注意這里,讓線程睡眠6秒,否則console不能輸出
? ? ? ? ? ?}
? ? ? ?});
? ? ? ?break; ? ? ?
? ?}
}

通過(guò)r2來(lái)獲取96對(duì)應(yīng)的asci碼是0x39 0x36

運(yùn)行frida腳本,這樣無(wú)論輸入什么的都可以Pass.

Thread.sleep(delay): suspend execution of the current thread for delay?seconds?specified as a number.?由于Ansi相關(guān)的函數(shù)只能用在Windows平臺(tái)中,所以這里才使用byte數(shù)組。

Note that writeAnsiString() is only available (and relevant) on Windows.

修改指令

修改跳轉(zhuǎn)指令。使得程序無(wú)論如何都可以成功運(yùn)行。

1.如果相等,則出現(xiàn)成功的提示,如果不相等,則跳轉(zhuǎn)到0x80484f4?cmp dword [var_8h], 0xf?jne 0x80484f4

代碼實(shí)現(xiàn)如下:

"use strict"

var targetModule = Process.findModuleByName("crackme0x04");
var symbols = targetModule.enumerateSymbols();
var targetFun = null;
for(var i = 0; i < symbols.length; i++) {
? ?targetFun = ?ptr(symbols[i].address);
? ?if (symbols[i].name == "check" && symbols[i].type == "function"){
? ? ? ?const maxPatchSize = 64; // Do not write out of bounds, may be a temporary buffer!
? ? ? ?Memory.patchCode(targetFun.add(0x56), maxPatchSize, code => {
? ? ? ? ? ?const cw = new X86Writer(code);
? ? ? ? ? ?cw.putJmpAddress(targetFun.add(0x56).add(0x2));//跳轉(zhuǎn)指令,跳轉(zhuǎn)到success分支
? ? ? ? ? ?console.log(hexdump(targetFun.add(0x56).add(0x2), {
? ? ? ? ? ? ? ?offset: 0,
? ? ? ? ? ? ? ?length: 64,
? ? ? ? ? ? ? ?header: true,
? ? ? ? ? ? ? ?ansi: true
? ? ? ? ? ?}));
? ? ? ? ? ?cw.flush();
? ? ? ?});
? ? ? ?break; ? ?
? ?}
}

代碼中的0x56是跳轉(zhuǎn)指令與check函數(shù)地址的偏移(offset),0x2是跳轉(zhuǎn)指令的長(zhǎng)度。

運(yùn)行腳本,無(wú)論輸入什么,都可以Pass。

r2pipe

官方文檔如下,簡(jiǎn)單點(diǎn)說(shuō)就是r2腳本編程的接口。

Radare2 provides a wide set of a features to automate boring work. It ranges from the simple sequencing of the commands to the calling scripts/another programs via IPC (Inter-Process Communication), called r2pipe.

舉個(gè)栗子(本文基于的是python3.8), 獲取通過(guò)r2分析得到的函數(shù)列表并且以json格式輸出

import r2pipe

r2 = r2pipe.open("/bin/ls")
r2.cmd('aa')
print(r2.cmd("afl"))
print(r2.cmdj("aflj")) # evaluates JSONs and returns an object

基于此可以調(diào)試和破解程序。

fuzz

這個(gè)方法綜合了上述的一些方式, 我們可以用暴力破解的方式來(lái)獲取密碼, 也可以利用libFuzzer 來(lái)自動(dòng)化找出該程序潛在的bug. 這種方式的壞處是太暴力了, 讓妹子不敢靠近(逃); 好處則是在一定程度上解放了大腦, 用計(jì)算機(jī)來(lái)幫我們計(jì)算, 算力越強(qiáng)就越有可能找到突破點(diǎn)!

對(duì)于libfuzz的使用,在漏洞挖掘(1)?中對(duì)libFuzzer進(jìn)行了介紹。

寫(xiě)在最后

crackme0x04開(kāi)始涉及到算法,crackerMe0x05之后難度會(huì)逐步增加,后續(xù)文章會(huì)陸續(xù)介紹。R2pipe和fuzz在這里挖個(gè)坑(主要是一兩句說(shuō)不清楚),哈哈。

公眾號(hào)

更多逆向破解內(nèi)容,歡迎關(guān)注我的微信公眾號(hào):無(wú)情劍客。


軟件破解-crackeme04的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
石门县| 通榆县| 临湘市| 罗甸县| 高陵县| 得荣县| 库车县| 县级市| 布尔津县| 精河县| 通渭县| 云浮市| 景洪市| 湄潭县| 通许县| 双峰县| 华容县| 名山县| 邵武市| 香港 | 北票市| 建阳市| 忻城县| 西昌市| 柞水县| 无为县| 巴青县| 大渡口区| 金山区| 楚雄市| 鹤岗市| 武定县| 旬邑县| 类乌齐县| 诏安县| 罗平县| 唐山市| 平潭县| 上思县| 朝阳县| 伊吾县|