Some small reverse programs

admin 2021年9月1日14:34:02评论40 views字数 6093阅读20分18秒阅读模式

Some small reverse programs

Last updated:Nov.21, 2015 CST 02:02:34

Here I'd like to share some small and simple problems in some CTF games. They are much too easy for those advanced players, so actually, this is just something could practice my English...

"Easy"

Load into the IDA and you can go to the kernel function directly, as the images below.

Some small reverse programs
Image 2

Since the password table is hard-coded into the program, a easy way to solve it is enter a random string, which length is 16 chars, and break on every time EIP==0x8048521. Do not forget to modify 74 1A to EB 1A.
However, to let it painful, I decided to look into its algorithm and calculate out a register code.

In the picture above, s is the location of inputed string, while var_C is loop counter i. FYI, sar eax, 1Fh here is equal to shr eax, 1Fh since eax is always a relatively small positive number.
We can write the python version of the check function:

password = [0x76,0x70,0x42,0x4A,0x51,0x5F,
            0x5E,0x5D,0x40,0x41,0x54,0x53,
            0x59,0x5A,0x50,0x56]
inputcode = raw_input()
if len(inputcode)!=16:
    print("Error!")
    exit(-1)
for i in range(len(inputcode)):
    if password[i] != ord(inputcode[i]) ^ ord(inputcode[(((((i+1)>>0x1F)>>0x1C)+(i+1))&0x0F)-(((i+1)>>0x1F)>>0x1C)]):
        print("Error!")
        exit(-1)
print("OK!")

Then it's time to simplify this program. Since i is not big, so the shr will result in zero. Then the if sentence can be changed into:

if password[i] != inputcode[i] ^ inputcode[(i+1)&0x0F]

So we can ensure that this program will treat string as a loop, and do xor between current item and next item. When those values meets, it is the right char.
Apparently, just get a possible string:

password = [0x76,0x70,0x42,0x4A,0x51,0x5F,
            0x5E,0x5D,0x40,0x41,0x54,0x53,
            0x59,0x5A,0x50,0x56]
visiable_chars=list("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-*/.`[email protected]#$%^&()_{}[]|\;:'",<.>")


for init_char in visiable_chars:
    code = [ [] for i in range(16) ]
    flag = 1
    code[0] = ord(init_char)
    for i in range(15):
        code[i+1] = code[i] ^ password[i]
        if chr(code[i+1]) in visiable_chars:
            flag = 1
        else:   
            flag = 0
            break
    if flag:
        if code[0]^code[15]==password[15]:
            for i in range(16):
                code[i]=chr(code[i])
            print(str().join(code))

Here is a possible list:

0F6t>o0n3s2f5l6f
2D4v<m2l1q0d7n4d
4B2p:k4j7w6b1h2b
5C3q;j5k6v7c0i3c
[email protected]`3j0`
7A1s9h7i4t5a2k1a
+]-o%t+u(h)}.w-}
-[+i#r-s.n/{(q+{
*,n$u*t)i(|/v,|
/Y)k!p/q,l-y*s)y
$R"`*{$z'g&r!x"r
(^.l&w(v+k*~-t.~
'Q!c)x'y$d%q"{!q
,Z*h"s,r/o.z)p*z

Let's test it in the real world:
Image 3

"Too easy"

This one is rather easy. Take a look at the kernel code:
Image 4

Just simple one-by-one xor encryption, so this one is much easier

password=[0x2A, 0x23, 0x21, 0x29, 0x27, 0x30, 0x63, 0x63, 0x25, 0x2D, 0x25, 0x2D, 0x25, 0x2D, 0x63, 0x63]
code=""
for i in password:
    code=code+chr(i^0x42)

print(code)

Image 5

"Keygen"

This is quite old, and same as the one I've did during summer camp. I'd like to refer to some old pics in my old report.

Image 6

Obviously, just have a look at pepper(), gaia(), Thor() and hades(). And during the analysis we can see the table is dynamically generated with the following code:

Image 7

Apparently that I used X-rays, since some small tricks of complier should be resolved by the machine itself. Generally, we need to find all integers ranged at 0x3E8~0x7D0 and could be mod by 20 with 3. Then we can use another diagram to show its procedure of judging register code:

Image 8

Finally, time for our keygen and test:

#!/usr/bin/python
from random import randint

if __name__=="__main__":
        start=randint(1000,1900)
        end=2001
        v=start
        while v%20!=3:
                v=v+1
        p=2*(int(v/3)+16)
        if (p<=999):
                p=7*int(v/3)+42
        v=str(v)
        p=str(p)
        q=str(randint(10,99))
        print("da-%s-%sX%s-%s%s-da"%(v,p[:1:-1],p[1::-1],q,q))

Image 9

"CrackMe2.exe"

Run it at first and input a random string, we can see the hint as below:
Some small reverse programs
Load it into IDA and nothing could be found. It's apparently since our IDA is not set to view Unicode strings as default. Press ^U in IDA-Strings, and select "Unicode", we can find that string:
Image 11

Do some jobs(trace call flow) and we can see that when the function at 0x411A20 returns true, our code is right. Another way is that, since it's an GUI program, we can just find it out by checking the xref of GetDlgItemTextW(), which exists in User32.dll. After all, we've reached 0x411A20, and saw the following code(after some modification):

Image 12

And as for detect A:

Image 13

So we need to ensure input[2*i]==table_419080[4*i] and while i in range(0,0x20,2). Then it turns out that detect B is:

Image 14

And that means for every i in range(1,0x1F,2) has ```input[2i]==table_419000[4i].
Considering this program is a unicode one, we can write this python script:

table=[  0x00, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x5F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0xB1, 0x19, 0xBF, 0x44, 0x4E, 0xE6, 
  0x40, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 
  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 
  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

]
code=[chr(0) for i in range(0,0x20)]
for i in range(0,0x20,2):
    code[1*i]=chr(table[0x80+4*i])

for j in range(1,0x1F,2):
    code[1*j]=chr(table[4*j])

print(str().join(code[:0x20]))

FROM :blog.iret.xyz | Author:blog.iret.xyz

相关推荐: 内网肾透实战指北

缘由心血来潮参笔试,做了两套试题发现大部分考的内网渗透的基础命令。例如:控制靶机发布域策略,组策略。添加用户进入组,添加主机进入域的命令(划重点,命令!!!) 作为平时要用问度娘问咕咕从来不记的我,只能空了。话入正题是觉得web渗透学的差不多了(谜之自信.jp…

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年9月1日14:34:02
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Some small reverse programshttps://cn-sec.com/archives/499505.html

发表评论

匿名网友 填写信息