现在我们已经分析了第恶意软件加载器 让我们来看看第二个 看看配置是否被不同地存储 看看我们是否能找到提取它的方法 等等 So now we've analyzed the first malware loader, let's have look at the second one and see if the configuration is stored differently, see if we can figure out a way to extract it, and so on.
让我们来看看虚拟机 So let's help over to the virtual machine.
现在我们要继续看我们的第二个加载器在一章的初始阶段 So now we're going to go ahead and look at our second loader in this initial stages, chapter.
对于第二个装载机 我想去做一些更困难和模糊的东西 我决定使用Z装载机 最初的 And for this second loader, I wanted to go for something more difficult and obphiscated, so I decided to go with Z Loader. So the initial.
拆封 以及所有涉及到它的东西 使用P-E注入来注入MSI 精确点 E-X-C 我们会创建流程 注入进去 Unpacking, and everything involves it, using P-E injection to inject into MSI, exact dot, E-X-C, so we'll create a process and then inject into it.
通常需要很长时间 我想略过一点 因为我们将在后面讨论注入 That typically takes quite a while, so I wanted to sort of skip that bit, as we're going to cover injection later on.
我想主要关注loader元素 当它注入到MSI时 它不会调用 And I wanted to mainly focus on the loader elements, so when it does inject into MSI, exact, it doesn't call the.
D-L入口点或注册服务器 你会调用 D-L entry point or register server, you'll actually call a.
不同的函数 在种情况下 它实际上没有被IDA认可为一种功能 Different function in the binary. And in this case, it wasn't actually recognized as a function by IDA.
因为它从来没有真正的引用任何地方 由于数额的混淆 zelo用户 它基本上是在调用创建远程线程之前计算的 As it's never really referenced anywhere, due to the amount of obfuscation that zelo to users. And so it's basically calculated before create remote thread is called.
我在里所做的是 正如我之前分析过的 我继续使用Lumina And so what I've gone ahead and done here is, as I've analyze this before, I went ahead and used Lumina to.
基本上找到配置提取部分 允许我找到里的函数 但如果你要自己动手 Basically locate the config extraction part, and that allowed me to find the function here. But if you were going to do it yourself,
如果你没有lumina 你几乎可以在小虫子里引爆它 And you didn't have lumina, you could pretty much detonate it in a dbugger.
确保你使用RundeelL 32调用包装样品 在执行过程中跟随它 Make sure you use Rundeel L. Thirty two to call the packed sample, follow it through execution.
确保在创建过程中有内部断点 W 在点上 你会放断点 And make sure there's a break point on create process, internal. W, at that point, you would then put a break point on.
恢复线程或创建远程线程 当它被击中时 你可以看到偏移量 你可以跳转到IDA 从偏移量开始分析 Resume thread or create remote thread, and when that gets hit, you can see the offset, so you can then jump over to IDA and then start analyzing from that offset. So.
不管怎样 往下滚动 你可以看到里有很多 Anyway, scrolling down, you can see there's quite quite a mess of.
函数和字符串 它还使用了字符串加密 也很有趣 Functions and strings here it. It also uses string encryption, which is also quite fun.
但是我们要从构型提取开始 让我们跳到 But we're going to focus on the configuration extraction to begin with, so let's go ahead and jump over to the.
伪代码 因为它让分析变得简单多了 Pseudo code because it makes it hell of a lot easier to analyze. So.
是通过MSI调用的主要函数 如果我们试图找到交叉引用 是找不到的 This is the main function here called through MSI, exact, if we try and find cross references can't be found.
因此 快速浏览一下伪代码中的main函数 So having a quick look at the main function in pseudo code.
里有从属函数它被调用了很多次 它传递给它不同的值 We have this subertine here that's called quite a lot, and it passes different values to it.
里是十六进制 里还有十六进制值 So here we have this hex value. We've got another hex value here.
第参数 似乎和他的不同 0是1 0中有1 And the first argument pass to, it seems to differ to his, zero is a one, there's a one there in a zero.
此时 我假设有API哈希 So at this point, I'm assuming there's API hash and going on.
在些函数中 根据所传递的参数 以及使用所有些办公功能时 不使用API哈希是非常愚蠢的 In these functions, based on the arguments passed, as well as the fact that with all this officecation, it would be pretty stupid not to put an API hashing.
让我们重命名API哈希 如果我们进入函数 我们可以看到有更多的fisation在进行 Let's renam this API hashing. If we step into this function here, we can see there's a lot more of fiscation going on.
我们似乎又想起了API哈希 We then seem to recall API hashing again. So.
如果没有 它会调用相同的函数 It will just call the same function if it doesn't.
获取正确的API之类的 或者我们会尝试加载另API 可以是加载库或获取过程地址 里我们有 Get the correct API or something, or we'll try and load another api here, so this could be load library or get procedure address. So here we have a.
函数 似乎是有的 Function here. And this seems to be possibly.
里有字符串解密函数 我们有放逐 在里的偏移 指向似乎不是字符串 A string decryption function here. We have an exile going on with this offset here, which points to this apparen't string here.
马虎 试着把它转换成字符串 是字符串 还是实际的 Careless, try convert that to a string. Is it a string, or is it an actual.
咬 按a 看起来像字符串 不完全确定 但是字符串加密 我猜是 Bite, press a, okay, so this looks possibly like the string, not entirely sure, but that's for the string encryption, I'm guessing so.
如果我们看看传递给它的是 我们会看到里的偏移量 加上1 If we see what's passed into it, we see that this offset here, plus a one.
如果你还记得8 1是0 我们看到被传递的 里传递的是1 里是0 If you remember eight, one was the zero and the one we saw being passed. So here we have one being passed, and zero here.
我们来看看提议是 它指向一长串 So let's view what this offer is, so it points to a long list of.
未知值 我们跳到里 Unknown values, we jump over here.
我们可以看到它似乎是一些加密的数据 我猜是D ls的列表 We can see it seems to be some encrypted data, so what I'm guessing is this is probably going to be a list of D, ls.
它将用来装载 例如 是Feyeii上校 是Anti-D-L-L 而参数past的值是1 That it's going to use to load, so for example, this could be Colonel Feyeii, this could be Anti D-L-L, and the value that is past as argument, one.
对应于DL 样就不必在进程环境块中定位D-L Corresponds to the DL, that saves having to locate the D-L in the processes environment block. And then.
对不同的D和l进行哈希 看看是否匹配 等等 Hashing the different D, l's found to see if it matches, and all the stuff. And so.
我想它更有效率 尽管我不知道他们为要提高效率而不是安全性 因为你很容易就能知道它用的是哪个D-L I guess it's more efficient, although I don't know why they'd go up for a efficiency over security, cause you can easily just figure out which D-L it's using, but anyway,
继续 我们把函数命名为string decrypt Moving on, let's actually name this function to string, decrypt.
回到里 我们可以看到里实际上有一些字符串B 叫做eryps Back out here, so we can see here there's actually a few string B, eryps called.
但让我们跳到第函数 因为我想我们现在已经尽多地算出了 But let's jump into the first function here, because I think we've pretty much figured out as much as we can at the moment.
我们来看第函数 我们有子分支 我们有字符串解密 So let's step into the first function. We have this subarine here, we've got a string decrypt.
subertine This subertine here.
里还有另子结点 我们还有几个子结点 包含未知值 是字符串 Another subbertine here, we've got several more subberines, this one contains a unknown value, and then what seems to be a string.
关心一下有趣的字符串Ida已经认出了它 Cares this an interesting string there that's been recognized by Ida.
而且都是小写字母 它不像里的些东西是随机的 是解密字符串 或者是密码 或者是里面的东西 我们以后再看 And it's all lower case characters as well. It's not random bites like this stuff here, so this could be a decryption string or a cipher or something inside there, so we'll have to look at that later.
有副项和其他一些 些似乎都没有论点 但我有一种感觉 如果我们跳进些 就会跳出来 明白吗 So there's this subportine and few more, and none of these have arguments, it seems, but I have a feeling if we jump into these, jump back out, okay?
有时候因为数量的上升 ITA做得不是很好 Sometimes because of the amount of upscation, ITA doesn't do a very good job of.
第一次传递所有参数时 你必须自己跳到它们中 刷新 看看它是否能识别任何参数 Passing everything the first time, you've got to self jump into them and then refresh to see if it'll recognize any arguments.
好吧 看起来不像 又来了 我们刚刚解决了一些类似于函数类型的问题 Okay, doesn't look like it. Oh, there we go. We just resolved something there looks like the type of the function.
一步进去 一步出来 里我们调用了字符串解密函数 让我们进入里 Step into there, step out, OK, and so we have a call to a string decrypt function here. Let's step into here.
好了 就走了 OK, it's go.
很小的字符串并不太大 不确定它是 因为我们没有字符串解密器 This fairly small string here is nothing too big, not entirely sure what it is, because we haven't got a string decryptor.
我们可以遍历里的每个函数 到里 到里 继续 So we could go through each function we see here, so going to here, and then going to here, and then continue.
但是因为有很多混淆 比如我们看 我们可以看到所有的操作 But because of the amount of obfuscation, like if we jump into this one, we can see all of the operations performed just to.
用参数执行所有操作 如果我们手动执行的话 会花很长时间 因为我们没有任何参数 Performing all operation with argument, one or two, it would, it would take quite a while if we were going through it manually, and because we don't have any.
脚本来处理所有事情 我们必须 Scripts to deal to scale everything for us. We'll have to.
尽量做到高效 因为一开始 我们要找构型 Try and be as efficient as possible. So because to begin with, we're looking for a configuration.
我在看两个值 你们会发现很奇怪 I'm, I'm looking at these two values here, and it's quite odd that you're going to see.
长度为20字节的字符串 格式相同 小写字母 A string that's about twenty bites in length, all the same format. So lower case characters.
我觉得有重要的事发生了 一场暗杀 如果我们进入函数 他 So I think there's something important going on, a hit, so if we step into this function, him.
我们可以看到还有很多函数 它似乎有一些D的符号 V 7被赋给了些D的单词 We can see there's quite a few more functions, it seems to have signed some D words, so V, seven gets assigned to these D words here.
7的符号是 6的 8的 9的 So we seven gets a sign to this, we six to that, we eight to that and be nine to that.
如果你还记得 我研究过 它在配置中有变量 我相信它是分配给字符串中心命令控制服务器的四个比特 So if you remember, I study, it had variables inside of the configuration, so I believe it was that four bites that was assigned to the string Centre command control server.
在例子中 我有一种感觉它也会样做 因为我们可以看到v In this case, I have a feeling it's going to be doing the same, because we can see V. Six as being.
用于两艘潜艇 有 Used in these two subarines. Have.
它移动到A-D单词 如果我们检查交叉引用 我们可以看到它正在被用在另子帆船上 如果我们跳到它 我们可以看到它正在被返回 And then it's moved into A-D word, and if we check for cross references, so we can see it's being used in this other subarine, so if we jump to it, we can see that it's being returned.
找到的交叉引用 Find cross references to this.
V 12包含D 它来自构型 So V, twelve will contain our D word, which could be from the configuration.
如果你曾经看过动物园银行木马 你会认出值还有整个存储箱和所有东西 Now if you've ever looked at the zoos banking Trojan, you will probably recognize a value like this and the whole binstorage and everything, so.
一旦你拿到通讯记录 我们会调查的 We'll look into the communications once you've got.
关于如何存储配置的想法 但基本上需要从ZeusBankingGeorgia的源代码中获取大量代码 是不久前泄露的 An idea of how the configates stored, but basically this takes a lot of code from the source code of the Zeus Banking Georgia that was leaked a while ago.
让我们回到的配置解密函数 让我们看看些函数做 So let's jump back to the possible config decryption function, and let's have a look at what these functions do.
我们进入第 我们有D单词 输出值 它返回给VI 进入两步 So we step into this first one here, we have this D word, exort with this value here, which is returned to VI, two step into this one.
只是饶舌歌手函数 同样 里我们称之为子程序 It's just a Rapper function step into this one. Again, we call Sub Routine here.
一切都不好玩 All this obscation is really not fun.
但它会回来的 V 3 777 But it will return. V, three, which is going to be 777.
或者它会是0 你可以看到 函数是完全没用的 它所做的只是比较1和2 它会返回基于的值 Or it's going to be zero, so as you can see, this function here is entirely useless, and all that is doing is comparing a one to a two, and it will return a value based on that.
1通过它传递进来 2是0 我们有API哈希调用 它会移动到V中 3 So a one is passed in through that, and a two is a zero, so we then have this API hashing call, which will be moved into V, three.
我们三个会被单独调用API 调用它 And we three will be called so alone, API, and then call it.
如果我们跳进艘潜艇 我们可以看到它返回Fee3 是另D单词exord 有值 And then if we jump into this submarine here, we can see it returns Fee three, which is another D word exord with this value.
并不重要 现在让我们进入函数 好吗 我将返回 让我们读入 因为它被使用了两次 读 So that's not important, really, so now let's jump into this function, okay? I'll just return this, so let's read in that, because it's used twice, so read this.
我们有D 我们把V分配给 D字在任何地方被指责 它似乎被推到了功能上 And we've got this D word, and then we have V being assigned to this. D word is accused anywhere, it is pushed to a function, it seems.
我们有分离的冷 它返回另值 值是通过xoringA-Dword计算出来的 还有值 hip So then we have this separating cold here, which returns another value, which is calculated through xoring A-D word, and this value, hip.
如果我们看看D木 你可以看到里有很多东西 些都是用来计算偏移量或需要用到的值的 So if we actually view the D woods, you can see there's a lot of stuff here, and this is all used for calculation of offsets or calculation of values that need to be used.
你可以继续写脚本来自动计算所有些 以便找到交叉引用 So you could go ahead and probably write a script to automatically calculate all these for you to find the cross references. So.
找到交叉引用 找到它 找出它被使用的是 你可以看到它被超越 在里 你可以重命名d字 以任何值返回 Find the cross reference, go to it and then figure out what it's being used, so you can see it's being excelled Here You can renam the d word to whatever value is returned.
但显然 对于我们在里做的事情 就更有深度了 But obviously that's a bit more in depth for what we're doing here.
它存储在v-4中 如果我们进入值 我们可以看到它将通过一些东西循环 So that's stored in V. Four. If we step into this value, we can see that it will loop through something.
基于3 是长度 因为它循环直到I等于3 Based on a three, which is probably going to be a length, because it loops until I equals a three.
I在每个循环中都是递增的 我猜3是计数器 And I is incremented on each loop, so I'm going to guess a three is a counter.
我们把它重命名为counter 当它循环时 它会得到1+I=2+I So let's rename that to counter, and so as it loops through, it will do a one plus I is equal to a two plus I.
看起来像是把2加计数器的咬痕复制到1加计数器的咬痕 So that looks like it's copying a bite from a two plus the counter into a one plus the counter.
在种情况下 我会说 So in that case, I'm going to say.
1是目标 2是源 基本上是memm拷贝的实现 A one is the destination, and a two is the source. This is basically an implementation of what seems to be mem copy.
如果我们进入 它只返回2加1 似乎返回长度 If we jump into this, it just returns a two plus a one, which seems to be possibly returning a length. So.
我要做的是将Z加载器命名为 mem copy What I'm going to do is name this Z loader, mem, copy.
因为它的基本功能 我们复制1 访问 3 1是记忆中的未知区域 如果我们刷新它 Because that's what it basically does, so we'll copy a one, interview, three, A one is that unknown region of memory, if we refresh that and.
把重命名为新的A Renam this to new A one.
那么新 A1似乎没有在任何地方使用 尽管它是 So new, A one doesn't seem to be used anywhere, although it is.
存储在D单词里 我不确定它是否会被用来指向解密的配置 如果是话 Stored inside of this D word here, I'm not sure if that's going to be used as a pointed to the decrypted configuration, if it is that.
不管怎样 我们可以看到1被复制到新的a1中 我们有子程序 我们跳到里 So anyway, we can see a one is copied into a new A one, and then we have this sub routine here, we jump into here.
我们检查一下3是否等于-1 We have a check to see if a three is equal to minus one.
如果是的话 它会调用子程序 它会对1执行检查 把结果设为-1 它会循环 And if it is, then it will call this sub routine here, where it performs a check on a one, sets the result as minus one, and then it will loop round.
看似递增 结果 Seemingly incrementing. Result.
返回结果在store中 V 3 V 3可以是点的长度 So a return result in store, and V, three, so V, three could be a length in this point.
它被用在mem复制函数中 很是长度 我们可以看到2被复制成1 And it is used in a mem copy function, again, so most likely going to be a length, we can see a two is copied into a one.
是 mem拷贝函数的包装器 我将命名为Zeelotmem拷贝 大小未知 So this is a, probably, I'd say, a wrapper for the mem copy function, so I've named this Zeelot mem copy, unknown size.
因为它会用函数计算大小 让我们重命名mem拷贝 大小未知 So because it will basically calculate a size with this function here, so let's renam this mem copy, unknown size.
将把2复制到未知数上 So this will copy a two to this unknown value here.
ATO是我们看到的有趣的字符串 我们也来Renam一下 And ATO is that interesting string we saw, so let's Renam this too.
有趣 Interesting.
我们返回B6 它似乎没有被用于任何事情 我要做的是 再次按下5来重新分析段代码 看看是否有变化 And then we return B, six, which doesn't seem to be used for anything. So what I'm going to do is, I'm going to press a five again to renalyze this code and see if anything changes.
显然 返回值不是很有用 Okay, it didn't, so obviously, the return value doesn't seem to be very useful.
让我们进入函数 里我们又给Xiloder打了个电话 妈妈 复制 我们都复制D字 也0 Uh, so let's jump into this function. So here we have another call to Xiloder, mam, copy, we're all copy this D word here, which is zero.
把b1赋给 在下面用 我们有函数 Into this, and B one is assigned to this, which is used down here. So then we have this function here, which will.
基本上 再次得到大小 将得到有趣字符串的大小 是RenamV 2 2的大小 Basically get the size again, so this will get the size of the interesting string, so that's Renam V, two, two size of.
有趣的力量 Interesting strength.
有趣的字符串作为第值传入 Interesting string is passed in as the first value.
尺寸应该是751 This looks to be a size, so 751.
V 1包含D 我们重命名为包含D的功 And then V, one contains this D word here, so let's renam to contains D work.
现在让我们找到的交叉引用 你可以看到或包含ESI 它被移到里面 我们跳到它 它实际上是我们在之前的函数中见过的D Now let's find cross references to this, and as you can see or contain ESI, which is moved into it, we jump to it. It's actually this D word we saw in the previous function.
所以 So.
新的 New A one.
包含传入的第未知值 如果我们回到调用函数 我们可以看到将是 Contains our first unknown value that was passed in. So if we jump back to the calling function, we can see this is going to be.
1 让我们重命名的冲突 A one, so let's rename a want to possible conflict.
哦 Oh,
的冲突被转移到新的A1 我们可以看到指向新的A1的指针被存储在D单词中 So possible conflict is moved into new A one, and then here we can see that a pointer to new A one was stored in this D word.
我们把它重命名为指向冲突的指针 So let's renam this to pointer to conflict.
现在让我们回到函数 And now let's jump back into this function here.
现在我们可以看到我们有振动 它取有趣的弦 有趣的弦的大小 So now we can see that we have this sebrating called, which takes the interesting string, the size of the interesting string.
冲突点 我们把它重命名为指针 指向冲突的指针 The point of the conflict, let's renam this to pointer, pointer to conflict.
指向 指向冲突的指针 很让人困惑 但基本上 So this is pointing to this, which points to the pointer to the conflict, and it's all confusing, but basically.
函数接受有趣的字符串 有趣字符串的大小 This function takes the interesting string, the size of the interesting string.
的配置和我猜测的配置大小 现在我们知道参数被推到函数 让我们进入它 The possible config and the size I'm guessing of the configuration, so now we know arguments are pushed to this function, let's step into it.
我们有了第一次庆祝和第二次庆祝 让我们进入第一次庆祝 马上开始 So we have this first celebrating and this second one, let's step into the first one, and immediately upon doing so.
我注意到值256出现了两次 似乎是线循环 将Fifa与结果进行比较 I notice the value 256 appear twice, and what seems to be a wire loop that will compare Fifa with result.
Result等于的返回值 在里 Result is equal to the return value of this. Here.
又是一团乱 1比2好 每次结果都是一样的 因为1和2不变 但是 Which is another mess, A one's excelled with a two, so this will be the same result each time, because a one and a two don't change, but.
我们可以根据函数的其他部分做一些假设 而不是把它算出来 看函数的最上面 3被设为0 Rather than figure that out, we can probably make some assumptions based on what we see in the rest of the function. So looking at the very top of the function, be three is set to zero.
3+256等于0 我们进入第循环 A three plus 256 is set to zero. Then we enter our first loop, which will.
做三加三等于三 三 加费 三 Do a three plus three equals three, three, and then increment fee, three.
在每个循环中 它基本上是0 1 2 3 4 5 6 7 8 9 是A-B-C-D-E-F 将持续到 So on every loop, it basically goes zero, one two, three, four, five, six, seven, eight, nine, and then A-B-C-D-E-F. And this will continue until the.
函数的返回值不是零 如果我们跳到里 它会返回 V 11 V 11等于V 7 Value return from this function is not zero, so if we jump into this, it will return, V, eleven, V, eleven equals V, seven.
V 7等于233 除非1不等于2 在种情况下它将返回0 V, seven equals 233 unless a one doesn't equal a two, in which case it will return zero.
如果1等于2 那么它将返回233 从而跳出循环 If a one is equal to a two, then it will return 233, making this break out of the loop.
意味着V必须等于256 我认为将是替代盒冰冷的外国加密 So that means V must equal 256. So this is making what I believe is going to be a substitution box for icy foreign encryption.
因此 替换方框的RC的置乱会在里完成 And therefore, the scrambling of this RC for substitution box is probably going to be done in this.
Lupel Lupel.
我猜函数的返回值是256 So I would guess that the return value of this function is going to be 256.
里没有实际的解密 我们可以简单地命名I-C 在里面 There's no actual decryption going on here, so we can simply name this I-C for, in it.
对于icy4初始化 我们进入 在里分开 For icy four initialize, and then we step into this, separate in here.
解密的I-C 里我们可以看到EXO And this is where the I-C for decryption is going on. So here we can see there's an EXO.
用返回的值 在awe操作中是1和2 是的 差不多 With the value return from this, which is a one in an awe operation with a two. And yeah, pretty much.
它在里所做的一切 尽管看起来还有很多事情在发生 那只是因为海洋装载机内部的隐避 它基本上是arcy All it does here, even though it looks like there's a lot more going on, that's just because of the obphiscation inside of sea loader. It's basically an arcy for.
里的解密操作 你可以看到1+B 6 a-V 6是计数器 里是V 11 Decryption operation here, you can see a one plus B, six, A-V, six is going to be the counter, and we've got V, eleven here.
严重 十一是一加三 六 Severe, eleven is a one plus three, six.
在种情况下 对于每个循环 它都会覆盖加密的数据 而不是分配新的区域内存 And in that case, what will do is for every loop, it will override the encrypted data. So rather than allocate a new regional memory and then have.
十一exod与V 十二复制到V 十 它将简单地覆盖加密的数据 The eleven exod with V, twelve copied into V, ten, it will simply overrite the encrypted data.
一加三 六等于一口 So a one plus three, six is equal to one bite.
11等于1加6 So the eleven is equal to a one plus a six.
的返回值等于3加上V 10 V 10等于V 9 子结点的返回值 And the return value of this is equal to a three plus V, ten, v, ten is equal V, nine, and the return value of this subartine.
V 9等于V 8 V 8等于8 3加3 7 V, nine is equal to V, eight, and V, eight is equal to eight, three plus three, seven.
B 7等于4加上B 6 B, seven is equal to be four plus B, six.
基本上很多混淆 试图放慢研究速度 你知道 要弄清楚是事实 And it's basically just a lot of obfuscation, trying to slow research down, and you know to figure out that this is in fact.
一种用于解密循环的冰同时也能防止Yara规则在看到一点时触发 An icy for decryption loop as well as to prevent Yara rules triggering when it sees this at this point,
我们很确信它使用了手机加密技术 名字是冰四的地下室 We're pretty confident that it's using Icy phone encryptions. So this name is to Icy Four crypt.
我们可以退出 改成RC 4号 We can back out and changes to RC, four.
正确的 Correct.
再次退出 更改为解密冲突 因为它正在做的 我们可以再次退出 Back out again, changes to decrypt conflict, because that's what it is doing. And then we can back out once again.
构型 让我们选择里所有的数据 向下滚动 So we have our configuration here. Let's select all of the data here, so scroll all the way down.
直到我们得到20字节字符串 Until we get to that twenty bite character string.
里 我们想选择所有些 移动它 Here we are, and we want to select all of that, and then shift it.
现在我们可以把它提取成十六进制数据 So now we can extract it as hex data.
我们要做的是我们要跳到cyberchef实例 我们要看看我们能否在不知道它是否使用RC的情况下解密它 And what we're going to want to do is we're going to jump over to a cyberchef instance, and we're going to see if we can decrypt this without any other knowledge on whether it uses RC, for or not.
我们复制一下 跳到我们的网络厨师 So let's copy that out, jump over to our cyber chef, instance,
粘贴在里 我们想从hecks Pasted in here do we want to do from hecks.
把放到里 选择R-C 四 Put that in there and select R-C. Four.
现在我们要跳回IDA实例并复制20by键 Now we're going to jump back to the IDA instance and copy out this twenty by key.
回到网络大厨的节目中来 Jump back over to Cyber Chef and pace this in.
马上就能看到url了 里有一根弦 So immediately you can see that we now have URLS. We've got this string down here.
它可以是空的5哈希值 也可以是加密密钥 里还有一些其他的值 里有250 3 Which could be an empty five hash, could be an encryption key, and there's a few other values here, so we've got twenty five zero, three here.
得到的 Got.
A-J-H-O 我不确定状态应该是 现在我们知道了构型是如何存储的 A-J-H-O, I'm not sure what this state is supposed to be, so now we figured out how the configuration is stored.
在转移到自动化配置提取开发之前 我们可以继续对通信例程进行简要分析 因此让我们继续并回到IDA We can go ahead and perform a brief analysis on the communications routine before moving over to automated configur extracted development, so let's go ahead and jump back over to IDA.
好的 现在我们要继续简单地看一下通信程序 Okay, so now we're going to go ahead and have a brief look at the communications routine. So.
当我们看配置提取的时候 我们有Deward在的通信功能中被使用 When we were looking at this config extraction, we had this Deward here being used in a possible communications function.
如果我们找到交叉引用 跳转到交叉引用对函数做同样的操作 我们就得到了 So if we find the cross references, jump to the cross reference and do the same for this function, we end up in this.
似乎是包例程 我认为主要是因为简单地传递给函数的值 What seems to be a packet routine, and the reason I think this is mainly because of the values that simply passed into this one function here.
我之前说的是Z加载器 So what I was saying before is the Z loader.
Dropper和后续Mallway从Zeus银行木马中获得了很多灵感 也从泄露的源代码中借用了很多代码 Dropper and the follow up Mallway takes a lot of inspiration from the Zeus banking Trojan, as well as borrowing a lot of code from the leaked source.
如果你还记得 当我们研究算法和类东西时 我们通常首先要找的是 So if you remember, when we look at algorithms and all those sorts of stuff, the first thing we normally look for is.
康斯坦斯 Constance.
在种情况下 我们的值看起来就像它们是特意在那里的 它们不是随机值 因为它们的值是0 0 And in this case, we have values that look like they're specifically meant to be there, so they're not random value, because they will have this one zero, zero. And then the.
数字后 现在 我要做的搜索 Numbers after it. So at this point, what I would go ahead and do is I would search up this.
值 我已经完成了 让我们快速跳到Chrome Value, which I have actually gone and done, so let's go ahead and jump over to Chrome quickly.
我搜索了宙斯 10002 我们在里看到的值 So I've searched up Zeus, and then one zero, zero, zero, two, which is the value that we can see over here.
我在最后加上了沟通 首先出现的是 And then I added communication on the end. So the first thing that comes up is.
一些公司叫宙斯通信公司 第二件事是蜂蜜网上的百科文件 做I-T 我们可以看到 Some company called Zeus Communications. And the second thing that comes up is this Pedia file on Honey Net, do I-T, and we can see that.
当item(1 0 02)被Butmaster指定时 我们得到了item(1 0 03) When item one zero zero two is specified by the Butmaster, we've got item one, zero zero three.
点击它 控制F 10002 So let's click that and control F, one, zero, zero, zero, two, we have.
里有完整的条目列表 1002是僵尸网络的ID A whole list of itemites here, so one, zero, zero, two is the botnet ID.
是购买版本 购买ID 网络延迟 Then we have the bought version, the bought ID, net latency.
我们在里的通信中使用了所有些值 如你所见 它提到了TCP数据包和指挥官控制服务 We have all these values used in the communications here, as you can see, it mentions TCP packets and commander control service, so.
此时 我猜函数与通信例程有关 让我们开始套路 我们已经 At this point, I'm guessing this function is related to the communications routine. Let's jump into this routine here, we've got quite a.
有点麻烦 让我们来命名过去的参数 我们的第论点是 Bit of obiscation, let's go ahead and actually name the arguments past to it. So the first argument in our case is.
未知 第二个参数是ID 让我们把2重命名为ID Unknown, the second argument is the ID, so let's renam a two to ID.
参数 3等于的标志之类的 我们把它重命名为 Argument, three is equal to a possible flag or something, so let's renam that to.
的 Possible.
标志 A 4等于V 12 从函数返回 从配置返回值 Flag, A, four is equal to V, twelve, which is returned from this function, which returns the value from the config.
我猜V 12是我们今天到里的时间 So I'm guessing V, twelve is going to be our day to here.
我们将其命名为data 5长度 里我们看到传入了4 So we name that to data, and then a five is going to be probably the length, so here we see four is passed in.
当我们沿着森林向下滚动时 在那里 As we scroll down forest past, in there.
看起来像另 This one looks like another.
与包结构相关的功能 因为它具有相同的传递值 但次没有规模 Function related to the packet structure, as it has the same values passed. But this time no size.
可以是字符串 它基本上算出了函数内部的大小 但不管怎样 让我们跳回去 里是Renam 两个大小 So that could be a string there, and it basically works out the size inside of the function, but anyway, let's jump back, and here Renam, this two size.
因为对于1是并没有冗长的内容 And because there's nothing really verbose about what a one is will have to.
在函数里面就能算出来了 里没有太多关于1的冗长内容 它是通过函数传入的 如果我们去找交叉引用 Pretty much figure that out inside of this function, so there's not really much verbose about a one here. It's passed in through this function here, so if we go and find cross references.
你看里的调用 1是 V 6 V 6被设为0 不是很有用 You see the call here, a one is, V, six, V, six is set to zero, not really very helpful.
里1作为参数传入 一次 Here a one is passed in as an argument. Again.
V14 里没有K 任何有用的东西 V, fourteen, V, fourteen isn't here K, anything really useful.
进入些函数 Step into these functions.
看起来他在做更多的API哈希 Looks like he's doing some more API hashing.
因为没有其他的解释来解释些函数是 我就直接说 A等于 So because there's no other explanation for what these functions could be, I'm gonna go ahead and say, A one is equal to.
空的记忆 Empty memory.
样做的原因是数据必须存储在某个地方 And the reason for this is because the data has to be stored somewhere.
似乎1被使用得很频繁 它被移到了v 9 And it seems that a one is being used quite a lot, so it's moved into V. Nine.
V 9是在mem复制函数中使用的 数据被复制为9加上V 16加上值 16 V, nine is used in a mem copy function here, so data is copyed to be nine plus V, sixteen plus the value, sixteen.
我假设将是空内存 它将包含我们的包 So I'm gonna assume that this is going to be empty memory, which will contain our packet.
我们可以看到 V fife 它会在20号位置的空内存中获取数据 So we can see, V, fife, it will get the data inside of empty memory at position twenty.
它将执行操作 将添加1和2 如果我们试着看看些值是 It will then perform this, which will add a one and a two. If we try and see what these values are.
从外观上看 你基本上会把些hecks值加在一起 You'll basically add these hecks values together, from the looks of it.
它会返回6 And it will return that to be six. So.
当我们向下滚动时 我们有子程序在子程序中 我们有更多的子程序 我们有一些API哈希在里进行 As we scroll down, we have this subarine here inside this subarine, we have a few more subarines, we've got some API hashing going on here.
一些更模糊的函数 Some more obscated functions.
更多的API散列 More API hashing.
我们把显然是空的记忆移到了第九节 诉九包含 Then we have the obviously empty memory moved into V. Nine. V. Nine contains.
空内存 并最终填入作为函数传入的数据和大小 The empty memory, and that is eventually filled with the data passed in as the function And the size.
我们继续 在里调用函数 用值驱逐D字 V14等于V17加20加V12 We then go ahead and call this function here, which exiles this D word with this value. V, fourteen is equal to V, seventeen plus twenty plus V, twelve.
里减去次子代 也1减去2 a1等于0 V 13等于函数的返回值 Minus a subarine here, which is a one minus a two, A one is zero. V, thirteen is equal to the return value of this function.
因此 执行基本的静态分析并不是最简单的 特别是在Z加载器的情况下 So performing basic static analysis isn't the easiest, especially in the case of Z loader.
很多都是猜测 虽然 因为我们知道它实际上在使用 A lot of it is sort of guesswork, although, because we do have the knowledge that it is in fact using.
你知道 宙斯的代码 或者至少是它的id让我们回到Chrome You know, code from Zeus or at least ids from it Let's jump back over to Chrome.
我们所能做的搜索Zeus的源代码 因为它已经泄露了很长一段时间 And what we can get ahead and do is simply search for the Zeus source code, because it was leaked quite a while ago.
希望我们能从中找到一些有趣的信息 也许他们从它那里窃取了特殊的函数 或者他们在它上面加了自旋 它们在某种程度上是相似的 And hopefully we can find some sort of interesting information from it, maybe they've stolen this particular function from it, or they've put a spin on it, and it's somewhat similar.
或者它是完全不同的 但寻找它也没有害处 Or it could be a completely different, but there's no harm in searching for it.
好 Good.
搜索房间 我们可以看到第一篇文章是我们想要的 而第二篇文章是 So searching the room, we can see that the first post is what we want, and the second post is a.
让她的宙斯特洛伊木马库泄露 在二千零一十一年 Get her repository of the Zeus Trojan horse leaked. In twenty eleven.
我们知道我们要找的是值 我们要处理值10029 So we know what values we're looking for, so we have to deal with the value one, zero, zero, two, nine.
让我们看看能否在跳过库中搜索它 我们也许能找到包生成程序 1029 So let's see if we can search it in this skip up repository, and we might be able to locate the packet generation routine. So one, zero, two, nine.
我们似乎都找不到 We can't seem to locate anything.
但是 在PDF文档中 我们并没有看到10029被使用 我们看到10002被使用 我们把替换成 But then again, in the PDF document, we didn't actually see one zero, zero, two, nine being used, we saw one zero, zero, zero, two being used. So let's replace this with.
另0和2 在里我们可以看到 在源 常见配置讨厌 我们有S-B-C-I-D僵尸网络正在被使用 Another zero and a two, and here we can see that in source, common config that hates, we have this S-B-C-I-D botnet being used.
如果你还记得PDF 我们看到些值被提到 So if you remember back on the PDF, we saw these values being mentioned.
我们继续选择 我们并不想查看冲突 但我们可以复制 粘贴进去 搜索值 So let's go ahead and select this, and we don't really want to look through the conflict, but we can go ahead and copy this out, paste it in and search for this value.
我们有Config定义gate 一些全局的东西 我们有报告 C+Code So we've got Config defines gate, some global stuff, and then we have this report, C plus Code.
进入控件 F 在SBC中粘贴 ID僵尸网络 So stepping into this control, F, again and paste, in the SBC, ID Botnet.
我们将其传递到名为Additem的UTF援助字符串的函数中 We have this being passed into a function called Add item's UTF aid string.
实际上是与储物箱相连的 在一点 是 And this is actually linked to the bin storage. So at this point, this is.
很有趣 我们复制一下 Quite interesting, let's go ahead and copy this out.
我们想要找到bin存储的源代码 我们来搜索一下 And we want to go ahead and find the bin storage source code, so let's search for it.
我们收到报告被储存在H并被储存 点 CPP We've got report been storaged at H and been storage. DOT. CPP,
里有pack函数 So we've got this pack function here.
是结构 我们有Deward大小 咬标志 存储阵列 heather 我们有校验哈希函数 Which is a structure, so we've got Deward size, bite flags, storage array, heather, we have a check hash function.
创建空 我们有additem函数 虽然它不是作为utf字符串的additem 它很接近我们要找的 Create empty, and then we have this add item function, although it's not the add item as utf string, it is close to what we're looking for.
当我们向下滚动时 你会看到与里的函数的相似之处 So as we scroll down, you may be able to see similarities to the function we have over here.
让我们向下滚动一点 即使它有点模糊 我们可以排序看到代码之间的相似之处 Let's just go ahead and scroll down a bit, so even though it is obphiscated a bit, we can sort see similarities between the code.
里我们有newstorage size=binstorage size+item的size+datasize So here we have new storage, size equals bin storage, and then size plus size of item plus data size.
基本上是函数在里 它不会移动大小的仓存储从看起来汗 This is basically what this function here, does it won't move the size of the bin storage from the looks sweat.
变成V5 计算大小加上值 再加上值 Into V five, and then it will calculate size plus this value, plus that value.
那我们就把五加六 Then we'll go ahead and add we five and be six together.
因此 将bin存储的大小与项的大小相加 作为参数传入 我们就得到了 Therefore, adding the size of the bin storage with the size of the item, so passed in as an argument, we then have this.
存储 P等于bin存储 它只是指针 Storage, P is equal to bin storage, so it's just a pointer.
里也是一样 9等于空内存 里我们有变量 它等于P+ We have exactly the same thing here, be nine equals empty memory. And then here we have this item variable, which is equal to P plus.
储物箱的大小 The size of the bin storage.
你可以看到里 V 16等于仓库的大小 V 10等于 And you can see here, V, sixteen is equal to the size of the bin storage, then V, ten is equal to.
空内存 在种情况下就等于平静 基本上是指向binstorage的指针加上V 16 也大小 The empty memory, which in this case is equal to peace. So this is basically a pointer to the binstorage plus V, sixteen, which is the size.
我们有item变量 V 10 我们有 So we have the item variable, which is V, ten, we have the.
P变量 也V 向下滚动9 它似乎在检查flags变量是否等于itemf compressed P variable, which is V, nine scrolling down. It seems to check to see if the flags variable is equal to itemf, compressed.
很是 如果V 7加1等于 This is most likely what this, if V, seven and one is equal to.
在源代码中 它似乎会压缩数据 里似乎没有 继续 它会的 And in this source code, it will seemingly compress the data. It doesn't seem to have that in here, so moving on, it will.
检查它是否等于压缩 在种情况下 它会继续 Check if it isn't equal to compressed, and in which case it will go ahead and.
把数据从数据拷贝到桌面 memm拷贝 Copy the data from data to desk, and that's what this mem copy here is.
向下滚动 我们可以看到更多相似之处 我们有完整的项目大小等于项目的大小加上项目的大小 我们有新的存储容量等于 So scrolling down, we can see some more similarities, so we've got full item size is equal to size of item plus item, that size. And then we have this new storage size is equal to.
储物箱的大小加上整个物品的大小 The bin storage size plus a full item size.
它会检查它是否小于或等于最大大小 它会把ID移动到 And it checks to see if it's less than or equal to the max size, and then what it will go ahead and do is it will move ID into.
进入二进制存储DashID 标志进入二进制存储Dash标志 数据大小被移动到二进制存储Dash 实际大小 Into binstorage Dash ID and then flags into binstorage Dash flags, and then the data size is moved into the binstorage Dash, real size.