[BUUCTF] REVERSE - [GXYCTF2019] einfaches CPP

[GXYCTF2019] einfaches CPP

annektieren

Schritt

  1. Routineinspektion, 64-Bit-Programm, keine Shell
    Fügen Sie hier eine Bildbeschreibung ein
  2. Versuchen Sie, das Programm auszuführen, um die allgemeine Situation zu sehen
    Fügen Sie hier eine Bildbeschreibung ein
  3. Wenn eine 64-Bit-IDA geladen ist, rufen Sie zuerst die Zeichenfolge ab und zeigen Sie die Informationen zum Flag an.
    Fügen Sie hier eine Bildbeschreibung ein
    Entsprechend der Zeichenfolge zum Flag ist die Schlüsselfunktion
    main () zu lang, sodass ich sie nicht direkt poste. Sehen Sie sich den Abschnitt an nach Abschnitten.
  4. Umgekehrt müssen wir das Programm von unten nach oben betrachten.
    Das erste betrifft die Beurteilung des Flags. Wenn das Urteil von 168 erfüllt ist, ist es das richtige Flag. Das Flag wird mit GXY {} in die
    Fügen Sie hier eine Bildbeschreibung ein
    Funktion sub_7FF603EF19C0 () eingeschlossen. Die Funktion ist zu lang. Es sollte keine Berechnung sein Es sollte eine von Ihnen selbst geschriebene Funktionsfunktion sein. Bei Aufruf in Verbindung mit sub_7FF603EF19C0 Es wird vermutet, dass die Funktion dieser Funktion darin besteht, die Parameterzeichenfolge auszugeben. Gemäß 171 ~ 175 kann vermutet werden, dass die Flag-Zeichenfolge in Block gespeichert ist
  5. Schauen Sie nach und sehen Sie, woher die verschiedenen Parameter im if-Urteil stammen
    Fügen Sie hier eine Bildbeschreibung ein

Der Algorithmus ist etwas chaotisch,
bitte sortieren Sie ihn aus v38 = v18 [2];
v19 = v18 [1];
v20 = v18 [0];

v22 = v19 & v20
v21 [0] = v19 & v20
getv22=v21[0]= v19 & v20=v18[1]&v18[0]

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

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

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

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

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

v27 = v23 | v22 | v25 | v26
getv27 =(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
gebenv30 =(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) zu
erhaltenv183^(v18[1]&v18[0]) | (v18[1]&v18[0]) |(v18[2]& ~v18[1]) | (v18[0]&~v18[1])=4483974544037412639

Schließlich werden alle Ausdrücke durch v18 [0], v18 [1], v18 [2], v18 [3] ersetzt, um sie auszudrücken. Verwenden Sie die z3-Bibliothek, um diese Gleichung zu lösen.
X, y, z, w stehen für 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()))

Fügen Sie hier eine Bildbeschreibung ein

  1. Unser Ziel ist es, den Wert im Block zu finden und weiterhin
    Fügen Sie hier eine Bildbeschreibung ein
    nachzuschlagen, woher die Daten in Version 18 stammen. Die Daten in Version 18 stammen aus Version 11, Version 12, Version 13, Version 14, und der Wert der Daten in Version 11 hängt zusammen zu v40 und v6., Weiter nachschlagen. Das
    Fügen Sie hier eine Bildbeschreibung ein
    Programm ruft zu Beginn sub_7FF603EF19C0 () auf, um die beiden Sätze auszugeben, die wir zu Beginn der Operation gesehen haben. Nach der Vermutung zur Laufzeit besteht die Funktion von sub_7FF603EF1DE0 () darin, uns zuzulassen Daten eingeben und im Block speichern. Gemäß der Vermutung in den Zeilen 51 und 53 sollte v40-5 größer als 25 sein und die 5 sollte GXY {} sein, sodass die Länge des Flags 25 und die Länge des in v40 gespeicherten Flags beträgt.
    Ab Zeile 76, von 76 bis 85, sollten die von uns eingegebenen Daten qword_7FF603EF6048XOR-verknüpft und in Version 6 gespeichert werden.
    Klicken Sie direkt auf qword_7FF603EF6048, um zu sehen, dass der Wert 0 ist, aber eine beliebige Anzahl von 0 XOR selbst ist und es sich falsch anfühlt, aber ich habe es trotzdem versucht. Wenn es gleich 0 ist, sind die Werte von v11 die Werte In v6. Es ist die Zeichenfolge, die wir eingeben, dh die Zahl, die wir mit z3 lösen, ist unser Flag, und es ist
    offensichtlich falsch , sie in eine Zeichenfolge umzuwandeln .
    Fügen Sie hier eine Bildbeschreibung ein
    Daher muss das Programm eine Funktion enthalten, die qword_7FF603EF6048 zuweist.
    Klicken Sie mit der rechten Maustaste auf den Parameter, wählen Sie Sprung zu xref und überprüfen Sie, wo auf den Parameter verwiesen wird. Sie
    Fügen Sie hier eine Bildbeschreibung ein
    werden feststellen, dass den
    Fügen Sie hier eine Bildbeschreibung ein
    beiden Funktionen eine Funktion sub_7FF603EF1720 zugewiesen ist von memcpy und memove, was auffälliger ist. Sie werden häufig zum Kopieren von Bytes verwendet. Daher sollte hier i_will_check_is_debug_or_not nach qword_7FF603EF6048 kopiert werden, wenn qword_7FF603EF6048 = i_will_check_is_debug_or_not, versuchen Sie es
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)

Fügen Sie hier eine Bildbeschreibung ein
Den verstümmelten Code in der Mitte zu sehen, seltsam, kein Trick. Baidu erfuhr, nachdem er anderen Master wp zugesehen hatte, dass der Grund darin besteht, dass die Gleichung mehr als eine Lösung ist und das Ergebnis des zweiten Teils e! P0or_a während des Wettbewerbs ist.

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)

Fügen Sie hier eine Bildbeschreibung ein
Ändern Sie von We1l_D0n äeéb '_ó in e! P0or_a ist das letzte Flag

flag {We1l_D0ne! P0or_algebra_am_i}

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

Dieser Master hat dieses Problem dynamisch gelöst, und es wurde festgestellt, dass es einfacher war, die Logik des Programms herauszufinden. Eigentlich weiß ich nicht, wie man Ida benutzt
Fügen Sie hier eine Bildbeschreibung ein

Ich denke du magst

Origin blog.csdn.net/mcmuyanga/article/details/113628506
Empfohlen
Rangfolge