reversing.kr

觉得revering.kr上面的题目有些设计得很有意思,加上自己也需要时刻练习,于是决定来做做看。

Easy_Crack

直接拖进ida,进入DialogFunc,WM_COMMAND分支的函数,发现是明文的比较
flag: Ea5yR3versing

Easy_KeygenMe

根据ReadMe.txt,是根据Serial推Name,程序拖入ida,一个简单的算法,对username进行0~2的循环异或,以十六进制打印进buffer里,然后和Serial比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/env python
#-*- coding:utf-8 -*-

serial = '5B134977135E7D13'
ans = ''
xor = [16,32,48]

for i in range(len(serial)/2):
tmp = serial[:2]
tmp = int(tmp,16)
tmp ^= xor[i%3]
ans += chr(tmp)
serial = serial[2:]
print ans

flag: K3yg3nm3

Easy_UnpackMe

这道题目,额,我觉得比较坑,原因是我不造flag要提交什么?
题目流程:首先是输入表重建,然后恢复原oep,即.text段,进入oep,然后进入winmain函数执行,winmain里就是建立一个方框,然后处理消息循环。
然而,始终不明白flag是什么,将内存dump下来,扔ida查看,也发现不了什么有用的东西。最后,flag竟然是oep,orz!
flag:00401150

Music_player

程序是用vb写的,对vb不是很熟悉,但是有弹对话框,上网查vb api,对rtcmsgbox下断,向上回溯,发现EA60即60000,猜测就是1分钟的原因。改值,运行,弹出Run-time error ‘380’:Invalid property value,对RaiseException下断,然后在栈中回溯,找到程序代码,向上查看,改判断条件jge为jle,另存为文件,运行得flag。
flag: LIstenCare

vb:对vbaLenstr,vbastrcmp,vbastrcpy,rtcmsgbox下断

Replace

程序拖进ida,静态不好分析,动态调试,对GetDlgItemInt下断,由于多处call指令,导致栈上返回地址的分布不再正常,之后将运算后的值保存在eax里,对eax内存写(程序非法访问的原因)。写入的值是90,即nop,发现对401071处2个字节码改写即可输出correct(一开始注意到了E8即call,想到会不会call到输出corret的地方,但是无法和90联系。后来又看到最后的retn,想retn到输出位置,发现retun的地方是动态链接库的地址,也没法修改)。

1
2
3
4
5
6
7
8
9
10
11
#include<Windows.h>
#include<stdio.h>

int main()
{
DWORD a = 0x601605CB;
DWORD ans = 0xFFFFFFFF - a + 1 + 0x401071;
printf("%u\n",ans);
system("pause");
return 0;
}

flag: 2687109798

ImagePrc

根据对话框显示,对MessageBox下断,向上回溯,发现LoadResource,使用Resource Hacker打开程序,发现一个文件。动态调试程序,在LoadResource后下断,发现Load的文件和资源中一致,且未发生改动,而后直接使用资源与另一地址处内容比较。再次运行程序,发现是一个绘图程序,猜测资源里的应该是标准图像。使用PIL库求解。
ImagePrc

1
2
3
4
5
6
7
8
9
10
from PIL import Image

width = 200
height = 150

fp = open('resource', 'rb')
data = fp.read()
im = Image.frombytes('RGB', (width, height), data)
im = im.transpose(Image.FLIP_TOP_BOTTOM)
im.save('result.jpg','jpeg')

flag: GOT

Position

用C++写的MFC程序,程序使用CSimpleString类的GetAt方法获得对应下标的字符,用户名的前两个字符作运算以后和密码的前五个字符作比较,后两个字符作运算以后和密码的后五个字符作比较。我使用爆破的方式求解,脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!usr/bin/env python
#-*- coding:utf-8 -*-

s = '76876-77776'
s1,s2 = s.split('-',1)
ans = ''

for u1 in range(97,123):
for u2 in range(97,123):
for u3 in range(97,123):
for u4 in range(97,123):

u1_1 = (u1 & 1) + 5;
u1_5 = ((u1 >> 4) & 1) + 5;
u1_2 = ((u1 >> 1) & 1) + 5;
u1_3 = ((u1 >> 2) & 1) + 5;
u1_4 = ((u1 >> 3) & 1) + 5;

u2_1 = (u2 & 1) + 1;
u2_5 = ((u2 >> 4) & 1) + 1;
u2_2 = ((u2 >> 1) & 1) + 1;
u2_3 = ((u2 >> 2) & 1) + 1;
u2_4 = ((u2 >> 3) & 1) + 1;

u3_1 = (u3 & 1) + 5;
u3_5 = ((u3 >> 4) & 1) + 5;
u3_2 = ((u3 >> 1) & 1) + 5;
u3_3 = ((u3 >> 2) & 1) + 5;
u3_4 = ((u3 >> 3) & 1) + 5;

u4_1 = (u4 & 1) + 1;
u4_5 = ((u4 >> 4) & 1) + 1;
u4_2 = ((u4 >> 1) & 1) + 1;
u4_3 = ((u4 >> 2) & 1) + 1;
u4_4 = ((u4 >> 3) & 1) + 1;

if (u1_1 + u2_3 == ord(s1[0]) - ord('0') and u1_4 + u2_4 == ord(s1[1]) - ord('0') and u1_2 + u2_5 == ord(s1[2]) - ord('0') and u1_3 + u2_1 == ord(s1[3]) - ord('0') and u1_5 + u2_2 == ord(s1[4]) - ord('0') and u3_1 + u4_3 == ord(s2[0]) - ord('0') and u3_4 + u4_4 == ord(s2[1]) - ord('0') and u3_2 + u4_5 == ord(s2[2]) - ord('0') and u3_3 + u4_1 == ord(s2[3]) - ord('0') and u3_5 + u4_2 == ord(s2[4]) - ord('0')):
ans = chr(u1) + chr(u2) + chr(u3) + chr(u4)
if ans[3] == 'p':
print ans

得到4组解:bump cqmp ftmp gpmp,一开始提交的ftmp,发现不对,但是程序是显示correct的,换bump提交成功!

flag: bump

Direct3D_FPS

一个射击游戏,用ida打开FPS.exe程序,搜索字符串,发现Game Clear!字符串,如果成功,某个地址间隔132的数组里的值要全不为1,对该数组交叉引用,发现置数组中值为0的位置,结合玩游戏的过程,猜测数组dword_409194为我们射击的对象,monster,数组dword_409190为monster_life,射击对象的生命值,每射中一次,减2的生命,将一次减2的生命改成减100(怪物生命100),每死一只怪物,程序对最后打印的加密字符串byte_407028解密一个字符。修改完程序,进行游戏,把怪物全部杀死,发现字符串并没有解密完,还差最后两个字符,应该怪物都杀死了,想不到其他点,由于是简单的异或,于是在动态调试下手解最后两个字符,得到0和m,把解密的字符串拼起来,得到flag。

flag: Thr3EDPr0m

ransomware

run.exe加密了file文件,用ida打开,要解析很长时间(401000处代码不用管),直接看对文件操作的部分,程序对file文件进行了循环的密钥异或,但是程序里没有密钥,十六进制工具打开file,观察文件结尾是循环的字节,猜测文件结尾原来都是00,写脚本得解密密钥letsplaychess,运行run.exe解密文件,解密后的文件是一个可执行文件,运行得flag。

flag: Colle System

Easy ELF

确实很easy……直接拖入ida,不是明文比较就是简单异或。

flag: L1NUX

Twist1

使用单步向下的方法,od手拖外面的壳后,用ida查看,发现之后的代码是被动态加密的,还是只能用od调试。逆向过程中碰到大量的自解代码,花指令,一些变化栈的call,retn等操作,还有反调试,给我的印象就是:程序代码分散式地干扰逆向者,会比较花费逆向者的时间,password的比较倒比较简单,不过也是分散开来的,都是一些简单的异或比较,和移位比较。出题人的手法很值得学习,汇编指令是相当的熟啊!逆向过程只要使用od一直往下调,下了断点的地方,在执行以后,记得取消断点,碰到程序异常退出,就退回去找条件分支,改判断条件就行,记得改了之后还要改回来,说不定程序在哪又检测了呢?或者是改地址处的字节码呢?

flag: RIBENA

WindowKernel

使用管理员权限运行程序,开启enable按钮,往对话框输入时的处理在sys文件里,根据DeviceIoControl的第二个参数dwIoControlCode,当dwIoControlCode为0x2000时,进行check操作,在sys文件里alt + I 搜索0x2000,找到关键返回值的地方,对dword_13024交叉引用,找到了三层算法处理过程,并不复杂,每次从READ_PORT_UCHAR读一个字符,放到al里,调试的时候找到DriverEntry,然后一路跟进,在这里下断点就好,整理出一个a-z的table表,写脚本得到flag:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/env python
#-*- coding:utf-8 -*-

index = {0x9e:'a',0xb0:'b',0xae:'c',0xa0:'d',0x92:'e',0xa1:'f',0xa2:'g',0xa3:'h',0x97:'i',0xa4:'j',0xa5:'k',0xa6:'l',0xb2:'m',0xb1:'n',0x98:'o',0x99:'p',0x90:'q',0x93:'r',0x9f:'s',0x94:'t',0x96:'u',0xaf:'v',0x91:'w',0xad:'x',0x95:'y',0xac:'z'}
compare_table1 = [0xA5,0x92,0x95,0xB0,0xB2,0x85,0xA3,0x86,0xB4,0x8F,0x8F,0xB2]
ans = ''

for i in range(len(compare_table1)):
if i > 3 and i <= 7 :
compare_table1[i] ^= 0x12
elif i > 7:
compare_table1[i] ^= 0x12
compare_table1[i] ^= 0x5

for j in range(len(compare_table1)):
tmp = index[compare_table1[j]]
ans += tmp

print ans

flag: keybdinthook

之前不会内核调试,这道题还是学会了很多的,23333!

AutoHotKey1

根据提示,需要找到两个md5值,然后解密。upx脱壳,运行出现”EXE corrupted”,搜索字符串,定位sub_4508C7这个函数,进入分析,程序取了自身的最后8个字节。验证的第一关,进行计算后的4个字节的值异或0xAAAAAAAA要与取的最后8个字节中后4个字节相同,然后以取的最后8个字节中前4个字节为偏移,从程序开头偏移前4个字节的大小,取16个字节和程序一处硬编码的值A3484BBE986C4AA9994C530A86D6487D比较。
AutoHotKey1
比较成功则解密一串16进制值,得到第一串md5值:220226394582d7117410e3c021748c2a,网上解密得isolated。我们只要在程序里搜索那串比较的十六进制值,然后将其偏移填在最后8-5字节的位置,然后根据程序计算结果得到最后4字节,覆盖原来的最后4字节即可通过第一关。
再次运行,可以进行输入,使用Resource_hacker定位id为201的对话框,在ida中找到GetDlgItemText下断。
AutoHotKey2
对存储字符串的buffer下读写断点,f9运行,程序自行断下,发现了一串比较的md5值:54593f6b9413fc4ff2b4dec2da337806,解密得pawn。拼起来就是flag,开始拼反了,提交了不对,orz。

flag: isolated pawn

CSHOP

额,这道题,只想用3个英文字母代替我现在所有的心情->orz!程序是一个.net程序,使用Reflector打开,对代码进行反编译,找到_Click(Object,EventArgs),发现一些字符串,运行程序,敲击回车或者空格,出来一串字符串,但是它竟然就是flag。

flag: P4W6RP6SES

PEpassword

这道题出的还是很有想法的,只是我的大脑没有转过弯来,对WM_COMMAND下断点,找到了消息处理函数,发现了esi存储着我们输入的字符串,对字符串下硬件访问断点,发现了对字符串的处理过程。程序根据我们的输入,进行了一个运算,运算结果要与一个4字节相等,jne改成je过了这个check,因为爆破基本不现实,后面两次运算,一次产生我们后面解密401000处代码用到的ebx,一次产生eax,如果输入的字符串正确,就能实现对401000处代码的正确解密,得到password。一开始想到爆破不可能,基本没有了思路,卡了很长时间。后来猜测origin.exe的开头字节可能就是解密后的字节,而加密以后的我们是知道的,二者进行简单的异或,就可以得到第一次的eax和以后正确的eax值,通过第一次正确的eax和第二次正确的eax,我们可以爆破第一次正确的ebx,从而更改寄存器的值,让401000处代码正确解密。获取第一次正确的ebx代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include<stdio.h>
#include<Windows.h>

int main(int argc,char *argv[])
{
BYTE cipher[8] = {0x17,0x2E,0xE6,0xB6,0x05,0x7E,0x0C,0x0D};
BYTE plaintext[8] = {0x81,0xEC,0x4C,0x01,0x00,0x00,0x56,0x57};
BYTE eax_byte[8] = {0,};
for(int i=0;i<8;i++)
{
eax_byte[i] = cipher[i] ^ plaintext[i];
}
DWORD *eax_dword = (DWORD *)eax_byte;
DWORD first_eax = eax_dword[0];
DWORD second_eax = eax_dword[1];
printf("%X %X\n",first_eax,second_eax);
DWORD eax_value = 0;
for(int i=1;i<0xFFFFFFFF;i++)
{
//printf("0x%X\n",i);f
__asm
{
mov eax,first_eax
mov ebx,i
mov cl,al
rol ebx,cl
xor eax,ebx
mov cl,bh
ror eax,cl
add ebx,eax
mov eax_value,eax
}
if(eax_value == second_eax)
{
printf("0x%X\n",i);
}
}
system("pause");
return 0;
}
//ebx
//0xA1BEEE22
//0xC263A2CB
//eax
//0xB7AAC296

PEpassword1

爆破结果有两组值,第二组0xC263A2CB正确,得到flag。

PEpassword2

flag: From_GHL2_!!

HateIntel

mach-o文件,arm架构,使用ida打开,可以反编译,搜索字符串”Input key”,简单的逻辑运算,然后作比较,脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include<stdio.h>
#include<Windows.h>
#include<string.h>

int main()
{
char ans[29] = {0,};
int j;
BYTE compare_Byte[29] = {0x44,0xF6,0xF5,0x57,0xF5,0xC6,0x96,0xB6,0x56,0xF5,0x14,0x25,0xD4,0xF5,0x96,0xE6,0x37,0x47,0x27,0x57,0x36,0x47,0x96,0x03,0xE6,0xF3,0xA3,0x92,0x00};
for(int i=0;i<29;i++)
{
for(int x=32;x<127;x++)
{
j = x;
//printf("%d\n",j);
for(int q=0;q<4;q++)
{
j = j << 1;
if(j & 0x100)
{
j |= 1;
}
}
//system("pause");
if((unsigned __int8)j == compare_Byte[i])
{
printf("%d: %c\n",i,x);
strcat(ans,(char *)&x);
break;
}
}
}
printf("%s\n",ans);
system("pause");
return 0;
}

flag: Do_u_like_ARM_instructi0n?:)

AutoHotKey2

这道题目和AutoHotkey1的思路一样,修改了pe文件之后,直接运行,出现冰与火之歌的一段描述,让你根据描述猜这个人是谁,百度一下知道是琼恩·雪诺,答案就是这个人名字的小写,去掉空格。

jonsnow

flag: jonsnow

SimpleVM

这道题目还是让自己涨了不少姿势,没有白忙活!23333,首先是linux下的加壳程序,让它直接运行,ida远程attach,然后dump代码段的内存,dump代码如下:

1
2
3
4
5
6
7
8
9
10
11
#include <idc.idc>

static main(void)
{
auto i,fp;
fp = fopen("f:\\dump.dex","wb");
for(i=0x8048000;i<0x804C000;i++)
{
fputc(Byte(i),fp);
}
}

虽然以前就知道idc和python的ida脚本,但是都很少用,这次需要dump内存,Windows系统下dump内存工具很多,但是linux我就不是很熟悉了,想到用ida去dump内存,dump下来的代码段没有VM加壳,庆幸只有外层加了,23333。简单分析了一下程序,程序需要root权限,fork了子进程和父进程,利用管道进行交互,子进程得到输入的数据,然后写到管道里,父进程从管道里读数据,进行验证。
首先,我尝试去分析代码的逻辑,脑补之后发现这个200大小的数组,我实在是看不出他是什么规律,也不像是迷宫之类的东西,但是密钥长度一定小于等于7(个人脑补的结论)。想了想,想尝试爆破,把代码copy了放到vs上跑,果然跑不出来,光是跑遍5位的密码就已经吃力得不行了。果断放弃。上网搜索题解,发现了他人的思路是pintools边信道攻击,下面的笔记主要是记录一下边信道攻击。

pintools边信道攻击利用原理

pintools之前就接触过,但是没想过能利用到CTF上面来,自己学习pintools也就想到能直接打印内存,绕过反调试之类的,感觉用处不是很大,还不如直接用ida动调,觉得这个动态插桩工具好像没法应用到CTF上来,不过,这题着实让自己开眼了!
刚接触pintools的人都知道,pintools最简单的一个示例就是指令计数,但是思维也仅限于指令计数而已,但是边信道攻击很巧妙,恰恰利用了这个最简单的用法。如果程序的check是一个一个字符的情况,每通过一个字符或者一部分字符就能继续执行下去,那么程序执行的指令数必然会有大的增加,而pintools就可以通过执行指令数的激增来判断输入的字符是否是正确的字符,从而一个个字符地爆破,把很大数量级的爆破问题化解成为从前往后验证字符每一位的问题,而一个字符的范围不过10的平方而已。利用这个原理,写脚本进行爆破,最终得到flag。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/usr/bin/env python
#-*- coding:utf-8 -*-

import popen2,string

INFILE = "fx"
CMD = "./pin -t source/tools/ManualExamples/obj-ia32/inscount1.so -- ./SimpleVM <" + INFILE

def execlCommand(command):
fin,fout = popen2.popen2(command)
result1 = fin.readline()#获取程序自带打印信息,wrong或者correct
print result1
result2 = fin.readline()#获取pintools打印的信息
print result2
fin.close()

choices = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#$%&'()*+,-./:;<=>?@[\]^_`{|}~"

def writefile(data):
f = open(INFILE,'w')
f.write(data)
f.close()

for entry in range(0,len(choices)):
key = 'i' + choices[entry:entry+1]#一个一个字符测试
print ">",key
writefile(key)
execlCommand(CMD)

爆破过程如下图:

SimpleVM1
SimpleVM2
SimpleVM3
SimpleVM4
SimpleVM5
SimpleVM6
SimpleVM7

flag: id3*ndh

x64 Lotto

64位的windows程序,拖入ida简单分析,输入的6个数和随机产生的6个数比较,这里直接patch掉就好,如下图:

Lotto1

后面对硬编码的字符进行两次异或处理,然后自动输出结果,所以我们只需要简单patch程序,然后自动运行就可以得到flag。

Lotto2

flag: from_GHL2_-_!

Csharp

用dnspy打开.net程序,点击main函数里的form1()函数,功能是对MetMett方法进行解密(由于直接点击MetMett函数,显示反编译错误),需要动态执行,解密MetMett方法。在MetMetMet方法里取了我们输入的字符串,作base64encode然后进行了一次比较,比较的东西应该就在加密的方法里。使用dnspy动态调试,在解密完的地方下断,应该就能看到解密完的函数。但是我都dnspy看不到MetMetM方法的指针,没法直接找到解密以后的内存,很是尴尬,于是只有手动找解密的开头和结尾,将加密的部分抠出来,然后用脚本解密,再粘贴到MetMetM的方法上覆盖,保存文件,重新使用dnspy打开,看到比较的代码,写脚本获得flag,脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#!/usr/bin/env python
#-*- coding:utf-8 -*-

import base64

origin = '028D681E0B3FDEFFFFFF0115179B0215901F8FFFFFFF601E492D030115169B0218901F8FFFFFFF601E452D030115169B0216901F8FFFFFFF601E562D030115169B0217901F8FFFFFFF601E4C2D030115169B021E0A901F8FFFFFFF601E2B2D030115169B021D901F8FFFFFFF601FF0FFFFFF2D030115169B0219901F8FFFFFFF601E1C2D030115169B021A901F8FFFFFFF601E302D030115169B021E08901F8FFFFFFF601FE1FFFFFF2D030115169B021C901F8FFFFFFF601FEDFFFFFF2D030115169B021E09901F8FFFFFFF601FA2FFFFFF2D030115169B021B901F8FFFFFFF601E742D030115169B29'

new_change = []
sum = 0
for i in range(len(origin)/2):
tmp = origin[:2]
tmp = int(tmp,16)
tmp += 1
tmp &= 0xFF
sum += tmp
sum &= 0xFF
new_change.append(tmp)
origin = origin[2:]

new_change[18] = (sum - 38) & 0xFF
new_change[35] = (sum - 3) & 0xFF
new_change[52] = (sum ^ 39) & 0xFF
new_change[69] = (sum - 21) & 0xFF
new_change[87] = (71 - sum) & 0xFF
new_change[124] = (sum ^ 114) & 0xFF
new_change[141] = (sum ^ 80) & 0xFF
new_change[159] = (235 - sum) & 0xFF
new_change[179] = (106 + sum) & 0xFF
new_change[200] = (36 - sum) & 0xFF
new_change[220] = (sum - 3) & 0xFF

for i in range(len(new_change)):
if new_change[i] < 16:
print '0' + "%x" % new_change[i],
else:
print ("%2x" % (new_change[i])),

s = '03 8e 69 1f 0c 40 df 00 00 00 02 16 18 9c 03 16 91 20 10 00 00 00 61 1f 4a 2e 04 02 16 17 9c 03 19 91 20 33 00 00 00 61 1f 46 2e 04 02 16 17 9c 03 17 91 20 11 00 00 00 61 1f 57 2e 04 02 16 17 9c 03 18 91 20 21 00 00 00 61 1f 4d 2e 04 02 16 17 9c 03 1f 0b 91 20 11 00 00 00 61 1f 2c 2e 04 02 16 17 9c 03 1e 91 20 90 00 00 00 61 20 f1 00 00 00 2e 04 02 16 17 9c 03 1a 91 20 44 00 00 00 61 1f 1d 2e 04 02 16 17 9c 03 1b 91 20 66 00 00 00 61 1f 31 2e 04 02 16 17 9c 03 1f 09 91 20 b5 00 00 00 61 20 e2 00 00 00 2e 04 02 16 17 9c 03 1d 91 20 a0 00 00 00 61 20 ee 00 00 00 2e 04 02 16 17 9c 03 1f 0a 91 20 ee 00 00 00 61 20 a3 00 00 00 2e 04 02 16 17 9c 03 1c 91 20 33 00 00 00 61 1f 75 2e 04 02 16 17 9c 2a'

print ''
print s.replace(' ','')

#038e691f0c40df0000000216189c0316912010000000611f4a2e040216179c0319912033000000611f462e040216179c0317912011000000611f572e040216179c0318912021000000611f4d2e040216179c031f0b912011000000611f2c2e040216179c031e9120900000006120f10000002e040216179c031a912044000000611f1d2e040216179c031b912066000000611f312e040216179c031f099120b50000006120e20000002e040216179c031d9120a00000006120ee0000002e040216179c031f0a9120ee0000006120a30000002e040216179c031c912033000000611f752e040216179c2a

ans = []

ans.append(chr(74^16))
ans.append(chr(87^17))
ans.append(chr(33^77))
ans.append(chr(51^70))
ans.append(chr(68^29))
ans.append(chr(102^49))
ans.append(chr(51^117))
ans.append(chr(160^238))
ans.append(chr(144^241))
ans.append(chr(181^226))
ans.append(chr(238^163))
ans.append(chr(17^44))

ans = ''.join(ans)
print ans

print base64.b64decode(ans)

flag: dYnaaMic

Flash Encrypt

flash的题目,用ffdec打开,点击scripts,然后选择其中一个打开发现是有问题的代码,Settings里勾选上Automatic deobfuscation自动反混淆,然后重新生成。此时再看scripts里的代码就很简单了,把那几个比较的数值记录下来,然后双击flashenc.swf运行,输入那些值,到达最后出现flag。

flashEnc

flag: 16876

Multiplicative

java程序逆向,使用jad或者dj反编译程序,直接看到源代码,一个通过溢出得到值的题目。脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env python
#-*- coding:utf-8 -*-

from ctypes import *

i = 1L
while (1):
tmp = ((2 ** 64) * i + 0xeaaeb43e477b8487L) / 26729
if ((tmp * 26729) % (2 ** 64)) == 0xeaaeb43e477b8487L:
print c_int64(temp),i
break
i += 1

flag: -8978084842198767761