好友
阅读权限25
听众
最后登录1970-1-1
|
本帖最后由 Anonymous、 于 2018-10-12 20:39 编辑
一、说明
钉钉CTF是一个网友昨晚给我的,比较简单,但是思路和AliCTF非常像,所以就放在一起了,一些坛友问工具怎么使用
其实很简单,在这也稍微加下使用说明,自己技术比较菜,全程靠猜~~~~~有什么不对的地方,还请各位师傅指点.
二、钉钉CTF
这一题比较简单,先打开app看下
随便输入
错了,但是有个welcome to flag blank!根据题目意思,尝试什么都不输入
什么??????居然就对了!!!!!
好了,开始看Ali的吧...............
算啦算啦,还是看看内部怎么实现的这么牛逼的功能的吧
[Java] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 | protected void onCreate(Bundle arg3) {
super .onCreate(arg3);
this .setContentView( 2130968603 );
this .text = this .findViewById( 2131427416 );
this .textView1 = this .findViewById( 2131427418 );
this .button = this .findViewById( 2131427415 );
this .button.setOnClickListener( new View$OnClickListener() {
public void onClick(View arg4) {
MainActivity. this .c = new CheckClass();
MainActivity. this .c.a(MainActivity. this .text.getText().toString());
if (MainActivity. this .c.check()) {
MainActivity. this .textView1.setText( "flag is XMAN{" + MainActivity. this .text.getText().toString() + "}" );
}
else {
MainActivity. this .textView1.setText( "WORING!" );
}
}
});
}
|
onCreate方法中,先看MainActivity.this.c.a
[Java] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 | public void a(String arg5) {
int v1 = 30 ;
this .A = new byte [v1];
this .B = arg5.getBytes();
int v0;
for (v0 = 0 ; v0 < arg5.length(); ++v0) {
this .A[v0] = this .B[v0];
}
this .B = new byte [v1];
}
|
获取输入的字符串,再看MainActivity.this.c.check()
[Java] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 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 64 65 66 67 68 69 70 71 | public boolean check() {
boolean v9 = false ;
int [] v0 = new int []{ 40 , 42 , 65 , 67 , 68 , 2 , 64 , 70 , 96 , 98 , 181 , 7 , 10 , 64 , 23 , 17 , 37 , 20 , 45 , 91 , 74 , 72 , 135 , 33 , 57 , 43 , 87 , 99 , 147 , 53 };
byte [] v5 = new byte []{ 52 , 111 , 102 , 113 , 52 , 52 , 98 };
int v2 = 0 ;
int v4 = 0 ;
int v7 = 0 ;
int v1;
for (v1 = 0 ; v1 < v0.length; ++v1) {
int v8 = this .b(v0[v1]);
new String();
Log.d( "now array:" , String.valueOf(v8));
switch (v8) {
case 0 : {
this .A[v7] = (( byte )( this .A[v7] ^ v7));
break ;
}
case 1 : {
if ( this .A[v4] != 0 ) {
++v4;
}
else {
}
break ;
}
case 2 : {
v5[v4] = (( byte )(v5[v4] ^ v4));
++v4;
break ;
}
case 3 : {
if (v5[v7] == this .A[v7]) {
++v7;
}
else {
}
break ;
}
case 4 : {
if (v7 == v4) {
v9 = true ;
}
return v9;
}
case 5 : {
if (v4 != v5.length) {
v1 = v0.length - 3 ;
}
else {
v4 = 0 ;
}
break ;
}
default : {
++v2;
break ;
}
}
}
return v9;
}
public int b( int arg4) {
int v0 = 181 & arg4;
return (v0 & 1 ) + ((v0 & 4 ) >> 2 ) + ((v0 & 16 ) >> 4 ) + ((v0 & 32 ) >> 5 ) + ((v0 & 128 ) >> 7 );
}
|
此函数为关键点,看着挺复杂的,只要返回为true即可
[Java] 纯文本查看 复制代码 1 2 3 4 5 6 | case 4 : {
if (v7 == v4) {
v9 = true ;
}
return v9;
}
|
case 4里的判断执行,下面再接着分析v8
由于v0是固定的,所以v8也是固定的,那么switch语句就好分析了
[Java] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public class DCtf {
private static byte [] A;
private static byte [] B;
public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException {
a( "4" );
check();
}
public static void a(String arg5) {
int v1 = 30 ;
A = new byte [v1];
B = arg5.getBytes();
int v0;
for (v0 = 0 ; v0 < arg5.length(); ++v0) {
A[v0] = B[v0];
}
B = new byte [v1];
}
public static int b( int arg4) {
int v0 = 181 & arg4;
return (v0 & 1 ) + ((v0 & 4 ) >> 2 ) + ((v0 & 16 ) >> 4 ) + ((v0 & 32 ) >> 5 ) + ((v0 & 128 ) >> 7 );
}
public static boolean check() {
boolean v9 = false ;
int [] v0 = new int []{ 40 , 42 , 65 , 67 , 68 , 2 , 64 , 70 , 96 , 98 , 181 , 7 , 10 , 64 , 23 , 17 , 37 , 20 , 45 , 91 , 74 , 72 , 135 , 33 , 57 , 43 , 87 , 99 , 147 , 53 };
byte [] v5 = new byte []{ 52 , 111 , 102 , 113 , 52 , 52 , 98 };
int v2 = 0 ;
int v4 = 0 ;
int v7 = 0 ;
int v1;
for (v1 = 0 ; v1 < v0.length; ++v1) {
int v8 = b(v0[v1]);
new String();
System.out.println( "now array:" + String.valueOf(v8));
switch (v8) {
case 0 : {
A[v7] = (( byte )(A[v7] ^ v7));
break ;
}
case 1 : {
if (A[v4] != 0 ) {
++v4;
}
else {
}
break ;
}
case 2 : {
v5[v4] = (( byte )(v5[v4] ^ v4));
++v4;
break ;
}
case 3 : {
if (v5[v7] == A[v7]) {
System.out.println( "v5[v7] " +v5[v7]+ "------A[v7] " +A[v7]+ " " +v7);
++v7;
}
else {
}
break ;
}
case 4 : {
if (v7 == v4) {
v9 = true ;
}
System.out.println( "v7 " +v7+ "------v4 " +v4);
return v9;
}
case 5 : {
if (v4 != v5.length) {
v1 = v0.length - 3 ;
}
else {
v4 = 0 ;
}
break ;
}
default : {
++v2;
break ;
}
}
}
return v9;
}
}
|
运行上面的代码,可以得到v8的值分别是
[C] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 | now array:1
now array:1
now array:1
now array:1
now array:1
now array:0
now array:0
now array:1
now array:1
now array:1
now array:5
now array:3
now array:4
|
最后执行的就是case 4,符合我们前面的分析,但是v7 == v4,能影响v7的只有case 3这个分支,看上面v8的值,知道下面的代码只执行了一次
[Java] 纯文本查看 复制代码 1 2 3 4 5 6 7 8 | case 3 : {
if (v5[v7] == this .A[v7]) {
++v7;
}
else {
}
break ;
}
|
所以要想v7 == v4,v7和v4只能为1或者0,0就是什么都不输入,++v7执行之后为1,执行之前v7为就为0,所以A[v7]=52,查找ascall码表结果为4
分析到这,你就认为完了?然后并没有结束、、、、
[Java] 纯文本查看 复制代码 1 2 3 4 5 6 7 8 9 | case 5 : {
if (v4 != v5.length) {
v1 = v0.length - 3 ;
} else {
v4 = 0 ;
}
break ;
}
|
上面的分析的是v4 != v5.length结果,如果v4 = v5.length呢,继续往下分析吧,也就是输入的字符串为7位
[Java] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | now array: 1
now array: 1
now array: 1
now array: 1
now array: 1
now array: 0
now array: 0
now array: 1
now array: 1
now array: 1
now array: 5
now array: 2
now array: 0
now array: 0
now array: 3
v5[v7] 52 ------A[v7] 52 v7 0
now array: 2
now array: 3
now array: 2
now array: 3
now array: 2
now array: 0
now array: 0
now array: 3
now array: 2
now array: 3
now array: 2
now array: 3
now array: 2
now array: 3
now array: 4
v7 1 ------v4 7
|
控制v7的的case只有一个
[Asm] 纯文本查看 复制代码 1 2 3 4 5 6 7 8 | case 3: {
if (v5[v7] == A[v7]) {
System. out .println( "v5[v7] " + v5[v7] + "------A[v7] " + A[v7] + " v7 " + v7);
++v7;
} else {
}
break;
}
|
根据上面的代码循环,可以慢慢倒推出来结果为4ndr01d,真是一波三折呀。。。
放下分析的代码
[Java] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public class ctf1 {
private static byte [] A;
private static byte [] B;
public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException {
a( "4ndr01d" );
check();
}
public static void a(String arg5) {
int v1 = 30 ;
A = new byte [v1];
B = arg5.getBytes();
int v0;
for (v0 = 0 ; v0 < arg5.length(); ++v0) {
A[v0] = B[v0];
}
B = new byte [v1];
}
public static int b( int arg4) {
int v0 = 181 & arg4;
return (v0 & 1 ) + ((v0 & 4 ) >> 2 ) + ((v0 & 16 ) >> 4 ) + ((v0 & 32 ) >> 5 ) + ((v0 & 128 ) >> 7 );
}
public static boolean check() {
boolean v9 = false ;
int [] v0 = new int [] { 40 , 42 , 65 , 67 , 68 , 2 , 64 , 70 , 96 , 98 , 181 , 7 , 10 , 64 , 23 , 17 , 37 , 20 , 45 , 91 , 74 , 72 ,
135 , 33 , 57 , 43 , 87 , 99 , 147 , 53 };
byte [] v5 = new byte [] { 52 , 111 , 102 , 113 , 52 , 52 , 98 };
int v2 = 0 ;
int v4 = 0 ;
int v7 = 0 ;
int v1;
for (v1 = 0 ; v1 < v0.length; ++v1) {
int v8 = b(v0[v1]);
new String();
System.out.println( "now array:" + String.valueOf(v8));
switch (v8) {
case 0 : {
A[v7] = (( byte ) (A[v7] ^ v7));
break ;
}
case 1 : {
if (A[v4] != 0 ) {
++v4;
} else {
}
break ;
}
case 2 : {
v5[v4] = (( byte ) (v5[v4] ^ v4));
++v4;
break ;
}
case 3 : {
if (v5[v7] == A[v7]) {
System.out.println( "v5[v7] " + v5[v7] + "------A[v7] " + A[v7] + " v7 " + v7);
++v7;
} else {
}
break ;
}
case 4 : {
if (v7 == v4) {
v9 = true ;
}
System.out.println( "v7 " + v7 + "------v4 " + v4);
return v9;
}
case 5 : {
if (v4 != v5.length) {
v1 = v0.length - 3 ;
} else {
v4 = 0 ;
}
break ;
}
default : {
++v2;
break ;
}
}
}
return v9;
}
}
|
三、Alictf
好啦,终于可以上主菜了~~~~~~
先用jeb反编译
[Java] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | package com.ali.mobisecenhance;
import android.app.Application;
import android.content.Context;
public class StubApplication extends Application {
static {
try {
Class v2 = Class.forName( "android.os.SystemProperties" );
Object v1 = v2.getDeclaredMethod( "get" , String. class ).invoke(v2, "ro.product.cpu.abi" );
}
catch (Exception v3) {
v3.printStackTrace();
}
if (((String)v1).equalsIgnoreCase( "x86" )) {
System.loadLibrary( "mobisecx" );
}
else {
System.loadLibrary( "mobisec" );
}
}
public StubApplication() {
super ();
}
protected native void attachBaseContext(Context arg1) {
}
public native void onCreate() {
}
}
|
加了壳子~~~~关键代码看不到,那就先用IDA脱壳吧
先打开DDMS
获取入口点
一键挂起
用ida附加
在ibdvm的dvmDefineClass下了个断点,通过DvmDex的指针,把odex dump下来,下好断点,点jdb启动
查看r0地址
跟随上面的地址
用脚步dump下来
[C] 纯文本查看 复制代码 1 2 3 4 5 6 7 8 | static main( void )
{
auto fp, dex_addr, end_addr;
fp = fopen ( "C:\\dump.dex" , "wb" );
end_addr = 0x75512000 + 0x00010000;
for ( dex_addr = 0x75512000; dex_addr < end_addr; dex_addr ++ )
fputc (Byte(dex_addr), fp);
}
|
然后修复,最后用版主的Apktool工具,反编译dex,再回编译,就可以用jeb打开了
下面就是分析java代码了
主要是根据这个表对我们输入的字符串,进行置换
[Java] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | static {
e.a = new HashMap();
e.a( "a" , ". _" );
e.a( "b" , "_ . . ." );
e.a( "c" , "_ . _ ." );
e.a( "d" , "_ . ." );
e.a( "e" , "." );
e.a( "f" , ". . _ ." );
e.a( "g" , "_ _ ." );
e.a( "h" , ". . . ." );
e.a( "i" , ". ." );
e.a( "j" , ". _ _ _" );
e.a( "k" , "_ . _" );
e.a( "l" , ". _ . ." );
e.a( "m" , "_ _" );
e.a( "n" , "_ ." );
e.a( "o" , "_ _ _" );
e.a( "p" , ". _ _ ." );
e.a( "q" , "_ _ . _" );
e.a( "r" , ". _ ." );
e.a( "s" , ". . ." );
e.a( "t" , "_" );
e.a( "u" , ". . _" );
e.a( "v" , ". . . _" );
e.a( "w" , ". _ _" );
e.a( "x" , "_ . . _" );
e.a( "y" , "_ . _ _" );
e.a( "z" , "_ _ . ." );
e.a( "2" , ". _ _ _ _" );
e.a( "1" , ". . _ _ _" );
e.a( "3" , ". . . _ _" );
e.a( "4" , ". . . . _" );
e.a( "0" , ". . . . ." );
e.a( "6" , "_ . . . ." );
e.a( "9" , "_ _ . . ." );
e.a( "8" , "_ _ _ . ." );
e.a( "7" , "_ _ _ _ ." );
e.a( "5" , "_ _ _ _ _" );
}
public e() {
super ();
}
public String a(String arg8) {
String v0;
dn.b(dn.a());
if (arg8.equals( "...___..." )) {
v0 = "sos" ;
}
else {
StringBuilder v2 = new StringBuilder();
String[] v3 = arg8.split( "\\s+" );
int v4 = v3.length;
int v1 = 0 ;
while ( true ) {
if (v1 < v4) {
Object v0_1 = e.a.get(v3[v1]);
if (v0_1 != null ) {
v2.append(((String)v0_1));
++v1;
continue ;
}
else {
break ;
}
}
else {
goto label_26;
}
return v0;
}
throw new IllegalArgumentException();
label_26:
v0 = v2.toString();
}
return v0;
}
|
下面这部分代码,根据压缩包里的strings.xml和public.xml可以分析run()返回值为0时,提示成功的字符
[Java] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 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 64 65 66 67 | public void handleMessage(Message arg5) {
dn.b(dn.a());
int v2 = - 65536 ;
this .a.b.setEnabled( true );
switch (arg5.what) {
case 0 : {
goto label_10;
}
case 1 : {
goto label_27;
}
case 2 : {
goto label_51;
}
case 3 : {
goto label_66;
}
}
return ;
label_66:
this .a.a.setTextColor(v2);
TextView v1 = this .a.a;
int v0 = Main.a( this .a).nextBoolean() ? 2130968582 : 2130968581 ;
v1.setText(v0);
return ;
try {
label_51:
this .a.a.setTextColor(- 65536 );
}
catch (Exception v0_1) {
this .a.a.setTextColor(- 7829368 );
}
this .a.a.setText( 2130968580 );
return ;
label_10:
this .a.a.setTextColor(- 16776961 );
try {
this .a.a.setText( 103 / arg5.what);
}
catch (Exception v0_1) {
this .a.a.setText( 2130968586 );
}
return ;
label_27:
this .a.a.setTextColor(v2);
switch (Main.a( this .a).nextInt( 3 )) {
case 0 : {
goto label_36;
}
case 1 : {
goto label_41;
}
case 2 : {
goto label_46;
}
}
return ;
label_36:
this .a.a.setText( 2130968583 );
return ;
label_41:
this .a.a.setText( 2130968585 );
return ;
label_46:
this .a.a.setText( 2130968584 );
}
|
下面的run()函数为关键点,只要返回0即可,分析逻辑和上面那个CTF很类似
[Java] 纯文本查看 复制代码 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | b(a arg1, Handler arg2, String arg3) {
this .d = arg1;
this .b = arg2;
this .input = arg3;
super ();
}
public void run() {
int v0_6;
String v0_5;
String v1_5;
byte [] v2_3;
Cipher v1_1;
MessageDigest v0_3;
String str;
dn.b(dn.a());
MessageDigest v1 = null ;
if (Build$VERSION.SDK_INT >= 10 && (Debug.isDebuggerConnected())) {
this .b.sendEmptyMessage( 1 );
return ;
}
try {
str = new e().a( this .input);
}
catch (Exception v0) {
this .b.sendEmptyMessage( 3 );
return ;
}
try {
if (str.equals( "sos" )) {
this .b.sendEmptyMessage( 2 );
return ;
}
CRC32 v0_1 = new CRC32();
v0_1.update(str.getBytes());
v0_1.getValue();
str.hashCode();
try {
v0_3 = MessageDigest.getInstance( "sha1" );
}
catch (NoSuchAlgorithmException v0_2) {
v0_2.printStackTrace();
v0_3 = v1;
}
try {
v1_1 = Cipher.getInstance( "AES" );
}
catch (NoSuchPaddingException v0_4) {
v0_4.printStackTrace();
return ;
}
catch (NoSuchAlgorithmException v2) {
v2.printStackTrace();
}
if (!b.a && v1_1 == null ) {
throw new AssertionError();
}
}
catch (Exception v0) {
goto label_26;
}
int v2_1 = 2 ;
try {
v1_1.init(v2_1, new SecretKeySpec(Base64.decode( "GXiQHT1CZ2elMzwpvvAoPA==" .getBytes(), 0 ), "AES" ));
goto label_69;
}
catch (Exception v0) {
}
catch (InvalidKeyException v2_2) {
label_69:
try {
new byte [ 0 ];
try {
v2_3 = v1_1.doFinal(Base64.decode( "hjdsUjIT5je69WXIZP7Kzw==" .getBytes( "UTf-8" ), 0 ));
goto label_78;
}
catch (UnsupportedEncodingException v1_2) {
try {
v1_2.printStackTrace();
label_78:
String v6 = new String(v2_3);
v0_3.update( new byte []{ 127 });
v0_3.update(str.getBytes());
v0_3.update( new byte []{ 1 });
}
catch (Exception v0) {
goto label_26;
}
}
catch (BadPaddingException v1_3) {
goto label_78;
}
catch (IllegalBlockSizeException v1_4) {
goto label_78;
}
}
catch (Exception v0) {
goto label_26;
}
try {
v1_5 = new String(Base64.encode(v0_3.digest(), 0 ));
goto label_99;
}
catch (Exception v0) {
try {
v0.printStackTrace();
return ;
label_99:
if (!str.equals(v6)) {
goto label_190;
}
else if (Arrays.equals(v1_5.getBytes(), "2398lj2n" .getBytes())) {
this .b.sendEmptyMessage( 0 );
return ;
}
else {
v0_5 = "234" ;
}
goto label_117;
}
catch (Exception v0) {
goto label_26;
}
}
label_190:
v0_5 = v1_5;
try {
label_117:
if (v0_5.equals( "lsdf==" )) {
this .b.sendEmptyMessage( 0 );
return ;
}
char [] v1_6 = str.toCharArray();
v0_6 = str.substring( 0 , 2 ).hashCode();
if (v0_6 > 3904 ) {
this .b.sendEmptyMessage( 4 );
return ;
}
if (v0_6 == 3618 ) {
if (v1_6[ 0 ] + v1_6[ 1 ] != 168 ) {
goto label_178;
}
do {
label_144:
byte [] v5_1 = e. class .getAnnotation(f. class ).a() + a. class .getAnnotation(f. class ).a().getBytes();
if (v1_6.length - 2 == v5_1.length) {
v0_6 = 0 ;
while ( true ) {
if (v0_6 >= v5_1.length) {
goto label_188;
}
else if (v1_6[v0_6 + 2 ] != v5_1[v0_6]) {
v0_6 = 0 ;
}
else {
++v0_6;
continue ;
}
goto label_170;
}
}
goto label_177;
}
while ( true );
}
goto label_178;
}
catch (Exception v0) {
goto label_26;
}
label_188:
v0_6 = 1 ;
try {
label_170:
if (v0_6 != 0 ) {
this .b.sendEmptyMessage( 0 );
return ;
}
label_177:
if (v2_3 == null ) {
goto label_144;
}
label_178:
this .b.sendEmptyMessage( 1 );
}
catch (Exception v0) {
label_26:
this .b.sendEmptyMessage( 1 );
}
}
}
|
只有为这个的时候this.b.sendEmptyMessage(0);才会提示成功, label_188: ---label_117:---label_190:,跳转这三个点才能成功,
[Java] 纯文本查看 复制代码 1 2 3 4 5 6 7 8 | label_190:
v0_5 = v1_5;
try {
label_117:
if (v0_5.equals( "lsdf==" )) {
this .b.sendEmptyMessage( 0 );
return ;
}
|
[Java] 纯文本查看 复制代码 1 2 3 4 | v0_3.update( new byte []{ 127 });v0_3.update(str.getBytes());
v0_3.update( new byte []{ 1 });
v1_5 = new String(Base64.encode(v0_3.digest(), 0 ));
v0_5 = v1_5;
|
由于前面对v0_3的处理,导致不能相等,所以只剩下label_170:这个独苗,然后看可以谁跳转到label_170:
[Java] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 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 | char [] v1_6 = str.toCharArray();
v0_6 = str.substring( 0 , 2 ).hashCode();
if (v0_6 > 3904 ) {
this .b.sendEmptyMessage( 4 );
return ;
}
if (v0_6 == 3618 ) {
if (v1_6[ 0 ] + v1_6[ 1 ] != 168 ) {
goto label_178;
}
do {
label_144:
byte [] v5_1 = e. class .getAnnotation(f. class ).a() + a. class .getAnnotation(f. class ).a().getBytes();
if (v1_6.length - 2 == v5_1.length) {
v0_6 = 0 ;
while ( true ) {
if (v0_6 >= v5_1.length) {
goto label_188;
}
else if (v1_6[v0_6 + 2 ] != v5_1[v0_6]) {
v0_6 = 0 ;
}
else {
++v0_6;
continue ;
}
goto label_170;
}
}
goto label_177;
}
while ( true );
}
goto label_178;
}
|
分析可知,v0_6 == 3618 和 v1_6[0] + v1_6[1] = 168必须同时成立,v0_6 = str.substring(0, 2).hashCode();,由于前面置换表只有小写字母和数字,所以可以直接遍历
[C] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 | #include <stdio.h>
#include <stdlib.h>
int main()
{
int arry[] = { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122 };
int n = sizeof (arry) / sizeof (arry[0]);
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < n; j++)
{
if ((arry[i] * 31 + arry[j]) == 3618)
{
printf ( "%d----%d\n" , arry[i],arry[j]);
}
}
}
system ( "pause" );
return 0;
}
|
c语言很垃圾,只能写这个了.........结果有两个113----115和115----53,只有后面的符合要求,转换成acsll为s5,接着往下看
[Java] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 | byte [] v5_1 = e. class .getAnnotation(f. class ).a() + a. class .getAnnotation(f. class ).a().getBytes();
if (v1_6.length - 2 == v5_1.length) {
v0_6 = 0 ;
while ( true ) {
if (v0_6 >= v5_1.length) {
goto label_188;
}
else if (v1_6[v0_6 + 2 ] != v5_1[v0_6]) {
v0_6 = 0 ;
}
else {
++v0_6;
continue ;
}
goto label_170;
}
}
|
下面就可以看出来是比较了,要长度相等,字符相等,所以后面的为7e1p,加上前面的s5为s57e1p,然后再置换一下就行了,结果为... _____ ____. . ..___ .__.
贴下java的分析代码,很垃圾····························
[Java] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 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 | import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
public class aestest {
public static void main(String[] args) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException {
byte [] v2_3;
Cipher v1_1;
String v5 = "s57e1p" ;
String v1_5;
int v0_6;
MessageDigest v0_3;
char [] v1_6 = v5.toCharArray();
v0_3 = MessageDigest.getInstance( "sha1" );
v1_1 = Cipher.getInstance( "AES" );
Decoder decoder = Base64.getDecoder();
Encoder encode = Base64.getEncoder();
v1_1.init( 2 , new SecretKeySpec(decoder.decode( "GXiQHT1CZ2elMzwpvvAoPA==" .getBytes()), "AES" ));
v2_3 = v1_1.doFinal(decoder.decode( "hjdsUjIT5je69WXIZP7Kzw==" .getBytes( "UTf-8" )));
System.out.println(v2_3);
v0_3.update( new byte []{ 127 });
v0_3.update(v5.getBytes());
v0_3.update( new byte []{ 1 });
String v6 = new String(v2_3);
v1_5 = new String(encode.encode(v0_3.digest()));
System.out.println(v1_5);
v0_6 = v5.substring( 0 , 2 ).hashCode();
System.out.println(v0_6);
}
}
|
|
-
-
CTF.zip
1.62 MB, 下载次数: 15, 下载积分: 吾爱币 -1 CB
免费评分
-
查看全部评分
|