吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1916|回复: 5
收起左侧

[CTF] 2024春节领红包部分 WP

[复制链接]
max9min 发表于 2024-2-25 01:07


送分题

关注公众号

解题领红包之二 {Windows 初级题}(初二 2/11 10:00 上线)

动调直接拿

fl@g{H@ppy_N3w_e@r!2o24!Fighting!!!}

【春节】解题领红包之三 {Android 初级题}(初三 2/12 10:00 上线)

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.io.RandomAccessFile;

//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
public class Main {

    public static String extractDataFromFile(String p0){
        int i;
        try{
            RandomAccessFile randomAccess = new RandomAccessFile(p0, "r");
            long l = randomAccess.length();
            p0 = "flag{";
            long l1 = Math.max((l - (long)30), 0);
            while (true) {
                if ((l1 - l) < 0) {
                    randomAccess.seek(l1);
                    byte[] uobyteArray = new byte[30];
                    randomAccess.read(uobyteArray);
                    String str = new String(uobyteArray, StandardCharsets.UTF_8);
                    if ((i = str.indexOf(p0)) != -1) {
                        randomAccess.close();
                        return str.substring(i).split("\\}")[0]+"}";
                    }else {
                        l1 = l1 + 1;
                    }
                }else {
                    randomAccess.close();
                    break ;
                }
            }
        }catch(java.lang.Exception e9){
            e9.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        String filePath = "xxx\\xxx\\xxx\\ys.mp4"; //你的路径
    System.out.println(extractDataFromFile(filePath));

    }

    }

运行就是flag

flag{happy_new_year_2024}

当然可以看到字符串是明文存储,直接010看也可以

【春节】解题领红包之四 {Android 初级题}(初四 2/13 10:00 上线)

2

2
这里要到FlagActivity里面去,一开始准备是修改跳转,直接进的。发现是获取签名进行异或,
这里换一下思路,启动FlagActivity就好

adb shell am start -n com.kbtx.redpack_simple/.FlagActivity

3

3

【2024春节】解题领红包之五 {Android 中级题}

审计代码后发现有个dex修复
我添加调试之后,调试总是异常。
后面纯纯脑洞题

package com.zj.wuaipojie2024_2;

import android.content.Context;
import android.util.Log;
import dalvik.system.DexClassLoader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.util.HashMap;

public class C {
    public static final String SIGNATURE = "fe4f4cec5de8e8cf2fca60a4e61f67bcd3036117";
    private static final String TAG = "ZJ595";

    private static File fix(ByteBuffer byteBuffer0, int v, int v1, int v2, Context context0) throws Exception {
        try {
            File file0 = context0.getDir("data", 0);
            int v3 = (int)(((Integer)D.getClassDefData(byteBuffer0, v).get("class_data_off")));
            HashMap hashMap0 = D.getClassData(byteBuffer0, v3);
            ((int[][])hashMap0.get("direct_methods"))[v1][2] = v2;
            byte[] arr_b = D.encodeClassData(hashMap0);
            byteBuffer0.position(v3);
            byteBuffer0.put(arr_b);
            byteBuffer0.position(0x20);
            byte[] arr_b1 = new byte[byteBuffer0.capacity() - 0x20];
            byteBuffer0.get(arr_b1);
            byte[] arr_b2 = Utils.getSha1(arr_b1);
            byteBuffer0.position(12);
            byteBuffer0.put(arr_b2);
            int v4 = Utils.checksum(byteBuffer0);
            byteBuffer0.position(8);
            byteBuffer0.putInt(Integer.reverseBytes(v4));
            byte[] arr_b3 = byteBuffer0.array();
            File file1 = new File(file0, "2.dex");
            FileOutputStream fileOutputStream0 = new FileOutputStream(file1);
            fileOutputStream0.write(arr_b3);
            fileOutputStream0.close();
            return file1;
        }
        catch(Exception exception0) {
            exception0.printStackTrace();
            return null;
        }
    }

    private static Method getStaticMethod(Context context0, int[] arr_v, String s, String s1, Class[] arr_class) throws Exception {
        try {
            File file0 = C.fix(C.read(context0), arr_v[0], arr_v[1], arr_v[2], context0);
            ClassLoader classLoader0 = context0.getClass().getClassLoader();
            File file1 = context0.getDir("fixed", 0);
            Method method0 = new DexClassLoader(file0.getAbsolutePath(), file1.getAbsolutePath(), null, classLoader0).loadClass(s).getDeclaredMethod(s1, arr_class);
            file0.delete();
            new File(file1, file0.getName()).delete();
            return method0;
        }
        catch(Exception exception0) {
            exception0.printStackTrace();
            return null;
        }
    }

    public static String isValidate(Context context0, String s, int[] arr_v) throws Exception {
        try {
            return (String)C.getStaticMethod(context0, arr_v, "com.zj.wuaipojie2024_2.A", "d", new Class[]{Context.class, String.class}).invoke(null, context0, s);
        }
        catch(Exception exception0) {
            Log.e("ZJ595", "咦,似乎是坏掉的dex呢!");
            exception0.printStackTrace();
            return "";
        }
    }

    private static ByteBuffer read(Context context0) {
        try {
            File file0 = new File(context0.getDir("data", 0), "decode.dex");
            if(!file0.exists()) {
                return null;
            }

            FileInputStream fileInputStream0 = new FileInputStream(file0);
            byte[] arr_b = new byte[fileInputStream0.available()];
            fileInputStream0.read(arr_b);
            ByteBuffer byteBuffer0 = ByteBuffer.wrap(arr_b);
            fileInputStream0.close();
            return byteBuffer0;
        }
        catch(Exception unused_ex) {
            return null;
        }
    }
}

这里先把a的数组值找出来

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <array name="A_offset">
        <item>@null</item>
        <item>3</item>
        <item>7908</item>
    </array>
    <array name="B_offset">
        <item>1</item>
        <item>1</item>
        <item>8108</item>
    </array>
</resources>

这里解部分dex,获取关键代码
这里解密的dex名称是1.dex

4

4
解密dex
image4.png

打断点,这里先运行完,直接adb 拉出来
关键代码

public static String d(Context context0, String s) {
        MainActivity.sSS(s);
        String s1 = Utils.getSignInfo(context0);
        if(s1 != null && (s1.equals("fe4f4cec5de8e8cf2fca60a4e61f67bcd3036117"))) {
            StringBuffer stringBuffer0 = new StringBuffer();
            for(int v = 0; stringBuffer0.length() < 9 && v < 40; ++v) {
                String s2 = "0485312670fb07047ebd2f19b91e1c5f".substring(v, v + 1);
                if(!stringBuffer0.toString().contains(s2)) {
                    stringBuffer0.append(s2);
                }
            }

            return s.equals(stringBuffer0.toString().toUpperCase()) ? "唉!哪有什么亿载沉睡的玄天帝,不过是一位被诅咒束缚的旧日之尊,在灯枯之际挣扎的南柯一梦罢了。有缘人,这份机缘就赠予你了。坐标在B.d" : "";
        }

        return "";
    }

看情况要解密B
我先解出来密码

StringBuffer stringBuffer0 = new StringBuffer();
            for(int v = 0; stringBuffer0.length() < 9 && v < 40; ++v) {
                String s2 = "0485312670fb07047ebd2f19b91e1c5f".substring(v, v + 1);
                if(!stringBuffer0.toString().contains(s2)) {
                    stringBuffer0.append(s2);
                }
            }//048531267
            System.out.println(stringBuffer0.toString().toUpperCase());

密码就是048531267
解密完B

package com.zj.wuaipojie2024_2;

public class B {
    public static String d(String s) {
        return "机缘是{" + Utils.md5(Utils.getSha1("password+你的uid".getBytes())) + "}";
    }
}

把自己论坛id加上去跑一下就行。

【春节】解题领红包之六 {Windows 高级题}(初六 2/15 10:00 上线)

客户端

crackme2024 upx壳,抹去upx信息,只能手脱
oep=00000001400038DC

int __cdecl main(int argc, const char **argv, const char **envp)
{
  HANDLE StdHandle; // rdi
  __int64 uid; // rcx
  unsigned __int64 v7; // rax
  char *EndPtr; // [rsp+50h] [rbp-138h] BYREF
  unsigned int v10; // [rsp+58h] [rbp-130h] BYREF
  char serial[272]; // [rsp+60h] [rbp-128h] BYREF

  printf_s("%s @ www.52pojie.cn\n", &ConsoleTitle);
  onexit(Func);
  SetConsoleTitleA(&ConsoleTitle);
  printf("Happy New Year!\nAuthor: solly\n\n");
  v10 = 0;
  memset(serial, 0, 0x104ui64);
  StdHandle = GetStdHandle(0xFFFFFFF5);
  if ( argc <= 3 )
  {
    printf("   Enter your uid: ");
    scanf_s("%lu", &v10);
    uid = v10;
    if ( v10 )
    {
      printf("Enter your serial: ");
      scanf_s("%s", serial);
      uid = v10;
    }
  }
  else
  {
    v10 = strtoul(argv[1], &EndPtr, 10);
    memcpy_s(serial, 0x24ui64, argv[2], 0x104ui64);
    uid = v10;
  }
  if ( !(_DWORD)uid )
    goto LABEL_12;
  v7 = -1i64;
  do
    ++v7;
  while ( serial[v7] );
  if ( v7 >= 0x23 )
  {
    if ( (unsigned __int8)check(uid, serial) )
    {
      printf("\nChecking result: ");
      SetConsoleTextAttribute(StdHandle, 9u);
      printf("SUCCESS. ");
      SetConsoleTextAttribute(StdHandle, 7u);
      printf("Congratulations!!\n\n");
      printf("You can run crackme2024service.exe /UnregServer as administrator to unload the server.\n");
    }
    else
    {
      printf("\nChecking result: ");
      SetConsoleTextAttribute(StdHandle, 0xCu);
      printf("FAILURE. ");
      SetConsoleTextAttribute(StdHandle, 7u);
      printf("Try it again!!!!!\n\n");
    }
  }
  else
  {
LABEL_12:
    printf("\nERROR: uid or serial is error\n");
  }
  return 0;
}

审计之后发现我们的uid和序列号 到check里面了

__int64 __fastcall check(unsigned int uid, const char *serial)
{
  LPVOID ppv; // [rsp+30h] [rbp-F8h] BYREF
  char v6[8]; // [rsp+38h] [rbp-F0h] BYREF
  char Destination[208]; // [rsp+40h] [rbp-E8h] BYREF

  v6[0] = 0;
  qword_140020E50 = (unsigned __int8)sub_1400022F0(346i64, 56i64, 0i64);
  if ( CoInitialize(0i64) >= 0 )
  {
    if ( CoCreateInstance(&rclsid, 0i64, 0x14u, &riid, &ppv) < 0 )
    {
      printf("\nCreate Server Instance failure. Please run crackme2024service.exe /RegServer as administrator first.\n");
    }
    else
    {
      memset(Destination, 0, 0xC8ui64);
      strcpy_s(Destination, 0xC8ui64, serial);
      (*(void (__fastcall **)(LPVOID, _QWORD))(*(_QWORD *)ppv + 56i64))(ppv, uid);
      if ( *(_QWORD *)lpBaseAddress )
        *(_QWORD *)lpBaseAddress = (*(__int64 (__fastcall **)(_QWORD))lpBaseAddress)(*((unsigned int *)lpBaseAddress + 2));
      (*(void (__fastcall **)(LPVOID, char *))(*(_QWORD *)ppv + 64i64))(ppv, Destination);
      if ( (*(unsigned int (__fastcall **)(LPVOID, char *))(*(_QWORD *)ppv + 72i64))(ppv, v6) == 1 )
      {
        v6[0] = 0;
        printf("Running failure. Please run crackme2024service.exe /RegServer as administrator first.\n");
      }
      (*(void (__fastcall **)(LPVOID))(*(_QWORD *)ppv + 16i64))(ppv);
    }
  }
  CoUninitialize();
  return (unsigned __int8)v6[0];
}

调试爆异常看到反调试了,先把反调试处理了

_BOOL8 sub_140002350()
{
  struct _PEB *v0; // rax

  v0 = NtCurrentPeb();
  return v0->BeingDebugged || LOBYTE(v0->NtGlobalFlag) == 112;
}

image5.png

服务端

找服务端,https://github.com/ergrelet/unlicense/releases/tag/0.4.0 脱壳
sub_401B50 初始化函数有反调试,还有反调试,同理处理patch为,mov eax,0
image6.png

uid接收函数
void __stdcall sub_401280(_DWORD *a1, int a2)
{
  *(_DWORD *)(a1[60] + a1[3] + 8) = a2;
  a1[4] = 0;
  a1[5] = 0;
}
serical接收函数

这里主要就是格式

int __stdcall sub_4012B0(_DWORD *a1, char *Str)
{
  const char *v2; // edi
  unsigned int *v3; // ebx
  int v4; // ebp
  char *i; // esi
  unsigned int v6; // eax
  _DWORD *v7; // ecx
  char *EndPtr; // [esp+14h] [ebp-8h] BYREF

  v2 = Str;
  v3 = a1 + 6;
  memset(a1 + 6, 0, 0xC8u);
  v4 = 0;
  for ( i = strstr(Str, asc_418F50); i; i = strstr(i + 1, asc_418F50) )
  {
    *i = 0;
    v6 = strtoul(v2, &EndPtr, 16);
    v2 = i + 1;
    *v3 = v6;
    ++v4;
    ++v3;
  }
  a1[v4 + 6] = strtoul(v2, &EndPtr, 16);
  v7 = (_DWORD *)a1[3];
  a1[4] = *v7;
  a1[5] = v7[1];
  return 0;
}
check函数
do
  {
    v5 = *(_DWORD *)v3;
    v6 = &data1[17];
    v7 = *((_DWORD *)v3 + 1);
    do
    {
      v8 = *v6--;
      v9 = v5 ^ (BeingDebugged + v8);
      v5 = v7 ^ (data2[HIBYTE(v9) + 768]
               + (data2[BYTE2(v9) + 512] ^ (data2[(unsigned __int8)v9] + data2[BYTE1(v9) + 256])));
      v7 = v9;
    }
    while ( (int)v6 >= (int)&data1[2] );
    v10 = v5 ^ data1[1];
    v11 = v9 ^ data1[0];
    *((_DWORD *)v3 + 1) = v10;
    *(_DWORD *)v3 = v11;
    v3 += 8;
    --v4;
  }
  while ( v4 );
  LOBYTE(v16) = 0;
  *a2 = v14 == _strtoui64(String, 0, 16);

dump出data1和data2数据即可
先模拟算法

 _DWORD input[] = { 0x00111111, 0x00111111, 0x00111111, 0x00111111, };
//111111-111111-111111-111111-111111
    int v5;
    int v7;
    _DWORD v9;
    for (int i = 0; i < 2; i++)
    {
        v5 = input[i * 2];
        v7 = input[i * 2 + 1];
        for (int j = 17; j >= 2; j--)
        {
            v9 = v5 ^ (data1[j]);
            v5 = v7 ^ (data2[HIBYTE(v9) + 768]+ (data2[BYTE2(v9) + 512] ^ (data2[(unsigned __int8)v9] + data2[BYTE1(v9) + 256])));
            v7 = v9;
        }
        input[i * 2+1] = v5^data1[1];
        input[i * 2] = v9 ^ data1[0];

    }

image8.png
image7.png

 _DWORD input[] = { 0x00111111, 0x00111111, 0x00111111, 0x00111111, };
//111111-111111-111111-111111-111111
    int v5;
    int v7;
    _DWORD v9;
    for (int i = 0; i < 2; i++)
    {
        v5 = input[i * 2];
        v7 = input[i * 2 + 1];
        for (int j = 17; j >= 2; j--)
        {
            v9 = v5 ^ (data1[j]);
            v5 = v7 ^ (data2[HIBYTE(v9) + 768]+ (data2[BYTE2(v9) + 512] ^ (data2[(unsigned __int8)v9] + data2[BYTE1(v9) + 256])));
            v7 = v9;
        }
        input[i * 2+1] = v5^data1[1];
        input[i * 2] = v9 ^ data1[0];

    }

逆向脚本

_DWORD enc[4] = { 0x0D65ACCB, 0xF7C1225A, 0x0D65ACCB, 0xF7C1225A };
    for (int i = 0; i < 2; i++)
    {
        v9 = enc[i * 2] ^ data1[0];
        v5 = enc[i * 2 + 1] ^ data1[1];
        for (int j = 17; j >= 2; j--)
        {

            v7= v5^(data2[HIBYTE(v9) + 768] + (data2[BYTE2(v9) + 512] ^ (data2[(unsigned __int8)v9] + data2[BYTE1(v9) + 256])));
            v5 = v9 ^ data1[j];
            v9 = v7;
        }
        enc[i * 2] = v5;
        enc[i * 2+1] = v7;
    }

image9.png
如果调试过来,密文会变,可能哪里有检测,直接在这里下断点

这里我推测是对uid**3 再跟solly202 进行异或生成的密文
获取密文后,恢复顺序

s='3BE4F544EB760266'
a=[]
for i in range(0,len(s),2):
    x=s[i:i+2]
    a.append(x)
b=''.join(i for i in a[::-1])
print(b)
#660276EB44F5E43B

然后逆一下算法

 char String[] = "660276EB44F5E43B";
   _DWORD* enc = (_DWORD*)&String;
   //_DWORD enc[4] = { 0x0019F3E4, 0x0019F42C, 0x0019F5D0, 0x767D0E90 };
    for (int i = 0; i < 2; i++)
    {
        v9 = enc[i * 2] ^ data1[0];
        v5 = enc[i * 2 + 1] ^ data1[1];
        for (int j = 2; j<=17; j++)
        {

            v7= v5^(data2[HIBYTE(v9) + 768] + (data2[BYTE2(v9) + 512] ^ (data2[(unsigned __int8)v9] + data2[BYTE1(v9) + 256])));
            v5 = v9 ^ data1[j];
            v9 = v7;
        }
        enc[i * 2] = v5;
        enc[i * 2+1] = v7;
    }

image10.png

def get(s):
    z=s.split(' ')
    z_=''
    for i in range(0,len(z),4):
        z_+=''.join(i for i in z[i:i+4][::-1])+'-'
    z_=z_[:-1]
    print(z_)
    #125413ff-936888ec-88eae67e-bd9bb1c7    
s='ff 13 54 12 ec 88 68 93 7e e6 ea 88 c7 b1 9b bd'
get(s)

1

1

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Hmily 发表于 2024-2-26 18:08
厉害,请问unlicense这个脱壳后的程序能直接跑?
 楼主| max9min 发表于 2024-2-26 19:32
Hmily 发表于 2024-2-26 18:08
厉害,请问unlicense这个脱壳后的程序能直接跑?

我使用后能直接跑

点评

这么厉害  详情 回复 发表于 2024-2-26 19:39
Hmily 发表于 2024-2-26 19:39
anidelong 发表于 2024-2-26 20:28
是不是可以直接抢红包那种
fuum2pimbeb 发表于 2024-3-6 08:54
这么厉害
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 06:55

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表