CTF逆向记录
常见汇编指令记录
SHL
与SHR
SHL
左移指令使目的操作数逻辑左移一位,最低位用0
填充,最高位移入进位标志位,而进位标志位中原来的数值被丢弃
SHR
右移指令使目的操作数逻辑右移一位,最高位用0
填充,最低位移入进位标志位,而进位标志位中原来的数值被丢弃
SAL
与SAR
SAL
算术左移指令与SHL
指令相同
SAR
算术右移指令将目的操作数进行算术右移
SAR
会根据最高位是否为1来拓展符号位
假设AX=1000 0000
,SAR AX 1
,AX=1100 0000
0xE8
:CALL
0x90
:NOP
test eax,eax
test
逻辑与运算结果为零,就把ZF(零标志)置1
当eax=0
时,置z标志位为1,jz
跳转,jnz
不跳转
当eax=1
时,置z标志位为0,jz
不跳转,jnz
跳转
cmp eax,eax
cmp
算术减法运算结果为零,就把ZF(零标志)置1
当eax=0
时,置z标志位为1,jz
跳转,jnz
不跳转
当eax=1
时,置z标志位为1,jz
跳转,jnz
不跳转
test相当于两个参数做逻辑与运算,cmp相当与两个参数做减法运算
如果结果为0就置z标志位为1,如果结果不为0就置z标志位为0
当z标志位为1时,jz
跳转,jnz
不跳转
当z标志位为0时,jz
不跳转,jnz
跳转
jz
:结果为0时跳转
jnz
:结果不为0时跳转
常用脚本 base64改表 1 2 3 4 5 6 import base64a = "R9Ly6NoJvsIPnWhETYtHe4Sdl+MbGujaZpk102wKCr7/ODg5zXAFqQfxBicV3m8U" b = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" base_fix = "+wXp+xDkldnFdFNFdxnzdFWpGx2m" table = '' .maketrans(a, b) print(base64.b64decode(base_fix.translate(table)))
1 b'flag{bas3_1s_s0_3asy}'
z3求解器 https://github.com/Z3Prover/z3
安装
pip install z3-solver
常用数据类型
Int
:整数(数学意义上)
Bool
:布尔型
Array
:数组
BitVec('x',n)
:n位整型,例如:char
类型可被设置为Bitvec('x',8)
常用API
Solver()
:创建一个通用求解器,创建后我们可以添加我们的约束条件,进行下一步的求解
add()
:添加约束条件,通常在solver()
命令之后,添加的约束条件通常是一个逻辑等式
check()
:通常用来判断在添加完约束条件后,来检测解的情况,有解的时候会回显sat
,无解的时候会回显unsat
model()
:在存在解的时候,该函数会将每个限制条件所对应的解集取交集,进而得出正解
解题记录 https://drive.misaka.gq/CTF_Re/
32c3ctf-2015 libdroid 通过jadx得到部分代码,同时通过ida反编译so文件得到原生函数代码
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 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 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 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 package ctf.stratumauhhur.libdroid;import android.os.Bundle;import android.support.design.widget.Snackbar;import android.support.v7.app.AppCompatActivity;import android.util.Base64;import android.view.View;import java.io.BufferedReader;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.InputStream;import java.io.InputStreamReader;public class a extends AppCompatActivity { static String a = a(getOperatingSystem(), 1 ); static String b = a(getPhoneNumber(), 1 ); static String c = a(installRootkit(), 1 ); static String d = a(generateConfusion(), 1 ); static Object f = a(obtainWorldDomination(), 1 ); static String flag = a(getFlag(), 1 ); static String g = a(installiOS(), 1 ); String e; public static native String generateConfusion () ; public static native String getFlag () ; public static native String getOperatingSystem () ; public static native String getPhoneNumber () ; public static native String installRootkit () ; public static native String installiOS () ; public static native String obtainWorldDomination () ; private static native void phoneHome (byte [] bArr, byte [] bArr2) ; @Override public void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_a); try { a(a); } catch (Exception e2) { } this .e = "" ; } public byte [] a(byte [] a0, String a1) { byte [] a2 = new byte [a0.length]; for (char a3 = 0 ; a3 < a2.length; a3 = (char ) (a3 + 1 )) { a2[a3] = (byte ) (a0[a3] ^ a1.charAt(a3 % a1.length())); } return a2; } public void a (View v) { if (v.getId() == R.id.button) { this .e += d.charAt(1 ); } if (v.getId() == R.id.button2) { this .e += d.charAt(2 ); } if (v.getId() == R.id.button3) { this .e += d.charAt(3 ); } if (v.getId() == R.id.button4) { this .e += d.charAt(4 ); } if (v.getId() == R.id.button5) { this .e += d.charAt(5 ); } if (v.getId() == R.id.button6) { this .e += d.charAt(6 ); } if (v.getId() == R.id.button7) { this .e += d.charAt(7 ); } if (v.getId() == R.id.button8) { this .e += d.charAt(8 ); } if (v.getId() == R.id.button9) { this .e += d.charAt(9 ); } if (v.getId() == R.id.button10) { this .e += d.charAt(0 ); } if (this .e.length() == 6 || v.getId() == R.id.button11) { String flag2 = flag; try { InputStream b2 = getAssets().open(g); ByteArrayOutputStream b22 = new ByteArrayOutputStream(); byte [] data = new byte [16384 ]; while (true ) { int nRead = b2.read(data, 0 , data.length); if (nRead == -1 ) { break ; } b22.write(data, 0 , nRead); } b22.flush(); byte [] j = b22.toByteArray(); byte [] f_ = new byte [16 ]; System.arraycopy((byte []) f, 0 , f_, 0 , ((byte []) f).length); System.arraycopy(this .e.getBytes(), 0 , f_, 10 , this .e.getBytes().length); phoneHome(j, f_); if (new String(j).startsWith(c)) { flag2 = new String(j); } } catch (Exception e1) { e1.printStackTrace(); } Snackbar.make(v, flag2, 0 ).setAction("Action" , (View.OnClickListener) null ).show(); this .e = "" ; } } public void a (String a2) throws Exception { InputStream b2 = getAssets().open(a2); ByteArrayOutputStream b22 = new ByteArrayOutputStream(); byte [] data = new byte [16384 ]; while (true ) { int nRead = b2.read(data, 0 , data.length); if (nRead == -1 ) { break ; } b22.write(data, 0 , nRead); } b22.flush(); BufferedReader b4 = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(a(b22.toByteArray(), b)))); while (true ) { String c2 = b4.readLine(); if (c2 != null ) { if (c2.startsWith(g)) { g = c2.substring(g.length()); } if (c2.startsWith((String) f)) { f = Base64.decode(c2.substring(((String) f).length()), 0 ); } } else { return ; } } } static String a (String a2, int b2) { StackTraceElement a0 = new Exception().getStackTrace()[b2]; StringBuilder a1 = new StringBuilder(); a1.append(a0.getClassName()).insert(b2, a0.getMethodName()); String a12 = a1.toString(); char [] a22 = new char [a2.length()]; char a4 = 0 ; char a3 = (char ) a12.length(); while (a4 < a2.length()) { a22[a4] = (char ) (a12.charAt(a3 - 1 ) ^ (a2.charAt(a4) ^ 18 )); char a42 = (char ) (a4 + 1 ); if (a42 >= a2.length()) { break ; } a22[a42] = (char ) (a12.charAt(a3 - 1 ) ^ (a2.charAt(a42) ^ 250 )); a4 = (char ) (a42 + 1 ); a3 = (char ) (a3 - 1 ); if (a3 <= 0 ) { a3 = (char ) a12.length(); } } return String.valueOf(a22); } static { System.loadLibrary("libdroid" ); } }
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 int __cdecl Java_ctf_stratumauhhur_libdroid_a_getOperatingSystem (int *a1) { int v1; __int16 v3; __int16 v4; __int16 v5; __int16 v6; __int16 v7; __int16 v8; __int16 v9; __int16 v10; __int16 v11; __int16 v12; v3 = 0x10 ; v4 = 0xF4 ; v1 = *a1; v5 = 0x52 ; v6 = 0xB2 ; v7 = 0x1F ; v8 = 0xF9 ; v9 = 0x55 ; v10 = 0xFA ; v11 = 0x13 ; v12 = 0xFC ; return (*(v1 + 652 ))(a1, &v3, 10 ); }
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 int __cdecl Java_ctf_stratumauhhur_libdroid_a_getPhoneNumber (int *a1) { int v1; __int16 v3; __int16 v4; __int16 v5; __int16 v6; __int16 v7; __int16 v8; __int16 v9; __int16 v10; __int16 v11; __int16 v12; __int16 v13; __int16 v14; v3 = 0x11 ; v4 = 0xF7 ; v1 = *a1; v5 = 0x5D ; v6 = 0xB6 ; v7 = 0x1A ; v8 = 0xFF ; v9 = 0x19 ; v10 = 0xFF ; v11 = 0x1C ; v12 = 0xF7 ; v13 = 0xC ; v14 = 0xE9 ; return (*(v1 + 652 ))(a1, &v3, 12 ); }
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 int __cdecl Java_ctf_stratumauhhur_libdroid_a_generateConfusion (int *a1) { int v1; __int16 v3; __int16 v4; __int16 v5; __int16 v6; __int16 v7; __int16 v8; __int16 v9; __int16 v10; __int16 v11; __int16 v12; __int16 v13; v3 = 0x53 ; v4 = 0xAA ; v1 = *a1; v5 = 0xE ; v6 = 0xE7 ; v7 = 0x42 ; v8 = 0xAB ; v9 = 0x4D ; v10 = 0xA4 ; v11 = 0x45 ; v12 = 0xAC ; v13 = 0x50 ; return (*(v1 + 652 ))(a1, &v3, 11 ); }
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 int __cdecl Java_ctf_stratumauhhur_libdroid_a_getFlag (int *a1) { int v1; __int16 v3; __int16 v4; __int16 v5; __int16 v6; __int16 v7; __int16 v8; __int16 v9; __int16 v10; __int16 v11; __int16 v12; __int16 v13; __int16 v14; __int16 v15; __int16 v16; __int16 v17; __int16 v18; __int16 v19; __int16 v20; __int16 v21; __int16 v22; __int16 v23; __int16 v24; __int16 v25; __int16 v26; __int16 v27; __int16 v28; __int16 v29; v3 = 0x20 ; v4 = 0xF4 ; v1 = *a1; v5 = 0x4E ; v6 = 0xA6 ; v7 = 0xF ; v8 = 0xBE ; v9 = 0x15 ; v10 = 0xFC ; v11 = 0x5D ; v12 = 0xE7 ; v13 = 0xF ; v14 = 0xE7 ; v15 = 2 ; v16 = 0xF5 ; v17 = 0x19 ; v18 = 0xEC ; v19 = 0x5B ; v20 = 0xF5 ; v21 = 0x11 ; v22 = 0xE4 ; v23 = 0x1C ; v24 = 0xAD ; v25 = 0xF ; v26 = 0xFD ; v27 = 0x47 ; v28 = 0xB5 ; v29 = 0x52 ; return (*(v1 + 652 ))(a1, &v3, 27 ); }
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 int __cdecl Java_ctf_stratumauhhur_libdroid_a_installRootkit (int *a1) { int v1; __int16 v3; __int16 v4; __int16 v5; __int16 v6; __int16 v7; __int16 v8; __int16 v9; __int16 v10; __int16 v11; __int16 v12; v3 = 0x30 ; v4 = 0xF4 ; v1 = *a1; v5 = 0x52 ; v6 = 0xB3 ; v7 = 4 ; v8 = 0xFF ; v9 = 0xF ; v10 = 0xE6 ; v11 = 0x11 ; v12 = 0xF4 ; return (*(v1 + 652 ))(a1, &v3, 10 ); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 int __cdecl Java_ctf_stratumauhhur_libdroid_a_obtainWorldDomination (int *a1) { int v1; __int16 v3; __int16 v4; __int16 v5; __int16 v6; v3 = 0x18 ; v4 = 0xFE ; v1 = *a1; v5 = 0x45 ; v6 = 0xE9 ; return (*(v1 + 652 ))(a1, &v3, 4 ); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 int __cdecl Java_ctf_stratumauhhur_libdroid_a_installiOS (int *a1) { int v1; __int16 v3; __int16 v4; __int16 v5; __int16 v6; __int16 v7; __int16 v8; __int16 v9; __int16 v10; v3 = 1 ; v4 = 0xF4 ; v1 = *a1; v5 = 0x53 ; v6 = 0xA0 ; v7 = 0x1D ; v8 = 0xF7 ; v9 = 0xF ; v10 = 0xAE ; return (*(v1 + 652 ))(a1, &v3, 8 ); }
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 int __cdecl Java_ctf_stratumauhhur_libdroid_a_phoneHome (int a1, int a2, int a3, int a4) { unsigned __int8 *v4; int v5; int v6; unsigned int v7; unsigned int v8; unsigned int v9; int v10; int v12; int v13; int v14; char *v15; unsigned int v16; int v17; int v18; v17 = (*(*a1 + 736 ))(a1, a3, 0 ); v18 = (*(*a1 + 736 ))(a1, a4, 0 ); v4 = v18; v5 = (*(*a1 + 684 ))(a1, a3); v12 = (v4[2 ] << 16 ) | (v4[3 ] << 24 ) | *v4 | (v4[1 ] << 8 ); v13 = (v4[6 ] << 16 ) | (v4[7 ] << 24 ) | v4[4 ] | (v4[5 ] << 8 ); v14 = (v4[10 ] << 16 ) | (v4[11 ] << 24 ) | v4[8 ] | (v4[9 ] << 8 ); v6 = (v4[15 ] << 24 ) | v4[12 ] | (v4[13 ] << 8 ) | (v4[14 ] << 16 ); if ( v5 > 0 ) { v15 = (v17 + 1 ); v16 = v17 + ((v5 - 1 ) & 0xFFFFFFF8 ) + 9 ; do { v7 = (*v15 << 8 ) | (v15[2 ] << 24 ) | *(v15 - 1 ) | (v15[1 ] << 16 ); v8 = 0xD5B7DDE0 ; v9 = (v15[4 ] << 8 ) | v15[3 ] | (v15[6 ] << 24 ) | (v15[5 ] << 16 ); do { v9 -= (v7 + v8) ^ (16 * v7 + v14) ^ (v6 + (v7 >> 5 )); v7 -= (v9 + v8) ^ (16 * v9 + v12) ^ (v13 + (v9 >> 5 )); v8 += 0x21524111 ; } while ( v8 ); *(v15 - 1 ) = v7; v10 = (v15 + 8 ); *(v10 - 8 ) = BYTE1(v7); *(v10 - 7 ) = BYTE2(v7); *(v10 - 6 ) = HIBYTE(v7); *(v10 - 5 ) = v9; *(v10 - 3 ) = BYTE2(v9); *(v10 - 2 ) = HIBYTE(v9); v15 += 8 ; } while ( v10 != v16 ); } (*(*a1 + 768 ))(a1, a3, v17, 0 ); return (*(*a1 + 768 ))(a1, a4, v18, 0 ); }
static String a(String a2, int b2)
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 a12="c<clinit>tf.stratumauhhur.libdroid.a" a=[0x10 ,0xF4 ,0x52 ,0xB2 ,0x1F ,0xF9 ,0x55 ,0xFA ,0x13 ,0xFC ] b=[0x11 ,0xF7 ,0x5D ,0xB6 ,0x1A ,0xFF ,0x19 ,0xFF ,0x1C ,0xF7 ,0x0C ,0xE9 ] c=[0x30 ,0xF4 ,0x52 ,0xB3 ,0x04 ,0xFF ,0x0F ,0xE6 ,0x11 ,0xF4 ] d=[0x53 ,0xAA ,0x0E ,0xE7 ,0x42 ,0xAB ,0x4D ,0xA4 ,0x45 ,0xAC ,0x50 ] f=[0x18 ,0xFE ,0x45 ,0xE9 ] flag=[0x20 ,0xF4 ,0x4E ,0xA6 ,0x0F ,0xBE ,0x15 ,0xFC ,0x5D ,0xE7 ,0x0F ,0xE7 ,0x02 ,0xF5 ,0x19 ,0xEC ,0x5B ,0xF5 ,0x11 ,0xE4 ,0x1C ,0xAD ,0x0F ,0xFD ,0x47 ,0xB5 ,0x52 ] file_name=[0x01 ,0xF4 ,0x53 ,0xA0 ,0x1D ,0xF7 ,0x0F ,0xAE ] a4=0 a3=len (a12) a2=file_name a22=[0 for i in range (len (a2))] while a4<len (a2): a22[a4]=ord (a12[a3-1 ])^(a2[a4]^18 ) a42=a4+1 if a42>=len (a2): break a22[a42]=ord (a12[a3-1 ])^(a2[a42]^250 ) a4=a42+1 a3-=1 if a3<=0 : a3=len (a12) for i in a22: print(chr (i),end="" ) ''' a="config.ini" b="blablablabla" c="Congratula" d=" 1234567890" f="key=" flag="Sorry no rootkit for you :(" file_name="rootkit=" '''
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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 #include <stdio.h> void test (unsigned char arg1,unsigned char arg2,unsigned char arg3,unsigned char arg4,unsigned char arg5,unsigned char arg6) { unsigned char *v10; unsigned char v17[113 ]={0xFE ,0xA0 ,0xAD ,0x80 ,0x20 ,0x59 ,0xAB ,0x12 ,0xD7 ,0xC3 ,0x9C ,0x88 ,0xFA ,0x2C ,0x1D ,0xFC ,0x81 ,0x46 ,0x0D ,0xDC ,0xE9 ,0xCE ,0xCC ,0x57 ,0x78 ,0xF5 ,0x41 ,0x5F ,0x52 ,0x02 ,0x36 ,0xD5 ,0x33 ,0x18 ,0x66 ,0x3A ,0x40 ,0x26 ,0xE8 ,0x6E ,0xB6 ,0xCD ,0x72 ,0xB7 ,0x3C ,0x01 ,0x66 ,0xB1 ,0x4F ,0x99 ,0x23 ,0x63 ,0x95 ,0x77 ,0x34 ,0x61 ,0x69 ,0xF6 ,0xA9 ,0x53 ,0x40 ,0x37 ,0x41 ,0x43 ,0x4F ,0x98 ,0x95 ,0x2C ,0x7A ,0x27 ,0x3C ,0x98 ,0x68 ,0x1A ,0x88 ,0xA8 ,0xB7 ,0x85 ,0xBB ,0x15 ,0x4F ,0x1A ,0x01 ,0x4D ,0xC9 ,0xC8 ,0x9B ,0x75 ,0x78 ,0x57 ,0x7F ,0x98 ,0x0D ,0xD8 ,0x51 ,0xA8 ,0x22 ,0xB9 ,0x5E ,0x59 ,0x4D ,0x71 ,0x4F ,0x1A ,0x81 ,0xA9 ,0xBF ,0x07 ,0x29 ,0xED ,0xFD ,0x83 }; unsigned char v18[16 ]={0x21 ,0x00 ,0x86 ,0xb7 ,0xff ,0x86 ,0x5d ,0x06 ,0x2d ,0x30 }; v18[10 ]=arg1; v18[11 ]=arg2; v18[12 ]=arg3; v18[13 ]=arg4; v18[14 ]=arg5; v18[15 ]=arg6; unsigned int v12 = (v18[2 ] << 16 ) | (v18[3 ] << 24 ) | *v18 | (v18[1 ] << 8 ); unsigned int v13 = (v18[6 ] << 16 ) | (v18[7 ] << 24 ) | v18[4 ] | (v18[5 ] << 8 ); unsigned int v14 = (v18[10 ] << 16 ) | (v18[11 ] << 24 ) | v18[8 ] | (v18[9 ] << 8 ); unsigned int v6 = (v18[15 ] << 24 ) | v18[12 ] | (v18[13 ] << 8 ) | (v18[14 ] << 16 ); int v5=112 ; if (v5>0 ){ unsigned char *v15=v17+1 ; unsigned char *v16 = v17 + ((v5 - 1 ) & 0xFFFFFFF8 ) + 9 ; do { unsigned int v7 = (*v15 << 8 ) | (v15[2 ] << 24 ) | *(v15 - 1 ) | (v15[1 ] << 16 ); unsigned int v8 = 0xD5B7DDE0 ; unsigned int v9 = (v15[4 ] << 8 ) | v15[3 ] | (v15[6 ] << 24 ) | (v15[5 ] << 16 ); do { v9 -= (v7 + v8) ^ (16 * v7 + v14) ^ (v6 + (v7 >> 5 )); v7 -= (v9 + v8) ^ (16 * v9 + v12) ^ (v13 + (v9 >> 5 )); v8 += 0x21524111 ; }while (v8); unsigned char v7_0,v7_1,v7_2,v7_3,v9_0,v9_1,v9_2,v9_3; v7_0=v7&0xff ; v7_1=(v7>>8 )&0xff ; v7_2=(v7>>16 )&0xff ; v7_3=(v7>>24 )&0xff ; v9_0=v9&0xff ; v9_1=(v9>>8 )&0xff ; v9_2=(v9>>16 )&0xff ; v9_3=(v9>>24 )&0xff ; *(v15 - 1 ) = v7_0; unsigned char *v10 = (v15 + 8 ); *(v10 - 8 ) = v7_1; *(v10 - 7 ) = v7_2; *(v10 - 6 ) = v7_3; *(v10 - 5 ) = v9_0; *(v10 - 4 ) = v9_1; *(v10 - 3 ) = v9_2; *(v10 - 2 ) = v9_3; v15 += 8 ; }while (v10 != v16 && v15-v17<=112 ); } if (v17[0 ]==67 &&v17[1 ]==111 &&v17[2 ]==110 ){ printf ("%c%c%c%c%c%c " ,arg1,arg2,arg3,arg4,arg5,arg6); for (int i=0 ;i<112 ;++i){ printf ("%c" ,v17[i]); } printf ("\n\n" ); } } int main () { unsigned char button[12 ]=" 1234567890" ; for (int i=0 ;i<12 ;++i){ for (int j=0 ;j<12 ;++j){ for (int k=0 ;k<12 ;++k){ for (int l=0 ;l<12 ;++l){ for (int m=0 ;m<12 ;++m){ for (int n=0 ;n<12 ;++n){ test(button[i],button[j],button[k],button[l],button[m],button[n]); } } } } } } return 0 ; }
1 1 3875 Congratulations! The rootkit is sucessfully installed. The Flag is 32C3_this_is_build_for_flag_ship_phones
输入103875
得到flag32C3_this_is_build_for_flag_ship_phones
2019_西湖论剑_预选赛 testre main 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 __int64 __fastcall main (__int64 a1, char **a2, char **a3) { void *ptr; __int64 v5; char input; int v7; v7 = 0 ; v5 = 256LL ; sub_400D00(&input, 17uLL ); ptr = malloc (256uLL ); sub_400700(ptr, &v5, &input, 16uLL ); free (ptr); return 0LL ; }
读入函数
sub_400D00 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 __int64 __fastcall sub_400D00 (__int64 a1, unsigned __int64 a2) { char buf; unsigned __int64 i; unsigned __int64 v5; __int64 v6; v6 = a1; v5 = a2; for ( i = 0LL ; i < v5; ++i ) { read(0 , &buf, 1uLL ); *(v6 + i) = buf; } *(v6 + v5 - 1 ) = 0 ; fflush(stdout ); return i; }
输入长度为17,最后一位被去除,实际有效长度为16位
处理函数
sub_400700 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 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 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 123 124 125 126 127 128 129 130 131 132 133 __int64 __fastcall sub_400700 (void *a1, _QWORD *a2, __int64 a3, size_t a4) { unsigned __int8 *v4; __int64 v6; int c; char v8; int v9; bool v10; unsigned __int8 *v11; char v12; int v13; int v14; unsigned __int64 i; size_t n_num_23; size_t v17; size_t v18; size_t j; size_t v20; int per_ch; unsigned __int64 temp; int v23_num_20; __int64 *v24; __int64 input; void *v26; int v27; unsigned __int64 len_16; __int64 v29; _QWORD *v30; void *result; char v32; result = a1; v30 = a2; v29 = a3; len_16 = a4; v27 = 0xDEADBEEF ; v26 = malloc (0x100 uLL); input = v29; v24 = &v6; temp = 0LL ; v17 = 0LL ; for ( i = 0LL ; i < len_16; ++i ) { v13 = *(input + i); *(v26 + i) = byte_400E90[i % 29 ] ^ v13; *(v26 + i) += *(input + i); } while ( 1 ) { v12 = 0 ; if ( v17 < len_16 ) v12 = ~(*(input + v17) != 0 ); if ( !(v12 & 1 ) ) break ; ++v17; } n_num_23 = ((0x28F5C28F5C28F5C3 LL * (138 * (len_16 - v17) >> 2 ) >> 64 ) >> 2 ) + 1 ; v23_num_20 = ((0xAAAAAAAAAAAAAAAB LL * ((v17 + len_16) << 6 ) >> 64 ) >> 5 ) - 1 ; v11 = &v6 - ((((0x28F5C28F5C28F5C3 LL * (138 * (len_16 - v17) >> 2 ) >> 64 ) >> 2 ) + 16 ) & 0xFFFFFFFFFFFFFFF0 LL); memset (v11, 0 , n_num_23); v20 = v17; v18 = n_num_23 - 1 ; while ( v20 < len_16 ) { per_ch = *(input + v20); for ( j = n_num_23 - 1 ; ; --j ) { v10 = 1 ; if ( j <= v18 ) v10 = per_ch != 0 ; if ( !v10 ) break ; temp = v11[j] << 6 ; per_ch += v11[j] << 8 ; v9 = 64 ; v11[j] = per_ch % 58 ; *(v26 + j) = temp & 0x3F ; temp >>= 6 ; per_ch /= 58 ; v27 /= v9; if ( !j ) break ; } ++v20; v18 = j; } for ( j = 0LL ; ; ++j ) { v8 = 0 ; if ( j < n_num_23 ) v8 = ~(v11[j] != 0 ); if ( !(v8 & 1 ) ) break ; } if ( *v30 > n_num_23 + v17 - j ) { if ( v17 ) { c = 61 ; memset (result, 49 , v17); memset (v26, c, v17); } v20 = v17; while ( j < n_num_23 ) { v4 = v11; *(result + v20) = byte_400EB0[v11[j]]; *(v26 + v20++) = byte_400EF0[v4[j++]]; } *(result + v20) = 0 ; *v30 = v20 + 1 ; if ( !strncmp (result, "D9" , 2uLL ) && !strncmp (result + 20 , "Mp" , 2uLL ) && !strncmp (result + 18 , "MR" , 2uLL ) && !strncmp (result + 2 , "cS9N" , 4uLL ) && !strncmp (result + 6 , "9iHjM" , 5uLL ) && !strncmp (result + 11 , "LTdA8YS" , 7uLL ) ) { HIDWORD(v6) = puts ("correct!" ); } v32 = 1 ; v14 = 1 ; } else { *v30 = n_num_23 + v17 - j + 1 ; v32 = 0 ; v14 = 1 ; } return v32 & 1 ; }
从结果往前推导,便于提出混淆函数与变量
目标结果为D9cS9N9iHjMLTdA8YSMRMp
,而result
与v11
有关
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 while ( v20 < len_16 ) { per_ch = *(input + v20); for ( j = n_num_23 - 1 ; ; --j ) { v10 = 1 ; if ( j <= v18 ) v10 = per_ch != 0 ; if ( !v10 ) break ; temp = v11[j] << 6 ; per_ch += v11[j] << 8 ; v9 = 64 ; v11[j] = per_ch % 58 ; *(v26 + j) = temp & 0x3F ; temp >>= 6 ; per_ch /= 58 ; v27 /= v9; if ( !j ) break ; } ++v20; v18 = j; }
1 2 3 per_ch += v11[j] << 8 ; v11[j] = per_ch % 58 ; per_ch /= 58 ;
可以推断为base58
根据密文D9cS9N9iHjMLTdA8YSMRMp
进行解密,得到flagbase58_is_boring
1 2 import base58print(base58.b58decode(b"D9cS9N9iHjMLTdA8YSMRMp" ))
2019_DDCTF Windows_Reverse2 PEiD查壳(ASPack 2.12 -> Alexey Solodovnikov)
x32dbg载入,步进到call 6B600A
得到ESP00F8FF00
,在此处下断点
运行到断点处,然后步进到第二个ret
,得到push ebp
处的地址进行dump
dump后进行查壳
main 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 int maybe_main () { char v1; char v2; char input; char v4; char v5; char v6; input = 0 ; memset (&v4, 0 , 1023 ); v5 = 0 ; memset (&v6, 0 , 1023 ); MEMORY[0x712420C1 ]("input code:" ); MEMORY[0x712426D4 ]("%s" , &input); if ( !sub_6D11F0(&input) ) { MEMORY[0x712420C1 ]("invalid input\n" ); MEMORY[0x71232455 ](0 ); } sub_6D1240(&input, &v5); v1 = 0 ; memset (&v2, 0 , 1023 ); MEMORY[0x71242E73 ](&v1, "DDCTF{%s}" , &v5); if ( !strcmp (&v1, "DDCTF{reverse+}" ) ) MEMORY[0x712420C1 ]("You've got it !!! %s\n" , &v1); else MEMORY[0x712420C1 ]("Something wrong. Try again...\n" ); return 0 ; }
sub_6D1240(&input, &v5);
对输入进行处理
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 int __usercall sub_6D1240@<eax>(const char *input@<esi>, int a2){ signed int input_len; signed int index; char v4; char each; char each_1; unsigned int v7; char v9; char v10; char v11; input_len = strlen (input); v10 = 0 ; memset (&v11, 0 , 1023 ); index = 0 ; if ( input_len > 0 ) { v4 = v9; do { each = input[index]; if ( (input[index] - 48 ) > 9u ) { if ( (each - 65 ) <= 5u ) v9 = each - 55 ; } else { v9 = input[index] - 48 ; } each_1 = input[index + 1 ]; if ( (input[index + 1 ] - 48 ) > 9u ) { if ( (each_1 - 65 ) <= 5u ) v4 = each_1 - 55 ; } else { v4 = input[index + 1 ] - 48 ; } v7 = index >> 1 ; index += 2 ; *(&v10 + v7) = v4 | 16 * v9; } while ( index < input_len ); } return sub_6D1000(input_len / 2 , a2); }
sub_6D1000(input_len / 2, a2);
真正的处理
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 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 int __cdecl sub_6D1000 (int a1, int a2) { char *v2; int v3; char *v4; signed int v5; unsigned __int8 v6; signed int v7; int v8; int v9; int v10; int v11; int *v12; unsigned __int8 v14; unsigned __int8 v15; unsigned __int8 v16; int v17; int v18; char v19; int *v20; int v21; unsigned int v22; int v23; v3 = a1; v4 = v2; v18 = a2; MEMORY[0x74A15E81 ](&v19); v5 = 0 ; v23 = 0 ; if ( a1 ) { do { *(&v14 + v5) = *v4; v6 = v15; ++v5; --v3; ++v4; if ( v5 == 3 ) { LOBYTE(v17) = v14 >> 2 ; BYTE1(v17) = (v15 >> 4 ) + 16 * (v14 & 3 ); BYTE2(v17) = (v16 >> 6 ) + 4 * (v15 & 0xF ); HIBYTE(v17) = v16 & 0x3F ; v7 = 0 ; do MEMORY[0x74A172EE ](&v19, (byte_6D3020[*(&v17 + v7++)] ^ 0x76 )); while ( v7 < 4 ); v5 = 0 ; } } while ( v3 ); if ( v5 ) { if ( v5 < 3 ) { memset ((&v14 + v5), 0 , 3 - v5); v6 = v15; } BYTE1(v17) = (v6 >> 4 ) + 16 * (v14 & 3 ); LOBYTE(v17) = v14 >> 2 ; BYTE2(v17) = (v16 >> 6 ) + 4 * (v6 & 0xF ); v8 = 0 ; for ( HIBYTE(v17) = v16 & 0x3F ; v8 < v5 + 1 ; ++v8 ) MEMORY[0x74A172EE ](&v19, (byte_6D3020[*(&v17 + v8)] ^ 0x76 )); if ( v5 < 3 ) { v9 = 3 - v5; do { MEMORY[0x74A172EE ](&v19, '=' ); --v9; } while ( v9 ); } } } v10 = v21; v11 = v18; memset (v18, 0 , v21 + 1 ); v12 = v20; if ( v22 < 0x10 ) v12 = &v20; sub_6D1C64(v11, v12, v10); v23 = -1 ; return MEMORY[0x74A15EBB ](); }
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 base64_table=[55 , 52 , 53 , 50 , 51 , 48 , 49 , 62 , 63 , 60 , 61 , 58 , 59 , 56 , 57 , 38 , 39 , 36 , 37 , 34 , 35 , 32 , 33 , 46 , 47 , 44 , 23 , 20 , 21 , 18 , 19 , 16 , 17 , 30 , 31 , 28 , 29 , 26 , 27 , 24 , 25 , 6 , 7 , 4 , 5 , 2 , 3 , 0 , 1 , 14 , 15 , 12 , 70 , 71 , 68 , 69 , 66 , 67 , 64 , 65 , 78 , 79 , 93 , 89 ] s="reverse+" s_list=[4 , 19 , 0 , 19 , 4 , 5 , 19 , 93 ] s_posi=[43 , 30 , 47 , 30 , 43 , 44 , 30 , 62 ] for i in s_posi: print(bin (i)[2 :].zfill(8 )) ''' 00101011 00011110 00101111 00011110 00101011 00101100 00011110 00111110 hex(0b10101101) ad hex(0b11101011) eb hex(0b11011110) de hex(0b10101110) ae hex(0b11000111) c7 hex(0b10111110) be flag:DDCTF{ADEBDEAEC7BE} '''
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 int __cdecl main (int argc, const char **argv, const char **envp) { char Dest; char v5; char v6; char Dst; char v8; char v9; v6 = 0 ; memset (&Dst, 0 , 0x3FF u); v8 = 0 ; memset (&v9, 0 , 0x3FF u); printf (Format); scanf (aS, &v6); if ( !(unsigned __int8)sub_7411F0() ) { printf (aInvalidInput); exit (0 ); } sub_741240(&v8); Dest = 0 ; memset (&v5, 0 , 0x3FF u); sprintf (&Dest, aDdctfS, &v8); if ( !strcmp (&Dest, aDdctfReverse) ) printf (aYouVeGotItS, &Dest); else printf (aSomethingWrong); return 0 ; }
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 int __usercall sub_741240@<eax>(const char *a1@<esi>, int a2){ signed int v2; signed int v3; char v4; char v5; char v6; unsigned int v7; char v9; char v10; char Dst; v2 = strlen (a1); v10 = 0 ; memset (&Dst, 0 , 0x3FF u); v3 = 0 ; if ( v2 > 0 ) { v4 = v9; do { v5 = a1[v3]; if ( (unsigned __int8)(a1[v3] - 48 ) > 9u ) { if ( (unsigned __int8)(v5 - 65 ) <= 5u ) v9 = v5 - 55 ; } else { v9 = a1[v3] - 48 ; } v6 = a1[v3 + 1 ]; if ( (unsigned __int8)(a1[v3 + 1 ] - 48 ) > 9u ) { if ( (unsigned __int8)(v6 - 65 ) <= 5u ) v4 = v6 - 55 ; } else { v4 = a1[v3 + 1 ] - 48 ; } v7 = (unsigned int )v3 >> 1 ; v3 += 2 ; *(&v10 + v7) = v4 | 16 * v9; } while ( v3 < v2 ); } return sub_741000(v2 / 2 , a2); }
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 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 int __cdecl sub_741000 (int a1, void *a2) { char *v2; int v3; char *v4; signed int v5; unsigned __int8 v6; signed int v7; int v8; int v9; size_t v10; void *v11; const void *v12; unsigned __int8 Dst; unsigned __int8 v15; unsigned __int8 v16; char v17; char v18; char v19; char i; void *v21; char v22; void *Src; size_t Size; unsigned int v25; int v26; v3 = a1; v4 = v2; v21 = a2; std ::basic_string<char ,std ::char_traits<char >,std ::allocator<char >>::basic_string<char ,std ::char_traits<char >,std ::allocator<char >>(&v22); v5 = 0 ; v26 = 0 ; if ( a1 ) { do { *(&Dst + v5) = *v4; v6 = v15; ++v5; --v3; ++v4; if ( v5 == 3 ) { v17 = Dst >> 2 ; v18 = (v15 >> 4 ) + 16 * (Dst & 3 ); v19 = (v16 >> 6 ) + 4 * (v15 & 0xF ); i = v16 & 0x3F ; v7 = 0 ; do std ::basic_string<char ,std ::char_traits<char >,std ::allocator<char >>::operator +=( &v22, (unsigned __int8)(byte_743020[(unsigned __int8)*(&v17 + v7++)] ^ 0x76 )); while ( v7 < 4 ); v5 = 0 ; } } while ( v3 ); if ( v5 ) { if ( v5 < 3 ) { memset (&Dst + v5, 0 , 3 - v5); v6 = v15; } v18 = (v6 >> 4 ) + 16 * (Dst & 3 ); v17 = Dst >> 2 ; v19 = (v16 >> 6 ) + 4 * (v6 & 0xF ); v8 = 0 ; for ( i = v16 & 0x3F ; v8 < v5 + 1 ; ++v8 ) std ::basic_string<char ,std ::char_traits<char >,std ::allocator<char >>::operator +=( &v22, (unsigned __int8)(byte_743020[(unsigned __int8)*(&v17 + v8)] ^ 0x76 )); if ( v5 < 3 ) { v9 = 3 - v5; do { std ::basic_string<char ,std ::char_traits<char >,std ::allocator<char >>::operator +=(&v22, 61 ); --v9; } while ( v9 ); } } } v10 = Size; v11 = v21; memset (v21, 0 , Size + 1 ); v12 = Src; if ( v25 < 0x10 ) v12 = &Src; memcpy (v11, v12, v10); v26 = -1 ; return std ::basic_string<char ,std ::char_traits<char >,std ::allocator<char >>::~basic_string<char ,std ::char_traits<char >,std ::allocator<char >>(); }
2019嘉韦思杯 梅津美治郎 进行动态调试
main 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 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 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 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 int __cdecl main (int argc, const char **argv, const char **envp) { const CHAR *v3; HMODULE v4; void (__stdcall *v5)(HMODULE, LPCSTR); char v7; char v8[4 ]; int v9; int v10; int v11; int v12; int v13; int v14; int v15; __int16 v16; int v17; int v18; int v19; int v20; int v21; int v22; int v23; int v24; int v25; int v26; int v27; int v28; int v29; char v30; int v31; int v32; int v33; int v34; int v35; int v36; int v37; int v38; __int16 v39; int v40; int v41; int v42; int v43; int v44; int v45; int v46; int v47; char v48; int v49; int v50; int v51; int v52; int v53; int v54; int v55; int v56; int v57; char v58; int v59; int v60; int v61; int v62; int v63; int v64; int v65; int v66; __int16 v67; int v68; int v69; char v70; int v71; int v72; int v73; int v74; int v75; int v76; int v77; int v78; int v79; int v80; int v81; int v82; int v83; int v84; int v85; int v86; int v87; __int16 v88; int *v89; v89 = &argc; sub_402940(); puts ( " . \n" " _|_ ROBOTIC AUTHENTICATION SYSTEM\n" " /\\/\\ (. .) /\n" " `||' |#| \n" " ||__.-\"-\"-.___ \n" " `---| . . |--.\\ \n" " | : : | ,||,\n" " `..-..' \\/\\/\n" " || || \n" " || || \n" " |__|__| \n" ); v49 = 1337 ; v50 = 1617194321 ; v51 = 1679910002 ; v52 = 1935963503 ; v53 = 1684632865 ; v54 = 1936221985 ; v55 = 1361147250 ; v56 = 1987211872 ; v57 = 996504430 ; v58 = 1 ; v40 = 1617194321 ; v41 = 1679910002 ; v42 = 1935963503 ; v43 = 1684632865 ; v44 = 1936221985 ; v45 = 1361147250 ; v46 = 1987211872 ; v47 = 996504430 ; v48 = 1 ; v59 = 1617194321 ; v60 = 1679910002 ; v61 = 1935963503 ; v62 = 1684632865 ; v63 = 1650749985 ; v64 = 560295790 ; v65 = 1920098385 ; v66 = 1702063734 ; v67 = 315 ; v31 = 1617194321 ; v32 = 1679910002 ; v33 = 1935963503 ; v34 = 1684632865 ; v35 = 1650749985 ; v36 = 560295790 ; v37 = 1920098385 ; v38 = 1702063734 ; v39 = 315 ; v68 = 1869557876 ; v69 = 1718432615 ; v70 = 3 ; v28 = 1869557876 ; v29 = 1718432615 ; v30 = 3 ; v71 = 1869833322 ; v72 = 858942820 ; v73 = 1835885871 ; v74 = 20906241 ; v24 = 1869833322 ; v25 = 858942820 ; v26 = 1835885871 ; v27 = 20906241 ; v75 = 1466262848 ; v76 = 1853186660 ; v77 = 1147495539 ; v78 = 1902404217 ; v79 = 1869506677 ; v80 = 1701797961 ; v81 = 24339565 ; v17 = 1466262848 ; v18 = 1853186660 ; v19 = 1147495539 ; v20 = 1902404217 ; v21 = 1869506677 ; v22 = 1701797961 ; v23 = 24339565 ; v82 = 561278552 ; v83 = 795830390 ; v84 = 1869496865 ; v85 = 1969255270 ; v86 = 1969253748 ; v87 = 1919905384 ; v88 = 288 ; v10 = 561278552 ; v11 = 795830390 ; v12 = 1869496865 ; v13 = 1969255270 ; v14 = 1969253748 ; v15 = 1919905384 ; v16 = 288 ; v9 = 1337 ; strcpy (v8, "r0b0RUlez!" ); dword_40AD94 = (int )&v9; dword_40ADA0 = (int )&v49; plz_enter_first_pwd = (char *)&v40; plz_enter_second_pwd = (char *)&v31; dword_40AD98 = (int )&v28; lpProcName = (LPCSTR)&v17; lpModuleName = (LPCSTR)&v24; dword_40ADA4 = (char *)&v10; sub_401500(0 ); v3 = lpProcName; v4 = GetModuleHandleA(lpModuleName); v5 = (void (__stdcall *)(HMODULE, LPCSTR))GetProcAddress(v4, v3); v5((HMODULE)1 , (LPCSTR)sub_40157F); puts (plz_enter_first_pwd); scanf ("%20s" , &v7); if ( !strcmp (&v7, v8) ) { puts ("You passed level1!" ); sub_4015EA(0 ); } return 0 ; }
v8
被赋值为r0b0RUlez!
sub_401500
用于对lpProcName
等字符串进行变换,变换完成后lpProcName
为AddVectoredExceptionHandler
(功能是在异常前执行指定函数),lpModuleName
为kernel32.dll
第一个密码输入r0b0RUlez!
,可以进入第二关
1 2 3 4 5 6 7 8 9 int __cdecl sub_4015EA (signed int a1) { if ( a1 <= 9 ) return sub_4015EA(a1 + 1 ); puts (plz_enter_second_pwd); dword_40ADA8 = 4199961 ; __debugbreak(); return 0 ; }
查看汇编代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 .text:00401607 loc_401607: ; CODE XREF: sub_4015EA+A↑j .text:00401607 mov eax, ds:plz_enter_second_pwd .text:0040160C mov [esp], eax ; char * .text:0040160F call puts .text:00401614 call $+5 .text:00401619 pop eax .text:0040161A mov ds:dword_40ADA8, eax .text:0040161F int 3 ; Trap to Debugger .text:00401620 mov eax, 0 .text:00401625 .text:00401625 locret_401625: ; CODE XREF: sub_4015EA+1B↑j .text:00401625 leave .text:00401626 retn .text:00401626 sub_4015EA endp
注意
1 2 .text:00401614 call $+5 .text:00401619 pop eax
call $+5
(从当前开始向下五个字节处开始执行)也就是跳转到pop eax
,看起来和直接跳到下一条指令没什么区别
但实际上,call
会把下一条要执行的指令地址压栈,这里也就是把00401619
压栈,再pop eax
,这时eax就是00401619
有一个int 3
的异常,可以被AddVectoredExceptionHandler
捕捉,由v5((HMODULE)1, (LPCSTR)sub_40157F);
进入sub_40157F
1 2 3 4 5 6 7 8 9 10 11 12 13 14 void __cdecl __noreturn sub_40157F (int a1) { char v1; int v2; v2 = *(_DWORD *)(*(_DWORD *)(a1 + 4 ) + 184 ); if ( v2 == dword_40ADA8 + 6 ) { scanf ("%20s" , &v1); if ( !sub_401547(&v1, (_BYTE *)dword_40AD98) ) puts (dword_40ADA4); } ExitProcess(0 ); }
1 2 3 4 5 6 7 8 9 10 11 signed int __cdecl sub_401547 (_BYTE *a1, _BYTE *a2) { while ( *a2 != 2 ) { if ( *a1 != (*a2 ^ 2 ) ) return 1 ; ++a1; ++a2; } return 0 ; }
dword_40AD98
为[117, 49, 110, 110, 102, 50, 108, 103]
由此可得第二关的密码
1 2 3 dword_40AD98=[117 , 49 , 110 , 110 , 102 , 50 , 108 , 103 ] for i in dword_40AD98: print(chr (i^2 ),end="" )
w3lld0ne
flag为flag{r0b0RUlez!_w3lld0ne}
9447 CTF 2014 no-strings-attached
可知这是32位的ELF程序,尝试运行
出现了无法运行的情况,安装gcc-multilib
sudo apt-get install gcc-multilib
main 1 2 3 4 5 6 7 8 int __cdecl main (int argc, const char **argv, const char **envp) { setlocale(6 , &locale); banner(); prompt_authentication(); authenticate(); return 0 ; }
banner 1 2 3 4 5 6 7 8 9 10 int banner () { unsigned int v0; v0 = time(0 ); srand(v0); wprintf(&unk_80488B0); rand(); return wprintf(&unk_8048960); }
prompt_authentication 1 2 3 4 int prompt_authentication () { return wprintf(&unk_80489F8); }
在authenticate
中,将s
和dword_8048A90
传递给了decrypt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 void authenticate () { wchar_t ws[8192 ]; wchar_t *s2; s2 = (wchar_t *)decrypt(&s, &dword_8048A90); if ( fgetws(ws, 0x2000 , stdin ) ) { ws[wcslen(ws) - 1 ] = 0 ; if ( !wcscmp(ws, s2) ) wprintf(&unk_8048B44); else wprintf(&unk_8048BA4); } free (s2); }
decrypt 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 wchar_t *__cdecl decrypt (wchar_t *s, wchar_t *a2) { size_t v2; signed int v4; signed int i; signed int v6; signed int v7; wchar_t *dest; v6 = wcslen(s); v7 = wcslen(a2); v2 = wcslen(s); dest = (wchar_t *)malloc (v2 + 1 ); wcscpy(dest, s); while ( v4 < v6 ) { for ( i = 0 ; i < v7 && v4 < v6; ++i ) dest[v4++] -= a2[i]; } return dest; }
s
和dword_8048A90
选中数据,用shift+E
提取数据,选择C xxx (dec)
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 s=[ 58 , 20 , 0 , 0 , 54 , 20 , 0 , 0 , 55 , 20 , 0 , 0 , 59 , 20 , 0 , 0 , 128 , 20 , 0 , 0 , 122 , 20 , 0 , 0 , 113 , 20 , 0 , 0 , 120 , 20 , 0 , 0 , 99 , 20 , 0 , 0 , 102 , 20 , 0 , 0 , 115 , 20 , 0 , 0 , 103 , 20 , 0 , 0 , 98 , 20 , 0 , 0 , 101 , 20 , 0 , 0 , 115 , 20 , 0 , 0 , 96 , 20 , 0 , 0 , 107 , 20 , 0 , 0 , 113 , 20 , 0 , 0 , 120 , 20 , 0 , 0 , 106 , 20 , 0 , 0 , 115 , 20 , 0 , 0 , 112 , 20 , 0 , 0 , 100 , 20 , 0 , 0 , 120 , 20 , 0 , 0 , 110 , 20 , 0 , 0 , 112 , 20 , 0 , 0 , 112 , 20 , 0 , 0 , 100 , 20 , 0 , 0 , 112 , 20 , 0 , 0 , 100 , 20 , 0 , 0 , 110 , 20 , 0 , 0 , 123 , 20 , 0 , 0 , 118 , 20 , 0 , 0 , 120 , 20 , 0 , 0 , 106 , 20 , 0 , 0 , 115 , 20 , 0 , 0 , 123 , 20 , 0 , 0 , 128 , 20 , 0 , 0 ] a2=[ 1 , 20 , 0 , 0 , 2 , 20 , 0 , 0 , 3 , 20 , 0 , 0 , 4 , 20 , 0 , 0 , 5 , 20 , 0 , 0 ] len_s = len (s) print(s,a2) len_a2 = len (a2) v2 = len (s) out=[] v4=0 while v4 < len_s: for i in range (len_a2): if v4<len_s: out.append(s[v4]-a2[i]) v4+=1 print(out) for i in out: if i>=0 : print(chr (i),end="" )
flag:9447{you_are_an_international_mystery}
由IDA分析知,在decrypt
函数运行结束时会返回flag,在decrypt
函数结束的地方0x08048707
下断点,并查看寄存器中的内容
在IDA中查看authenticate
的汇编
1 2 call decrypt mov [ebp+s2], eax
因此flag暂时位于寄存器eax中
也可以把断点打在decrypt
函数,然后执行下一步操作
西湖论剑 easycpp 首先进行静态分析
main 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 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 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 int __cdecl main (int argc, const char **argv, const char **envp) { char v3; char v4; __int64 v5; __int64 v6; __int64 v7; __int64 v8; __int64 input_vector_temp_back_inserter; __int64 input_vector_end; __int64 input_vector[1 ]; __int64 v12; __int64 input_vector_temp_end; __int64 input_vector_temp_begin; __int64 v15; __int64 v16; __int64 flag_end; __int64 input_vector_end_1; __int64 input_vector_begin_1; __int64 v20; __int64 v21; __int64 v22; unsigned int *v23; const char **v25; signed int i; signed int j; char fib_vector; char input_vector; char input_vector_temp; char input_vector_; char flag; __int64 v33; __int64 input_vector_begin; char input_array[72 ]; unsigned __int64 v36; v25 = argv; v36 = __readfsqword(0x28 u); std ::vector <int ,std ::allocator<int >>::vector (&fib_vector, argv, envp); std ::vector <int ,std ::allocator<int >>::vector (&input_vector, argv, v5); std ::vector <int ,std ::allocator<int >>::vector (&input_vector_temp, argv, v6); std ::vector <int ,std ::allocator<int >>::vector (&input_vector_, argv, v7); std ::vector <int ,std ::allocator<int >>::vector (&flag, argv, v8); for ( i = 0 ; i <= 15 ; ++i ) { scanf ("%d" , &input_array[4 * i], v25); std ::vector <int ,std ::allocator<int >>::push_back(&input_vector, &input_array[4 * i]); } for ( j = 0 ; j <= 15 ; ++j ) { LODWORD(input_vector_begin) = fib(j); std ::vector <int ,std ::allocator<int >>::push_back(&fib_vector, &input_vector_begin); } std ::vector <int ,std ::allocator<int >>::push_back(&input_vector_temp, input_array); input_vector_temp_back_inserter = std ::back_inserter<std ::vector <int ,std ::allocator<int >>>(&input_vector_temp); input_vector_end = std ::vector <int ,std ::allocator<int >>::end(&input_vector); input_vector_begin = std ::vector <int ,std ::allocator<int >>::begin(&input_vector); input_vector[1 ] = __gnu_cxx::__normal_iterator<int *,std ::vector <int ,std ::allocator<int >>>::operator +( &input_vector_begin, 1LL ); std ::transform<__gnu_cxx::__normal_iterator<int *,std ::vector <int ,std ::allocator<int >>>,std ::back_insert_iterator<std ::vector <int ,std ::allocator<int >>>,main::{lambda(int )#1 }>( input_vector[1 ], input_vector_end, input_vector_temp_back_inserter, (__int64)input_array); std ::vector <int ,std ::allocator<int >>::vector (&v33, input_vector_end, v12); input_vector_temp_end = std ::vector <int ,std ::allocator<int >>::end(&input_vector_temp); input_vector_temp_begin = std ::vector <int ,std ::allocator<int >>::begin(&input_vector_temp); std ::accumulate<__gnu_cxx::__normal_iterator<int *,std ::vector <int ,std ::allocator<int >>>,std ::vector <int ,std ::allocator<int >>,main::{lambda(std ::vector <int ,std ::allocator<int >>,int )#2 }>( (__int64)&input_vector_begin, input_vector_temp_begin, input_vector_temp_end, (__int64)&v33, v15, v16, v4); std ::vector <int ,std ::allocator<int >>::operator =(&input_vector_, &input_vector_begin); std ::vector <int ,std ::allocator<int >>::~vector (&input_vector_begin); std ::vector <int ,std ::allocator<int >>::~vector (&v33); if ( (unsigned __int8)std ::operator !=<int ,std ::allocator<int >>(&input_vector_, &fib_vector) ) { puts ("You failed!" ); exit (0 ); } flag_end = std ::back_inserter<std ::vector <int ,std ::allocator<int >>>(&flag); input_vector_end_1 = std ::vector <int ,std ::allocator<int >>::end(&input_vector); input_vector_begin_1 = std ::vector <int ,std ::allocator<int >>::begin(&input_vector); std ::copy_if<__gnu_cxx::__normal_iterator<int *,std ::vector <int ,std ::allocator<int >>>,std ::back_insert_iterator<std ::vector <int ,std ::allocator<int >>>,main::{lambda(int )#3 }>( input_vector_begin_1, input_vector_end_1, flag_end, v20, v21, v22, v3); puts ("You win!" ); printf ("Your flag is:flag{" , input_vector_end_1, v25); v33 = std ::vector <int ,std ::allocator<int >>::begin(&flag); input_vector_begin = std ::vector <int ,std ::allocator<int >>::end(&flag); while ( (unsigned __int8)__gnu_cxx::operator !=<int *,std ::vector <int ,std ::allocator<int >>>(&v33, &input_vector_begin) ) { v23 = (unsigned int *)__gnu_cxx::__normal_iterator<int *,std ::vector <int ,std ::allocator<int >>>::operator *(&v33); std ::ostream::operator <<(&std ::cout , *v23); __gnu_cxx::__normal_iterator<int *,std ::vector <int ,std ::allocator<int >>>::operator ++(&v33); } putchar ('}' ); std ::vector <int ,std ::allocator<int >>::~vector (&flag); std ::vector <int ,std ::allocator<int >>::~vector (&input_vector_); std ::vector <int ,std ::allocator<int >>::~vector (&input_vector_temp); std ::vector <int ,std ::allocator<int >>::~vector (&input_vector); std ::vector <int ,std ::allocator<int >>::~vector (&fib_vector); return 0 ; }
main函数的主要逻辑为
读入16个数字,将其写入到input_vector
中
将斐波那契数列的前16项写入到fib_vector
中
std::transform
逻辑:
input_vector_temp[0]=input_vector[0]+input_vector[1]
input_vector_temp[1]=input_vector[0]+input_vector[2]
input_vector_temp[2]=input_vector[0]+input_vector[3]
…
std::accumulate
的逻辑较为复杂,静态难以推导,使用动态调试进行查看
在std::accumulate
完成后,将input_vector_
与fib_vector
进行比较
std::back_insert_iterator<std::vector<int,std::allocator<int>>>,main::{lambda(int)#3}>
将input_vector
中的奇数填入flag
中
进行动态调试
输入数据为51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
将断点下在std::vector<int,std::allocator<int>>::vector(&flag, argv, v8);
完成对input_vector
的写入后对其中的数据进行查看
双击input_vector
查看栈状态
根据栈中的内容01ACC2F0
进入堆中查看
完成对fib_vector
的写入后对其中的数据进行查看
双击fib_vector
查看栈状态
根据栈中的内容01ACC340
进入堆中查看
完成std::transform
后对input_vector_temp
进行查看
双击input_vector_temp
查看栈状态
根据栈中的内容01ACC390
进入堆中查看
完成std::accumulate
后对input_vector_
进行查看
双击input_vector_
查看栈状态
根据栈中的内容01ACC560
进入堆中查看
可以看到std::accumulate
主要对input_vector_temp
进行倒序处理
由此可得exp.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 def fib (a ): if a==0 or a==1 : return 1 return fib(a-1 )+fib(a-2 ) flag=[] for i in range (16 ): flag.append(fib(i)) flag=flag[::-1 ] for i in range (1 ,16 ): flag[i]-=flag[0 ] for i in range (16 ): print(flag[i],end=" " ) print() print() print("flag{" ,end="" ) for i in range (16 ): if flag[i]%2 : print(flag[i],end="" ) print("}" )
1 2 3 987 -377 -610 -754 -843 -898 -932 -953 -966 -974 -979 -982 -984 -985 -986 -986 flag{987-377-843-953-979-985}
将结果作为程序运行输入
CSAW CTF 2014 csaw2013reversing2
main 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 int __cdecl __noreturn main (int argc, const char **argv, const char **envp) { int v3; CHAR *lpMem; HANDLE hHeap; hHeap = HeapCreate(0x40000 u, 0 , 0 ); lpMem = (CHAR *)HeapAlloc(hHeap, 8u , MaxCount + 1 ); memcpy_s(lpMem, MaxCount, &unk_409B10, MaxCount); if ( sub_40102A() || IsDebuggerPresent() ) { __debugbreak(); sub_401000(v3 + 4 , lpMem); ExitProcess(0xFFFFFFFF ); } MessageBoxA(0 , lpMem + 1 , "Flag" , 2u ); HeapFree(hHeap, 0 , lpMem); HeapDestroy(hHeap); ExitProcess(0 ); }
HeapCreate
:Creates a private heap object that can be used by the calling process. The function reserves space in the virtual address space of the process and allocates physical storage for a specified initial portion of this block.(在进程中创建堆栈)
https://docs.microsoft.com/zh-cn/windows/win32/api/heapapi/nf-heapapi-heapcreate
HeapAlloc
:Allocates a block of memory from a heap. The allocated memory is not movable.(在指定的堆上分配内存)
https://docs.microsoft.com/en-us/windows/win32/api/heapapi/nf-heapapi-heapalloc
sub_40102A()
是一个永远返回0
的函数
IsDebuggerPresent()
:Determines whether the calling process is being debugged by a user-mode debugger.(确定调用进程是否由用户模式的调试器调试,用来反调试)
https://docs.microsoft.com/en-us/windows/win32/api/debugapi/nf-debugapi-isdebuggerpresent
MessageBoxA(0, lpMem + 1, "Flag", 2u)
这个函数直接将lpMem
输出,而lpMem
中的内容并非ascii,因此造成乱码
正确流程应为进入if
中的sub_401000(v3 + 4, lpMem)
函数中,对lpMem
进行转换,得到正确的flag
sub_401000(v3 + 4, lpMem)
函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 unsigned int __fastcall sub_401000 (int a1, int a2) { int v2; unsigned int v3; unsigned int v4; unsigned int result; v2 = dword_409B38; v3 = a2 + 1 + strlen ((const char *)(a2 + 1 )) + 1 ; v4 = 0 ; result = ((v3 - (a2 + 2 )) >> 2 ) + 1 ; if ( result ) { do *(_DWORD *)(a2 + 4 * v4++) ^= v2; while ( v4 < result ); } return result; }
lpMem
的内容
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 .data:00409B10 unk_409B10 db 0BBh ; DATA XREF: _main+33↑o .data:00409B11 db 0CCh .data:00409B12 db 0A0h .data:00409B13 db 0BCh .data:00409B14 db 0DCh .data:00409B15 db 0D1h .data:00409B16 db 0BEh .data:00409B17 db 0B8h .data:00409B18 db 0CDh .data:00409B19 db 0CFh .data:00409B1A db 0BEh .data:00409B1B db 0AEh .data:00409B1C db 0D2h .data:00409B1D db 0C4h .data:00409B1E db 0ABh .data:00409B1F db 82h .data:00409B20 db 0D2h .data:00409B21 db 0D9h .data:00409B22 db 93h .data:00409B23 db 0B3h .data:00409B24 db 0D4h .data:00409B25 db 0DEh .data:00409B26 db 93h .data:00409B27 db 0A9h .data:00409B28 db 0D3h .data:00409B29 db 0CBh .data:00409B2A db 0B8h .data:00409B2B db 82h .data:00409B2C db 0D3h .data:00409B2D db 0CBh .data:00409B2E db 0BEh .data:00409B2F db 0B9h .data:00409B30 db 9Ah .data:00409B31 db 0D7h .data:00409B32 db 0CCh .data:00409B33 db 0DDh
dword_409B38
的内容
1 .data:00409B38 dword_409B38 dd 0DDCCAABBh
P.S.1:语句*(_DWORD *)(a2 + 4 * v4++) ^= v2;
说明a2
中的值为每四个hex
与v2
进行一次异或
P.S.2:注意大小端
1 2 3 4 5 6 7 v2=0xBBAACCDD a2=[0xBBCCA0BC ,0xDCD1BEB8 ,0xCDCFBEAE ,0xD2C4AB82 ,0xD2D993B3 ,0xD4DE93A9 ,0xD3CBB882 ,0xD3CBBEB9 ,0x9AD7CCDD ] flag="" for i in range (9 ): flag+=format ((a2[i]^v2),"x" ) print(flag) print(bytearray .fromhex(flag).decode())
flag{reversing_is_not_that_hard!}
由于在if
的条件判断中存在IsDebuggerPresent()
,这个函数在汇编中添加了int3
这个断点,因此可以尝试在x32dbg中将int3
修改为nop
csaw-ctf-2016-quals gametime 游戏题目,利用动态调试进行
main 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 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 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 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 210 211 212 213 214 215 216 217 218 int __cdecl main (int argc, const char **argv, const char **envp) { int v3; unsigned int v4; int v5; int v6; int v7; void (__stdcall *v8)(DWORD); signed int v9; signed int v10; signed int v11; signed int v12; signed int v13; signed int v14; int v15; int *v16; signed int v17; DWORD separate_time; int v19; int v20; int v21; int v22; char v23; int v24; int v26; int v27; char v28; int v29; int v30; int v31; __int16 v32; LOWORD(v29) = 32 ; v27 = 7630702 ; *(int *)((char *)&v29 + 2 ) = 0 ; v30 = 0 ; v31 = 0 ; v32 = 0 ; v3 = 0 ; v26 = 0 ; print_out((int )"\r\tZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMG\n" ); print_out((int )"\tkey is %s (%s)" , &v27, &v29); sub_B81423(); print_out((int )"\r\tZOMGZOMG ZOMGZOMG\n" ); print_out((int )"\tkey is %s (%s)" , &v27, &v29); sub_B81423(); print_out((int )"\r\tZOMGZOMG TAP TAP REVOLUTION!!!!!!! ZOMGZOMG\n" ); print_out((int )"\tkey is %s (%s)" , &v27, &v29); sub_B81423(); print_out((int )"\r\tZOMGZOMG ZOMGZOMG\n" ); print_out((int )"\tkey is %s (%s)" , &v27, &v29); sub_B81423(); print_out((int )"\r\tZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMG\n\n\n" ); print_out((int )"\tkey is %s (%s)" , &v27, &v29); sub_B81423(); print_out((int )"\r\t R U READDY?!\n\n\n" ); print_out((int )"\tkey is %s (%s)" , &v27, &v29); sub_B81423(); print_out((int )"\rThe game is starting in...\n" ); v4 = _time64(0 ); srand(v4); Countdown(); get_ready_to_play(200u ); if ( !sub_B81435(0x1F4 u, ' ' , 10 , v5, (int )&v29, (int )&v27) ) return 0 ; if ( !sub_B81435(0x12C u, 'x' , 8 , v6, (int )&v29, (int )&v27) ) return 0 ; if ( !sub_B81435(0x12C u, 'm' , 5 , v7, (int )&v29, (int )&v27) ) return 0 ; print_out((int )"key is %s (%s)" , &v27, &v29); print_out((int )"\rTRAINING COMPLETE! \n" ); v8 = Sleep; v9 = 20 ; do { Sleep(0xC8 u); print_out((int )"\n" ); --v9; } while ( v9 ); print_out((int )"key is %s (%s)" , &v27, &v29); print_out((int )"\rNow you know everything you need to know" ); v10 = 4 ; do { print_out((int )"." ); Sleep(0x3E8 u); --v10; } while ( v10 ); print_out((int )"\n\n\nfor the rest of your life!\n" ); v11 = 20 ; do { Sleep(0xC8 u); print_out((int )"\n" ); --v11; } while ( v11 ); print_out((int )"LETS PLAY !\n" ); v12 = 20 ; do { Sleep(0xC8 u); print_out((int )"\n" ); --v12; } while ( v12 ); Countdown(); get_ready_to_play(100u ); if ( !sub_B81507(5 , ' ' , 200u , (int )&v29, (int )&v27) ) return 0 ; if ( !sub_B81507(2 , 'x' , 200u , (int )&v29, (int )&v29) ) return 0 ; if ( !sub_B81507(1 , 'm' , 200u , (int )&v29, (int )&v29) ) return 0 ; print_out((int )"key is %s (%s)" , &v27, &v29); sub_B81423(); print_out((int )"\rooooh, you fancy!!!\n" ); if ( !sub_B81507(5 , 'm' , 200u , (int )&v29, (int )&v27) || !sub_B81507(2 , 'x' , 200u , (int )&v29, (int )&v27) || !sub_B81507(1 , ' ' , 200u , (int )&v29, (int )&v27) ) { return 0 ; } print_out((int )"key is %s (%s)" , &v27, &v29); print_out((int )"\b\b" ); print_out((int )"NIIICE JOB)!!!!\n" ); v13 = 20 ; do { Sleep(0x32 u); print_out((int )"\n" ); --v13; } while ( v13 ); v28 = 1 ; do { if ( v3 % 3 == 1 ) { print_out((int )"key is %s (%s)" , &v27, &v29); sub_B81423(); print_out((int )"\rTURBO TIME! \n" ); v14 = 0 ; do { v8(0x32 u); print_out((int )"\n" ); if ( v14 == 19 ) { v15 = sub_B8141D(); sub_B81D02(&v29, v15 - 5514 ); MEMORY[0xB9A1F8 ] = &v29; MEMORY[0xB9A1FC ] = v15 - 5498 ; sub_B81AA5(); sub_B81CC9(); print_out((int )"key is %s (%s)" , &unk_B97D02, &v27); print_out((int )"\b\b" ); v16 = &v29; v17 = 16 ; do { separate_time = *(unsigned __int8 *)v16; print_out((int )"%02x" ); v16 = (int *)((char *)v16 + 1 ); --v17; } while ( v17 ); print_out((int )")\n\n" ); v8 = Sleep; } ++v14; } while ( v14 < 20 ); v19 = 0 ; while ( 1 ) { v20 = rand(); if ( !sub_B81507(1 , byte_B97B08[v20 % 3 ], 100u , (int )&v29, (int )&v27) ) break ; if ( ++v19 >= 10 ) goto LABEL_33; } v28 = 0 ; LABEL_33: v3 = v26; } v21 = 0 ; while ( 1 ) { v22 = rand(); v23 = v28; v24 = v22 % 3 ; if ( v28 ) break ; LABEL_38: if ( ++v21 >= 10 ) goto LABEL_41; } if ( sub_B81507(v24 + 3 , byte_B97B08[v24], 100u , (int )&v29, (int )&v27) ) { v23 = v28; goto LABEL_38; } v23 = 0 ; v28 = 0 ; LABEL_41: if ( v3 == 1337 ) { success(); v23 = v28; } v26 = ++v3; } while ( v23 ); return 0 ; }
关键部分(即对输入进行处理)
1 2 3 if ( !sub_B81507(5 , 'm' , 200u , (int )&v29, (int )&v27) || !sub_B81507(2 , 'x' , 200u , (int )&v29, (int )&v27) || !sub_B81507(1 , ' ' , 200u , (int )&v29, (int )&v27) )
进入该函数
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 char __usercall sub_B81507@<al>(int a1@<edx>, int a2@<ecx>, DWORD dwMilliseconds, int a4, int a5){ int v5; int input_char; v5 = a1; input_char = a2; print_out((int )"key is %s (%s)" , a5, a4); sub_B81423(); print_out((int )"\r \r" ); if ( v5 > 0 ) { do { print_out((int )"." ); Sleep(dwMilliseconds); --v5; } while ( v5 ); } if ( sub_B81260(input_char, 500 * dwMilliseconds) ) return 1 ; print_out((int )"key is %s (%s)\r" , a5, a4); print_out((int )"UDDER FAILURE! http://imgur.com/4Ajx21P \n" ); return 0 ; }
前半部分为输出key
和.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 v5 = a1; input_char = a2; print_out((int )"key is %s (%s)" , a5, a4); sub_B81423(); print_out((int )"\r \r" ); if ( v5 > 0 ) { do { print_out((int )"." ); Sleep(dwMilliseconds); --v5; } while ( v5 ); }
此处为关键部分,用于判断输入并进行计时
1 2 if ( sub_B81260(input_char, 500 * dwMilliseconds) ) return 1 ;
进入函数
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 bool __fastcall sub_B81260 (int a1, int a2) { int input_char; int v3; int v4; input_char = a1; v3 = a2; if ( a1 == ' ' ) print_out((int )&unk_B97868); else print_out((int )&unk_B9786C, a1); if ( v3 ) { while ( !_kbhit() ) { if ( !--v3 ) goto LABEL_7; } v4 = _getch(); } else { LABEL_7: v4 = -1 ; } return v4 != -1 && v4 == input_char; }
如果超时,则会跳转到LABEL_7
,则游戏失败,因此,尝试在goto LABEL_7
处下断点进行调试
将断点下在B81294
Hack-you-2014 Newbie_calculations 通过观察反汇编,三个函数分别为加减乘
将c代码转换成python代码,直接得到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 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 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 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 def mul (a,b ): return a*b def sub (a,b ): return a-b def add (a,b ): return a+b v120=[1 for i in range (32 )] v121 = 0 v120[0 ] = mul(v120[0 ], 1000000000 ) v120[0 ] = sub(v120[0 ], 999999950 ) v120[0 ] = mul(v120[0 ], 2 ) v120[1 ] = add(v120[1 ], 5000000 ) v120[1 ] = sub(v120[1 ], 6666666 ) v120[1 ] = add(v120[1 ], 1666666 ) v120[1 ] = add(v120[1 ], 45 ) v120[1 ] = mul(v120[1 ], 2 ) v120[1 ] = add(v120[1 ], 5 ) v120[2 ] = mul(v120[2 ], 1000000000 ) v120[2 ] = sub(v120[2 ], 999999950 ) v120[2 ] = mul(v120[2 ], 2 ) v120[2 ] = add(v120[2 ], 2 ) v120[3 ] = add(v120[3 ], 55 ) v120[3 ] = sub(v120[3 ], 3 ) v120[3 ] = add(v120[3 ], 4 ) v120[3 ] = sub(v120[3 ], 1 ) v120[4 ] = mul(v120[4 ], 100000000 ) v120[4 ] = sub(v120[4 ], 99999950 ) v120[4 ] = mul(v120[4 ], 2 ) v120[4 ] = add(v120[4 ], 2 ) v120[5 ] = sub(v120[5 ], 1 ) v120[5 ] = mul(v120[5 ], 1000000000 ) v120[5 ] = add(v120[5 ], 55 ) v120[5 ] = sub(v120[5 ], 3 ) v120[6 ] = mul(v120[6 ], 1000000 ) v120[6 ] = sub(v120[6 ], 999975 ) v120[6 ] = mul(v120[6 ], 4 ) v120[7 ] = add(v120[7 ], 55 ) v120[7 ] = sub(v120[7 ], 33 ) v120[7 ] = add(v120[7 ], 44 ) v120[7 ] = sub(v120[7 ], 11 ) v120[8 ] = mul(v120[8 ], 10 ) v120[8 ] = sub(v120[8 ], 5 ) v120[8 ] = mul(v120[8 ], 8 ) v120[8 ] = add(v120[8 ], 9 ) v120[9 ] = add(v120[9 ], 0 ) v120[9 ] = sub(v120[9 ], 0 ) v120[9 ] = add(v120[9 ], 11 ) v120[9 ] = sub(v120[9 ], 11 ) v120[9 ] = add(v120[9 ], 53 ) v120[10 ] = add(v120[10 ], 49 ) v120[10 ] = sub(v120[10 ], 2 ) v120[10 ] = add(v120[10 ], 4 ) v120[10 ] = sub(v120[10 ], 2 ) v120[11 ] = mul(v120[11 ], 1000000 ) v120[11 ] = sub(v120[11 ], 999999 ) v120[11 ] = mul(v120[11 ], 4 ) v120[11 ] = add(v120[11 ], 50 ) v120[12 ] = add(v120[12 ], 1 ) v120[12 ] = add(v120[12 ], 1 ) v120[12 ] = add(v120[12 ], 1 ) v120[12 ] = add(v120[12 ], 1 ) v120[12 ] = add(v120[12 ], 1 ) v120[12 ] = add(v120[12 ], 1 ) v120[12 ] = add(v120[12 ], 10 ) v120[12 ] = add(v120[12 ], 32 ) v120[13 ] = mul(v120[13 ], 10 ) v120[13 ] = sub(v120[13 ], 5 ) v120[13 ] = mul(v120[13 ], 8 ) v120[13 ] = add(v120[13 ], 9 ) v120[13 ] = add(v120[13 ], 48 ) v120[14 ] = sub(v120[14 ], 1 ) v120[14 ] = mul(v120[14 ], -294967296 ) v120[14 ] = add(v120[14 ], 55 ) v120[14 ] = sub(v120[14 ], 3 ) v120[15 ] = add(v120[15 ], 1 ) v120[15 ] = add(v120[15 ], 2 ) v120[15 ] = add(v120[15 ], 3 ) v120[15 ] = add(v120[15 ], 4 ) v120[15 ] = add(v120[15 ], 5 ) v120[15 ] = add(v120[15 ], 6 ) v120[15 ] = add(v120[15 ], 7 ) v120[15 ] = add(v120[15 ], 20 ) v120[16 ] = mul(v120[16 ], 10 ) v120[16 ] = sub(v120[16 ], 5 ) v120[16 ] = mul(v120[16 ], 8 ) v120[16 ] = add(v120[16 ], 9 ) v120[16 ] = add(v120[16 ], 48 ) v120[17 ] = add(v120[17 ], 7 ) v120[17 ] = add(v120[17 ], 6 ) v120[17 ] = add(v120[17 ], 5 ) v120[17 ] = add(v120[17 ], 4 ) v120[17 ] = add(v120[17 ], 3 ) v120[17 ] = add(v120[17 ], 2 ) v120[17 ] = add(v120[17 ], 1 ) v120[17 ] = add(v120[17 ], 20 ) v120[18 ] = add(v120[18 ], 7 ) v120[18 ] = add(v120[18 ], 2 ) v120[18 ] = add(v120[18 ], 4 ) v120[18 ] = add(v120[18 ], 3 ) v120[18 ] = add(v120[18 ], 6 ) v120[18 ] = add(v120[18 ], 5 ) v120[18 ] = add(v120[18 ], 1 ) v120[18 ] = add(v120[18 ], 20 ) v120[19 ] = mul(v120[19 ], 1000000 ) v120[19 ] = sub(v120[19 ], 999999 ) v120[19 ] = mul(v120[19 ], 4 ) v120[19 ] = add(v120[19 ], 50 ) v120[19 ] = sub(v120[19 ], 1 ) v120[20 ] = sub(v120[20 ], 1 ) v120[20 ] = mul(v120[20 ], -294967296 ) v120[20 ] = add(v120[20 ], 49 ) v120[20 ] = sub(v120[20 ], 1 ) v120[21 ] = sub(v120[21 ], 1 ) v120[21 ] = mul(v120[21 ], 1000000000 ) v120[21 ] = add(v120[21 ], 54 ) v120[21 ] = sub(v120[21 ], 1 ) v120[21 ] = add(v120[21 ], 1000000000 ) v120[21 ] = sub(v120[21 ], 1000000000 ) v120[22 ] = add(v120[22 ], 49 ) v120[22 ] = sub(v120[22 ], 1 ) v120[22 ] = add(v120[22 ], 2 ) v120[22 ] = sub(v120[22 ], 1 ) v120[23 ] = mul(v120[23 ], 10 ) v120[23 ] = sub(v120[23 ], 5 ) v120[23 ] = mul(v120[23 ], 8 ) v120[23 ] = add(v120[23 ], 9 ) v120[23 ] = add(v120[23 ], 48 ) v120[24 ] = add(v120[24 ], 1 ) v120[24 ] = add(v120[24 ], 3 ) v120[24 ] = add(v120[24 ], 3 ) v120[24 ] = add(v120[24 ], 3 ) v120[24 ] = add(v120[24 ], 6 ) v120[24 ] = add(v120[24 ], 6 ) v120[24 ] = add(v120[24 ], 6 ) v120[24 ] = add(v120[24 ], 20 ) v120[25 ] = add(v120[25 ], 55 ) v120[25 ] = sub(v120[25 ], 33 ) v120[25 ] = add(v120[25 ], 44 ) v120[25 ] = sub(v120[25 ], 11 ) v120[25 ] = add(v120[25 ], 42 ) v120[26 ] = add(v120[26 ], v120[25 ]) v120[27 ] = add(v120[27 ], v120[12 ]) v120[27 ] = v120[27 ] v120[28 ] = sub(v120[28 ], 1 ) v120[28 ] = add(v120[28 ], v120[27 ]) v120[28 ] = sub(v120[28 ], 1 ) v120[23 ] = v120[23 ] v120[29 ] = sub(v120[29 ], 1 ) v120[29 ] = mul(v120[29 ], 1000000 ) v120[29 ] = add(v120[29 ], v120[23 ]) v120[27 ] = v120[27 ] v120[30 ] = add(v120[30 ], 1 ) v120[30 ] = mul(v120[30 ], v120[27 ]) v120[31 ] = add(v120[31 ], v120[30 ]) for i in v120: print(chr (i),end="" )
daf8f4d816261a41a115052a1bc21ade
mma-ctf-2nd-2016 reverse-box 题目提示
$ ./reverse_box ${FLAG} 95eeaf95ef94234999582f722f492f72b19a7aaf72e6e776b57aee722fe77ab5ad9aaeb156729676ae7a236d99b1df4a
main 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 int __cdecl main (int a1, char **a2) { size_t i; int v4; unsigned int v5; v5 = __readgsdword(0x14 u); if ( a1 <= 1 ) { printf ("usage: %s flag\n" , *a2); exit (1 ); } sub_804858D(&v4); for ( i = 0 ; i < strlen (a2[1 ]); ++i ) printf ("%02x" , *(&v4 + a2[1 ][i])); putchar ('\n' ); return 0 ; }
sub_804858D 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 int __cdecl sub_804858D (_BYTE *a1) { unsigned int v1; int v2; char v3; char v4; char v5; int result; unsigned __int8 v7; char v8; char v9; int v10; v1 = time(0 ); srand(v1); do v10 = rand(); while ( !v10 ); *a1 = v10; v7 = 1 ; v8 = 1 ; do { v2 = v7 ^ 2 * v7; if ( (v7 & 0x80 u) == 0 ) v3 = 0 ; else v3 = 0x1B ; v7 = v2 ^ v3; v4 = 4 * (2 * v8 ^ v8) ^ 2 * v8 ^ v8; v9 = 16 * v4 ^ v4; if ( v9 >= 0 ) v5 = 0 ; else v5 = 9 ; v8 = v9 ^ v5; result = __ROR1__(v8, 4 ) ^ __ROR1__(v8, 5 ) ^ __ROR1__(v8, 6 ) ^ __ROR1__(v8, 7 ) ^ (v8 ^ *a1); a1[v7] = result; } while ( v7 != 1 ); return result; }
sub_804858D函数根据一个在0
到0xff
之间的随机数,生成了一个长度为256的随机数组,根据题目提示输入flag得到的结果进行反推,进而得到flag,flag的头部为TWCTF
,由此进行爆破
使用pwntools进行爆破
1 2 3 4 5 6 7 8 9 10 11 12 from pwn import *import timepayload="TWCTF{1234567890-=!@#$%^&*()_+qwertyuiop[]\\asdfghjkl;'zxcvbnm,./QWERTYUIOP{}|ASDFGHJKL:\"ZXCVBNM<>?}" target="95eeaf95ef" a=[] while a[0 :10 ]!=target: p = process(argv=["/home/misaka/Downloads/reverse_box" , payload]) a=bytes .decode(p.recvline(keepends=False )) p.recvall() time.sleep(1 ) print(a) print(a[0 :10 ])
得到字符串中每个字符对应的hex为95eeaf95ef94729676ad23b02fb2a7b16d9248bc93838aed425081107a441640f8f52703284c1de48cf9ff5a3af68630f0b7cae557796f094e8d1f2a89c484a064eedbb5957e498e31e6944aa53658aeef15e763069c35260bdfaf04999a565e07c04a
根据hex构建字典进行推导
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 a="95eeaf95ef94729676ad23b02fb2a7b16d9248bc93838aed425081107a441640f8f52703284c1de48cf9ff5a3af68630f0b7cae557796f094e8d1f2a89c484a064eedbb5957e498e31e6944aa53658aeef15e763069c35260bdfaf04999a565e07c04a" b="TWCTF{1234567890-=!@#$%^&*()_+qwertyuiop[]\\asdfghjkl;'zxcvbnm,./QWERTYUIOP{}|ASDFGHJKL:\"ZXCVBNM<>?}" flag_hex="95eeaf95ef94234999582f722f492f72b19a7aaf72e6e776b57aee722fe77ab5ad9aaeb156729676ae7a236d99b1df4a" list_a=[] list_flag=[] for i in range (0 ,len (a),2 ): list_a.append("0x" +a[i]+a[i+1 ]) for i in range (0 ,len (flag_hex),2 ): list_flag.append("0x" +flag_hex[i]+flag_hex[i+1 ]) print(list_flag) for i in range (len (b)): print("\"" ,list_a[i],"\"" ,":" ,"\"" ,b[i],"\"" ,sep="" ,end="," ) print() dic={"0x95" :"T" ,"0xee" :"W" ,"0xaf" :"C" ,"0x95" :"T" ,"0xef" :"F" ,"0x94" :"{" ,"0x72" :"1" ,"0x96" :"2" ,"0x76" :"3" ,"0xad" :"4" ,"0x23" :"5" ,"0xb0" :"6" ,"0x2f" :"7" ,"0xb2" :"8" ,"0xa7" :"9" ,"0xb1" :"0" ,"0x6d" :"-" ,"0x92" :"=" ,"0x48" :"!" ,"0xbc" :"@" ,"0x93" :"#" ,"0x83" :"$" ,"0x8a" :"%" ,"0xed" :"^" ,"0x42" :"&" ,"0x50" :"*" ,"0x81" :"(" ,"0x10" :")" ,"0x7a" :"_" ,"0x44" :"+" ,"0x16" :"q" ,"0x40" :"w" ,"0xf8" :"e" ,"0xf5" :"r" ,"0x27" :"t" ,"0x03" :"y" ,"0x28" :"u" ,"0x4c" :"i" ,"0x1d" :"o" ,"0xe4" :"p" ,"0x8c" :"[" ,"0xf9" :"]" ,"0xff" :"\\" ,"0x5a" :"a" ,"0x3a" :"s" ,"0xf6" :"d" ,"0x86" :"f" ,"0x30" :"g" ,"0xf0" :"h" ,"0xb7" :"j" ,"0xca" :"k" ,"0xe5" :"l" ,"0x57" :";" ,"0x79" :"'" ,"0x6f" :"z" ,"0x09" :"x" ,"0x4e" :"c" ,"0x8d" :"v" ,"0x1f" :"b" ,"0x2a" :"n" ,"0x89" :"m" ,"0xc4" :"," ,"0x84" :"." ,"0xa0" :"/" ,"0x64" :"Q" ,"0xee" :"W" ,"0xdb" :"E" ,"0xb5" :"R" ,"0x95" :"T" ,"0x7e" :"Y" ,"0x49" :"U" ,"0x8e" :"I" ,"0x31" :"O" ,"0xe6" :"P" ,"0x94" :"{" ,"0x4a" :"}" ,"0xa5" :"|" ,"0x36" :"A" ,"0x58" :"S" ,"0xae" :"D" ,"0xef" :"F" ,"0x15" :"G" ,"0xe7" :"H" ,"0x63" :"J" ,"0x06" :"K" ,"0x9c" :"L" ,"0x35" :":" ,"0x26" :"\"" ,"0x0b" :"Z" ,"0xdf" :"X" ,"0xaf" :"C" ,"0x04" :"V" ,"0x99" :"B" ,"0x9a" :"N" ,"0x56" :"M" ,"0x5e" :"<" ,"0x07" :">" ,"0xc0" :"?" ,"0x4a" :"}" } print(len (list_flag)) for i in list_flag: print(dic[i],end="" )
得到flagTWCTF{5UBS717U710N_C1PH3R_W17H_R4ND0M123D_5-B0X}
NJUPT CTF 2017 maze 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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 __int64 __fastcall main (__int64 a1, char **a2, char **a3) { signed __int64 v3; signed int v4; bool v5; bool v6; const char *v7; __int64 v9; v9 = 0LL ; puts ("Input flag:" ); scanf ("%s" , &input, 0LL ); if ( strlen (&input) != 24 || strncmp (&input, "nctf{" , 5uLL ) || *(&byte_6010BF + 24 ) != '}' ) { LABEL_22: puts ("Wrong flag!" ); exit (-1 ); } v3 = 5LL ; if ( strlen (&input) - 1 > 5 ) { while ( 1 ) { v4 = *(&input + v3); v5 = 0 ; if ( v4 > 'N' ) { v4 = (unsigned __int8)v4; if ( (unsigned __int8)v4 == 'O' ) { v6 = Left((_DWORD *)&v9 + 1 ); goto LABEL_14; } if ( v4 == 'o' ) { v6 = Right((int *)&v9 + 1 ); goto LABEL_14; } } else { v4 = (unsigned __int8)v4; if ( (unsigned __int8)v4 == '.' ) { v6 = Up(&v9); goto LABEL_14; } if ( v4 == '0' ) { v6 = Down((int *)&v9); LABEL_14: v5 = v6; goto LABEL_15; } } LABEL_15: if ( !(unsigned __int8)Check((__int64)maze, SHIDWORD(v9), v9) ) goto LABEL_22; if ( ++v3 >= strlen (&input) - 1 ) { if ( v5 ) break ; LABEL_20: v7 = "Wrong flag!" ; goto LABEL_21; } } } if ( maze[8 * (signed int )v9 + SHIDWORD(v9)] != '#' ) goto LABEL_20; v7 = "Congratulations!" ; LABEL_21: puts (v7); return 0LL ; }
将迷宫提取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import numpy as npasc=' ******* * **** * **** * *** *# *** *** *** *********' asc=list (asc) asc=np.array(asc).reshape(8 ,8 ) print(asc) ''' [[' ' ' ' '*' '*' '*' '*' '*' '*'] ['*' ' ' ' ' ' ' '*' ' ' ' ' '*'] ['*' '*' '*' ' ' '*' ' ' '*' '*'] ['*' '*' ' ' ' ' '*' ' ' '*' '*'] ['*' ' ' ' ' '*' '#' ' ' ' ' '*'] ['*' '*' ' ' '*' '*' '*' ' ' '*'] ['*' '*' ' ' ' ' ' ' ' ' ' ' '*'] ['*' '*' '*' '*' '*' '*' '*' '*']] 00111111 10001001 11101011 11001011 1001#001 11011101 11000001 11111111 '''
确定移动方向所代表的函数以及所使用的代表字符
1 if ( maze[8 * (signed int )v9 + SHIDWORD(v9)] != '#' )
而根据移动函数的边界判断可以确认该函数的移动方向,由此可以确认函数和函数所使用的字符
走迷宫
1 2 3 4 dic={"上" :"." ,"下" :"0" ,"左" :"O" ,"右" :"o" } answer="右下右右下下左下下下右右右右上上左左" for i in answer: print(dic[i],end="" )
flag:nctf{o0oo00O000oooo..OO}
nullcon-hackim-2016 zorropub main 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 64 65 66 67 68 69 70 71 int __fastcall main (__int64 a1, char **a2, char **a3) { size_t v3; int num; int id; int i; unsigned int seed; unsigned int v9; char v10; char v11[16 ]; char flag[32 ]; char s; char s1[40 ]; unsigned __int64 v15; v15 = __readfsqword(0x28 u); seed = 0 ; puts ("Welcome to Pub Zorro!!" ); printf ("Straight to the point. How many drinks you want?" , a2); __isoc99_scanf("%d" , &num); if ( num <= 0 ) { printf ("You are too drunk!! Get Out!!" , &num); exit (-1 ); } printf ("OK. I need details of all the drinks. Give me %d drink ids:" , num); for ( i = 0 ; i < num; ++i ) { __isoc99_scanf("%d" , &id); if ( id <= 16 || id > 65535 ) { puts ("Invalid Drink Id." ); printf ("Get Out!!" , &id); exit (-1 ); } seed ^= id; } i = seed; v9 = 0 ; while ( i ) { ++v9; i &= i - 1 ; } if ( v9 != 10 ) { puts ("Looks like its a dangerous combination of drinks right there." ); puts ("Get Out, you will get yourself killed" ); exit (-1 ); } srand(seed); MD5_Init(&v10); for ( i = 0 ; i <= 29 ; ++i ) { v9 = rand() % 1000 ; sprintf (&s, "%d" , v9); v3 = strlen (&s); MD5_Update(&v10, &s, v3); flag[i] = v9 ^ LOBYTE(unk_6020C0[i]); } flag[i] = 0 ; MD5_Final(v11, &v10); for ( i = 0 ; i <= 15 ; ++i ) sprintf (&s1[2 * i], "%02x" , v11[i]); if ( strcmp (s1, "5eba99aff105c9ff6a1a913e343fec67" ) ) { puts ("Try different mix, This mix is too sloppy" ); exit (-1 ); } return printf ("\nYou choose right mix and here is your reward: The flag is nullcon{%s}\n" , flag); }
根据逻辑在Linux下进行爆破
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 "stdlib.h" #include "openssl/md5.h" #include "string.h" int main () { for (int seed=17 ;seed<=65535 ;++seed){ int i=seed,v9=0 ; while (i){ ++v9; i&=i-1 ; } if (v9==10 ){ srand(seed); MD5_CTX v10; MD5_Init(&v10); unsigned char v11[16 ]; char s1[40 ]; for (i=0 ;i<=29 ;++i){ v9=rand()%1000 ; char s[5 ]; sprintf (s,"%d" , v9); s[4 ]=0 ; int v3=strlen (s); MD5_Update(&v10,s,v3); } MD5_Final(v11,&v10); for (i=0 ;i<=15 ;++i) sprintf (&s1[2 *i],"%02x" ,v11[i]); if (!strcmp (s1,"5eba99aff105c9ff6a1a913e343fec67" )){ printf ("%d" ,seed); } } } return 0 ; }
gcc test.c -lcrypto -o test
得到seed
为59306
school-ctf-winter-2015 parallel-comparator-200 1 2 3 4 for (i = 0 ; i < FLAG_LEN; i++) { if (generated_string[i] != just_a_string[i]) return 0 ; }
说明generated_string[i] == just_a_string[i]
由generated_string[i] = *(char *)result + just_a_string[i];
知,result
等于0
1 2 *result = (argument[0 ]+argument[1 ]) ^ argument[2 ]; return result;
返回的result
为NULL
,(first_letter+difference)^user_string=0
,first_letter+difference=user_string
1 2 3 4 5 6 7 difference=[0 , 9 , -9 , -1 , 13 , -13 , -4 , -11 , -9 , -1 , -7 , 6 , -13 , 13 , 3 , 9 , -13 , -11 , 6 , -7 ] for first_letter in range (97 ,123 ): user_string="" for i in range (20 ): user_string+=chr (first_letter+difference[i]) print(user_string)
flag:lucky_hacker_you_are
P.S.
在Linux环境下
1 2 3 4 while ((initialization_number = random()) >= 64 ); int first_letter; first_letter = (initialization_number % 26 ) + 97 ;
initialization_number
恒为37
,first_letter
恒为108
,因为只有random
而没有srand
1 2 3 4 5 6 7 8 9 10 11 #include <stdlib.h> #include <stdio.h> #include <pthread.h> int main () { int a; while ((a=random())>=64 ); int f=(a%26 )+97 ; printf ("a=%d,f=%d" ,a,f); return 0 ; }
a=37,f=108
然而在Windows环境下
first_letter
恒为112
SharifCTF 2016 getit
1 2 3 4 5 6 7 8 9 10 LODWORD(v5) = 0 ; while ( (signed int )v5 < strlen (s) ) { if ( v5 & 1 ) v3 = 1 ; else v3 = -1 ; *(&t + (signed int )v5 + 10 ) = s[(signed int )v5] + v3; LODWORD(v5) = v5 + 1 ; }
把上述代码改写成python,即可得到flag
1 2 3 4 5 6 7 8 9 10 11 12 v5=0 v3=0 s="c61b68366edeb7bdce3c6820314b7498" while v5<len (s): if v5&1 : v3=1 else : v3=-1 print(chr (ord (s[v5])+v3),end="" ) v5+=1 print() a=[24 ,25 ,32 ,40 ,36 ,28 ,17 ,34 ,39 ,16 ,33 ,19 ,26 ,5 ,3 ,29 ,27 ,31 ,4 ,8 ,15 ,37 ,42 ,14 ,41 ,2 ,23 ,21 ,0 ,10 ,20 ,7 ,11 ,1 ,13 ,6 ,38 ,18 ,35 ,12 ,22 ,9 ]
flag:SharifCTF{b70c59275fcfa8aebf2d5911223c6589}
在0x400824
处下断点
SHCTF-2017 crackme PEiD查壳(北斗3.7)
x32dbg载入,运行到pushad
,记录ESP地址,在内存窗口中下断点
再次运行,达到jmp
,可知OEP为401336
使用插件中的Scylla
进行dump
PEiD再次查壳
进行静态分析
main 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 int __cdecl main (int argc, const char **argv, const char **envp) { int result; int v4; char v5; char v6; v5 = 0 ; sub_4018F4(&v6, 0 , 49 ); MEMORY[0x6BF831D1 ]("Please Input Flag:" ); MEMORY[0x6BF82E80 ](&v5, 44 ); if ( strlen (&v5) == 42 ) { v4 = 0 ; while ( (*(&v5 + v4) ^ byte_402130[v4 % 16 ]) == dword_402150[v4] ) { if ( ++v4 >= 42 ) { MEMORY[0x6BF831D1 ]("right!\n" ); goto LABEL_8; } } MEMORY[0x6BF831D1 ]("error!\n" ); LABEL_8: result = 0 ; } else { MEMORY[0x6BF831D1 ]("error!\n" ); result = -1 ; } return result; }
byte_402130为this_is_not_flag
dword_402150
1 2 3 4 a="this_is_not_flag" b=[18 , 4 , 8 , 20 , 36 , 92 , 74 , 61 , 86 , 10 , 16 , 103 , 0 , 65 , 0 , 1 , 70 , 90 , 68 , 66 , 110 , 12 , 68 , 114 , 12 , 13 , 64 , 62 , 75 , 95 , 2 , 1 , 76 , 94 , 91 , 23 , 110 , 12 , 22 , 104 , 91 , 18 ] for i in range (42 ): print(chr (b[i]^ord (a[i%16 ])),end="" )
flag{59b8ed8f-af22-11e7-bb4a-3cf862d1ee75}
suctf-2016 serial-150
main函数(未去除混淆)
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 64 65 66 67 68 69 70 71 72 .text:000000000040099C ; int __cdecl main(int argc, const char **argv, const char **envp) .text:000000000040099C public main .text:000000000040099C main: ; DATA XREF: _start+1D↑o .text:000000000040099C ; __unwind { // ___gxx_personality_v0 .text:000000000040099C push rbp .text:000000000040099D mov rbp, rsp .text:00000000004009A0 sub rsp, 200h .text:00000000004009A7 lea rsi, [rbp-200h] .text:00000000004009AE mov eax, 0 .text:00000000004009B3 mov edx, 20h .text:00000000004009B8 mov rdi, rsi .text:00000000004009BB mov rcx, rdx .text:00000000004009BE rep stosq .text:00000000004009C1 lea rsi, [rbp-100h] .text:00000000004009C8 mov eax, 0 .text:00000000004009CD mov edx, 20h .text:00000000004009D2 mov rdi, rsi .text:00000000004009D5 mov rcx, rdx .text:00000000004009D8 rep stosq .text:00000000004009DB .text:00000000004009DB loc_4009DB: ; CODE XREF: .text:00000000004009E1↓j .text:00000000004009DB mov ax, 5EBh .text:00000000004009DF xor eax, eax .text:00000000004009E1 jz short near ptr loc_4009DB+2 .text:00000000004009E3 call near ptr 404DB6A6h .text:00000000004009E8 add ds:_ZSt4cout@@GLIBCXX_3_4[rdi], bh .text:00000000004009EE ; try { .text:00000000004009EE call __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc ; std::operator<<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,char const*) .text:00000000004009F3 .text:00000000004009F3 loc_4009F3: ; CODE XREF: .text:00000000004009F9↓j .text:00000000004009F3 mov ax, 5EBh .text:00000000004009F7 xor eax, eax .text:00000000004009F9 jz short near ptr loc_4009F3+2 .text:00000000004009FB call near ptr 0C59748h .text:00000000004009FB ; --------------------------------------------------------------------------- .text:0000000000400A00 dq 0C0BFC68948FFFFFEh, 0FFFFFE50E8006012h, 0FA74C03105EBB866h .text:0000000000400A00 dq 0FFFFFE00858D48E8h, 0FFFFFE28E8C78948h, 0B8660E7410F88348h .text:0000000000400A00 dq 0E9E8FA74C03105EBh, 85B60F0000023Fh, 660E74453CFFFFFEh .text:0000000000400A00 dq 0E8FA74C03105EBB8h, 85B60F00000226E9h, 0FD0BE0FFFFFFE00h .text:0000000000400A00 dq 0BE0FFFFFFE0F85B6h, 9B3DD001C0h, 0C03105EBB8660E74h .text:0000000000400A00 dq 1FBE9E8FA74h, 3CFFFFFE0185B60Fh, 3105EBB8660E745Ah .text:0000000000400A00 dq 1E2E9E8FA74C0h, 0FFFFFE0185B60F00h, 0FE0E85B60FD0BE0Fh .text:0000000000400A00 dq 3DD001C0BE0FFFFFh, 0B8660E740000009Bh, 0E9E8FA74C03105EBh .text:0000000000400A00 dq 285B60F000001B7h, 660E74393CFFFFFEh, 0E8FA74C03105EBB8h .text:0000000000400A00 dq 85B60F0000019EE9h, 0FD0BE0FFFFFFE02h, 0BE0FFFFFFE0D85B6h .text:0000000000400A00 dq 9B3DD001C0h, 0C03105EBB8660E74h, 173E9E8FA74h, 3CFFFFFE0385B60Fh .text:0000000000400A00 dq 3105EBB8660E7464h, 15AE9E8FA74C0h, 0FFFFFE0385B60F00h .text:0000000000400A00 dq 0FE0C85B60FD0BE0Fh, 3DD001C0BE0FFFFFh, 0B8660E740000009Bh .text:0000000000400A00 dq 0E9E8FA74C03105EBh, 485B60F0000012Fh, 660E746D3CFFFFFEh .text:0000000000400A00 dq 0E8FA74C03105EBB8h, 85B60F00000116E9h, 0FD0BE0FFFFFFE04h .text:0000000000400A00 dq 0BE0FFFFFFE0B85B6h, 0B43DD001C0h, 0C03105EBB8660E74h .text:0000000000400A00 dq 0EBE9E8FA74h, 3CFFFFFE0585B60Fh, 3105EBB8660E7471h .text:0000000000400A00 dq 0D2E9E8FA74C0h, 0FFFFFE0585B60F00h, 0FE0A85B60FD0BE0Fh .text:0000000000400A00 dq 3DD001C0BE0FFFFFh, 0B8660E74000000AAh, 0E9E8FA74C03105EBh .text:0000000000400A00 dq 685B60F000000A7h, 660E74343CFFFFFEh, 0E8FA74C03105EBB8h .text:0000000000400A00 dq 85B60F0000008EE9h, 0FD0BE0FFFFFFE06h, 0BE0FFFFFFE0985B6h .text:0000000000400A00 dq 9B3DD001C0h, 0C03105EBB8660B74h, 85B60F66EBE8FA74h .text:0000000000400A00 dq 0B74633CFFFFFE07h, 0FA74C03105EBB866h, 0FE0785B60F50EBE8h .text:0000000000400A00 dq 85B60FD0BE0FFFFFh, 1C0BE0FFFFFFE08h, 0B740000009B3DD0h .text:0000000000400A00 dq 0FA74C03105EBB866h, 3105EBB86628EBE8h, 400DC9BEE8FA74C0h .text:0000000000400A00 dq 0D5E8006013E0BF00h, 3105EBB866FFFFFBh, 0B8E8FA74C0h .text:0000000000400A00 dq 3105EBB86626EB00h, 400DE4BEE8FA74C0h, 0ADE8006013E0BF00h .text:0000000000400A00 dq 3105EBB866FFFFFBh, 0B8E8FA74C0h .text:0000000000400CA0 db 0, 0EBh, 8 .text:0000000000400CA3 ; --------------------------------------------------------------------------- .text:0000000000400CA3 ; cleanup() // owned by 4009EE .text:0000000000400CA3 mov rdi, rax .text:0000000000400CA6 call __Unwind_Resume .text:0000000000400CAB ; --------------------------------------------------------------------------- .text:0000000000400CAB leave .text:0000000000400CAC retn .text:0000000000400CAC ; } // starts at 40099C
去除混淆
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 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 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 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 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 .text:0000000000400A19 lea rax, [rbp-200h] .text:0000000000400A20 mov rdi, rax .text:0000000000400A23 call _strlen .text:0000000000400A28 cmp rax, 16 ; 输入长度为16 .text:0000000000400A2C jz short loc_400A3C .text:0000000000400A2E .text:0000000000400A2E loc_400A2E: ; CODE XREF: .text:0000000000400A34↓j .text:0000000000400A2E mov ax, 5EBh .text:0000000000400A32 xor eax, eax .text:0000000000400A34 jz short near ptr loc_400A2E+2 .text:0000000000400A34 ; --------------------------------------------------------------------------- .text:0000000000400A36 db 0E8h .text:0000000000400A37 ; --------------------------------------------------------------------------- .text:0000000000400A37 jmp near ptr loc_400C7A+1 .text:0000000000400A3C ; --------------------------------------------------------------------------- .text:0000000000400A3C .text:0000000000400A3C loc_400A3C: ; CODE XREF: .text:0000000000400A2C↑j .text:0000000000400A3C movzx eax, byte ptr [rbp-200h] .text:0000000000400A43 cmp al, 'E' ; input[0]=E .text:0000000000400A45 jz short loc_400A55 .text:0000000000400A45 ; --------------------------------------------------------------------------- .text:0000000000400A47 db 66h ; f .text:0000000000400A48 db 0B8h .text:0000000000400A49 db 0EBh .text:0000000000400A4A db 5 .text:0000000000400A4B db 31h ; 1 .text:0000000000400A4C db 0C0h .text:0000000000400A4D db 74h ; t .text:0000000000400A4E db 0FAh .text:0000000000400A4F db 0E8h .text:0000000000400A50 db 0E9h .text:0000000000400A51 db 26h ; & .text:0000000000400A52 db 2 .text:0000000000400A53 db 0 .text:0000000000400A54 db 0 .text:0000000000400A55 ; --------------------------------------------------------------------------- .text:0000000000400A55 .text:0000000000400A55 loc_400A55: ; CODE XREF: .text:0000000000400A45↑j .text:0000000000400A55 movzx eax, byte ptr [rbp-200h] .text:0000000000400A5C movsx edx, al .text:0000000000400A5F movzx eax, byte ptr [rbp-1F1h] .text:0000000000400A66 movsx eax, al .text:0000000000400A69 add eax, edx .text:0000000000400A6B cmp eax, 9Bh ; input[0]+input[15]=0x9b .text:0000000000400A70 jz short loc_400A80 .text:0000000000400A70 ; --------------------------------------------------------------------------- .text:0000000000400A72 db 66h ; f .text:0000000000400A73 db 0B8h .text:0000000000400A74 db 0EBh .text:0000000000400A75 db 5 .text:0000000000400A76 db 31h ; 1 .text:0000000000400A77 db 0C0h .text:0000000000400A78 db 74h ; t .text:0000000000400A79 db 0FAh .text:0000000000400A7A db 0E8h .text:0000000000400A7B db 0E9h .text:0000000000400A7C db 0FBh .text:0000000000400A7D db 1 .text:0000000000400A7E db 0 .text:0000000000400A7F db 0 .text:0000000000400A80 ; --------------------------------------------------------------------------- .text:0000000000400A80 .text:0000000000400A80 loc_400A80: ; CODE XREF: .text:0000000000400A70↑j .text:0000000000400A80 movzx eax, byte ptr [rbp-1FFh] .text:0000000000400A87 cmp al, 'Z' ; input[1]=Z .text:0000000000400A89 jz short loc_400A99 .text:0000000000400A89 ; --------------------------------------------------------------------------- .text:0000000000400A8B db 66h ; f .text:0000000000400A8C db 0B8h .text:0000000000400A8D db 0EBh .text:0000000000400A8E db 5 .text:0000000000400A8F db 31h ; 1 .text:0000000000400A90 db 0C0h .text:0000000000400A91 db 74h ; t .text:0000000000400A92 db 0FAh .text:0000000000400A93 db 0E8h .text:0000000000400A94 db 0E9h .text:0000000000400A95 db 0E2h .text:0000000000400A96 db 1 .text:0000000000400A97 db 0 .text:0000000000400A98 db 0 .text:0000000000400A99 ; --------------------------------------------------------------------------- .text:0000000000400A99 .text:0000000000400A99 loc_400A99: ; CODE XREF: .text:0000000000400A89↑j .text:0000000000400A99 movzx eax, byte ptr [rbp-1FFh] .text:0000000000400AA0 movsx edx, al .text:0000000000400AA3 movzx eax, byte ptr [rbp-1F2h] .text:0000000000400AAA movsx eax, al .text:0000000000400AAD add eax, edx .text:0000000000400AAF cmp eax, 9Bh ; input[1]+input[14]=0x9b .text:0000000000400AB4 jz short loc_400AC4 .text:0000000000400AB4 ; --------------------------------------------------------------------------- .text:0000000000400AB6 db 66h ; f .text:0000000000400AB7 db 0B8h .text:0000000000400AB8 db 0EBh .text:0000000000400AB9 db 5 .text:0000000000400ABA db 31h ; 1 .text:0000000000400ABB db 0C0h .text:0000000000400ABC db 74h ; t .text:0000000000400ABD db 0FAh .text:0000000000400ABE db 0E8h .text:0000000000400ABF db 0E9h .text:0000000000400AC0 db 0B7h .text:0000000000400AC1 db 1 .text:0000000000400AC2 db 0 .text:0000000000400AC3 db 0 .text:0000000000400AC4 ; --------------------------------------------------------------------------- .text:0000000000400AC4 .text:0000000000400AC4 loc_400AC4: ; CODE XREF: .text:0000000000400AB4↑j .text:0000000000400AC4 movzx eax, byte ptr [rbp-1FEh] .text:0000000000400ACB cmp al, '9' ; input[2]=9 .text:0000000000400ACD jz short loc_400ADD .text:0000000000400ACD ; --------------------------------------------------------------------------- .text:0000000000400ACF db 66h ; f .text:0000000000400AD0 db 0B8h .text:0000000000400AD1 db 0EBh .text:0000000000400AD2 db 5 .text:0000000000400AD3 db 31h ; 1 .text:0000000000400AD4 db 0C0h .text:0000000000400AD5 db 74h ; t .text:0000000000400AD6 db 0FAh .text:0000000000400AD7 db 0E8h .text:0000000000400AD8 db 0E9h .text:0000000000400AD9 db 9Eh .text:0000000000400ADA db 1 .text:0000000000400ADB db 0 .text:0000000000400ADC db 0 .text:0000000000400ADD ; --------------------------------------------------------------------------- .text:0000000000400ADD .text:0000000000400ADD loc_400ADD: ; CODE XREF: .text:0000000000400ACD↑j .text:0000000000400ADD movzx eax, byte ptr [rbp-1FEh] .text:0000000000400AE4 movsx edx, al .text:0000000000400AE7 movzx eax, byte ptr [rbp-1F3h] .text:0000000000400AEE movsx eax, al .text:0000000000400AF1 add eax, edx .text:0000000000400AF3 cmp eax, 9Bh ; input[2]+input[13]=0x9b .text:0000000000400AF8 jz short loc_400B08 .text:0000000000400AF8 ; --------------------------------------------------------------------------- .text:0000000000400AFA db 66h ; f .text:0000000000400AFB db 0B8h .text:0000000000400AFC db 0EBh .text:0000000000400AFD db 5 .text:0000000000400AFE db 31h ; 1 .text:0000000000400AFF db 0C0h .text:0000000000400B00 db 74h ; t .text:0000000000400B01 db 0FAh .text:0000000000400B02 db 0E8h .text:0000000000400B03 db 0E9h .text:0000000000400B04 db 73h ; s .text:0000000000400B05 db 1 .text:0000000000400B06 db 0 .text:0000000000400B07 db 0 .text:0000000000400B08 ; --------------------------------------------------------------------------- .text:0000000000400B08 .text:0000000000400B08 loc_400B08: ; CODE XREF: .text:0000000000400AF8↑j .text:0000000000400B08 movzx eax, byte ptr [rbp-1FDh] .text:0000000000400B0F cmp al, 'd' ; input[3]=d .text:0000000000400B11 jz short loc_400B21 .text:0000000000400B11 ; --------------------------------------------------------------------------- .text:0000000000400B13 db 66h ; f .text:0000000000400B14 db 0B8h .text:0000000000400B15 db 0EBh .text:0000000000400B16 db 5 .text:0000000000400B17 db 31h ; 1 .text:0000000000400B18 db 0C0h .text:0000000000400B19 db 74h ; t .text:0000000000400B1A db 0FAh .text:0000000000400B1B db 0E8h .text:0000000000400B1C db 0E9h .text:0000000000400B1D db 5Ah ; Z .text:0000000000400B1E db 1 .text:0000000000400B1F db 0 .text:0000000000400B20 db 0 .text:0000000000400B21 ; --------------------------------------------------------------------------- .text:0000000000400B21 .text:0000000000400B21 loc_400B21: ; CODE XREF: .text:0000000000400B11↑j .text:0000000000400B21 movzx eax, byte ptr [rbp-1FDh] .text:0000000000400B28 movsx edx, al .text:0000000000400B2B movzx eax, byte ptr [rbp-1F4h] .text:0000000000400B32 movsx eax, al .text:0000000000400B35 add eax, edx .text:0000000000400B37 cmp eax, 9Bh ; input[3]+input[12]=0x9b .text:0000000000400B3C jz short loc_400B4C .text:0000000000400B3C ; --------------------------------------------------------------------------- .text:0000000000400B3E db 66h ; f .text:0000000000400B3F db 0B8h .text:0000000000400B40 db 0EBh .text:0000000000400B41 db 5 .text:0000000000400B42 db 31h ; 1 .text:0000000000400B43 db 0C0h .text:0000000000400B44 db 74h ; t .text:0000000000400B45 db 0FAh .text:0000000000400B46 db 0E8h .text:0000000000400B47 db 0E9h .text:0000000000400B48 db 2Fh ; / .text:0000000000400B49 db 1 .text:0000000000400B4A db 0 .text:0000000000400B4B db 0 .text:0000000000400B4C ; --------------------------------------------------------------------------- .text:0000000000400B4C .text:0000000000400B4C loc_400B4C: ; CODE XREF: .text:0000000000400B3C↑j .text:0000000000400B4C movzx eax, byte ptr [rbp-1FCh] .text:0000000000400B53 cmp al, 'm' ; input[4]=m .text:0000000000400B55 jz short loc_400B65 .text:0000000000400B57 .text:0000000000400B57 loc_400B57: ; CODE XREF: .text:0000000000400B5D↓j .text:0000000000400B57 mov ax, 5EBh .text:0000000000400B5B xor eax, eax .text:0000000000400B5D jz short near ptr loc_400B57+2 .text:0000000000400B5D ; --------------------------------------------------------------------------- .text:0000000000400B5F db 0E8h .text:0000000000400B60 db 0E9h .text:0000000000400B61 db 16h .text:0000000000400B62 db 1 .text:0000000000400B63 db 0 .text:0000000000400B64 db 0 .text:0000000000400B65 ; --------------------------------------------------------------------------- .text:0000000000400B65 .text:0000000000400B65 loc_400B65: ; CODE XREF: .text:0000000000400B55↑j .text:0000000000400B65 movzx eax, byte ptr [rbp-1FCh] .text:0000000000400B6C movsx edx, al .text:0000000000400B6F movzx eax, byte ptr [rbp-1F5h] .text:0000000000400B76 movsx eax, al .text:0000000000400B79 add eax, edx .text:0000000000400B7B cmp eax, 0B4h ; input[4]+input[11]=0xb4 .text:0000000000400B80 jz short loc_400B90 .text:0000000000400B80 ; --------------------------------------------------------------------------- .text:0000000000400B82 db 66h ; f .text:0000000000400B83 db 0B8h .text:0000000000400B84 db 0EBh .text:0000000000400B85 db 5 .text:0000000000400B86 db 31h ; 1 .text:0000000000400B87 db 0C0h .text:0000000000400B88 db 74h ; t .text:0000000000400B89 db 0FAh .text:0000000000400B8A db 0E8h .text:0000000000400B8B db 0E9h .text:0000000000400B8C db 0EBh .text:0000000000400B8D db 0 .text:0000000000400B8E db 0 .text:0000000000400B8F db 0 .text:0000000000400B90 ; --------------------------------------------------------------------------- .text:0000000000400B90 .text:0000000000400B90 loc_400B90: ; CODE XREF: .text:0000000000400B80↑j .text:0000000000400B90 movzx eax, byte ptr [rbp-1FBh] .text:0000000000400B97 cmp al, 'q' ; input[5]=q .text:0000000000400B99 jz short loc_400BA9 .text:0000000000400B99 ; --------------------------------------------------------------------------- .text:0000000000400B9B db 66h ; f .text:0000000000400B9C db 0B8h .text:0000000000400B9D db 0EBh .text:0000000000400B9E db 5 .text:0000000000400B9F db 31h ; 1 .text:0000000000400BA0 db 0C0h .text:0000000000400BA1 db 74h ; t .text:0000000000400BA2 db 0FAh .text:0000000000400BA3 db 0E8h .text:0000000000400BA4 db 0E9h .text:0000000000400BA5 db 0D2h .text:0000000000400BA6 db 0 .text:0000000000400BA7 db 0 .text:0000000000400BA8 db 0 .text:0000000000400BA9 ; --------------------------------------------------------------------------- .text:0000000000400BA9 .text:0000000000400BA9 loc_400BA9: ; CODE XREF: .text:0000000000400B99↑j .text:0000000000400BA9 movzx eax, byte ptr [rbp-1FBh] .text:0000000000400BB0 movsx edx, al .text:0000000000400BB3 movzx eax, byte ptr [rbp-1F6h] .text:0000000000400BBA movsx eax, al .text:0000000000400BBD add eax, edx .text:0000000000400BBF cmp eax, 0AAh ; input[5]+input[10]=0xaa .text:0000000000400BC4 jz short loc_400BD4 .text:0000000000400BC4 ; --------------------------------------------------------------------------- .text:0000000000400BC6 db 66h ; f .text:0000000000400BC7 db 0B8h .text:0000000000400BC8 db 0EBh .text:0000000000400BC9 db 5 .text:0000000000400BCA db 31h ; 1 .text:0000000000400BCB db 0C0h .text:0000000000400BCC db 74h ; t .text:0000000000400BCD db 0FAh .text:0000000000400BCE db 0E8h .text:0000000000400BCF db 0E9h .text:0000000000400BD0 db 0A7h .text:0000000000400BD1 db 0 .text:0000000000400BD2 db 0 .text:0000000000400BD3 db 0 .text:0000000000400BD4 ; --------------------------------------------------------------------------- .text:0000000000400BD4 .text:0000000000400BD4 loc_400BD4: ; CODE XREF: .text:0000000000400BC4↑j .text:0000000000400BD4 movzx eax, byte ptr [rbp-1FAh] .text:0000000000400BDB cmp al, '4' ; input[6]=4 .text:0000000000400BDD jz short loc_400BED .text:0000000000400BDD ; --------------------------------------------------------------------------- .text:0000000000400BDF db 66h ; f .text:0000000000400BE0 db 0B8h .text:0000000000400BE1 db 0EBh .text:0000000000400BE2 db 5 .text:0000000000400BE3 db 31h ; 1 .text:0000000000400BE4 db 0C0h .text:0000000000400BE5 db 74h ; t .text:0000000000400BE6 db 0FAh .text:0000000000400BE7 db 0E8h .text:0000000000400BE8 db 0E9h .text:0000000000400BE9 db 8Eh .text:0000000000400BEA db 0 .text:0000000000400BEB db 0 .text:0000000000400BEC db 0 .text:0000000000400BED ; --------------------------------------------------------------------------- .text:0000000000400BED .text:0000000000400BED loc_400BED: ; CODE XREF: .text:0000000000400BDD↑j .text:0000000000400BED movzx eax, byte ptr [rbp-1FAh] .text:0000000000400BF4 movsx edx, al .text:0000000000400BF7 movzx eax, byte ptr [rbp-1F7h] .text:0000000000400BFE movsx eax, al .text:0000000000400C01 add eax, edx .text:0000000000400C03 cmp eax, 9Bh ; input[6]+input[9]=0x9b .text:0000000000400C08 jz short loc_400C15 .text:0000000000400C08 ; --------------------------------------------------------------------------- .text:0000000000400C0A db 66h ; f .text:0000000000400C0B db 0B8h .text:0000000000400C0C db 0EBh .text:0000000000400C0D db 5 .text:0000000000400C0E db 31h ; 1 .text:0000000000400C0F db 0C0h .text:0000000000400C10 db 74h ; t .text:0000000000400C11 db 0FAh .text:0000000000400C12 db 0E8h .text:0000000000400C13 db 0EBh .text:0000000000400C14 db 66h ; f .text:0000000000400C15 ; --------------------------------------------------------------------------- .text:0000000000400C15 .text:0000000000400C15 loc_400C15: ; CODE XREF: .text:0000000000400C08↑j .text:0000000000400C15 movzx eax, byte ptr [rbp-1F9h] .text:0000000000400C1C cmp al, 'c' ; input[7]=c .text:0000000000400C1E jz short loc_400C2B .text:0000000000400C1E ; --------------------------------------------------------------------------- .text:0000000000400C20 db 66h ; f .text:0000000000400C21 db 0B8h .text:0000000000400C22 db 0EBh .text:0000000000400C23 db 5 .text:0000000000400C24 db 31h ; 1 .text:0000000000400C25 db 0C0h .text:0000000000400C26 db 74h ; t .text:0000000000400C27 db 0FAh .text:0000000000400C28 db 0E8h .text:0000000000400C29 db 0EBh .text:0000000000400C2A db 50h ; P .text:0000000000400C2B ; --------------------------------------------------------------------------- .text:0000000000400C2B .text:0000000000400C2B loc_400C2B: ; CODE XREF: .text:0000000000400C1E↑j .text:0000000000400C2B movzx eax, byte ptr [rbp-1F9h] .text:0000000000400C32 movsx edx, al .text:0000000000400C35 movzx eax, byte ptr [rbp-1F8h] .text:0000000000400C3C movsx eax, al .text:0000000000400C3F add eax, edx .text:0000000000400C41 cmp eax, 9Bh ; input[7]+input[8]=0x9b .text:0000000000400C46 jz short loc_400C53
可提取的信息为
输入长度为16
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 input[0]=E input[0]+input[15]=0x9b input[1]=Z input[1]+input[14]=0x9b input[2]=9 input[2]+input[13]=0x9b input[3]=d input[3]+input[12]=0x9b input[4]=m input[4]+input[11]=0xb4 input[5]=q input[5]+input[10]=0xaa input[6]=4 input[6]+input[9]=0x9b input[7]=c input[7]+input[8]=0x9b
可得flag为EZ9dmq4c8g9G7bAV
输入的字符串被保存在[rbp-200h]
然后跳转到strlen进行长度比较(长度应为16)
1 2 3 4 5 6 .text:0000000000400A19 loc_400A19: ; CODE XREF: .text:0000000000400A12↑j .text:0000000000400A19 lea rax, [rbp-200h] .text:0000000000400A20 mov rdi, rax .text:0000000000400A23 call _strlen .text:0000000000400A28 cmp rax, 10h .text:0000000000400A2C jz short near ptr loc_400A3B+1
判断第一个字符是否为E
1 2 3 .text:0000000000400A3C movzx eax, byte ptr [rbp-200h] ; CODE XREF: .text:0000000000400A2C↑j .text:0000000000400A43 cmp al, 'E' .text:0000000000400A45 jz short near ptr loc_400A54+1
手动对内存中的字符串进行修改,使其满足上述条件
第一个字符和最后一个字符相加等于0x9b
,即最后一个字符为V
1 2 3 4 5 6 7 .text:0000000000400A55 movzx eax, byte ptr [rbp-200h] ; CODE XREF: .text:0000000000400A45↑j .text:0000000000400A5C movsx edx, al .text:0000000000400A5F movzx eax, byte ptr [rbp-1F1h] .text:0000000000400A66 movsx eax, al .text:0000000000400A69 add eax, edx .text:0000000000400A6B cmp eax, 9Bh .text:0000000000400A70 jz short near ptr loc_400A7F+1
不断重复以上步骤,最终得到flag
tinyctf-2014 elrond32 main 1 2 3 4 5 6 7 8 9 10 11 12 13 int __cdecl main (int a1, char **a2) { if ( a1 > 1 && sub_8048414(a2[1 ], 0 ) ) { puts ("Access granted" ); sub_8048538((int )a2[1 ]); } else { puts ("Access denied" ); } return 0 ; }
sub_8048414 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 signed int __cdecl sub_8048414 (_BYTE *a1, int a2) { signed int result; switch ( a2 ) { case 0 : if ( *a1 == 'i' ) goto LABEL_19; result = 0 ; break ; case 1 : if ( *a1 == 'e' ) goto LABEL_19; result = 0 ; break ; case 3 : if ( *a1 == 'n' ) goto LABEL_19; result = 0 ; break ; case 4 : if ( *a1 == 'd' ) goto LABEL_19; result = 0 ; break ; case 5 : if ( *a1 == 'a' ) goto LABEL_19; result = 0 ; break ; case 6 : if ( *a1 == 'g' ) goto LABEL_19; result = 0 ; break ; case 7 : if ( *a1 == 's' ) goto LABEL_19; result = 0 ; break ; case 9 : if ( *a1 == 'r' ) LABEL_19: result = sub_8048414(a1 + 1 , 7 * (a2 + 1 ) % 11 ); else result = 0 ; break ; default : result = 1 ; break ; } return result; }
可以得出,a1是一个字符串,sub_8048414
读取字符串中的字符进行判断,直到result等于1,由此可以逆推出a1
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 #include <iostream> using namespace std ;void fun (int a) { if (a==0 ){ cout <<"i" ; fun(7 *(a+1 )%11 ); } else if (a==1 ){ cout <<"e" ; fun(7 *(a+1 )%11 ); } else if (a==3 ){ cout <<"n" ; fun(7 *(a+1 )%11 ); } else if (a==4 ){ cout <<"d" ; fun(7 *(a+1 )%11 ); } else if (a==5 ){ cout <<"a" ; fun(7 *(a+1 )%11 ); } else if (a==6 ){ cout <<"g" ; fun(7 *(a+1 )%11 ); } else if (a==7 ){ cout <<"s" ; fun(7 *(a+1 )%11 ); } else if (a==9 ){ cout <<"r" ; fun(7 *(a+1 )%11 ); } } int main () { fun(0 ); return 0 ; }
isengard
sub_8048538 1 2 3 4 5 6 7 8 9 10 int __cdecl sub_8048538 (int a1) { int v2[33 ]; int i; qmemcpy(v2, &unk_8048760, sizeof (v2)); for ( i = 0 ; i <= 32 ; ++i ) putchar (v2[i] ^ *(char *)(a1 + i % 8 )); return putchar (10 ); }
对a1字符串进行处理,得到flag
1 2 3 4 v2=[15 , 31 , 4 , 9 , 28 , 18 , 66 , 9 , 12 , 68 , 13 , 7 , 9 , 6 , 45 , 55 , 89 , 30 , 0 , 89 , 15 , 8 , 28 , 35 , 54 , 7 , 85 , 2 , 12 , 8 , 65 , 10 , 20 ] a="isengard" for i in range (33 ): print(chr (v2[i]^ord (a[i%8 ])),end="" )
flag{s0me7hing_S0me7hinG_t0lki3n}
也可以直接运行