前言
很多时候在讲课过程中,有些学员觉得讲的太快或者还不能完全理解。因此写这篇博客方便大家课后复习回顾。大家如果有什么问题也可以在下面评论(我如果看到会处理回复的)。或者加入安恒萌新粉丝群:928102972
共同交流学习!!!对于下面这些题目的话,如果没有特殊说明,crack_xxx文件是破解成功的。
CTF-RE
简单-逻辑分析
reverse1
难度:入门
考点:逻辑分析
下载地址
把题目拖入IDA pro
,shift+F12
打开strings windows
,观察字符串,找到可疑字符串或者正确错误提示字符串,比如this is right flag
或wrong flag
等,双击字符串跳转到数据段,然后在双击字符串后面的数据交叉引用DATA XREF:main:xxxx
跳转到.text
代码段(或者选中变量名,摁快捷键x
,弹出交叉引用窗口,选择跳转过去)然后摁快捷键F5
使用Hex-rays
插件进行反编译转成类C伪代码
。然后对代码逻辑进行分析即可。(下面题目分析步骤类似,就不详细描述了)
这个逻辑很简单,就是把Str2
字符串里的o
换成0
,双击Str2
可以看到他的值,只要我们输入的字符串是替换后的,说明我们输入的是正确的flag
,这里flag的值是{hell0_w0rld}
。
reverse2
难度:入门
考点:逻辑分析
下载地址
分析如上题,这里的逻辑是把i
和r
替换成1
。
flag是{hack1ng_fo1_fun}
。
xor
难度:入门
考点:异或
下载地址
这题的逻辑是把字符串的前一位和后一位进行异或,结果存在后一位中,
解题思路就逆运算,把密文再异或一边就可以了。
写个exp就很容易拿到flag1
2
3
4
5
6#-*- coding:UTF-8 -*-
out = 'f\nk\fw&O.@\x11x\rZ;U\x11p\x19F\x1Fv\"M#D\x0Eg\x06h\x0FG2O'
ret = ''
for i in range(1,len(out)):
ret += chr(ord(out[i])^ord(out[i-1]))
print 'f'+ret #flag{QianQiuWanDai_YiTongJiangHu}
rev1
难度:入门
考点:逻辑分析
下载地址
这个题目逻辑很简单,只要把代码运行一遍就可以了。
写个脚本跑一下1
2
3
4
5
6
7# -*- coding:UTF-8 -*-
str1="tikp[luX|aoTjaoh"
flag=""
for i in range(0,len(str1)):
flag+=chr(ord(str1[i])^i)
print 'CTF{%s}'%flag
# CTF{this_is_the_flag}
666
难度:简单
考点:异或、简单运算
下载地址
同样的方法定位到main函数
,或者可以直接在Functions windows
双击main
,跳转过去F5
。enflag
的值是已知的izwhroz""w"v.K".Ni
,只要s
和它相等即输入的值是正确flag。key
是12h
(h表示16进制,转成10进制就是18),说明我们输入的长度为18,变量s
以及输入的v5
和encode函数
有关。
双击进去看到逻辑是将字符串分为3个字符为组,第一个字符加6再和18异或,第二个减6和18异或,第三个是先和6异或再和18异或,a2
对应main函数
里的s
,返回值是a2
,这里把密文逆推回去就可以了
写个脚本算一下就出来了1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#coding=utf-8
enc = [0x69,0x7A,0x77,0x68,
0x72,0x6F,0x7A,0x22,
0x22,0x77,0x22,0x76,
0x2E,0x4B,0x22,0x2E,
0x4E,0x69]
j = 0
key = 18
for i in range(6):
a1 = (enc[j] ^ key) - 6
a2 = (enc[j+1] ^ key) + 6
a3 = (enc[j+2] ^ key) ^ 6
j += 3
print '\b'+chr(a1)+chr(a2)+chr(a3),
#unctf{b66_6b6_66b}
这个题有个flag字符串,看逻辑是比较错误才会打印出来,说明那个是假的,用来迷惑选手的。
game
难度:简单
考点:异或、简单运算
下载地址
同样的方法定位到核心代码位置,反编译后看到有个很长的字符串数组,从v2-v115
。把数组对半分,用v2
和v59
异或,同理后面是v3
和v60
……1
2
3
4
5
6
7
8
9b = [123,32,18,98,119,108,65,41,124,80,125,38,124,111,74,49,83,108,94,108,84,6,96,83,44,121,104,110,32,95,117,101,99,123,127,119,96,48,107,71,92,29,81,107,90,85,64,12,43,76,86,13,114,1,117,126]
a = [18,64,98,5,2,4,6,3,6,48,49,65,32,12,48,65,31,78,62,32,49,32,1,57,96,3,21,9,4,62,3,5,4,1,2,3,44,65,78,32,16,97,54,16,44,52,32,64,89,45,32,65,15,34,18,16]
c = ''
for i in range(len(a)):
a[i] ^= b[i]
a[i] ^= 19
c += chr(a[i])
print(c)
#zsctf{T9is_tOpic_1s_v5ry_int7resting_b6t_others_are_n0t}
CTF-Android
java逆向解密
难度:入门
考点:逻辑分析
下载地址
- 1.反编译
拿到的是一个Reverse.class
文件,直接用jadx
,看到反编译源码。核心看加密函数
- 2.逻辑分析,编写python-exp
简单分析一下写出exp脚本1
2
3
4
5
6strs = [180, 136, 137, 147, 191, 137, 147, 191,
148, 136, 133, 191, 134, 140, 129, 135, 191, 65]
flag = ""
for i in range(0,len(strs)):
flag += chr(strs[i] - ord('@') ^ 0x20)
print 'flag{'+flag+'}' #flag{This_is_the_flag_!}
也可以直接讲反编译的java代码复制出来稍微改改就可以了。
hello world
难度:入门
考点:逻辑分析
下载地址
这个题很容易,用反编译工具(jadx,Androidkill等)打开,可以看到账号密码,或者将里面的两个if-eqz
的条件判断跳转改成if-nez
。这里具体的大家可以看一下smail语法
。原来的程序逻辑:这里会把输入的用户名和密码赋值给p1
和p2
,然后正确的用户名存储在v0
里面,进行对比,如果相等结果存在v0
里面,如果不相等结果等于0,会跳转。
随意输入就可以拿到flag,这里会显示登陆成功ZmxhZ3tjb25ncmF0dWxhdGlvbl9sb2dpbl9zdWNjZXNzfQ==
,很明显的base64,解码一下出来flag{congratulation_login_success}
,这里有个错误的flag,输入错误会弹出来flag{this_is_wrong_flag}
简单注册器
难度:简单
考点:逻辑分析、apk破解
下载地址
- 1.反编译
用jadx-gui打开简单注册器.apk
文件,反编译看到源代码
2.1逻辑分析,编写exp
python-exp
用python写出这段的执行逻辑,运行一下1
2
3
4
5
6
7
8
9
10
11
12
13s = 'dd2940c04462b4dd7c450528835cca15'
x = list(s)
x[2] = chr(ord(x[2])+ord(x[3])-50)
x[4] = chr(ord(x[2])+ord(x[5])-48)
x[30] = chr(ord(x[31])+ord(x[9])-48)
x[14] = chr(ord(x[27])+ord(x[28])-91)
i=0
for i in range(0,15):
a = x[31-i];
x[31-i] = x[i];
x[i] = a;
flag = ''.join(x)
print 'flag{' + flag + '}' #flag{59acc538825054cd7k4b26440c0999dd}java-exp
直接把这段代码复制过去粘贴在IDE(我是用eclipse)里跑一下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18package easysingexp;
public class exp {
public static void main(String[] args) {
// TODO 自动生成的方法存根
char[] x = "dd2940c04462b4dd7c450528835cca15".toCharArray();
x[2] = (char) ((x[2] + x[3]) - 50);
x[4] = (char) ((x[2] + x[5]) - 48);
x[30] = (char) ((x[31] + x[9]) - 48);
x[14] = (char) ((x[27] + x[28]) - 97);
for (int i = 0; i < 16; i++) {
char a = x[31 - i];
x[31 - i] = x[i];
x[i] = a;
}
System.out.println("flag{" + String.valueOf(x) + "}");
return;
}
}
2.2破解APK
(1)判断条件分析
这里我们发现有个if条件判断如下:1
2
3if ((paramView.length() != 32) || (paramView.charAt(31) != 'a') || (paramView.charAt(1) != 'b') || (paramView.charAt(0) + paramView.charAt(2) - 48 != 56)) {
j = 0;
}
这里对输入的字符串长度
以及特定的字符
有个限定,只要我们输入满足这个要求,就可以不执行,直接往下走生成flag
字符串。
分析发现条件对应的分别是:
- 输入长度等于32
- 最后一个字符等于a
- 第2个字符等于b
- 第1个字符加第3个字符相加等于104(56+48)
所以我们构造个字符串6b20123456789012345678912345678a
即可
(2)修改smail代码,重打包
随意输入个字符
查看到报错字符串是输入注册码错误
。我们在Androidkill
里面工具
下面有个编码转换
搜索\u8F93\u5165\u6CE8\u518C\u7801\u9519\u8BEF
定位到关键代码。
往上翻找到if条件判断
分别把这4个if给改了,if-ne v7,v8, :cond_0
是不等于跳转,if-eq v7,v8,cond_1
是等于跳转,在if上面都是给v8赋值,v7是从我们输入的里面取,进行对比。这里最简单直接把跳转cond_0
都改成cond_1
。
遇到这种情况(这里是因为我们Androidkill回编译用的apktool版本太老,下载新版本替换进去这个问题就解决了),,我们可以用Android逆向助手
,先提取dex
,再反编译dex
,用记事本打开刚刚之前分析的那个smail文件
,然后进行修改后保存,再重打包dex
,再替换dex
。
安装成功运行,随意输入字符串,拿到flag。
还有一个思路直接修改给flag变量赋值,通过下图分析,可以知道这里对应的就是给flag变量赋值0的,我们把它改成0x1
,同样通过替换dex的方法可以成功达到我们破解的效果。(这个apk没有签名效验,如果有签名,需要回编译以后,再进行签名。看有没有签名效验可以搜索类似signatures
字符串找check函数
)当然这里还有其他思路,比如把if判断删了,或者把判断条件给改了。
上述方法对于简单apk的java代码反编译破解基本通用,实际可能存在其他的一些反编译手段或者签名效验等防二次打包。
findit
难度:简单
考点:逻辑分析、apk破解
下载地址
- 1.反编译
将APK拖入jadx
看一下反编译java代码 - 2.1逻辑分析
- (1)解出输入的字符串
如果大家对凯撒密码
比较熟悉,看这个逻辑很容易看出来是一个凯撒移位,这里的凯撒移位的原理可以看下面的分析(也可以把这部分代码复制出来运行一下跑出来)这里对a字符串ThisIsTheFlagHome
进行往前移动8位
生成答案LzakAkLzwXdsyZgew
,输入即可弹出flag。1
2
3
4
5...ABCDEFGHIJKLMNOPQRSTUVWXYZ...abcdefghijklmnopqrstuvwxyz... #ASCII表
ABCDEFGH abcdefgh #第一个if将A-H和a-h进行往后移动18位
... ... ... #第二个if限定除了A-Z和a-z以外的字符串不变
IJKLMNOPQRSTUVWXYZ ijklmnopqrstuvwxyz #第三个if将剩下部分往前移动8位
...IJKLMNOPQRSTUVWXYZABCDEFGH...ijklmnopqrstuvwxyzabcdefgh... #最终生成新的编码表,凯撒往后移动18位/往前移8位
- (1)解出输入的字符串
同理b字符串pvkq{m164675262033l4m49lnp7p9mnk28k75}
进行凯撒移位往前移10位
,生成flag{c164675262033b4c49bdf7f9cda28a75}
python-exp脚本,kaisa(str,k)
可以对字符串遍历移位,str是要移位的字符串,k为偏移量,通过num==k去取26种移位结果中需要的那个1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#!/usr/bin/env python
#coding=utf-8
def Caesar(str,k):
for num in range(0,26):
str1 = ''
for i in range(0,len(str)):
if not str[i].isalpha(): #判断是否为字母(不区分大小写)
str1 += str[i]
elif (str[i].isupper())and((ord(str[i])+num)>90):
str1 += chr(ord(str[i])+num-26)
elif (str[i].islower())and((ord(str[i])+num)>122):
str1 += chr(ord(str[i])+num-26)
else:
str1 += chr(ord(str[i])+num)
if num == k:
print('offset->{}:{}'.format(num,str1))
a = 'ThisIsTheFlagHome'
b = 'pvkq{m164675262033l4m49lnp7p9mnk28k75}'
Caesar(a,18)
Caesar(b,16)
除此之外用python实现凯撒移位
的方法有很多,后面会抽空再开一个帖子,将常用的一些加解密等脚本整理出来,选出最优方法放出来。
- 2.2破解APK
同样这里也可以破解去拿到flag,方法和上面的一样。
首先安装apk看一下,随便输入看一下报错信息,方便我们定位到关键的条件判断
我们把报错中的部分答案错了
转成Unicode
编码是\u7B54\u6848\u9519\u4E86
,我们搜索一下这段编码,需要把搜索范围
换成当前整个项目
。然后点击搜索出来的结果定位到这串字符串的位置。这个我们要定位到核心的if条件判断,可以通过标志位去找,有时候也可以通过变量去变量。
这里就一个标志位,简单分析一下smail语句很容易确定那个if就是要找的,往上走在112行的地方有个if-eqz v5, :cond_e
我们把他改成if-nez
,逻辑反一下就好啦。然后在左上角点一下编译,生成新的apk。在信息输出窗口会有新的apk链接,点一下打开拖进模板器安装即可,成功破解。