Mas0n
to be reverse engineer🐧
翻车鱼

[NepCTF] WriteUP

前段时间刚参加完V&N的线上赛,趁热打铁又有了这次Nep的欢乐个人赛( 我不欢乐

比赛举办在周六到周日,但是因为我的实力还有我的时间问题,周日我没有继续下去。

看好多大佬都没交wp,混了个20,没什么可比性

啊对,这题提一嘴,可能题目本身有问题,后期改过题所以与我做题的时候有所出入

下面是我解题的WP

hardcsharp

拿到手之后,习惯性去放IDA,结果发现不能反汇编,又看了看标题,C#的程序,放ILSpy就出源码了

// hardcsharp.Program
using System;

private static void Main(string[] args)
{
	AesClass aesClass = new AesClass();
	string text = "";
	string strB = "1Umgm5LG6lNPyRCd0LktJhJtyBN7ivpq+EKGmTAcXUM+0ikYZL4h4QTHGqH/3Wh0";
	byte[] array = new byte[32]
	{81, 82, 87, 81, 82, 87, 68, 92, 94, 86, 93, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18};
	Console.WriteLine("Welcome to nepnep csharp test! plz input the magical code:");
	string text2 = Console.ReadLine();
	if (text2.Length != 37)
	{
		Console.WriteLine("Nope!");
		Console.ReadKey();
		return;
	}
	if (text2.Substring(0, 4) != "Nep{" || text2[36] != '}')
	{
		Console.WriteLine("Nope!");
		Console.ReadKey();
		return;
	}
	for (int i = 0; i < 32; i++)
	{
		text += Convert.ToChar(array[i] ^ 0x33);
	}
	if (string.Compare(aesClass.AesEncrypt(text2, text), strB) == 0)
	{
		Console.WriteLine("wow, you pass it!");
		Console.ReadKey();
	}
	else
	{
		Console.WriteLine("Nope!");
		Console.ReadKey();
	}
}

很明显是AES加密

// hardcsharp.AesClass
using System;
using System.Security.Cryptography;
using System.Text;

public string AesEncrypt(string str, string key)
{
	if (string.IsNullOrEmpty(str))
	{
		return null;
	}
	byte[] bytes = Encoding.UTF8.GetBytes(str);
	byte[] array = new RijndaelManaged
	{
		Key = Encoding.UTF8.GetBytes(key),
		Mode = CipherMode.ECB,
		Padding = PaddingMode.PKCS7
	}.CreateEncryptor().TransformFinalBlock(bytes, 0, bytes.Length);
	return Convert.ToBase64String(array, 0, array.Length);
}

没难度

二十六进制

题如其名,程序是输入一个十进制数,使用魔改的码表转换成二十六进制后,与7异或,最后与密文比对

oldmaps = "2163qwe)(*&^%489$!057@#><A"
xortext = "Fb72>&6"
plaintext = ""
for i in xortext:
    plaintext += chr(ord(i) ^ 7)
k = 0
for i, p in enumerate(plaintext):
    k += oldmaps.index(p) * 26 ** i
print(k)

password

Android题,java层变种RC4(其实把变种的RC4放so更好点),so层Base64

public Encrypt en = new Encrypt();

    public native int verify(String str);

    static {
        System.loadLibrary("native-lib");
    }
// ......
public void onClick(View view) {
                if (MainActivity.this.verify(editText.getText().toString()) == 0) {
                    System.out.println(editText.getText().toString());
                    Toast.makeText(MainActivity.this, "key错误!", 0).show();
                } else if (MainActivity.this.en.file(editText2.getText().toString().getBytes(), editText.getText().toString())) {
                    Toast.makeText(MainActivity.this, "明文正确,快去解压缩包获取flag吧!", 0).show();
                } else {
                    Toast.makeText(MainActivity.this, "明文错误!", 0).show();
                }
            }

包含flag的压缩包在apk的assets目录下

需要拿到Key解出明文

首先是Native函数verify用了标准的Base64

https://cdn.shi1011.cn/2021/03/7a03456de29b3c5d7192bb2de030db41.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

拿到Key后,其实是变种的RC4,然而是java层,直接拷代码运行

// ......
public boolean file(byte[] bArr, String str) {
        int[] iArr = new int[256];
        int[] iArr2 = {139, 210, 217, 93, 149, 255, 126, 95, 41, 86, 18, 185, 239, 236, 139, 208, 69}; //密文字节
        en1(iArr, str, str.length()); //RC4 init Sbox生成
        en2(iArr, bArr, bArr.length); // RC4 crypt 加密
        if (bArr.length != 17) {
            return false;
        }
        for (int i = 0; i < 17; i++) {
            if ((bArr[i] & 255) != iArr2[i]) {
                return false;
            }
        }
        return true;
    }

解密得到明文

https://cdn.shi1011.cn/2021/03/31911f7ad1e99a2233c4d08b66c97c6b.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

压缩包的密码拿到了,flag也就有了

easy_mips

从题目就知道用的mips,放IDA里看主逻辑

int __fastcall tty_write(const char *a1, const char *a2)
{
  size_t v2; // $v0
  int fd; // [sp+24h] [+24h]
  char v6[20]; // [sp+28h] [+28h] BYREF
  char v7[24]; // [sp+3Ch] [+3Ch] BYREF
  strcpy(v7, "flag{it_is____fake}\n");
  fd = open(a1, 2);
  if ( fd < 0 )
  {
    printf("cannot open");
    exit(-1);
  }
  v2 = strlen(a2);
  write(fd, a2, v2);
  read(fd, v6, 0x13u);
  encry(v6); // 加密点
  if ( !strcmp(v6, v7) )
  {
    write(fd, "you get the fake flag\n", 0x16u);
LABEL_8:
    close(fd);
    return _stack_chk_guard;
  }
  if ( !strcmp(v6, "3_isjA0UeQZcNa\\`\\Vf") ) // 密文
  {
    write(fd, "good_job!\n", 0xAu);
    goto LABEL_8;
  }
  puts("you_don't_get_the_flag");
  return _stack_chk_guard;
}

有了密文往上看做了哪些处理

bool __fastcall encry(int a1)
{
  _BOOL4 result; // $v0
  int i; // [sp+18h] [+18h]
  int v3; // [sp+1Ch] [+1Ch]
  init(a1); // 初始化处理点
  v3 = 5;
  for ( i = 0; ; ++i )
  {
    result = i < 19;
    if ( i >= 19 )
      break;
    *(_BYTE *)(a1 + i) -= v3++; // 字符加减运算
  }
  return result;
}

对输入的文本做了简单的加减处理,继续往上看

int __fastcall init(_BYTE *a1)
{
  int v1; // $v0
  int i; // [sp+20h] [+20h]
  int v5; // [sp+24h] [+24h]
  int v6; // [sp+28h] [+28h]
  srand(0x1C5Eu); // 置随机数种子
  v5 = (rand() ^ 0x65) >> 24;
  v6 = (rand() ^ 0x70) >> 24;
  v1 = rand();
  *a1 ^= (_BYTE)v5 + 50; // 随机
  a1[5] ^= (_BYTE)v6 - 57; // 随机
  a1[6] ^= HIBYTE(v1) + 48; // 随机
  for ( i = 7; i < 13; ++i )
    ;
  return _stack_chk_guard;
}

发现明文的第一位和第6,7位是随机的,有点迷惑了

先写exp

code = "3_isjA0UeQZcNa\\`\\Vf"
plainText = ""
for i,s in enumerate(code):
    plainText += chr(ord(s) + i + 5)
print(plainText)  # 8ep{sK;ar_is_sotql}

题目里的solar就这用途了Nep{solar_is_sotql}

worrrrms

介绍写着go go go ghost,放IDA里一看是Go写的,但是没去掉符号信息,很快就找到函数和算法

https://cdn.shi1011.cn/2021/03/1574c12df8f78b99694bc4a2a55b9ebe.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

SM4,下面打断点找MK和密文

https://cdn.shi1011.cn/2021/03/b8872c1a91a71e0fb03d0810c5da1c69.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5
MK
https://cdn.shi1011.cn/2021/03/3795331cecb017adad4215fac656e9bd.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5
密文

上exp

import binascii
from pysm4 import encrypt, decrypt


def str_to_hexStr(hex_str):
    """
    字符串转hex
    :param hex_str: 字符串
    :return: hex
    """
    hex_data = hex_str.encode('utf-8')
    str_bin = binascii.unhexlify(hex_data)
    return str_bin.decode('utf-8')

mk = 0x6963616E74656C6C756173696D706C65
cipher_num = 0x021789C8D9DAFBE50E478C894C1D7AB9
clear_num = decrypt(cipher_num, mk)
print(str_to_hexStr(hex(clear_num)[2:].replace('L', '')))

Real_Base

变种的Base64,给了明文和密文还有一个编码后的flag

逆码表

b_char = "rTcb1BR8YVW2EOUjweXpIiLt5QCNg7ZAsD9muq3ylMhvofnx/P"
encchar = "2Br9y9fcu97zvB2OruZv0D3Bwhbj0uNQnvfdtC2TwAfPrdBJ3xeP4wNn0hzLzCVUlRa="

res = []
binstr = [bin(ord(b_char[i])).replace('0b', '').zfill(8) for i in range(len(b_char))]
p1 = len(binstr) // 3
p2 = len(binstr) % 3
part1 = binstr[0:3 * p1]
for i in range(p1):
    str_p1 = binstr[i * 3] + binstr[i * 3 + 1] + binstr[i * 3 + 2]
    tmp_str = [str_p1[x: x + 6] for x in [0, 6, 12, 18]]
    tmp_res = [int(x, 2) for x in tmp_str]
    res.append(tmp_res)

if p2:
    part2 = binstr[3 * p1:]
    str_p2 = ''.join(part2) + '0' * (3 - p2) * 8
    tmp_str = [str_p2[x: x + 6] for x in [0, 6, 12, 18]][:p2 + 1]
    tmp_res = [int(x, 2) for x in tmp_str]
    res.append(tmp_res)

data = ["#"] * 64
m = 0
for i in res:
    for j in i:
        data[j] = encchar[m]
        m += 1
print(''.join(data))  # abcdef#h#j#l#n###r#tuvwxyz0#234##7#9ABCD#####J#L#NOPQR#TUV###Z##

只能逆出一部分,不要紧,能补上,还原下码表解密

import base64


baseMaps = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
newMaps = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+/="
baseText = "tCvM4R3TzvZ7nhjBxSiNyxmP28e7qCjVxQn91SRM3gBKzxQ="
base2text = baseText.translate(baseText.maketrans(newMaps, baseMaps))
print(base64.b64decode(base2text.encode('utf-8')).decode())

本文链接:https://blog.shi1011.cn/ctf/1133
本文采用 CC BY-NC-SA 4.0 Unported 协议进行许可

Mas0n

文章作者

发表回复

textsms
account_circle
email

翻车鱼

[NepCTF] WriteUP
前段时间刚参加完V&N的线上赛,趁热打铁又有了这次Nep的欢乐个人赛( 我不欢乐 比赛举办在周六到周日,但是因为我的实力还有我的时间问题,周日我没有继续下去。 看好多大佬都没…
扫描二维码继续阅读
2021-03-22