学完了汇编,刷一下攻防世界新手区的逆向题玩玩
simple-unpack
题目描述
- 菜鸡拿到了一个被加壳的二进制文件
分析如下
- strings filename |grep flag 得到不完整flag
- 说了有壳应该要查壳脱壳
- 查壳为upx,吾爱破解工具包脱壳失败
- 扔到kali里upx -d filename脱壳成功
- strings filename |grep flag得到flag
open-soure
题目描述
- 菜鸡学逆向学得头皮发麻,终于它拿到了一段源代码
- 题目直接给出源码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
if (argc != 4) {
printf("what?\n");
exit(1);
}
unsigned int first = atoi(argv[1]);
if (first != 0xcafe) {
printf("you are wrong, sorry.\n");
exit(2);
}
unsigned int second = atoi(argv[2]);
if (second % 5 == 3 || second % 17 != 8) {
printf("ha, you won't get it!\n");
exit(3);
}
if (strcmp("h4cky0u", argv[3])) {
printf("so close, dude!\n");
exit(4);
}
printf("Brr wrrr grr\n");
unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;
printf("Get your key: ");
printf("%x\n", hash);
return 0;
}分析如下
- 很明显要输入三个参数(为什么是3而不是4可参考C语言argc详解)
- first=0xcafe(有眼就行),注意转换为十进制
- second需要满足不是5x+3并且取余17为8
- third=”h4cky0u”(有眼就行)
题解
- 直接爆破second,编译源程序然后输入三个参数即可
1
2
3
4gcc 1.c -o flag
./flag 51966 25 h4cky0u
Brr wrrr grr
Get your key: c0ffee
- 直接爆破second,编译源程序然后输入三个参数即可
- 直接写出解题脚本如下,运行即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <stdio.h>
#include <string.h>
int main()
{
int first = 51966;
int second = 0;
for (int i = 0;; i++)
{
if (i % 5 != 3 && i % 17 == 8)
{
second = i;
break;
}
}
char third[] = "h4cky0u";
unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(third) - 1615810207;
printf("%x\n", hash);
return 0;
}
- 直接写出解题脚本如下,运行即可
insanity
题目描述
- 菜鸡觉得前面的题目太难了,来个简单的缓一下
题解
- 我直接strings filename|grep flag就出来了。。。应该是非预期
- 非预期解是32位ida打开文件,F5反编译,搜flag字符串就找到了
getit
题目描述
- 菜鸡发现这个程序偷偷摸摸在自己的机器上搞事情,它决定一探究竟
思路分析
反编译得到以下核心代码以s做正向加密得到t,t便是flag1
2
3
4
5
6
7
8
9
10
11LODWORD(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;
}
}
数据段寻找变量s和t,发现
1 | s=c61b68366edeb7bdce3c6820314b7498 |
解题脚本
1 | #include <stdio.h> |
python-trade
题目描述
- 菜鸡和菜猫进行了一场Py交易
思路分析
- 给了个pyc文件,在线反编译pyc文件或者uncompyle得到源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import base64
def encode(message):
s = ''
for i in message:
x = ord(i) ^ 32
x = x + 16
s += chr(x)
return base64.b64encode(s)
correct = 'XlNkVmtUI1MgXWBZXCFeKY+AaXNt'
flag = ''
print 'Input flag:'
flag = raw_input()
if encode(flag) == correct:
print 'correct'
else:
print 'wrong'解题思路
思路很清晰,直接写脚本就行1
2
3
4
5
6
7
8
9
10import base64
s=base64.b64decode("XlNkVmtUI1MgXWBZXCFeKY+AaXNt")
print(s)
def decode(message):
s=''
for i in message:
x=(i-16)^32
s+=chr(x)
return s
print(decode(s))
re1
题目描述
- 菜鸡开始学习逆向工程,首先是最简单的题目
题目分析&题目思路
- IDA发现核心逻辑代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18_mm_storeu_si128((__m128i *)&v5, _mm_loadu_si128((const __m128i *)&word_413E34));
v7 = 0;
v6 = *(_QWORD *)&byte_413E44;
v8 = 0;
printf(&byte_413E4C);
printf(&byte_413E60);
printf(&byte_413E80);
scanf("%s", &v9);
v3 = strcmp((const char *)&v5, &v9);
if ( v3 )
v3 = -(v3 < 0) | 1;
if ( v3 )
printf(aFlag);
else
printf((const char *)&unk_413E90);
system("pause");
return 0;
} - 逻辑很明确,word_413E34的值拷贝到v5,比较v5和v9相等,所以直接看word_413E34,hex中可以直接看到flag
game
题目描述
- 菜鸡最近迷上了玩游戏,但它总是赢不了,你可以帮他获胜吗?
解题分析
- 追踪main函数,发现核心加密过程,简单异或,直接写exp就行
1
2
3
4
5for ( i = 0; i < 56; ++i )
{
*(&v5 + i) ^= *(&v62 + i);
*(&v5 + i) ^= 0x13u;
}
解题脚本
根据加密逻辑及异或的对称性,直接写出解密脚本即可。
1 | # include <stdio.h> |
Hello,CTF
题目描述
- 菜鸡发现Flag似乎并不一定是明文比较
题目分析
- 追踪main函数发现字符串”437261636b4d654a757374466f7246756e”
- 输入的字符会和该字符串做对比,长度为17
- 十六进制转字符串得到flag为CrackMeJustForFun
logmein
题目描述
- 菜鸡开始接触一些基本的算法逆向了
题目分析
- IDA跟随主函数找到核心加密代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18v9 = 0;
strcpy(v8, ":\"AL_RT^L*.?+6/46");
v7 = 0x65626D61726168LL;
v6 = 7;
printf("Welcome to the RC3 secure password guesser.\n", a2, a3);
printf("To continue, you must enter the correct password.\n");
printf("Enter your guess: ");
__isoc99_scanf("%32s", s);
v3 = strlen(s);
if ( v3 < strlen(v8) )
sub_4007C0();
for ( i = 0; i < strlen(s); ++i )
{
if ( i >= strlen(v8) )
sub_4007C0();
if ( s[i] != (char)(*((_BYTE *)&v7 + i % v6) ^ v8[i]) )
sub_4007C0();
} - sub_4007C0函数为密码错误,所以正确的密码指定就是if语句里的判断条件
- 写出exp即可
解题脚本
- 注意一下小端序和BYTE与字符串的转换即可
1
2
3
4
5
6
7
8
9
10
11
12# include <stdio.h>
# include <string.h>
int main()
{
int v6=7;
long long v7=28537194573619560;
char v8[]=":\"AL_RT^L*.?+6/46";
char s[18]="";
for(int i=0;i<strlen(v8);i++)
s[i]= (char)(*((char *)&v7 + i % v6) ^ v8[i]);
printf("%s",s);
}
no-strings-attached
题目描述
- 菜鸡听说有的程序运行就能拿Flag?
题目分析
- 跟着wp走的,基础gdb汇编调试
- 放到IDA分析,找到关键函数名,gdb调试程序,b对函数下断点,r跑起来,n运行到下一步,查看eax寄存器的值,即可得到flag
题解及知识点
1 | gdb filename:开启gdb调试 |
csaw2013reversing2
题目描述
- 听说运行就能拿到Flag,不过菜鸡运行的结果不知道为什么是乱码
题目分析
- IDA分析程序流程
- 正常程序流程为直接跳过解密flag的程序弹窗,所以为乱码
- 使用OD修改程序跳转,先使得程序跳转到解密函数,然后再跳转至弹窗界面即可。
程序题解
- OD打开程序,搜索Flag找到程序定位点
- 00301092下断点
- 修改00301094的je指令跳转到00301096
- 修改003010B7的jmp指令跳转到003010B9
- 将INT3修改为NOP(我的电脑会报错,所以改掉)
- 执行程序得到flag
maze
题目描述
- 菜鸡想要走出菜狗设计的迷宫
题目分析
- 四个if可以判断出来是迷宫类问题
- 根据函数来判断所代表的字符串与方向对应关系
- 寻找地图求解并得到flag即可
解题方案
Label15之中找到地图,为8*8
1 | ****** |
- 右下右右下下左下下下右右右右上上左左
- 转换为flag即可
- nctf{o0oo00O000oooo..OO}
本文作者:
yd0ng
本文链接: https://yd0ng.github.io/2020/11/03/%E6%94%BB%E9%98%B2%E4%B8%96%E7%95%8C%E6%96%B0%E6%89%8B%E9%80%86%E5%90%91%E5%8C%BA%E9%A2%98%E8%A7%A3/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!
本文链接: https://yd0ng.github.io/2020/11/03/%E6%94%BB%E9%98%B2%E4%B8%96%E7%95%8C%E6%96%B0%E6%89%8B%E9%80%86%E5%90%91%E5%8C%BA%E9%A2%98%E8%A7%A3/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!