[BUUCTF] REVERSE —— [GXYCTF2019] CPP simple

[GXYCTF2019] CPP simple

anexo

paso

  1. Inspección de rutina, programa de 64 bits, sin shell
    Inserte la descripción de la imagen aquí
  2. Intente ejecutar el programa para ver la situación general
    Inserte la descripción de la imagen aquí
  3. Se carga ida de 64 bits, primero recupere la cadena y vea la información sobre la bandera.
    Inserte la descripción de la imagen aquí
    De acuerdo con la cadena sobre la bandera, la función de tecla
    main () es demasiado larga, por lo que no la publico directamente. Mírala en la sección por sección.
  4. A la inversa, debemos mirar el programa de abajo hacia arriba.
    La primera es sobre el juicio de la bandera. Si se satisface el juicio de 168, es la bandera correcta. La bandera está envuelta con GXY {} en la función
    Inserte la descripción de la imagen aquí
    sub_7FF603EF19C0 (). La función es demasiado larga. No debería ser un cálculo .Debería ser una función escrita por usted mismo.Cuando se llama junto con sub_7FF603EF19C0 Se supone que la función de esta función es generar la cadena de parámetros. De acuerdo con 171 ~ 175, se puede adivinar que la cadena de banderas se almacena en Block
  5. Mire hacia arriba y vea de dónde provienen los diversos parámetros en el juicio if
    Inserte la descripción de la imagen aquí

El algoritmo es un poco complicado,
resuélvalo v38 = v18 [2];
v19 = v18 [1];
v20 = v18 [0];

v22 = v19 y
v20 v21 [0] = v19 y v20
obtenerv22=v21[0]= v19 & v20=v18[1]&v18[0]

v23 = v38 & ~
v20 v21 [1] = v23;
obtenerv23 =v21[1]= v38 & ~v20=v18[2]&~v18[0]

v24 = ~ v19;
obtenerv24 = ~v19=~v18[1]

v25 = v38 & v24;
v21 [2] = v38 & v24;
obtenerv21[2] = v38 & v24=v25=v18[2]& ~v18[1]

v26 = v20 &
v24 ; v21 [3] = v26;
obtenerv26 = v20 & v24=v21[3]=v18[0]&~v18[1]

v23 = v21 [1] = 1176889593874
obtenerv18[2]&~v18[0]=1176889593874

v27 = v23 | v22 | v25 | v26
obtenerv27 =(v18[1]&v18[0]) | (v18[1]&v18[0]) |(v18[2]& ~v18[1]) | (v18[0]&~v18[1])=4483974544037412639

V18 = V28 [. 1];
V29 = V18 [2];
V30 & V25 = V18 * | & V29 (V22 | V28 & V18 * ~ | ~ (V28 | V18 *)) = 577031497978884115i64
danv30 =(v18[2]& ~v18[1]) & v18[0] | v18[2] & ((v18[1]&v18[0]) | v18[1] & ~v18[0] | ~(v18[1] | v18[0]))=577031497978884115

v31 = v27 == 4483974544037412639i64;
v27 ^ v18 [3] == 4483974543195470111i64) para
obtenerv183^(v18[1]&v18[0]) | (v18[1]&v18[0]) |(v18[2]& ~v18[1]) | (v18[0]&~v18[1])=4483974544037412639

Finalmente, todas las expresiones se reemplazan con v18 [0], v18 [1], v18 [2], v18 [3] para expresar. Utilice la biblioteca z3 para resolver esta ecuación
x, y, z, w representan v18 [0] ~ v18 [3]

 from z3 import *

x,y,z,w=BitVecs('x y z w',64)

s=Solver()

s.add((~x)&z==1176889593874)
s.add(((z&~x)|(x&y)|(z&(~y))|(x&(~y)))^w==4483974543195470111)
s.add(((z&~y)&x|z&((x&y)|y&~x|~(y|x)))==577031497978884115)
s.add(((z&~x)|(x&y)|(z&~y)|(x&~y))==4483974544037412639)
s.add(((z&(~x)) | (x&y) | y & z) == (((~x)& z)|864693332579200012))

s.check()
m = s.model()
for i in m:
    print("%s = 0x%x"%(i,m[i].as_long()))

Inserte la descripción de la imagen aquí

  1. Nuestro propósito es encontrar el valor en el bloque y continuar buscando para ver de dónde
    Inserte la descripción de la imagen aquí
    provienen los datos en v18. Los datos en v18 provienen de v11, v12, v13, v14, y el valor de los datos en v11 está relacionado a v40 y v6., Continúe buscando. El
    Inserte la descripción de la imagen aquí
    programa llama a sub_7FF603EF19C0 () al principio para generar las dos oraciones que vimos al comienzo de la operación. De acuerdo con la suposición en tiempo de ejecución, la función de sub_7FF603EF1DE0 () es dejarnos introducir datos y almacenarlos en el bloque. Según la conjetura en las líneas 51 y 53, v40-5 debería ser mayor que 25, y el 5 debería ser GXY {}, por lo que la longitud de la bandera es 25 y la longitud de la bandera almacenada en v40.
    Luego, comenzando desde la línea 76, desde la 76 hasta la 85, los datos que ingresamos deben ser qword_7FF603EF6048XORed y almacenados en v6.
    Haga clic directamente en qword_7FF603EF6048 para ver que el valor es 0, pero cualquier número de 0 XOR es él mismo, y se siente mal, pero aún lo probé. Cuando es igual a 0, entonces los valores de v11 son los valores En v6. Es la cadena que ingresamos, es decir, el número que resolvemos con z3 es nuestra bandera, y
    obviamente es incorrecto convertirlo en una cadena .
    Inserte la descripción de la imagen aquí
    Por lo tanto, debe haber una función en el programa que asigne qword_7FF603EF6048.
    Haga clic con el botón derecho en el parámetro, seleccione saltar a xref y verifique dónde
    Inserte la descripción de la imagen aquí
    se hace referencia al parámetro. Encontrará que hay una función sub_7FF603EF1720, que está asignada a las
    Inserte la descripción de la imagen aquí
    dos funciones de memcpy y memove, que es más conspicuo, a menudo se usan para copiar bytes, por lo que aquí debería ser i_will_check_is_debug_or_not copiado a qword_7FF603EF6048, cuando qword_7FF603EF6048 = i_will_check_is_debug_or_not, inténtelo
Dst = 'i_will_check_is_debug_or_noi_wil'
flag=[0x3E,0x3A,0x46,0x05,0x33,0x28,0x6F,0x0D,0x8C,0x00,0x8A,0x09,0x78,0x49,0x2C,0xAC,0x08,0x02,0x07,0x17,0x15,0x3E,0x30,0x13,0x32,0x31,0x06]
s=''
for i in range(len(flag)):
    s+=chr(ord(Dst[i]) ^ flag[i])
    #s+=chr(flag[i])
print(s)

Inserte la descripción de la imagen aquí
Al ver el código distorsionado en el medio, extraño, no hay truco. Baidu aprendió después de ver a otro maestro wp que la razón es que la ecuación es más de una solución, y el resultado de la segunda parte es e! P0or_a durante la competencia.

from z3 import *

x,y,z,w=BitVecs('x y z w',64)

s=Solver()

s.add((~x)&z==1176889593874)
s.add(((z&~x)|(x&y)|(z&(~y))|(x&(~y)))^w==4483974543195470111)
s.add(((z&~y)&x|z&((x&y)|y&~x|~(y|x)))==577031497978884115)
s.add(((z&~x)|(x&y)|(z&~y)|(x&~y))==4483974544037412639)
s.add(((z&(~x)) | (x&y) | y & z) == (((~x)& z)|864693332579200012))

s.check()
m = s.model()
for i in m:
    print("%s = 0x%x"%(i,m[i].as_long()))

w = [0x32,0x31,0x06]
z = [0x08,0x02,0x07,0x17,0x15,0x3E,0x30,0x13]
y = "e!P0or_a"
x = [0x3e,0x3a,0x46,0x05,0x33,0x28,0x6f,0x0d]
Dst = 'i_will_check_is_debug_or_noi_wil'

flag=[0x3E,0x3A,0x46,0x05,0x33,0x28,0x6F,0x0D,0x8C,0x00,0x8A,0x09,0x78,0x49,0x2C,0xAC,0x08,0x02,0x07,0x17,0x15,0x3E,0x30,0x13,0x32,0x31,0x06]
s=''
for i in range(len(flag)):
    s+=chr(ord(Dst[i]) ^ flag[i])
    #s+=chr(flag[i])
print(s)

b=""
for i in range(len(x)):
    b+=chr(ord(Dst[i]) ^ x[i])
print(b)

Inserte la descripción de la imagen aquí
De We1l_D0n, cambie äeéb '_ó a e! P0or_a es la bandera final

flag {We1l_D0ne! P0or_algebra_am_i}

参考wp: https://www.cnblogs.com/LLeaves/p/13522069.html

Este maestro resolvió este problema dinámicamente y se encontró que era más fácil descifrar la lógica del programa. Bueno, en realidad no sé cómo usar ida
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/mcmuyanga/article/details/113628506
Recomendado
Clasificación