buu注册机部分题型汇总一 xor-8086-[GXYCTF2019]luck_guy
buu-xor
测试
首先,无法直接运行,其次,OD无法打开,接下来尝试静态调试
关键函数
通过关键字找到主函数
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *v3; // rsi
int result; // eax
signed int i; // [rsp+2Ch] [rbp-124h]
char v6[264]; // [rsp+40h] [rbp-110h]
__int64 v7; // [rsp+148h] [rbp-8h]
memset(v6, 0, 0x100uLL);
v3 = (char *)256;
printf("Input your flag:\n", 0LL);
get_line(v6, 256LL);
if ( strlen(v6) != 33 )
goto LABEL_12;
for ( i = 1; i < 33; ++i )
v6[i] ^= v6[i - 1];
v3 = global;
if ( !strncmp(v6, global, 0x21uLL) )
printf("Success", v3);
else
LABEL_12:
printf("Failed", v3);
result = __stack_chk_guard;
if ( __stack_chk_guard == v7 )
result = 0;
return result;
}
代码解析
关键步骤如下,即进行xor
操作后与global
进行比较
for ( i = 1; i < 33; ++i )
v6[i] ^= v6[i - 1];
v3 = global;
if ( !strncmp(v6, global, 0x21uLL) )
printf("Success", v3);
其中global
的定义如下
__data:0000000100001050 _global dq offset aFKWOXZUPFVMDGH
__data:0000000100001050 ; DATA XREF: _main+10D↑r
__data:0000000100001050 __data ends ; "f\nk\fw&O.@\x11x\rZ;U\x11p\x19F\x1Fv\"M"...
即前半部分f\nk\fw&O.@\x11x\rZ;U\x11p\x19F\x1Fv\"M
因为字符串太长省略了点进去可以看到
__cstring:0000000100000F6E aFKWOXZUPFVMDGH db 'f',0Ah ; DATA XREF: __data:_global↓o
__cstring:0000000100000F6E db 'k',0Ch,'w&O.@',11h,'x',0Dh,'Z;U',11h,'p',19h,'F',1Fh,'v"M#D',0Eh,'g'
__cstring:0000000100000F6E db 6,'h',0Fh,'G2O',0
后半段可得f\nk\fw&O.@\x11x\rZ;U\x11p\x19F\x1Fv\"M#D\x0Eg\x06h\x0FG2O
\x
两位十六进制表示的ASCII码 代表使用ascii编码,python会自动转换为文本对应字符最后一位是
\x00
即字符串结束字符,因为使用""
定义会自带因此没有加上
注册机
和http://poilzero.sipc115.club/index.php/archives/65/不同的在于
本题的每次xor
的修改影响了,下一个值的修改,因此,逆向需要用另一个数组来储存答案
str="f\nk\fw&O.@\x11x\rZ;U\x11p\x19F\x1Fv\"M#D\x0Eg\x06h\x0FG2O"
flag='f'
for i in range(1,len(str)):
flag+=chr(ord(str[i])^ord(str[i-1]))
print(flag)
运行结果:flag{QianQiuWanDai_YiTongJiangHu}
buu-8086
测试
首先,无法直接运行,其次,OD无法打开,接下来尝试静态调试
关键函数
IDA打开后发现只有两个函数,主函数和sub_10030()
,主函数只是调用了这个函数,而sub_10030()
只是不断的调用自己(jmp
自己)死循环。
按空格查看所有的汇编源码发现一段可疑的部分,这部分没转成汇编,只是单纯彰显了这块的原始数据
seg001:0002 db 0B9h, 22h, 0, 8Dh, 1Eh, 2 dup(0), 8Bh, 0F9h, 4Fh, 80h
seg001:0002 db 31h, 1Fh, 0E2h, 0F8h, 8Dh, 16h, 2 dup(0), 0B4h, 9, 0CDh
seg001:0002 db 21h, 0C3h
seg001:001A assume ss:dseg, ds:nothing
seg001:001A
强制转换成汇编(选中后按C
,之后Force-Yes
)得到以下内容,看起来这段就是真正的加密算法了
seg001:0002 mov cx, 22h ; '"'
seg001:0005 lea bx, aUDuTZWjQGjzZWz ; "]U[du~|t@{z@wj.}.~q@gjz{z@wzqW~/b;"
seg001:0009
seg001:0009 loc_10039: ; CODE XREF: seg001:000F↓j
seg001:0009 mov di, cx
seg001:000B dec di
seg001:000C xor byte ptr [bx+di], 1Fh
seg001:000F loop loc_10039
seg001:0011 lea dx, aUDuTZWjQGjzZWz ; "]U[du~|t@{z@wj.}.~q@gjz{z@wzqW~/b;"
seg001:0015 mov ah, 9
seg001:0017 int 21h ; DOS - PRINT STRING
seg001:0017 ; DS:DX -> string terminated by "$"
seg001:0019 retn
代码解析
loop:循环计数器,只要cx大于0就跳转
本处的代码,的含义即把每一个]U[du~|t@{z@wj.}.~q@gjz{z@wzqW~/b;
中的字符与0x1F
进行xor
操作,模拟他的正向操作
注册机
按照思路写注册机
str = "]U[du~|t@{z@wj.}.~q@gjz{z@wzqW~/b;"
flag = ''
for i in str:
flag+=chr(ord(i)^0x1F)
print(flag)
运行结果:BJD{jack_de_hu1b1an_xuede_henHa0}$
,提交去掉$就好了
buu-[GXYCTF2019]luck_guy
测试
首先,无法直接运行,其次,OD无法打开,接下来尝试静态调试
关键函数
main()-->patch_me(v4);-->get_flag()
关键语句如下
case 1:
puts("OK, it's flag:");
memset(&s, 0, 0x28uLL);
strcat((char *)&s, f1); //f1有直接定义,即前半段flag:GXY{do_not_
strcat((char *)&s, &f2); //f2没有定义
printf("%s", &s);
break;
case 2:
printf("Solar not like you");
break;
case 3:
printf("Solar want a girlfriend");
break;
case 4:
v6 = 0;
s = 9180147350284624745LL;
strcat(&f2, (const char *)&s);
break;
case 5:
for ( j = 0; j <= 7; ++j )
{
if ( j % 2 == 1 )
v1 = *(&f2 + j) - 2;
else
v1 = *(&f2 + j) - 1;
*(&f2 + j) = v1;
}
break;
代码解析
首先很容易看到,其中f1有直接定义,即前半段flag:GXY{do_not_
,f2没有定义
puts("OK, it's flag:");
memset(&s, 0, 0x28uLL);
strcat((char *)&s, f1);
strcat((char *)&s, &f2);
printf("%s", &s);
继续分析可以得,另一半flag。
先是初始化字符串,然后进行简单的加密操作就可以得到
s = 9180147350284624745LL;
strcat(&f2, (const char *)&s);
for ( j = 0; j <= 7; ++j )
{
if ( j % 2 == 1 )
v1 = *(&f2 + j) - 2;
else
v1 = *(&f2 + j) - 1;
*(&f2 + j) = v1;
}
其中要说明的是9180147350284624745LL
是字符串,因为计算机中大端小端存储问题(最小单位1byte,也就是八位两个十六进制)。
转换成一般理解的字符串需要如下操作
- 转十八进制
- 以两位十六进制为单位(1byte 1char)转为单个字符
- 字符逆序保存
注册机
后半段
str = 9180147350284624745
hst = hex(str)
st1 = ''
for i in range(len(hst)-1, 2, -2):
tmp = hst[i-1] + hst[i]
print(int(tmp, 16))
st1 += chr(int(tmp, 16))
print("---------------------------")
flag = ''
for i in range(8):
if i % 2 == 1:
tmp = chr(ord(st1[i])-2)
else:
tmp = chr(ord(st1[i])-1)
flag += tmp
print(flag)
解得hate_me}
,加上直接给的前半段GXY{do_not_
得到答案flag{do_not_hate_me}