simple-unpack
下载附件,放进PE分析,发现是upx壳
在linux用upx -d 文件名 的命令脱壳,然后将文件拖进ida
双击flag,得到flag
no-strings-attached
将文件拖入ida
点进authenticate()
函数
看一下decrypt
函数,发现是一个加密函数
这里采用动态调试的方法查看内存中的值,decrypt
函数
结束的位置为0x08048707,在这里下断点
然后运行程序,查看eax的值
可以得到flag
getit
将文件拖入PE,发现是64位的
将其拖入ida进行查看
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v3; // al
__int64 v5; // [rsp+0h] [rbp-40h]
int i; // [rsp+4h] [rbp-3Ch]
FILE *stream; // [rsp+8h] [rbp-38h]
char filename[8]; // [rsp+10h] [rbp-30h]
unsigned __int64 v9; // [rsp+28h] [rbp-18h]
v9 = __readfsqword(0x28u);
LODWORD(v5) = 0;
while ( (signed int)v5 < strlen(s) )
{
if ( v5 & 1 )
v3 = 1;
else
v3 = -1;
*(&t + (signed int)v5 + 10) = s[(signed int)v5] + v3;
LODWORD(v5) = v5 + 1;
}
strcpy(filename, "/tmp/flag.txt");
stream = fopen(filename, "w");
fprintf(stream, "%s\n", u, v5);
for ( i = 0; i < strlen(&t); ++i )
{
fseek(stream, p[i], 0);
fputc(*(&t + p[i]), stream);
fseek(stream, 0LL, 0);
fprintf(stream, "%s\n", u);
}
fclose(stream);
remove(filename);
return 0;
}
查看一些参数的值
t存储的应该就是flag的值,注意要加上0x53
只需要将t的值复现出来就行了
s='c61b68366edeb7bdce3c6820314b7498'
t=''
v5=0
while(v5<len(s)):
if(v5&1):
v3=1
else:
v3=-1
t=t+chr(ord(s[v5])+v3)
v5=v5+1
print(t)
最后运行结果为
所以flag为
SharifCTF{b70c59275fcfa8aebf2d5911223c6589}
csaw2013reversing2
将文件双击运行
将其拖入PE,发现是32位的
将其拖进ida
可以看到第16行应该是弹出flag的值,IpMem
存的应该就是flag的值,但是运行程序之后发现是乱码,这里应该是没有执行sub_401000
函数的原因。
我们用OD打开文件
可以看出,进行if判断后,程序直接跳过了sub_401000函数,然后跳出弹框,显示乱码,所以我们需要对程序进行修改使其执行sub_401000函数。
这里要注意,还需要修改下面的jmp跳转,使其跳转到第二个flag处,因为那里是弹框的函数
最后得到flag
maze
先将文件拖入PE,发现是64位的
将文件放在kali里运行一下
随便输入点东西,失败了
拖进64位ida
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
const char *v3; // rsi
signed __int64 v4; // rbx
signed int v5; // eax
char v6; // bp
char v7; // al
const char *v8; // rdi
__int64 v10; // [rsp+0h] [rbp-28h]
v10 = 0LL;
puts("Input flag:");
scanf("%s", &s1, 0LL);
if ( strlen(&s1) != 24 || (v3 = "nctf{", strncmp(&s1, "nctf{", 5uLL)) || *(&byte_6010BF + 24) != 125 )
{
LABEL_22:
puts("Wrong flag!");
exit(-1);
}
v4 = 5LL;
if ( strlen(&s1) - 1 > 5 )
{
while ( 1 )
{
v5 = *(&s1 + v4);
v6 = 0;
if ( v5 > 78 )
{
v5 = (unsigned __int8)v5;
if ( (unsigned __int8)v5 == 'O' )
{
v7 = sub_400650((_DWORD *)&v10 + 1);
goto LABEL_14;
}
if ( v5 == 'o' )
{
v7 = sub_400660((char *)&v10 + 4, v3);
goto LABEL_14;
}
}
else
{
v5 = (unsigned __int8)v5;
if ( (unsigned __int8)v5 == '.' )
{
v7 = sub_400670(&v10, v3);
goto LABEL_14;
}
if ( v5 == '0' )
{
v7 = sub_400680(&v10, v3);
LABEL_14:
v6 = v7;
goto LABEL_15;
}
}
LABEL_15:
v3 = (const char *)HIDWORD(v10);
if ( !(unsigned __int8)sub_400690(asc_601060, HIDWORD(v10), (unsigned int)v10) )
goto LABEL_22;
if ( ++v4 >= strlen(&s1) - 1 )
{
if ( v6 )
break;
LABEL_20:
v8 = "Wrong flag!";
goto LABEL_21;
}
}
}
if ( asc_601060[8 * (signed int)v10 + SHIDWORD(v10)] != '#' )
goto LABEL_20;
v8 = "Congratulations!";
LABEL_21:
puts(v8);
return 0LL;
}
代码中有O,o,0,.这四个字符,于是猜测可能对应上下左右四个方向,而迷宫应该是个二维数组
bool __fastcall sub_400650(_DWORD *a1)//(_DWORD *)&v9 + 1 'O'
{
int v1; // eax
v1 = (*a1)--;
return v1 > 0;
}
bool __fastcall sub_400660(int *a1)//(int *)&v9 + 1 'o'
{
int v1; // eax
v1 = *a1 + 1;
*a1 = v1;
return v1 < 8;
}
bool __fastcall sub_400670(_DWORD *a1)//&v9 '.'
{
int v1; // eax
v1 = (*a1)--;
return v1 > 0;
}
bool __fastcall sub_400680(int *a1)//&v9 '0'
{
int v1; // eax
v1 = *a1 + 1;
*a1 = v1;
return v1 < 8;
}
分别与O,o,.,0相对应
根据二维数组的性质,可以判断出
O对应左
o对应右
.对应上
0对应下
asc_601060里存放了迷宫
这里应该是一个8*8的迷宫
******
* * *
*** * **
** * **
** * **
* *# *
** *** *
** *
********
我们的目标是走到#,所以flag为
nctf{o0oo00O000oooo…OO}