buuctf re刷题笔记
简单记录两三道刷题的笔记和感悟
1.[FlareOn4]IgniteMe ##:
整体:
void __noreturn start()
{
DWORD NumberOfBytesWritten; // [esp+0h] [ebp-4h] BYREF
NumberOfBytesWritten = 0;
hFile = GetStdHandle(0xFFFFFFF6);
dword_403074 = GetStdHandle(0xFFFFFFF5);
WriteFile(dword_403074, aG1v3M3T3hFl4g, 0x13u, &NumberOfBytesWritten, 0);
sub_4010F0();
if ( sub_401050() )
WriteFile(dword_403074, aG00dJ0b, 0xAu, &NumberOfBytesWritten, 0);
else
WriteFile(dword_403074, aN0tT00H0tRWe7r, 0x24u, &NumberOfBytesWritten, 0);
ExitProcess(0);
}
sub_401050:
int sub_401050()
{
int v1; // [esp+0h] [ebp-Ch]
int i; // [esp+4h] [ebp-8h]
unsigned int j; // [esp+4h] [ebp-8h]
char v4; // [esp+Bh] [ebp-1h]
v1 = sub_401020((int)byte_403078);
v4 = sub_401000();
for ( i = v1 - 1; i >= 0; --i )
{
byte_403180[i] = v4 ^ byte_403078[i];
v4 = byte_403078[i];
}
for ( j = 0; j < 0x27; ++j )
{
if ( byte_403180[j] != (unsigned __int8)byte_403000[j] )
return 0;
}
return 1;
}
sub_401000主要看下这个函数,得到v4
__int16 sub_401000()
{
return (unsigned __int16)__ROL4__(-2147024896, 4) >> 1;
}
发现被写到了内存里,我们利用ida动调下
发现是4
根据sub_401050这个函数,最好要进行一次比对,才会返回1,所以,这个最后比对的值是知道的,直接把这个值跟之前进行异或即可
exp:
# -*- coding:utf-8 -*-
key = [0x0D,0x26,0x49,0x45,0x2A,0x17,0x78,0x44,0x2B,0x6C,0x5D,0x5E,0x45,0x12,0x2F,0x17,
0x2B,0x44,0x6F,0x6E,0x56,0x09,0x5F,0x45,0x47,0x73,0x26,0x0A,0x0D,0x13,0x17,0x48,
0x42,0x01,0x40,0x4D,0x0C,0x02,0x69]
value = []
v4 = 4
for i in range(len(key)-1,-1,-1):
value.append(key[i] ^ v4)
v4 = arr1[-1]
print ('flag{'+''.join([chr(x) for x in key[::-1]])+'}')
2.[MRCTF2020]Xor ##:
![@SR[P1%{]5EO@}Z6)6XRFEE.png][2]
由于没法查看ida伪代码,。所以这里分析了汇编,可以明显看出是简单的异或,这里直接fuzz一下异或是能够求出flag
exp:
str1 = 'MSAWB~FXZ:J:`tQJ"N@ bpdd}8g'
str2 = ''
for i in range(len(str1)):
str2 += chr(i ^ ord(str1[i]))
print(str2)
3.[GWCTF 2019]xxor ##:
__int64 __fastcall main(int a1, char **a2, char **a3)
{
int i; // [rsp+8h] [rbp-68h]
int j; // [rsp+Ch] [rbp-64h]
__int64 v6[6]; // [rsp+10h] [rbp-60h] BYREF
__int64 v7[6]; // [rsp+40h] [rbp-30h] BYREF
v7[5] = __readfsqword(0x28u);
puts("Let us play a game?");
puts("you have six chances to input");
puts("Come on!");
memset(v6, 0, 40);
for ( i = 0; i <= 5; ++i )
{
printf("%s", "input: ");
a2 = (char **)((char *)v6 + 4 * i);
__isoc99_scanf("%d", a2);
}
memset(v7, 0, 40);
for ( j = 0; j <= 2; ++j )
{
dword_601078 = v6[j];
dword_60107C = HIDWORD(v6[j]);
a2 = (char **)&unk_601060;
sub_400686(&dword_601078, &unk_601060);
LODWORD(v7[j]) = dword_601078;
HIDWORD(v7[j]) = dword_60107C;
}
if ( (unsigned int)sub_400770(v7, a2) != 1 )
{
puts("NO NO NO~ ");
exit(0);
}
puts("Congratulation!\n");
puts("You seccess half\n");
puts("Do not forget to change input to hex and combine~\n");
puts("ByeBye");
return 0LL;
}
sub_400686:
__int64 __fastcall sub_400686(unsigned int *a1, _DWORD *a2)
{
__int64 result; // rax
unsigned int v3; // [rsp+1Ch] [rbp-24h]
unsigned int v4; // [rsp+20h] [rbp-20h]
int v5; // [rsp+24h] [rbp-1Ch]
unsigned int i; // [rsp+28h] [rbp-18h]
v3 = *a1;
v4 = a1[1];
v5 = 0;
for ( i = 0; i <= 0x3F; ++i )
{
v5 += 1166789954;
v3 += (v4 + v5 + 11) ^ ((v4 << 6) + *a2) ^ ((v4 >> 9) + a2[1]) ^ 0x20;
v4 += (v3 + v5 + 20) ^ ((v3 << 6) + a2[2]) ^ ((v3 >> 9) + a2[3]) ^ 0x10;
}
*a1 = v3;
result = v4;
a1[1] = v4;
return result;
}
可以发现这里进行了数据的一个异或处理,这里我们只要跟它反向来即可,也就是+变-
sub_400770:
__int64 __fastcall sub_400770(_DWORD *a1)
{
if ( a1[2] - a1[3] == 2225223423LL
&& a1[3] + a1[4] == 4201428739LL
&& a1[2] - a1[4] == 1121399208LL
&& *a1 == -548868226
&& a1[5] == -2064448480
&& a1[1] == 550153460 )
{
puts("good!");
return 1LL;
}
else
{
puts("Wrong!");
return 0LL;
}
}
这个只知道几个变量,这里我们可以用z3求出其余变量
z3.py:
# -*- coding:utf-8 -*-
from z3 import *
a2,a3,a4 = BitVecs('a2 a3 a4',64)
s = Solver()
s.add(a2 - a3 == 2225223423)
s.add(a3 + a4 == 4201428739)
s.add(a2 - a4 == 1121399208)
if s.check() == sat:
m = s.model()
for i in m:
print("%s = %ld" % (i, m[i].as_long()))
求出以后,就可以按照正常操作进行写exp 了
exp:
#include <stdio.h>
int main()
{
unsigned int xorm[6];
xorm[0] = 3746099070;
xorm[1] = 550153460;
xorm[2] = 3774025685;
xorm[3] = 1548802262;
xorm[4] = 2652626477;
xorm[5] = 2230518816;
int i = 0,j=0,sum;
int temp[2] = {0};
int data[4] = { 2,2,3,4 };//unk哪个数字
for (i = 0; i < 5; i += 2)
{
temp[0] = xorm[i];
temp[1] = xorm[i + 1];
sum = 0x458BCD42 * 64;
for (j = 0; j < 64; j++)
{
temp[1] -= (temp[0] + sum + 20) ^ ((temp[0] << 6) + 3) ^ ((temp[0] >> 9) + 4) ^ 0x10;
temp[0] -= (temp[1] + sum + 11) ^ ((temp[1] << 6) + 2) ^ ((temp[1] >> 9) + 2) ^ 0x20;
sum -= 0x458BCD42;
}
xorm[i] = temp[0];
xorm[i + 1] = temp[1];
}
for (i = 0; i < 6; i++)
printf("%c%c%c", *((char*)&xorm[i]+2), *((char*)&xorm[i] + 1), *(char*)&xorm[i]);
}
总结:学到了,逆向的基本操作,以后还要多多刷题,爬.......