https://adworld.xctf.org.cn/task/task_list?type=reverse&number=4&grade=0
https://adworld.xctf.org.cn/task/task_list?type=reverse&number=4&grade=1
新手练习区
open-source(c)
难度系数: 3.0 题目来源: HackYou CTF 题目描述:菜鸡学逆向学得头皮发麻,终于它拿到了一段源代码 题目场景: 暂无 题目附件: 附件1.c
附件1.c
#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;
}
- 可以看出 29 行在计算 key,需要用到 first、second、argv3
- 5-8 行:必须满足输入 4 个参数(exe文件本身是 argv0)即:
1.exe(argv0) argv1 argv2 argv3
- 10-14 行:
atoi
是将 ASCII串 转为 int, first 必须为 0xcafe 16-20 行:second 除 5 不能余 3,除 17 要余 8,用 python 计算:
for i in range(1000):
if i % 5 != 3 and i % 17 == 8:
print(i)
得到:25, 42, 59, 76, …… 取 second = 25
22-25 行:argv3 必须为 “h4cky0u”
- 修改程序计算 key
程序输出:unsigned int hash = 0xcafe * 31337 + (25 % 17) * 11 + strlen("h4cky0u") - 1615810207;
Get your key: c0ffee
insanity(elf)
难度系数: 3.0 题目来源: 9447 CTF 2014 题目描述:菜鸡觉得前面的题目太难了,来个简单的缓一下 题目场景: 暂无 题目附件: 附件1
附件给出一个没有后缀名的文件,拖到 010Editor,可以看出这是一个 ELF 文件
搜索 flag,发现 9447{This_is_a_flag}
python-trade(pyc)
难度系数: 3.0 题目来源: NJUPT CTF 2017 题目描述:菜鸡和菜猫进行了一场Py交易 题目场景: 暂无 题目附件: 附件1.pyc
放到 https://tool.lu/pyc 上反编译
import 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'
分析代码,编写程序解 flag
import base64
s = base64.b64decode('XlNkVmtUI1MgXWBZXCFeKY+AaXNt')
flag = ''
for i in s:
x = (i - 16) ^ 32
flag += chr(x)
print(flag)
flag: nctf{d3c0mpil1n9_PyC}
re1(exe)
难度系数: 4.0 题目来源: DUTCTF 题目描述:菜鸡开始学习逆向工程,首先是最简单的题目 题目场景: 暂无 题目附件: 附件1.exe
拖到 010Editor,搜索 flag,得到 DUTCTF{We1c0met0DUTCTF}
game(exe)
难度系数: 4.0 题目来源: ZSCTF 题目描述:菜鸡最近迷上了玩游戏,但它总是赢不了,你可以帮他获胜吗 题目场景: 暂无 题目附件: 附件1.exe
IDA 打开,查看伪代码 main -> main_0 -> sub_457AB4 -> sub_45E940,发现关键代码
sub_45A7BE("done!!! the flag is ");
v5[0] = 18; v5[1] = 64; v5[2] = 98; v5[3] = 5; v5[4] = 2; v5[5] = 4; v5[6] = 6; v5[7] = 3; v5[8] = 6; v5[9] = 48; v5[10] = 49; v5[11] = 65; v5[12] = 32; v5[13] = 12; v5[14] = 48; v5[15] = 65; v5[16] = 31; v5[17] = 78; v5[18] = 62; v5[19] = 32; v5[20] = 49; v5[21] = 32; v5[22] = 1; v5[23] = 57; v5[24] = 96; v5[25] = 3; v5[26] = 21; v5[27] = 9; v5[28] = 4; v5[29] = 62; v5[30] = 3; v5[31] = 5; v5[32] = 4; v5[33] = 1; v5[34] = 2; v5[35] = 3; v5[36] = 44; v5[37] = 65; v5[38] = 78; v5[39] = 32; v5[40] = 16; v5[41] = 97; v5[42] = 54; v5[43] = 16; v5[44] = 44; v5[45] = 52; v5[46] = 32; v5[47] = 64; v5[48] = 89; v5[49] = 45; v5[50] = 32; v5[51] = 65; v5[52] = 15; v5[53] = 34; v5[54] = 18; v5[55] = 16; v5[56] = 0;
v2[0] = 123; v2[1] = 32; v2[2] = 18; v2[3] = 98; v2[4] = 119; v2[5] = 108; v2[6] = 65; v2[7] = 41; v2[8] = 124; v2[9] = 80; v2[10] = 125; v2[11] = 38; v2[12] = 124; v2[13] = 111; v2[14] = 74; v2[15] = 49; v2[16] = 83; v2[17] = 108; v2[18] = 94; v2[19] = 108; v2[20] = 84; v2[21] = 6;
for ( i = 0; i < 56; ++i ) {
v2[i] ^= v5[i];
v2[i] ^= 0x13u;
}
编写程序求 flag
v5 = [18, 64, 98, 5, 2, 4, 6, 3, 6, 48, 49, 65, 32, 12, 48, 65, 31, 78, 62, 32, 49, 32, 1, 57, 96, 3, 21, 9, 4, 62, 3, 5, 4, 1, 2, 3, 44, 65, 78, 32, 16, 97, 54, 16, 44, 52, 32, 64, 89, 45, 32, 65, 15, 34, 18, 16, 0]
v2 = [123, 32, 18, 98, 119, 108, 65, 41, 124, 80, 125, 38, 124, 111, 74, 49, 83, 108, 94, 108, 84, 6, 96, 83, 44, 121, 104, 110, 32, 95, 117, 101, 99, 123, 127, 119, 96, 48, 107, 71, 92, 29, 81, 107, 90, 85, 64, 12, 43, 76, 86, 13, 114, 1, 117, 126]
for i in range(56):
v2[i] ^= v5[i]
v2[i] ^= 0x13
print(chr(v2[i]), end='')
zsctf{T9is_tOpic_1s_v5ry_int7resting_b6t_others_are_n0t}
Hello, CTF(exe)
难度系数: 3.0 题目来源: Pediy CTF 2018 题目描述:菜鸡发现Flag似乎并不一定是明文比较的 题目场景: 暂无 题目附件: 附件1.exe
IDA 打开,F5 查看伪代码,发现关键代码
int __cdecl main(int argc, const char **argv, const char **envp) {
//...
strcpy(v13, "437261636b4d654a757374466f7246756e");
while ( 1 )
{
//...
if ( !strcmp(v10, v13) )
sub_40134B(aSuccess, v7);
else
sub_40134B(aWrong, v7);
}
//...
}
Hex_to_ascii(437261636b4d654a757374466f7246756e) = CrackMeJustForFun
simple-unpack(elf)
难度系数: 4.0 题目来源: 暂无 题目描述:菜鸡拿到了一个被加壳的二进制文件 题目场景: 暂无 题目附件: 附件1
010Editor 打开发现是 ELF 文件,搜索 flag 得到 flag{Upx_1s_n0t_a_d3liv3r_c0mp4n†ß³Ûy}
,
flag 中不常见字符,提交也不对,说明被混淆了,拖到 exeinfope
看到有 upx 壳,用下面命令脱壳:upx.exe -d 847be14b3e724782b658f2dda2e8045b
再用 010Editor 打开,搜索 flag 得到 flag{Upx_1s_n0t_a_d3liv3r_c0mp4ny}
logmein(elf)
难度系数: 4.0 题目来源: RC3 CTF 2016 题目描述:菜鸡开始接触一些基本的算法逆向了 题目场景: 暂无 题目附件: 附件1
拖入 exeinfope,发现是 64 位 elf
IDA 打开,发现关键代码
void __fastcall __noreturn main(int a1, char **a2, char **a3)
{
size_t v3; // rsi
int i; // [rsp+3Ch] [rbp-54h]
char s[36]; // [rsp+40h] [rbp-50h] BYREF
int v6; // [rsp+64h] [rbp-2Ch]
__int64 v7; // [rsp+68h] [rbp-28h]
char v8[28]; // [rsp+70h] [rbp-20h] BYREF
int v9; // [rsp+8Ch] [rbp-4h]
v9 = 0;
strcpy(v8, ":\"AL_RT^L*.?+6/46");
v7 = 0x65626D61726168LL;
v6 = 7;
printf("Welcome to the RC3 secure password guesser.\n");
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(); // Incorrect password!
for ( i = 0; i < strlen(s); ++i )
{
if ( i >= strlen(v8) )
sub_4007C0(); // Incorrect password!
if ( s[i] != (char)(*((_BYTE *)&v7 + i % v6) ^ v8[i]) )
sub_4007C0(); // Incorrect password!
}
sub_4007F0(); // You entered the correct password!\nGreat job!
}
- 20-21 行:
len(flag) >= len(':\"AL_RT^L*.?+6/46')
- 24-25 行:
len(flag) = len(':\"AL_RT^L*.?+6/46')
√ - 26-27 行:
flag[i] = chr(v7[i%7] ^ v8[i])
- 13、27 行:(BYTE )v7 -> [0x68, 0x65, 0x62, 0x6D, 0x61, 0x72, 0x61](*注意是小端存储) ->
'harambe'
编写程序求 flag
v7 = 'harambe'
v8 = ':\"AL_RT^L*.?+6/46'
for i in range(len(v8)):
print(chr(ord(v7[i % 7]) ^ ord(v8[i])), end='')
flag:RC3-2016-XORISGUD
no-strings-attached(elf)
难度系数: 4.0 题目来源: 9447 CTF 2014 题目描述:菜鸡听说有的程序运行就能拿Flag? 题目场景: 暂无 题目附件: 附件1
32 位 elf,无壳,拖入 ida 反编译
main 函数
int __cdecl main(int argc, const char **argv, const char **envp)
{
setlocale(6, &locale);
banner();
prompt_authentication();
authenticate();
return 0;
}
分析 authenticate() 知 s2 存储 flag
void authenticate()
{
wchar_t ws[8192]; // [esp+1Ch] [ebp-800Ch] BYREF
wchar_t *s2; // [esp+801Ch] [ebp-Ch]
s2 = (wchar_t *)decrypt((wchar_t *)&s, (wchar_t *)&dword_8048A90);
if ( fgetws(ws, 0x2000, stdin) )
{
ws[wcslen(ws) - 1] = 0;
if ( !wcscmp(ws, s2) ) // 比较ws和s2
wprintf(&unk_8048B44); // Success!
else
wprintf(&unk_8048BA4); // Access denied!
}
free(s2);
}
继续分析 decrypt() ,只需提取 s 和 a2 运算即可求 flag
wchar_t *__cdecl decrypt(wchar_t *s, wchar_t *a2)
{
size_t v2; // eax
signed int j; // [esp+1Ch] [ebp-1Ch]
signed int i; // [esp+20h] [ebp-18h]
signed int len_s; // [esp+24h] [ebp-14h]
signed int len_a2; // [esp+28h] [ebp-10h]
wchar_t *dest; // [esp+2Ch] [ebp-Ch]
len_s = wcslen(s);
len_a2 = wcslen(a2);
v2 = wcslen(s);
dest = (wchar_t *)malloc(v2 + 1);
wcscpy(dest, s);
while ( j < len_s )
{
for ( i = 0; i < len_a2 && j < len_s; ++i )
dest[j++] -= a2[i];
}
return dest;
}
shift-e 提取数据,末尾要去掉 4 字节
编写程序求 dest
s = [
58, 20, 0, 0, 54, 20, 0, 0, 55, 20,
0, 0, 59, 20, 0, 0, 128, 20, 0, 0,
122, 20, 0, 0, 113, 20, 0, 0, 120, 20,
0, 0, 99, 20, 0, 0, 102, 20, 0, 0,
115, 20, 0, 0, 103, 20, 0, 0, 98, 20,
0, 0, 101, 20, 0, 0, 115, 20, 0, 0,
96, 20, 0, 0, 107, 20, 0, 0, 113, 20,
0, 0, 120, 20, 0, 0, 106, 20, 0, 0,
115, 20, 0, 0, 112, 20, 0, 0, 100, 20,
0, 0, 120, 20, 0, 0, 110, 20, 0, 0,
112, 20, 0, 0, 112, 20, 0, 0, 100, 20,
0, 0, 112, 20, 0, 0, 100, 20, 0, 0,
110, 20, 0, 0, 123, 20, 0, 0, 118, 20,
0, 0, 120, 20, 0, 0, 106, 20, 0, 0,
115, 20, 0, 0, 123, 20, 0, 0, 128, 20,
0, 0,
]
a2 = [
1, 20, 0, 0, 2, 20, 0, 0, 3, 20,
0, 0, 4, 20, 0, 0, 5, 20, 0, 0,
]
dest = s
j = 0
while j < len(s):
i = 0
while i < len(a2) and j < len(s):
dest[j] -= a2[i]
j += 1
i += 1
for b in dest:
if b > 32:
print(chr(b), end='')