DozerCTF re

这个题目出的还行,不错。。。。比赛中做出了三题,刷了1000分,却被两个150 200分的签到题难住了。。。太菜了

  1. Maze
    Maze这类题都是老套路了,不过出题人还是变着花样,想出新点子阿。。。
    首先upx脱壳,之后发现程序内置反调试懒得nop了,干脆静态分析得了
    在这里插入图片描述
    发现我每走一步,我的方向健都会发生变化,同时发现这个迷宫是有插入的,
    于是我想到一个绝妙的点子,只要我把插入的a换成b或0就可以了,同时每走一步方向键按照他换一下就可以了(看的我眼睛都瞎了。。。。。a换b真tm多)
#include<stdio.h>
#include<string.h>

int main()
{int u;
	
	unsigned char op[]="WASD";
	unsigned  char q;
	int i =144;
	int l=0;
	int o=0;
	int r;
	unsigned char C[] =
{
  0x41, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 
  0x41, 0x42, 0x42, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 
  0x41, 0x42, 0x42, 0x41, 0x42, 0x41, 0x0, 0x0, 0x42, 0x42, 0x41, 0x41, 0x00, 
  0x41, 0x42, 0x42, 0x41, 0x42, 0x41, 0x42, 0x41, 0x42, 0x42, 0x42, 0x41, 0x00, 
  0x41, 0x41, 0x41, 0x41, 0x42, 0x41, 0x42, 0x41, 0x42, 0x42, 0x42, 0x41, 0x00,
  0x42, 0x42, 0x42, 0x42, 0x42,  0x41, 0x42, 0x42, 0x42, 0x41, 0x0, 0x0, 0x00, 
  0x42, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x0, 0x42, 0x42, 0x00, 
  0x42, 0x41, 0x42, 0x42, 0x42, 0x42, 0x42, 0x41, 0x41, 0x41, 0x41, 0x0, 0x00, 
  0x42, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, 0x41, 0x42, 0x42, 0x41, 0x42, 0x00, 
  0x42, 0x42, 0x42, 0x42, 0x42, 0x41, 0x42, 0x41, 0x42, 0x42, 0x41, 0x42, 0x00, 
  0x42, 0x42, 0x42, 0x42, 0x42, 0x41, 0x42, 0x41, 0x42, 0x42, 0x41, 0x42, 0x00, 
  0x42, 0x42, 0x42, 0x0, 0x0, 0x41, 0x41, 0x41, 0x42, 0x42, 0x41, 0x45, 0x00
};
unsigned char s[200];
for( r=0;r<150;++r)
s[r]=0;
s[0]=1;

	
	while(i--)
	{
		int tmp1 = l;
		int tmp2 = o;
		if((tmp1<11)&& (s[13*(tmp1+1)+tmp2]==0))
	{
			if(C[13*(tmp1+1)+tmp2]==0x41||C[13*(tmp1+1)+tmp2]==0x45)
	 {
	 
		 
			printf("%c",op[2]);
					char v0 = op[1];
			op[1] = op[3];
			op[3] = v0;
			char v1 = op[0];
			op[0] = op[2];
			op[2] = v1;
			l++;
		
	
			s[13*l+o]=1;
		
			continue;
			
		}
	}
		
		if((tmp1>0)&&(s[13*(tmp1-1)+tmp2]==0))
		if(C[13*(tmp1-1)+tmp2]==0x41||C[13*(tmp1-1)+tmp2]==0x45)
		{	printf("%c",op[0]);
			char v1 = op[0];
			
			op[0] = op[2];
			op[2] = v1;
			
			l--;
			s[13*l+o]=1;
				
			
			continue;
		   
			
		}
		
		if((tmp2>0)&&(s[13*(tmp1)+tmp2-1]==0))
		if(C[13*tmp1+tmp2-1]==0x41||C[13*tmp1+tmp2-1]==0x45)
		{
			printf("%c",op[1]);
			char v0 = op[0];
			op[0] = op[1];
			op[1] = op[2];
			op[2] = op[3];
			op[3] = v0;
			
			o--;
				s[13*l+o]=1;
				
			continue;
		
			
		}
		
		if((tmp2<11)&&(s[13*(tmp1)+tmp2+1]==0))
		if(C[13*tmp1+tmp2+1]==0x41||C[13*tmp1+tmp2+1]==0x45)
		{
			printf("%c",op[3]);
				char v1 = op[3];
			op[3] = op[2];
			op[2] = op[1];
			op[1] = op[0];
			op[0]  =v1;
			o++;
			s[13*l+o]=1;
			
			continue;
			
		}
		
		
		
		

		
	}
}
之后换成MD5j就可以了


  1. vm
    这道题 我一开始是没什么想法的,跟踪流程发现流程有点复杂,于是我瞎输了几个

在这里插入图片描述
于是 察觉 或许是将我的数加密然后比较 于是对我的输入下一个硬件断点 发现了对比的数 和 加密的方法。。。(放的怎么近真的好吗。。。。)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200615210236535.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NDM5MjI5,size_16,color_FFFFFF,t_70`

 >>> a = [0x50 , 0x7b , 0x66, 0x71,0x5e, 0x4f,0x60,0x72,0x67,0x50,0x7b,0x66,0x71,0x5e,0x4b,0x42,0x59,0x4b,0x75,0x5f,0x4b,0x5f,0x7b,0x4b,0x71,0x6d,0x5f,0x65,0x2d,0x69]
>>> s = ""
>>> for i in range(len(a)):
...    d= (a[i]-0xfc)&0xff
...    d = d^0x10
...    s+=chr(d)
... 
>>> print s
DozerCtf{Dozer_VM_is_so_easy!}

  1. Num
    首先,在cutter上 去掉几个指令, 创建一个函数看伪代码

在这里插入图片描述在这里插入图片描述代码太长了。。。就放两张) 之后出题人给了提示题目使用位运算表达加减乘除
百度一下后知道
int add(int a,int b) {
int carry,add;
do{
add = a^b;
carry = (a&b)<<1;
a = add;
b=carry;
}while(carry!=0);
return add; } 表示+

int subtract(int a,int b){
return add(a,add(~b,1));}
表示减

使用z3解方程
>>> from z3 import *
>>> v0 = Int('v0')
>>> v1 = Int('v1')
>>> a3 = Int('a3')
>>> s = Solver()
>>> s.add(a3*2+a3+4*v0-0x13cc==v1)
>>> s.add(8*v0+v0+a3+8*v1-2*v1==0x3518)
>>> s.add(0x1759==2*(v0+a3)+(v0+a3)+v1)
>>> if s.check()==sat:
...    print(s.model())
... 
[v0 = 833, v1 = 871, a3 = 869]

知道07加起来为833,60xf为871,0x10~0x18为869
之后就慢慢解方程了。。。。。。。
不过cutter反编译出来的运算过程是对的,但但参与的数不对,得对应参照看看mips指令找到对应的数才行
方程得一个个解,但都比较简单,大多数都是使用xor的恒等式和位运算的加减乘除,我就说说解的过程中比较特殊的几个函数
fcn.0041a4e4我猜是strcmp事实证明我猜的差不多 比较的字符串有ctf is
比较的位置没看出了于是靠蒙,结果蒙对了。。。。
fcn.0041a4e4

在这里插入图片描述
经过测试是比较两个字符是否相等
接下来的都是一个个解,
最后得到flag Dozerctf{num_is_so_good}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值