BUUCTF Reverse_wp
- easyre
- reverse1
- SimpleRev
- Java逆向解密
- [GXYCTF2019]luck_guy
- [BJDCTF2020]JustRE
- 刮开有奖
- 简单注册器 1
- [GWCTF 2019]pyre 1
- [ACTF新生赛2020]easyre 1
- findit 1
- [ACTF新生赛2020]rome 1
- rsa 1
- login
- CrackRTF 1
- [WUSTCTF2020]level1 1
- [GUET-CTF2019]re 1
- [2019红帽杯]easyRE 1
- [MRCTF2020]Transform 1
- [WUSTCTF2020]level2 1
- [SUCTF2019]SignIn 1
- [ACTF新生赛2020]usualCrypt 1
easyre
一个.exe文件
用DIE看一下,64位
在ida64打开,直接看到flag
reverse1
DIE查看
拖入IDA64
shift+F12寻找flag信息
双击点开,ctrl+x查看引用函数
F5查看伪代码
“this is the right flag"的情况是:
str1和str2两个字符串前v3位数相等
其中str1需要我们输入
双击str2发现str2为{hello_world}
再往上看:
选中数字按R键,将数字转换为字符
意思是将str2中所有o都换成0,故
flag为flag{hell0_w0rld}
SimpleRev
看一下用ida64打开,shift+f12
发现字符串,打开,ctrl+x,找到main,点开,f5反编译打开伪代码
在数字上按r转换成字符,可以理解成这是一个初始界面,关键函数就是这个Decry()了。
这里涉及了一个大小端序的问题,最终输入的字符串就是经过那一行运算后,需要等于text。
这里可以编写脚本了,一个一个找到经过运算等于text对应位置字符的字符,最后拼接为v1
key='adsfkndcls'
text='killshadow'
for i in range(10):
for j in range(128):
if (j>64 and j<91) or (j>96 and j<123):
if chr((j-39-ord(key[i])+97)%26+97)==text[i]:
print(chr(j),end='')
break
Java逆向解密
.class文件,使用idea打开看看,自动反编译了,这里自己分析一下加了注释
逻辑很简单,写脚本
#共18位key,故str也18位
key=[180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65]
for i in range(18):
for j in range(128):
if j+64^32==key[i]:
print(chr(j),end='')
break
[GXYCTF2019]luck_guy
DIE看一下
放入IDA64
看看patch_me()
a1得是偶数才能到get_flag(),接下来看看get_flag()是啥
大概分析注释一下
写流程脚本:
f1='GXY{do_not_'
f2=[0x69,0x63,0x75,0x67,0x60,0x6f,0x66,0x7F]
s=''
for j in range(8):
if j%2==1: f2[j]-=2
else: f2[j]-=1
s+=chr(f2[j])
s=f1+s
print(s)
注意提交flag时将GXY改为flag
[BJDCTF2020]JustRE
或许这个点击就是突破点
DIE看一下
放入IDA,找到特殊字符串
定位到DialogFunc()
这应该就是点击19999次就给flag,而flag就是sprintf(String, " BJD{%d%d2069a45792d233ac}", 19999, 0);这一句了。
将19999和0填入%d处即为输出的flag。
刮开有奖
并不能刮开哈哈
拖入IDA
(呜呜呜呜呜呜呜呜写的好多题昨天关电脑没保存,人傻了呜呜呜,直接放脚本吧)
#include<stdio.h>
int sub(char* a1,int a2,int a3)
{
int result;
int i;
int v5;
int v6;
result=a3;
for(i=a2;i<=a3;a2=i)
{
v5=i;
v6=a1[i];
if(a2<result && i<result)
{
do
{
if(v6>a1[result])
{
if(i>=result)
break;
++i;
a1[v5]=a1[result];
if(i>=result)
break;
while(a1[i]<=v6)
{
if(++i>=result)
goto LABEL_13;
}
if(i>=result)
break;
v5=i;
a1[result]=a1[i];
}
--result;
} while (i<result);
}
LABEL_13:
a1[result]=v6;
sub(a1,a2,i-1);
result=a3;
++i;
}
return result;
}
int main()
{
char v7[]="ZJSECaNH3ng";
sub(v7,0,10);
printf("%s",v7);
}
简单注册器 1
[GWCTF 2019]pyre 1
python逆向直接逆着写脚本即可
[ACTF新生赛2020]easyre 1
findit 1
[ACTF新生赛2020]rome 1
(补完了,想想还是蛮心痛,狠狠点了保存)
rsa 1
RSA咋出现在了REVERSE里哈哈
把公钥拿去分解
在线公钥分解
然后上脚本(p、q是分解而来)
login
打开是网页
这个+13和-26就有rot13的感觉,在线一解出来了
flag{ClientSideLoginsAreEasy@flare-on.com}
这串代码理解一下就是将每个字符后移13位再与’z’或’Z‘比较,若大于就-26
CrackRTF 1
32位无壳,拖入ida
找到关键函数main_0
看一下这个sub_40100A()是什么,跟到了sub_401230(),有关CryptoAPI,查了些资料也学习了其他文章
即sha1(passwd1+@DBApp)=6E32D0943418C2C33385BC35A1470250DD8923A9,先爆破一下
得到123321
看下sub_401019(),跳到了sub_401040(),同上,不过这个是md5加密
这个md5有点难爆破了因为没有说明范围
最后来看sub_40100F(),跳到sub_4014D0()
看了一个大哥说的,这一段代码的含义就是,从AAA文件中查找字符,然后如果没有找到就返回,找到了的话就计算出资源的大小,把资源第一个字符出的指针传给lpBuffer
学到了
使用Resource Hacker工具,确实看到了AAA
(不愿面对。。。又没保存。。。。。。。。。。。。。。。。。。。。。。。。。。)
这几题还是先把脚本放着,以后要是复习了再补上分析吧
这个脚本是把.rtf格式文件和上面这个resource的前六位进行异或(因为密码就是六位)
[WUSTCTF2020]level1 1
这题很简单,就是进行了一系列运算然后得到output,逆着写脚本就好
[GUET-CTF2019]re 1
这题也是逆着写脚本
[2019红帽杯]easyRE 1
这题难,还有两个迷惑性的地方
第一个迷惑处:
迷惑二:十轮base64加密
而真正的flag在这base64的下面,某个“角落”有个常量正在被引用。。。
解题脚本:
[MRCTF2020]Transform 1
进入关键代码,感觉可以直接写脚本
先把代码逻辑捋一下
第二个for循环中,第一个for循环得到的byte_414040需要等于byte_40F0E0(已知),也就是我们现在只需逆第一个for循环
写脚本
[WUSTCTF2020]level2 1
32位UPX壳,先脱一下
IDA打开,额我大为震惊,一开始以为是在搞笑,试了一下发现真在搞笑
[SUCTF2019]SignIn 1
64位无壳
跟进到关键函数
看下sub_96A()
大概过程应该是输入flag,flag经过sub_96A()得到v9(字符串转16进制),v9赋值给v6,v6和v5v4经过__gmpz_powm运算后需要等于v7。
先来看__gmpz_powm(v6, v6, v5, v4);查了一下,是计算v6的v5次方,并对v4取模,这个过程是不是很熟悉,对,就是rsa了,所以这里我们先解密一个rsa
大数分解一下 http://factordb.com
写脚本解密:
[ACTF新生赛2020]usualCrypt 1
IDA打开