【Writeup】i春秋网络安全领域专项技能赛_Reverse_srcleak

【Writeup】i春秋网络安全领域专项技能赛_Reverse_srcleak

​ 本题给了一个cpp文件,其内容如下:

#include<iostream>
using namespace std;

typedef unsigned int uint;



template <bool Flag, class MaybeA, class MaybeB> class IfElse;

template <class MaybeA, class MaybeB>
class IfElse<true, MaybeA, MaybeB> {
public:
	using ResultType = MaybeA;
};

template <class MaybeA, class MaybeB>
class IfElse<false, MaybeA, MaybeB> {
public:
	using ResultType = MaybeB;
};

template <uint N, uint L, uint R> struct func1 {
	enum { mid = (L + R + 1) / 2 };

	using ResultType = typename IfElse<(N < mid * mid),
		func1<N, L, mid - 1>, func1<N, mid, R> >::ResultType;

	enum { result = ResultType::result };
};

template <uint N, uint L> struct func1<N, L, L> { enum { result = L }; };

template <uint N> struct _func1 { enum { result = func1<N, 1, N>::result }; };









template<size_t Input>
constexpr size_t func2 = (Input % 2) + func2< (Input / 2) >;

template<>
constexpr size_t func2<0> = 0;









template<size_t num>
constexpr size_t func3 = num % 2;









template<uint n, uint m>struct NEXTN {
	const static uint value = ((n % m != 0) * n);
};
template<uint n, uint m>struct NEXTM {
	const static uint value = (m * m <= n ? (m + 1) : 0);
};
template<uint n, uint m>struct TEST {
	const static uint value = TEST<NEXTN<n, m>::value, NEXTM<n, m>::value>::value;
};
template<uint m>struct TEST<0, m> {
	const static uint value = 0;
};
template<uint n>struct TEST<n, 0> {
	const static uint value = 1;
};
template<uint n>struct func4 {
	const static uint value = TEST<n, 2>::value;
};
template<>struct func4<1> {
	const static uint value = 0;
};
template<>struct func4<2> {
	const static uint value = 1;
};











int main(int argc, char**argv) {
	//input 5 uint numbers ,x1,x2,x3,x4,x5
	//the sum of them should be MIN


	cout << func3< func2<x1> > << endl;
	cout << func3< func2<x2> > << endl;
	cout << func3< func2<x3> > << endl;
	cout << func3< func2<x4> > << endl;
	cout << func3< func2<x5> > << endl;

	// output: 1 1 1 1 1


	cout << _func1<x1>::result << endl;
	cout << _func1<x2>::result << endl;
	cout << _func1<x3>::result << endl;
	cout << _func1<x4>::result << endl;
	cout << _func1<x5>::result << endl;

	//output: 963 4396 6666 1999 3141




	//how many "1" will func4<1>,func4<2>,fun4<3>......fun4<10000> ::value  return?
	x6 = count;


	// your flag is flag{x1-x2-x3-x4-x5-x6}
	// if x1=1,x2=2,x3=3,x4=4,x5=5,x6=6
	// flag is     flag{1-2-3-4-5-6}



	return 0;
}

要求比较明确:读懂源码按条件计算得到x1-x6并以-连接即为flag。

笨一点的方法就是改写一下源码写出python脚本爆破出x1-x5,再计算出x6:

x1-x5:

def func2(x):
	if x == 0:
		return 0
	return (x % 2) + func2(x // 2)

def func3(x):
	return x % 2

def func1(N, L, R):
	if L == R:
		return L
	mid = (L + R + 1) // 2
	if N < mid * mid:
		return func1(N, L, mid - 1)
	else:
		return func1(N, mid, R)

def _func1(x):
	return func1(x, 1, x)



if __name__ == '__main__':
	x1_flag = False
	x2_flag = False
	x3_flag = False
	x4_flag = False
	x5_flag = False
	for i in range(10000000, 100000000):
		if func3(func2(i)) != 1:
			continue
		if _func1(i) == 963 and not x1_flag:
			print("x1:",i)
			x1_flag = True
		if _func1(i) == 4396 and not x2_flag:
			print("x2:",i)
			x2_flag = True
		if _func1(i) == 6666 and not x3_flag:
			print("x3:",i)
			x3_flag = True
		if _func1(i) == 1999 and not x4_flag:
			print("x4:",i)
			x4_flag = True
		if _func1(i) == 3141 and not x5_flag:
			print("x5:",i)
			x5_flag = True

x6:

def nextm(n, m):
	if m*m <= n:
		return m+1
	else:
		return 0

def nextn(n, m):
	return (n % m != 0) * n

def test(n, m):
	if n == 0:
		return 0
	if m == 0:
		return 1
	return test(nextn(n, m), nextm(n, m))

def func4(x):
	if x == 1:
		return 0
	if x == 2:
		return 1
	return test(x, 2)


if __name__ == '__main__':
	x6 = 0
	for i in range(1, 5):
		if func4(i*2-1) == 1:
			x6 += 1
	print(x6)

  快一点的话就是由语义和简单的测试可以得出,_func1的输入值是输出值的平方,即x1-x5可以由output的5个数分别平方获取;而x6是1-10000整数中质数的个数。

​ 最终flag:
flag{927369-19324816-44435556-3996001-9865881-1229}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值