当前位置:网站首页>[software reverse - solve flag] memory acquisition, inverse transformation operation, linear transformation, constraint solving

[software reverse - solve flag] memory acquisition, inverse transformation operation, linear transformation, constraint solving

2022-07-07 00:46:00 Black zone (rise)

Catalog

One 、 Direct memory access

1.1、 brief introduction :

1.2、 Example :

1.3、 analysis :

Two 、 Carry out inverse transformation operation on the algorithm

2.1、 Example :

3、 ... and 、 Solution of linear transformation

3.1、 brief introduction :

3.2、 Example :

Four 、 Constraint solving

4.1、 brief introduction :

4.2、 Example :


One 、 Direct memory access

1.1、 brief introduction :

Simple case , Directly view the memory to get flag

That is, you only need to set a breakpoint at the place of comparison , Then you can get flag

Pseudo code :

input = get_input()
if(input == calc_flag())
{
        puts(flag is input)
}

1.2、 Example :

main function ( Decompiled code ):

1.3、 analysis :

The loop calculates a dest, Then with the input parameters argv[1] Compare , If equal , be argv[1] Namely flag

Choose to call memcmp Where the breakpoint is , And then run the program . After the breakpoint breaks ,RDI What the register points to
That is to say flag, stay GDB Read from flag



Two 、 Carry out inverse transformation operation on the algorithm

2.1、 Example :

A code of judgment process :

To analyze convert The algorithm of , Then analyze the results and write the corresponding inverse algorithm , adopt reverse_convert(stardard) To find out by means of flag

input = get_input()
if(standard == convert(input))
{
        puts(flag is input)
}


Locate where the program compares :

yes base64 Coded program

First analysis main function , among change Function according to the input input Get one output character string , And then output String and “ms4otszPhcr7tMmz GMkHyFn=” Compare ---> Need to analyze change function


change function ( Decompiled code ):

Variant base64:

Set up a to_string(i) And v22[i] Of map, then , take input Convert to binary string , Every time 6 byte , Convert to an integer , Then look up map, Get the corresponding output bytes


base64 inverse transformation :

import base64
s1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
s2 = 'ELF8n0BKxOCbj/WU9mwle4cG6hytqD+P3kZ7AzYsag2NufopRSIVQHMXJri51Tdv'
dict = {}
for i in range(len(s1)):
        dict[s2[i]] = s1[i]
dict['='] = '='
output = 'ms4otszPhcr7tMmzGMkHyFn='
s3 = ' '
for i in range(len(output)):
        s3 += dict[output[i]]
flag = base64.b64decode(s3)
print flag



3、 ... and 、 Solution of linear transformation

3.1、 brief introduction :

If convert It's a linear transformation , So in output=convert(input) in ,output Of the i Bits can only be input Of the i Bit decided . By acquiring input[i] All possible inputs of the corresponding output output[i], You can find out. input[i].

For this transformation , Single character blasting can be carried out

3.2、 Example :

Provides a cipher Executable programs and ciphertext Ciphertext data . function cipher, You will be asked to enter plaintext , And save the encrypted results to out In file

cipher Program run results


Try to find out when the input is only 1 Bytes are different , The output is only 1 Different bytes

Multiple attempts , It can be determined as a linear transformation


Use single byte blasting

Code :

from zio import *
with open('./ciphertext') as f:
d = f.read()
flag = ' '
for i in range(len(d)):
        for c in range(0x21, 0x80):
                try_input = flag + chr(c)
                io = zio('./cipher')
                io.writeline(try_input)
                io.close()
                f = open('./out', 'rb')
                d2 = f.read()
                if d2[i] == d[i]:
                        flag += chr(c)
                        break
print flag



Four 、 Constraint solving

4.1、 brief introduction :

If output=convert(input) after , need output Satisfy multiple constraints

Usually you choose constraint solving , The constraint solver commonly used is z3.

4.2、 Example :

Run the program , Error dialog box will pop up

use OD load , Lower breakpoint GetWindowsTextA, Press down check key , The program was successfully disconnected

call Stack , You can know that the return address of the function is 0x40bd7b.

stay IDA View in 0x40bd7b Address , It is found that this function is recognized as CWnd::GetWindowTextA, So we have to go back one more layer , Final arrival address 0x4017AD.


0x4017AD Decompile code of function

( Besides judging the length , The requirement is less than 40 Beyond bytes , Also called 3 Subfunctions , Transform the input )

Locate the main judgment logic of the program :

The first function sub_401380( Decompiled code )

conversant base64 character string ---> The function of base64 encryption

The second function sub_401000( Decompiled code )

A subtraction is made for each character 3 The operation of

The third function sub_401040( Decompiled code )


  Need to meet the conditions :

a2[i]+a2[i+1] == v5[i]
a2[9]-a2[20]==22
a2[40]==0

Conditions are difficult to calculate directly , Therefore, the method of constraint solution is adopted to solve

Code :

from z3 import *
import base64
s2 = [151, 130, 175, 190, 163, 189, 149, 132, 192, 188, 159, 162, 131, 99, 168, 197, 151, 151, 164, 164, 152, 166, 205, 188, 1

s1 = [BitVec('s1_%d' % i, 8) for i in range(41)]
s = Solver()
for i in range(39):
        s.add(s1[i]+s1[i+1] == s2[i])
s.add(s1[9] - s1[20] == 22)
s.add(s1[40] == 0)
s3 = ' '
if s.check() == z3.sat:
        m = s.model()
        for i in range(40):
                s3 += chr(m[s1[i]].as_long())
s4 = ' '.join([chr(ord(s3[i])+3) for i in range(len(s3))])
flag = base64.b64decode(s4)
print flag

原网站

版权声明
本文为[Black zone (rise)]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207061650048763.html