Reversing-x64Elf-100
64位ida打开
看if语句,根据i的不同,选择不同的数组,后面的2*i/3选择数组中的某一个元素,我们输入的是a1
直接逆向得到就行
二维字符数组写法:前一个是代表有几个字符串,后一个是每一个字符串长度,会在最后默认有\0
#include<stdio.h>
#include<string.h>
int main()
{char k;int i,j;char flag[18];char str[3][8]={"Dufhbmf","pG`imos","ewUglpt"};for(i=0;i<=11;i++){flag[i]=str[i%3][2*(i/3)]-1;}puts(flag);return 0;
}
//Code_Talkers
666
64位无壳
就是那个enflag里面有双引号,所以处理的时候加一个\,注意的地方
加密的部分
key是12h=18!!!
#include<stdio.h>
#include<string.h>
int main()
{char str[]="izwhroz\"\"\w\"v.K\".Ni";int i,n;char input[20];int key=18;for ( i = 0; i < key; i += 3 ){ /*str[i]= key ^ (input[i] + 6); )str[i+1] = (input[i + 1] - 6) ^ key;str[i+2] = input[i + 2] ^ 6 ^ key;*/input[i]=(str[i]^key)-6;input[i+1]=(str[i+1]^key)+6;input[i+2]=(str[i+2]^key)^6;}puts(input);return 0;
}
//unctf{b66_6b6_66b}
easyRE1
水题
打开就得到flag
lucknum
签到题
reverse_re3
学习:http://t.csdnimg.cn/gd0Pb
找到关键函数
迷宫问题
看wsad
四个sub函数里面有一个数组dword202020
导出数据发现,其中3是起点4是终点并得知数组中数据为按每隔四位取一位
强行解释:导出的数组有2700项元素,恰好202020是675个元素,观察,2700/4=675,每个数据后面会有3个零,所以,数据每四位取一位。
BYTE是无符号char类型,WORD是无符号short型,DWORD是无符号long型
在VC++6.0中,char的1字节,short是2字节,int和long都是4字节,因此可以认为BYTE、WORD、DWORD定义的变量分别是1节,2字节,4字节。
导出的为unsigned char,为一个字节,原来的dWord类型四个字节。
该数组的长度是675 。代码中的dword_202020[225 * dword_202AB0 + 15 * i + j :表示dword_202020可以看成是一个三维数组:dword_202020[3][15][15]。而sub_940中的外循环进行了3次,那就是我们要处理3个二维表(尺寸为15X15)。
1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0,
1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
ddsssddddsssdss
ddsssddddsssdss
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 3, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0,
1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0,
1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0,
1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
dddddsssddddsssaassssddds
dddddsssddddsssaassssddds
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0,
ddssddwddssssssdddssssdddss
ddssddwddssssssdddssssdddss
1000Click
32bits
ida打开
shift f12查找字符串,发现了一堆flag
发现有一个不太一样
这个是正是flag
crypt
明天说,睡觉睡觉
见另一篇博客
happyctf
参考:http://t.csdnimg.cn/5grSX
给了一个pdb文件,不知道干什么用的
记得加载附有的pdb文件,不然可能会显示的不一样
32位ida打开
发现有一堆函数,分析发现大部分都没什么作用,看到那个可疑的字符串那里上面有一个异或函数
#include<stdio.h>
int main()
{int i,n;char ch[]="rxusoCqxw{yqK`{KZqag{r`i";char flag[80];for(i=0;i<50;i++){flag[i]=ch[i]^0x14;}puts(flag);return 0;}
//flag{Welcome_to_Neusoft}
xxxorrr
学习:http://t.csdnimg.cn/ls2Zi
64位ELF文件
看一下sub916函数
就是很疑惑,sub-A90作用和sub916的判断为什么在上面
C 库函数 int atexit(void (*func)(void)) 当程序正常终止时,调用指定的函数 func。您可以在任何地方注册你的终止函数,但它会在程序终止的时候被调用。
下面是 atexit() 函数的声明。
int atexit(void (*func)(void))
- func -- 在程序终止时被调用的函数。
如果函数成功注册,则该函数返回零,否则返回一个非零值。
s1交叉引用发现有一处init函数
先进行此项运算
#include<stdio.h>
int main()
{int i,n;char s1[]="qasxcytgsasxcvrefghnrfghnjedfgbhn";char s2[] ={0x56, 0x4E, 0x57, 0x58, 0x51, 0x51, 0x09, 0x46, 0x17, 0x46, 0x54, 0x5A, 0x59, 0x59, 0x1F, 0x48, 0x32, 0x5B, 0x6B, 0x7C, 0x75, 0x6E, 0x7E, 0x6E, 0x2F, 0x77, 0x4F, 0x7A, 0x71, 0x43, 0x2B, 0x26, 0x89, 0xFE};char in[40];//initfor ( i = 0; i <= 33; ++i )s1[i] ^= 2 * i + 65;//s1与input的字符串异或后=s2for(i=0;i<=33;i++) {in[i]=s1[i]^s2[i];}puts(in);return 0;} //flag{c0n5truct0r5_functi0n_in_41f}
bad_python
根据题目提示少了点 什么,盲猜字节码
补充少的两个字节码,python3.6版本的,记得把后面的E3也补充上
得到py文件
# uncompyle6 version 3.9.0
# Python bytecode version base 3.6 (3379)
# Decompiled from: Python 3.8.2 (tags/v3.8.2:7b3ab59, Feb 25 2020, 23:03:10) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: pyre.py
from ctypes import *
from Crypto.Util.number import bytes_to_long
from Crypto.Util.number import long_to_bytesdef encrypt(v, k):v0 = c_uint32(v[0])v1 = c_uint32(v[1])sum1 = c_uint32(0)delta = 195935983for i in range(32):v0.value += (v1.value << 4 ^ v1.value >> 7) + v1.value ^ sum1.value + k[sum1.value & 3]sum1.value += deltav1.value += (v0.value << 4 ^ v0.value >> 7) + v0.value ^ sum1.value + k[sum1.value >> 9 & 3]return (v0.value, v1.value)if __name__ == '__main__':flag = input('please input your flag:')k = [255, 187, 51, 68]if len(flag) != 32:print('wrong!')exit(-1)a = []for i in range(0, 32, 8):v1 = bytes_to_long(bytes(flag[i:i + 4], 'ascii'))v2 = bytes_to_long(bytes(flag[i + 4:i + 8], 'ascii'))a += encrypt([v1, v2], k)enc = ['4006073346', '2582197823', '2235293281', '558171287', '2425328816', '1715140098', '986348143', '1948615354']for i in range(8):if enc[i] != a[i]:print('wrong!')exit(-1)print('flag is flag{%s}' % flag)
# okay decompiling re.pyc
看着像tea加密
找的解密脚本为什么下面要异或0xfffff00000
解密脚本
#include<stdio.h>
#define u_int unsigned int
int main()
{u_int enc[] = { 4006073346, 2582197823, 2235293281, 558171287,2425328816, 1715140098, 986348143, 1948615354 };u_int k[] = { 255, 187, 51, 68 };for (int i = 0; i < 8; i += 2){u_int delta = 195935983;u_int s1 = delta * 32;for (int j = 0; j < 32; j++){enc[i + 1] -= (enc[i] << 4 ^ enc[i] >> 7) + enc[i] ^ s1 + k[s1 >> 9 & 3];s1 -= delta;enc[i] -= (enc[i + 1] << 4 ^ enc[i + 1] >> 7) + enc[i + 1] ^ s1 + k[s1 & 3];}}char flag[32] = { 0 };for (int i = 0; i < 8; i++){flag[4 * i] = enc[i] >> 24;flag[4 * i + 1] = (enc[i] >> 16) ^ 0xFF000000;flag[4 * i + 2] = (enc[i] >> 8) ^ 0xFF000000;flag[4 * i + 3] = enc[i] ^ 0xFF000000;}for (int i = 0; i < 32; i++){printf("%c", flag[i]);}
}
ereere
32位ida打开看一下字符串、
感觉像base64换表,带入字符串看一下,不对,再仔细分析一下
看RC4函数
开始调用的函数
rc4需要密文和key去解密
RC4+base64换表
需要装一个库
import base64
from Crypto.Cipher import ARC4key = "ScDZC1cNDZaxnh/2eW1UdqaCiJ0ijRIExlvVEgP43rpxoxbYePBhpwHDPJ=="
string1 = "ZYXWVUTSRQPONMLKJIHGFEDCBAabcdefghijklmnopqrstuvwxyz/+9876543210" # string1表示更换后的码表
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" # string2表示原始码表
Str = base64.b64decode(key.translate(str.maketrans(string1, string2))) # Base64解密,bytes型aFlag1233213211 = "flag{123321321123badbeef012}"
flag = ARC4.new(bytes(aFlag1233213211, encoding='utf-8')).decrypt(Str)
print(flag)
手动
import base64flag = ""
key = "ScDZC1cNDZaxnh/2eW1UdqaCiJ0ijRIExlvVEgP43rpxoxbYePBhpwHDPJ=="
string1 = "ZYXWVUTSRQPONMLKJIHGFEDCBAabcdefghijklmnopqrstuvwxyz/+9876543210" # string1表示更换后的码表
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" # string2表示原始码表
print("Base64还原: ", key.translate(str.maketrans(string1, string2))) # 将 key 还原成初始码表加密后的结果
Str = base64.b64decode(key.translate(str.maketrans(string1, string2))) # Base64解密,bytes型
print("Base64解密: ", Str)byte_4A0860 = []
aFlag1233213211 = "flag{123321321123badbeef012}"# rc4_init
for i in range(256):byte_4A0860.append(i)
v4 = 0
v3 = 0
for j in range(256):v5 = byte_4A0860[j]v3 = (v5 + v3 + ord(aFlag1233213211[int(j % len(aFlag1233213211))])) & 0xffbyte_4A0860[j] = byte_4A0860[v3]byte_4A0860[v3] = v5v4 = v4 + 1if v4 >= len(aFlag1233213211):v4 = 0print("s_box:", end=" ")
for j in range(256):print(byte_4A0860[j], end=" ")
print()# rc4_crypt
v4 = 0
v3 = 0
for k in range(len(Str)):v3 = (v3 + 1) & 0xffv4 = (byte_4A0860[v3] + v4) & 0xffv5 = byte_4A0860[v3]byte_4A0860[v3] = byte_4A0860[v4]byte_4A0860[v4] = v5flag += chr(Str[k] ^ byte_4A0860[(byte_4A0860[v3] + byte_4A0860[v4]) & 0xff])print(flag)
easyEZbaby_app
学一手
看不太懂,转一下语言
分为username和password两个部分
username:
"zhishixuebao" md5加密得到:7da5fec345fecde5fdcd641f68e0b6d1
又因为i=i+2所以取7afc4fcefc616ebd
password要求str的长度为15并且经过运算每次都得到字符‘0’
#include<stdio.h>
int main()
{int i,j;char ch;char str[15];for(i=0;i<15;i++){for(str[i]=32;str[i]<128;str[i]++){if(((((255 - i) + 2) - 98) - str[i])=='0')break;}}puts(str);return 0;}
//onmlkjihgfedcba
所以flag{7afc4fcefc616ebdonmlkjihgfedcba}
easyre-xctf
upx -d
少一部分
part1函数
数据是放在栈上的,小端序存储方式存储(高位字节放高地址,低位字节放低地址)。所以这里字符顺序正好是反着的。正过来就是flag{UPX_4n