0%

Nep欢乐个人赛-RE-二十六进制

菜猫一只,对着大佬们的wp复现(好难啊…我好菜5555)
参考了官方wp和这位大佬的文章
REVERSE-COMPETITION-NEPCTF

题目链接:
链接:https://pan.baidu.com/s/1PzZ7uYlxSHjj9L7-iuWqjQ
提取码:8lw2
复制这段内容后打开百度网盘手机App,操作更方便哦

在这里插入图片描述
无壳,ida32位打开,交叉引用字符串plz input right num:\n:来到sub_4010A0()函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void __noreturn sub_4010A0()
{
__int64 v0; // rax
char Dst; // [esp+0h] [ebp-108h]

memset(&Dst, 0, 0xFFu);
dword_403378 = (int)malloc(8u);
Memory = (void *)dword_403378;
*(_DWORD *)(dword_403378 + 4) = 0;
sub_401020("plz input right num:\n", Dst);
sub_401060("%s", (unsigned int)&Dst);
v0 = atoi64(&Dst); // 将输入的字符转换为整型数字
sub_401120(v0, HIDWORD(v0)); // 对输入进行变换和检查
}

进入sub_401120
这里普及一下
HIDWORD:指的是低位
LODWORD:指的是高位
在这里插入图片描述
关于13行的sub_401F00的解释
在这里插入图片描述
在这里插入图片描述
关于v3==Fb72>&6的解释
我们之前在字符串窗口找到了flag right之类的字样,跳转过去之后发现了最后是判断aFb726
在这里插入图片描述
向上看之后发现
在这里插入图片描述
双击aFb726得到Fb72>&6

查看byte_402194
在这里插入图片描述
2163qwe)(*&^%489$!057@#><A

17行的sub_401160()应该是有比较,比较的内容就是v3

可以写脚本了

1
2
3
4
5
6
7
8
9
10
11
12
arr="2163qwe)(*&^%489$!057@#><A"
v3="Fb72>&6"
flag=[]
for i in range(len(v3)):
v4=chr(ord(v3[i])^7)
index=arr.find(v4)
flag.append(index)
sum=0
for i in range(len(flag)-1,0,-1):
sum=(flag[i]+sum)*26
sum+=flag[0]
print(sum)

跑出来结果是:
在这里插入图片描述
flag:Nep{md5(518100101)}

以下是官方给出的本题的源码

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
源码:
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
/*
进制加密的思路input_data: 518100101
加密后的数据: Fb72>&6
*/
const char jinzhi_table[] = "2163qwe)(*&^%489$!057@#><A";
const int jz = 26;
char key[] = { "Fb72>&6" };
struct node {
char data;
struct node* next;
}*head, * cur_node;
void check_the_flag(); // 检查flag 是否正确
//void wrong();
//void right();
void linklist_add(char i);
void base_conversion(long long int n);
int del_linked(int sum);
int v6 = 0;
int main()
{
char input[255] = { 0 };
long long int x;
head = cur_node = (struct node*)malloc(sizeof(struct node));
cur_node->next = NULL;
printf("plz input right num:\n");
scanf_s("%s", input, 32);
x = _atoi64(input);
base_conversion(x);
return 0;
}
void base_conversion(long long int n)
{
// 进制转换
int i = 0;
char a;
while (n)
{
a = jinzhi_table[n % jz];
n = n / jz;
linklist_add(a ^ 7);
i++;
}check_the_flag();
}
void linklist_add(char i)
{
cur_node->next = (struct node*)malloc(sizeof(struct node));
cur_node->data = i;
cur_node = cur_node->next;
cur_node->next = NULL;
}
void check_the_flag()
{
int i, sum = 0;
struct node* tmp = head;
for (i = 0; i < 8; i++)
{
if (tmp == NULL) {
break;
}
//printf("%c", tmp->data);
if (tmp->data == key[i]) {
sum++;
}
tmp = tmp->next;
}
// 链表释放内存
int code = del_linked(sum);
if (sum != 8) {
/*right();*/
puts("flag is Error!!!");
exit(code);
}
else {
//wrong();
puts("flag is Right!!!, please md5('Nep{you_input_num}') submit th4
flag");
system("pause");
exit(code);
}
}
int del_linked(int sum){
if (head == NULL) {
return -1;
}
int tmp = sum;while (head != NULL) {
cur_node = head;
head = head->next;
free(cur_node);
tmp -= 1;
}
return tmp;
}