-
-
[原创]看雪.纽盾 KCTF晋级赛2019 Q2 第五题 丛林的秘密
-
发表于: 2019-6-18 15:31 3414
-
用JADX找到MainActivity
public class MainActivity extends AppCompatActivity { private Button button1; private EditText eText1; private TextView txView1; public String u = gogogoJNI.sayHello(); static { System.loadLibrary("gogogo"); } protected void onCreate(Bundle bundle) { super.onCreate(bundle); setContentView((int) R.layout.activity_main); this.eText1 = (EditText) findViewById(R.id.editText); this.txView1 = (TextView) findViewById(R.id.textView); ((WebView) findViewById(R.id.text1View)).loadUrl(this.u); ((WebView) findViewById(R.id.text1View)).getSettings().setJavaScriptEnabled(true); this.button1 = (Button) findViewById(R.id.button); this.button1.setOnClickListener(new OnClickListener() { public void onClick(View view) { if (gogogoJNI.check_key(MainActivity.this.eText1.getText().toString()) == 1) { MainActivity.this.txView1.setText("Congratulations!"); } else { MainActivity.this.txView1.setText("Not Correct!"); } } }); } }
看起来是调用了gogogo文件里的check_key函数,但是上面出现了一个很可疑的东西:WebView,并且加载sayHello返回的网址。
public class MainActivity extends AppCompatActivity { private Button button1; private EditText eText1; private TextView txView1; public String u = gogogoJNI.sayHello(); static { System.loadLibrary("gogogo"); } protected void onCreate(Bundle bundle) { super.onCreate(bundle); setContentView((int) R.layout.activity_main); this.eText1 = (EditText) findViewById(R.id.editText); this.txView1 = (TextView) findViewById(R.id.textView); ((WebView) findViewById(R.id.text1View)).loadUrl(this.u); ((WebView) findViewById(R.id.text1View)).getSettings().setJavaScriptEnabled(true); this.button1 = (Button) findViewById(R.id.button); this.button1.setOnClickListener(new OnClickListener() { public void onClick(View view) { if (gogogoJNI.check_key(MainActivity.this.eText1.getText().toString()) == 1) { MainActivity.this.txView1.setText("Congratulations!"); } else { MainActivity.this.txView1.setText("Not Correct!"); } } }); } }
看起来是调用了gogogo文件里的check_key函数,但是上面出现了一个很可疑的东西:WebView,并且加载sayHello返回的网址。
那我们用IDA打开
libgogogo.so
先看Java_com_example_assemgogogo_gogogoJNI_sayHello函数
int __fastcall Java_com_example_assemgogogo_gogogoJNI_sayHello(JNIEnv *a1) { int v1; // r11 JNIEnv *v2; // r4 int i; // r0 int v5; // [sp+0h] [bp-98h] char v6; // [sp+15h] [bp-83h] int v7; // [sp+88h] [bp-10h] v7 = v1; v2 = a1; _aeabi_memclr8(&v5, 128); for ( i = 0; i != 21; ++i ) *((_BYTE *)&v5 + i) = byte_2D28[i] ^ 0x66; // 异或解密,结果是http://127.0.0.1:8000 v6 = 0; return ((int (__fastcall *)(JNIEnv *, int *))(*v2)->NewStringUTF)(v2, &v5); }
那
MainActivity加载的就是本机的8000端口。但是在dex文件没发现类似网页的内容,我们继续分析so文件
int __fastcall Java_com_example_assemgogogo_gogogoJNI_sayHello(JNIEnv *a1) { int v1; // r11 JNIEnv *v2; // r4 int i; // r0 int v5; // [sp+0h] [bp-98h] char v6; // [sp+15h] [bp-83h] int v7; // [sp+88h] [bp-10h] v7 = v1; v2 = a1; _aeabi_memclr8(&v5, 128); for ( i = 0; i != 21; ++i ) *((_BYTE *)&v5 + i) = byte_2D28[i] ^ 0x66; // 异或解密,结果是http://127.0.0.1:8000 v6 = 0; return ((int (__fastcall *)(JNIEnv *, int *))(*v2)->NewStringUTF)(v2, &v5); }
那
MainActivity加载的就是本机的8000端口。但是在dex文件没发现类似网页的内容,我们继续分析so文件
先看JNI_OnLoad
signed int JNI_OnLoad() { j_inti_proc(); return 65540; }
只调用了一个j_inti_proc,
j_inti_proc里面又调用了inti_proc
signed int JNI_OnLoad() { j_inti_proc(); return 65540; }
只调用了一个j_inti_proc,
j_inti_proc里面又调用了inti_proc
int inti_proc() { char *v0; // r0 signed int v1; // r1 signed int i; // r6 struct addrinfo **v3; // r0 int v4; // r4 struct addrinfo *v5; // r5 int result; // r0 int arg; // [sp+8h] [bp-70h] int v8; // [sp+Ch] [bp-6Ch] int v9; // [sp+10h] [bp-68h] struct addrinfo *pai; // [sp+14h] [bp-64h] struct addrinfo req; // [sp+18h] [bp-60h] char v12[32]; // [sp+38h] [bp-40h] int v13; // [sp+58h] [bp-20h] v0 = &mm0; v1 = 34291; v9 = 1; while ( v1 ) { --v1; *v0 ^= 0x67u; ++v0; } i = 1; *(_QWORD *)&req.ai_protocol = 0LL; *(_QWORD *)&req.ai_addr = 0LL; req.ai_family = 0; req.ai_flags = 1; req.ai_socktype = 1; req.ai_next = 0; if ( getaddrinfo(0, "8000", &req, &pai) ) goto LABEL_19; v3 = &pai; i = 1; while ( 1 ) { v5 = *v3; if ( !*v3 ) { i = 2; goto LABEL_19; } v4 = socket(v5->ai_family, v5->ai_socktype, v5->ai_protocol); if ( v4 != -1 ) break; LABEL_10: v3 = &v5->ai_next; } if ( setsockopt(v4, 1, 2, &v9, 4u) == -1 ) goto LABEL_19; if ( bind(v4, (const struct sockaddr *)v5->ai_canonname, v5->ai_addrlen) == -1 ) { close(v4); goto LABEL_10; } freeaddrinfo(pai); if ( listen(v4, 128) == -1 ) { i = 1; } else { for ( i = 0; i != 32; i += 4 ) { arg = v4; v8 = 0; pthread_create((pthread_t *)&v12[i], 0, (void *(*)(void *))nullsub_, &arg); } sock_fd_g = v4; } LABEL_19: result = _stack_chk_guard - v13; if ( _stack_chk_guard == v13 ) result = i; return result; }
发现了初始化socket的代码,而且也是监视8000端口。代码一开始貌似在解密什么,尝试把mm0处的数据导出解密一下
int inti_proc() { char *v0; // r0 signed int v1; // r1 signed int i; // r6 struct addrinfo **v3; // r0 int v4; // r4 struct addrinfo *v5; // r5 int result; // r0 int arg; // [sp+8h] [bp-70h] int v8; // [sp+Ch] [bp-6Ch] int v9; // [sp+10h] [bp-68h] struct addrinfo *pai; // [sp+14h] [bp-64h] struct addrinfo req; // [sp+18h] [bp-60h] char v12[32]; // [sp+38h] [bp-40h] int v13; // [sp+58h] [bp-20h] v0 = &mm0; v1 = 34291; v9 = 1; while ( v1 ) { --v1; *v0 ^= 0x67u; ++v0; } i = 1; *(_QWORD *)&req.ai_protocol = 0LL; *(_QWORD *)&req.ai_addr = 0LL; req.ai_family = 0; req.ai_flags = 1; req.ai_socktype = 1; req.ai_next = 0; if ( getaddrinfo(0, "8000", &req, &pai) ) goto LABEL_19; v3 = &pai; i = 1; while ( 1 ) { v5 = *v3; if ( !*v3 ) { i = 2; goto LABEL_19; } v4 = socket(v5->ai_family, v5->ai_socktype, v5->ai_protocol); if ( v4 != -1 ) break; LABEL_10: v3 = &v5->ai_next; } if ( setsockopt(v4, 1, 2, &v9, 4u) == -1 ) goto LABEL_19; if ( bind(v4, (const struct sockaddr *)v5->ai_canonname, v5->ai_addrlen) == -1 ) { close(v4); goto LABEL_10; } freeaddrinfo(pai); if ( listen(v4, 128) == -1 ) { i = 1; } else { for ( i = 0; i != 32; i += 4 ) { arg = v4; v8 = 0; pthread_create((pthread_t *)&v12[i], 0, (void *(*)(void *))nullsub_, &arg); } sock_fd_g = v4; } LABEL_19: result = _stack_chk_guard - v13; if ( _stack_chk_guard == v13 ) result = i; return result; }
发现了初始化socket的代码,而且也是监视8000端口。代码一开始貌似在解密什么,尝试把mm0处的数据导出解密一下
我们要找的html就在这,
由于完整html代码太长,我就放在附件吧。
保存到html文件里面后,用chrome调试。JS代码调用了check_key来检查key, 而check_key这个函数在WebAssembly实现。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
他的文章
谁下载
谁下载
谁下载
看原图
赞赏
雪币:
留言: