2023NSSCTF2nd-RE-4道wp
NSSCTF2023
bytecode
import base64
import string
def check():
pass
def init():
pass
def fun():
pass
def encrypt1():
pass
def encrypt2():
pass
def encrypt():
pass
if __name__ == "__main__":
key = input("Please input your key:")
if check(key) == 1:
print("Right!")
else:
print("Wrong!")
exit()
msg = input("Please input your message:")
box = init(key)
encode = encrypt(msg, box)
string1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
string2 = "YRiAOe4PlGvxaCoNj2ZgX+q8t/5Em6IUpM9FrVb7BKwsT1n3fSydhDWuQHJ0ckzL"
encode = base64.b64encode(encode.encode()).decode().translate(str.maketrans(string1, string2))
if encode == "mWGFL24R/RSZY3pzK9H4FOmFOnXJKyCjXWbZ7Ijy11GbCBukDrjsiPPFiYB=":
print("Congraduation!You get the right flag!")
else:
print("Wrong!")
第一步解密出key:
def decrypt_key():
x = [78, 82, 81, 64, 80, 67, 125, 83, 96, 56, 121, 84, 61, 126, 81, 79, 79, 119, 38, 120, 39, 74, 112, 38, 44, 126, 103]
key_length = len(x)
decrypted_key = ""
for i in range(key_length):
for char in range(256):
if ord(chr(char)) ^ i == x[i]:
decrypted_key += chr(char)
break
return decrypted_key
decrypted_key = decrypt_key()
print("Decrypted Key:", decrypted_key)
NSSCTF{Th1s_1s_@_f4k3_f14g}
def encrypt1(msg, s_box):
x = []
i = 0
j = 0
for k in range(len(msg)):
i = (i + 1) % 256
j = (j + s_box[i]) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
t = (s_box[i] + s_box[j]) % 256
x.append(ord(msg[k]) ^ s_box[t])
return x
def encrypt2(msg, s_box, key):
x = []
i = 0
j = 0
for k in range(len(msg)):
i = (i + 1) % 256
j = (j + s_box[i]) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
t = (s_box[i] + s_box[j]) % 256
x.append(ord(msg[k]) ^ s_box[t] ^ ord(key[i]))
return x
def encrypt(msg, s_box):
x = []
i = 0
j = 0
for k in range(len(msg)):
i = (i + 1) % 256
j = (j + s_box[i]) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
t = (s_box[i] + s_box[j]) % 256
x.append(ord(msg[k]) ^ s_box[t] ^ i)
return x
def fun(msg, key):
key = "Just kidding, don't take it personally!"
x = []
for i in range(len(msg)):
x.append(ord(msg[i]) ^ ord(key[i % len(key)]))
for i in range(len(x)):
x[i] = x[i] ^ x[i % len(x)]
return x
解密
import base64
def check(key):
x = [78, 82, 81, 64, 80, 67, 125, 83, 96, 56, 121, 84, 61, 126, 81, 79, 79, 119, 38, 120, 39, 74, 112, 38, 44, 126,
103]
if len(key) != len(x):
print('Wrong length!')
exit()
for i in range(len(key)):
if ord(key[i]) ^ x[i] != 0:
return 0
return 1
def init(key):
s_box = list(range(256))
j = 0
for i in range(256):
j = (j + s_box[i] + ord(key[i % len(key)])) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
return s_box
def encrypt(msg, key):
x = []
i = 0
j = 0
s_box = init(key)
for k in range(len(msg)):
i = (i + 1) % 256
j = (j + s_box[i]) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
t = (s_box[i] + s_box[j]) % 256
x.append(msg[k] ^ s_box[t] ^ i)
return x
if __name__ == '__main__':
#msg = input("Please input your message:")
msg = bytes([0x73,0x62,0x63,0xfd,0x11,0x81,0x64,0x1c,0x52,0x02,0xf8,0x3e,0xa6,0x2e,0x46,0x8c,0x47,0x23,0x12,0xe5,0x3a,0xa7,0x23,0x50,0x53,0x69,0x92,0x9d,0xe4,0x32,0xb6,0xd2,0x66,0x36,0x8d,0xfd,0xd6,0x44,0x2b,0x08,0x71,0xe3,0x08,0x0a])
key=[]
key="NSSCTF{Th1s_1s_@_f4k3_f14g}"
encode = encrypt(msg, key)
print(encode)
for i in encode:
print(chr(i),end="")
base
挺有意思的一道题目,赛后偷过来学习
NSSCTF{Welc0me_T0_Re_World}
void __noreturn exception_handler()
{
generate_base64_table(base64_table);
longjmp_0(env, 1);
}
char *__fastcall generate_base64_table(const char *a1)
{
size_t v1; // rbx
size_t v2; // rax
int v3; // eax
char v5; // [rsp+27h] [rbp-59h]
char *Destination; // [rsp+30h] [rbp-50h]
char *v7; // [rsp+40h] [rbp-40h]
int i; // [rsp+4Ch] [rbp-34h]
v7 = (char *)malloc(0x41ui64);
srand(*a1);
v1 = strlen("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=");
v2 = strlen(a1);
Destination = (char *)malloc(v1 + v2 + 1);
strcpy(Destination, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=");
strcat(Destination, a1);
for ( i = 63; i > 0; --i )
{
v3 = rand();
v5 = Destination[v3 % (i + 1)];
Destination[v3 % (i + 1)] = Destination[i];
Destination[i] = v5;
}
strncpy(v7, Destination, 0x40ui64);
v7[64] = 61;
v7[65] = 0;
free(Destination);
strcpy(base64_table, v7);
return base64_table;
}
MYapk
挺有意思的,显示的数字是经过运算得出的,在内存中不存在这个数,导致了gg修改器修改不了这个数字
因为运算前的数字并不知道
跑出来不对?
// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
// then press Enter. You can now see whitespace characters in your code.
import java.util.Timer;
import java.util.TimerTask;
public class Main {
private Timer timer;
private TimerTask timerTask;
private Boolean started = false;
private int success = 0;
String getit(String input) {
int i;
byte[] message;
int messageLength;
int messageLength2;
int f;
int g;
int[] T = new int[64];
for (int i2 = 0; i2 < 64; i2++) {
T[i2] = (int) (Math.abs(Math.sin(i2 + 1)) * 4.294967296E9d);
}
byte[] message2 = input.getBytes();
int d = message2.length;
int numBlocks = ((d + 8) >>> 6) + 1;
int totalLength = numBlocks << 6;
byte[] paddedMessage = new byte[totalLength];
System.arraycopy(message2, 0, paddedMessage, 0, d);
paddedMessage[d] = Byte.MIN_VALUE;
long messageBits = d * 8;
int i3 = 0;
while (true) {
i = 8;
if (i3 >= 8) {
break;
}
paddedMessage[(totalLength - 8) + i3] = (byte) (messageBits >>> (i3 * 8));
i3++;
}
int[] state = {-1732584194, -271733879, 271733878, 1732584193};
int i4 = 0;
while (i4 < numBlocks) {
int[] block = new int[16];
for (int j = 0; j < 16; j++) {
int index = (i4 << 6) + (j << 2);
block[j] = (paddedMessage[index] & 255) | ((paddedMessage[index + 1] & 255) << i) | ((paddedMessage[index + 2] & 255) << 16) | ((paddedMessage[index + 3] & 255) << 24);
}
int a = state[0];
int b = state[1];
int c = state[2];
int j2 = 0;
int d2 = state[3];
while (j2 < 64) {
if (j2 < 16) {
message = message2;
messageLength = d;
messageLength2 = d2;
f = ((~b) & messageLength2) | (b & c);
g = j2;
} else {
message = message2;
messageLength = d;
messageLength2 = d2;
if (j2 < 32) {
f = (messageLength2 & b) | ((~messageLength2) & c);
g = ((j2 * 5) + 1) % 16;
} else if (j2 < 48) {
f = (b ^ c) ^ messageLength2;
g = ((j2 * 3) + 5) % 16;
} else {
f = ((~messageLength2) | b) ^ c;
g = (j2 * 7) % 16;
}
}
int temp = messageLength2;
int d3 = c;
c = b;
b += Integer.rotateLeft(a + f + block[g] + T[j2], 7);
a = temp;
j2++;
d2 = d3;
message2 = message;
d = messageLength;
T = T;
block = block;
}
int messageLength3 = d;
int messageLength4 = d2;
state[0] = state[0] + a;
state[1] = state[1] + b;
state[2] = state[2] + c;
state[3] = state[3] + messageLength4;
i4++;
d = messageLength3;
T = T;
i = 8;
}
byte[] hash = new byte[16];
for (int i5 = 0; i5 < 4; i5++) {
hash[i5 * 4] = (byte) (state[i5] & 255);
hash[(i5 * 4) + 1] = (byte) ((state[i5] >>> 8) & 255);
hash[(i5 * 4) + 2] = (byte) ((state[i5] >>> 16) & 255);
hash[(i5 * 4) + 3] = (byte) ((state[i5] >>> 24) & 255);
}
StringBuilder sb = new StringBuilder();
for (int i6 = 0; i6 < hash.length; i6++) {
sb.append(String.format("%02x", Integer.valueOf(hash[i6] & 255)));
}
return sb.toString();
}
public static void main(String[] args) {
Main ma=new Main();
System.out.println( ma.getit("66.666s"));
// Press Shift+F10 or click the green arrow button in the gutter to run the code.
}
}
d1be6793ed8569ee43950ef21f991095
采用frida来做
setImmediate(function() { //prevent timeout
console.log("[*] Starting script");
// //com.moible.r15.main
// Java.perform(function () {
// // var FridaActivity2 = Java.use(
// // "com.moible.r15.main");
// // console.log("static_bool_var:", FridaActivity2.static_bool_var.value);
// // FridaActivity2.setStatic_bool_var(); //调用静态函数
// // console.log("static_bool_var:", FridaActivity2.static_bool_var.value);
// //调用非静态函数
// Java.choose("com.moible.r15.main", {
// onMatch : function(instance) {
// console.log("bool_var:", instance.bool_var.value);
// instance.setBool_var();
// console.log("bool_var:", instance.bool_var.value);
// }, onComplete : function() {
// }
// })
// });
Java.perform(function() {
// 获取目标类的引用
var main = Java.use('com.moible.r15.main');
var mains=main.$new();
// 调用目标函数
var result = mains.getit("66.666s");
// 在这里处理返回值
console.log("Result: " + result);
});
})
//frida -U -l exp.js -f com.moible.r15 com.moible.r15.main
//getText
NSSCTF{d1be6793ed8569ee43950ef21f991095}
调用静态函数可以直接调用,不用implementation
再去定义。调用非静态函数需要用choose
去搜索实例,再从结果实例里调用非静态函数,无需手动触发了。
package com.github.androiddemo.Activity;
import android.content.Intent;
public class FridaActivity2 extends BaseFridaActivity {
private static boolean static_bool_var = false;
private boolean bool_var = false;
private static void setStatic_bool_var() {
static_bool_var = true;
}
private void setBool_var() {
this.bool_var = true;
}
}
function call_var() {
Java.perform(function () {
var FridaActivity2 = Java.use(
"com.github.androiddemo.Activity.FridaActivity2");
console.log("static_bool_var:", FridaActivity2.static_bool_var.value);
FridaActivity2.setStatic_bool_var(); //调用静态函数
console.log("static_bool_var:", FridaActivity2.static_bool_var.value);
//调用非静态函数
Java.choose("com.github.androiddemo.Activity.FridaActivity2", {
onMatch : function(instance) {
console.log("bool_var:", instance.bool_var.value);
instance.setBool_var();
console.log("bool_var:", instance.bool_var.value);
}, onComplete : function() {
}
})
});
}
最后的脚本:
setImmediate(function() { //prevent timeout
console.log("[*] Starting script");
// //com.moible.r15.main
// Java.perform(function () {
// // var FridaActivity2 = Java.use(
// // "com.moible.r15.main");
// // console.log("static_bool_var:", FridaActivity2.static_bool_var.value);
// // FridaActivity2.setStatic_bool_var(); //调用静态函数
// // console.log("static_bool_var:", FridaActivity2.static_bool_var.value);
// //调用非静态函数
// Java.choose("com.moible.r15.main", {
// onMatch : function(instance) {
// console.log("bool_var:", instance.bool_var.value);
// instance.setBool_var();
// console.log("bool_var:", instance.bool_var.value);
// }, onComplete : function() {
// }
// })
// });
Java.perform(function() {
// 获取目标类的引用
var main = Java.use('com.moible.r15.main');
var mains=main.$new();
// 调用目标函数
var result = mains.getit("66.666s");
// 在这里处理返回值
console.log("Result: " + result);
});
})
//frida -U -l exp.js -f com.moible.r15 com.moible.r15.main
//getText
flag
NSSCTF{1a74ee530fafa690dcddd0ce38260755}
Tea & XTEA
魔改TEA和XTEA,套了个控制流分发器,突然不想做了
sum -= 0x61C88647;
m1 += (key[1] + (m2 >> 9)) ^ (sum + m2 + 5) ^ (*key + 8 * m2) ^ 5;
m2 += (key[3] + (m1 >> 9)) ^ (sum + m1 + 5) ^ (key[2] + 8 * m1) ^ 5;
sum -= 0x61C88647;
m1 += (key[(sum >> 2) & 4] + sum) ^ (m2 + ((m2 >> 3) ^ (16 * m2)));
m2 += (key[sum & 4] + sum) ^ (m1 + ((m1 >> 3) ^ (16 * m1)));
#include <stdio.h>
#include <stdint.h>
void TEA_encrypt(uint32_t* v) {
uint32_t v0 = v[0], v1 = v[1], i; /* set up */
int sum = 0;
uint32_t delta = 0x61C88647; /* a key schedule constant */
uint32_t key2[] = {0x63,0x4D,0x37,0x21};
for (i = 0; i < 0x21; i++) { /* basic cycle start */
sum -= 0x61C88647;
v0 += (key2[1] + (v1 >> 9)) ^ (sum + v1 + 5) ^ (key2[0] + 8 * v1) ^ 5;
v1 += (key2[3] + (v0 >> 9)) ^ (sum + v0 + 5) ^ (key2[2] + 8 * v0) ^ 5;
} /* end cycle */
v[0] = v0; v[1] = v1;
printf("%x\n", sum);
printf("0x%x,0x%x\n", v[0], v[1]);
}
void TEA_decrypt(uint32_t* v) {
uint32_t v0 = v[0], v1 = v[1], i; /* set up */
int sum = (0x6526b0d9);
uint32_t key2[] = { 0x63,0x4D,0x37,0x21 };
for (i = 0; i < 0x21; i++) { /* basic cycle start */
v1 -= (key2[3] + (v0 >> 9)) ^ (sum + v0 + 5) ^ (key2[2] + 8 * v0) ^ 5;
v0 -= (key2[1] + (v1 >> 9)) ^ (sum + v1 + 5) ^ (key2[0] + 8 * v1) ^ 5;
sum += 0x61C88647;
} /* end cycle */
v[0] = v0; v[1] = v1;
printf("%c%c%c%c", *(v + 0), *((char*)v + 1), *((char*)v + 2), *((char*)v + 3));
printf("%c%c%c%c", *((char*)v + 4), *((char*)v + 5), *((char*)v + 6), *((char*)v + 7));
// printf("%c%c%c%c", *((char*)v + 4), *((char*)v + 5), *((char*)v + 6), *((char*)v + 7));
}
void XTEA_encrypt(uint32_t v[2]) {
unsigned int i;
uint32_t a2[5] = {0x21,0x37,0x4d,0x63,0};
unsigned int sum = 0xC6EF3720;
uint32_t v0 = v[0], v1 = v[1];
for (i = 0; i < 0x20; i++) {
sum -= 0x61C88647;
v0 += (a2[(sum >> 2)&4] + sum) ^ (v1 + ((v1 >> 3) ^ (16 * v1)));//卧槽还有0???
v1 += (a2[sum & 4] + sum) ^ (v0 + ((v0 >> 3) ^ (16 * v0)));
}
v[0] = v0; v[1] = v1;
printf("%x\n", sum);
printf("0x%x,0x%x\n", v[0], v[1]);
//0x8dde6e40
//0x2da8b84e, 0x2922fe73
}
void XTEA_decrypt(uint32_t v[2]) {
unsigned int i;
uint32_t a2[5] = { 0x21, 0x37, 0x4d, 0x63, 0 };
unsigned int sum = 0x8dde6e40;
uint32_t v0 = v[0], v1 = v[1];
for (i = 0; i < 0x20; i++) {
v1 -= (a2[sum & 4] + sum) ^ (v0 + ((v0 >> 3) ^ (16 * v0)));
v0 -= (a2[(sum >> 2) & 4] + sum) ^ (v1 + ((v1 >> 3) ^ (16 * v1)));
sum += 0x61C88647;
}
v[0] = v0;
v[1] = v1;
printf("%c%c%c%c", *(v + 0), *((char*)v + 1), *((char*)v + 2), *((char*)v + 3));
printf("%c%c%c%c", *((char*)v + 4), *((char*)v + 5), *((char*)v + 6), *((char*)v + 7));
// printf("0x%x,0x%x\n", v[0], v[1]);
}
int main()
{
unsigned int enc2[5] = { 470335525u, 249973311u, 374580838u, 3240423882u, 2290269766u };
uint32_t enc1[10] =
{
2014667888u,
2688520170u,
2589230026u,
3590956601u,
261108827u,
305138464u,
953159018u,
3287859733u,
2217542345u,
1456413435u,
};
for (int i = 0; i < 10; i+=2)
{
XTEA_decrypt((uint32_t*)(enc1+i));
}
return 0;
}