BUU刷题第一集合

第一题easyre

ida查壳直接看

flag{this_Is_a_EaSyRe}

第二题reverse1

定位到Str2{hello_world}

根据

 for ( j = 0; ; ++j )
  {
    v8 = j;
    v2 = j_strlen(Str2);
    if ( v8 > v2 )
      break;
    if ( Str2[j] == 'o' )
      Str2[j] = '0';
  }

把o换成0

flag{hell0_w0rld}

第三题reverse2

ELF即linux 下可执行文件

先用ida看看

找到{hacking_for_fun}

定位到关键代码

for ( i = 0; i <= strlen(&flag); ++i )
    {
      if ( *(&flag + i) == 'i' || *(&flag + i) == 'r' )
        *(&flag + i) = '1';
    }

把i或者r换成1

直接换flag{hack1ng_fo1_fun}

第四题内涵的软件

直接看

v6 = 5;
  v5 = "DBAPP{49d3c93df25caad81232130f3d2ebfad}";
  while ( v6 >= 0 )
  {
    printf("距离出现答案还有%d秒,请耐心等待!\n", v6);
    sub_40100A();
    --v6;
  }
  printf(
    "\n"
    "\n"
    "\n"
    "这里本来应该是答案的,但是粗心的程序员忘记把变量写进来了,你要不逆向试试看:(Y/N)\n");
  v4[0] = 1;
  scanf("%c", v4);
  if ( v4[0] == 'Y' )
  {
    printf("OD吾爱破解或者IDA这些逆向软件都挺好的!");
    result = sub_40100A();
  }
  else
  {
    if ( v4[0] == 'N' )
      printf("那没办法了,猜是猜不出的.");
    else
      printf(&byte_42501C);
    result = sub_40100A();
  }
  return result;

v5十分可疑,直接flag{49d3c93df25caad81232130f3d2ebfad}

第五题新年快乐

查壳,发现UPX,直接脱壳

定位关键

 __main();
  strcpy(Str2, "HappyNewYear!");
  Str1 = 0;
  memset(v6, 0, sizeof(v6));
  printf("please input the true flag:");
  scanf("%s", &Str1);
  if ( !strncmp((const char *)&Str1, Str2, strlen(Str2)) )
    result = puts("this is true flag!");
  else
    result = puts("wrong!");
  return result;

Str2就是flag

flag{HappyNewYear!}

第六题xor

mac 64位

ida进

定位关键的代码

 memset(__b, 0, 0x100uLL);
  printf("Input your flag:\n");
  get_line(__b, 256LL);
  if ( strlen(__b) != 33 )
    goto LABEL_7;
  for ( i = 1; i < 33; ++i )
    __b[i] ^= __b[i - 1];
  if ( !strncmp(__b, global, 0x21uLL) )
    printf("Success");
  else
LABEL_7:
    printf("Failed");
  return 0;

分析flag 33位,进入异或后和global相等

导出global

unsigned char aFK[] =
{
  102,  10, 107,  12, 119,  38,  79,  46,  64,  17, 
  120,  13,  90,  59,  85,  17, 112,  25,  70,  31, 
  118,  34,  77,  35,  68,  14, 103,   6, 104,  15, 
   71,  50,  79
};

写EXP

#include<stdio.h>
#include<windows.h>
#include<string.h>
int main(){
  char str[]={
  102,  10, 107,  12, 119,  38,  79,  46,  64,  17, 
  120,  13,  90,  59,  85,  17, 112,  25,  70,  31, 
  118,  34,  77,  35,  68,  14, 103,   6, 104,  15, 
   71,  50,  79
};
int i,len = 33;
for(i=len-1;i>=1;i--){str[i]^=str[i-1];}
puts(str);
}
//flag{QianQiuWanDai_YiTongJiangHu}

第七题helloword

apk逆向,准备工具jadx

定位到关键代码

package com.example.helloword;
​
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
​
public class MainActivity extends ActionBarActivity {
    /* access modifiers changed from: protected */
    @Override // android.support.v7.app.ActionBarActivity, android.support.v4.app.FragmentActivity
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        "flag{7631a988259a00816deda84afb29430a}".compareTo("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
    }
​
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
​
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

直接提取flag

flag{7631a988259a00816deda84afb29430a}

第八题reverse3

ida打开

定位到关键代码

sub_41132F("please enter the flag:", v7);
  sub_411375("%20s", (char)Str);
  v3 = j_strlen(Str);
  v4 = (const char *)sub_4110BE(Str, v3, v14);
  strncpy(Destination, v4, 0x28u);
  v11 = j_strlen(Destination);
  for ( j = 0; j < v11; ++j )
    Destination[j] += j;
  v5 = j_strlen(Destination);
  if ( !strncmp(Destination, Str2, v5) )
    sub_41132F("rigth flag!\n", v8);
  else
    sub_41132F("wrong flag!\n", v8);
  return 0;

接着分享 flag给到了Str,进入了函数sub_4110BE(Str, v3, v14);处理

然后处理为v4,v4复制到Destination,Destination进行加操作,接着和Str2比较

我们发现sub_4110BE对字符串flag进行base64加密(字符特征)

Str2=“e3nifIH9b_C@n@dH”

直接写EXP

#include<stdio.h>
#include<windows.h>
#include<string.h>
int main(){
  char str[]="e3nifIH9b_C@n@dH";
int i,len = strlen(str);
for(i=0;i<len;i++){str[i]-=i;}
puts(str);
}
//e2lfbDB2ZV95b3V9
//拿着e2lfbDB2ZV95b3V9进行常规base64解密
//flag{i_l0ve_you}

第九题不一样的flag

有点像游戏,用ida打开

f5直接看,定位到

 strcpy(v3, "*11110100001010000101111#");
 for ( i = 0; i <= 1; ++i )
    {
      if ( *(&v4 + i) < 0 || *(&v4 + i) > 4 )
        exit(1);
    }
    if ( v8[5 * v4 - 41 + v5] == '1' )
      exit(1);
    if ( v8[5 * v4 - 41 + v5] == '#' )
    {
      puts("\nok, the order you enter is the flag!");
      exit(0);
    }

首先

puts("1 up");
 puts("2 down");
 puts("3 left");
 printf("4 right\n:");

超出1到范围直接退出

其次在数组v3种遇到1或者#直接退出,但#提示我们输入的就是flag,这是一道典型的迷宫题

根据二维数组公式结合

 if ( v8[5 * v4 - 41 + v5] == '1' )
      exit(1);
    if ( v8[5 * v4 - 41 + v5] == '#' )

假设迷宫一列5位,v4是行,v5是列

*1111
01000
01010
00010
1111#

我们这种迷宫直接手写,如果是复杂的那种要用递归写。

flag{222441144222}

第十题SimpleRev

ELF文件

定位到Decry()关键函数

unsigned __int64 Decry()
{
  char v1; // [rsp+Fh] [rbp-51h]
  int v2; // [rsp+10h] [rbp-50h]
  int v3; // [rsp+14h] [rbp-4Ch]
  int i; // [rsp+18h] [rbp-48h]
  int v5; // [rsp+1Ch] [rbp-44h]
  char src[8]; // [rsp+20h] [rbp-40h] BYREF
  __int64 v7; // [rsp+28h] [rbp-38h]
  int v8; // [rsp+30h] [rbp-30h]
  __int64 v9[2]; // [rsp+40h] [rbp-20h] BYREF
  int v10; // [rsp+50h] [rbp-10h]
  unsigned __int64 v11; // [rsp+58h] [rbp-8h]
​
  v11 = __readfsqword(0x28u);
  *(_QWORD *)src = 'SLCDN';
  v7 = 0LL;
  v8 = 0;
  v9[0] = 'wodah';
  v9[1] = '\0';
  v10 = 0;
  text = (char *)join(key3, v9);                // key3="killshadow"
  strcpy(key, key1);
  strcat(key, src);                             // key="ADSFKNDCLS"
  v2 = 0;
  v3 = 0;
  getchar();
  v5 = strlen(key);
  for ( i = 0; i < v5; ++i )
  {
    if ( key[v3 % v5] > 64 && key[v3 % v5] <= 90 )
      key[i] = key[v3 % v5] + 32;
    ++v3;
  }
  printf("Please input your flag:");
  while ( 1 )
  {
    v1 = getchar();
    if ( v1 == 10 )
      break;
    if ( v1 == 32 )
    {
      ++v2;
    }
    else
    {
      if ( v1 <= '`' || v1 > 'z' )
      {
        if ( v1 > '@' && v1 <= 'Z' )
        {
          str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97;
          ++v3;
        }
      }
      else
      {
        str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97;
        ++v3;
      }
      if ( !(v3 % v5) )
        putchar(32);
      ++v2;
    }
  }
  if ( !strcmp(text, str2) )
    puts("Congratulation!\n");
  else
    puts("Try again!\n");
  return __readfsqword(0x28u) ^ v11;
}

text=str2 为key3,key经过变化后,与flag操作成为Str2

注意,大小端的问题,我们换成字符串的时候要注意顺序

我们直接写EXP

#include<stdio.h>
#include<windows.h>
#include<string.h>
int main(){
char key[]="adsfkndcls";
char str2[]="killshadow";
 int  v5 = strlen(key);
 char flag[v5+1];
 flag[v5] = '\0';
  int i;
  int j = 0;
  for( i = 0; i < v5; ++i ){
  j = 0;
    for( j = 0;j<10;j++) {
     flag[i]=str2[i]-97+26*j+39-97+key[i];
     if( flag[i]<='Z'&&flag[i]>='A'||flag[i]>='a'&&flag[i]<='z')
      break;
 }
    
 }
  puts(flag);
}
​
​

第十一题JAVA逆向

用jadx打开

package defpackage;
​
import java.util.ArrayList;
import java.util.Scanner;
​
/* renamed from: Reverse  reason: default package */
public class Reverse {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        System.out.println("Please input the flag :");
        String str = s.next();
        System.out.println("Your input is :");
        System.out.println(str);
        Encrypt(str.toCharArray());
    }
​
    public static void Encrypt(char[] arr) {
        int[] KEY;
        ArrayList<Integer> Resultlist = new ArrayList<>();
        for (char c : arr) {
            Resultlist.add(Integer.valueOf((c) +'@' ^ 32));
        }
        ArrayList<Integer> KEYList = new ArrayList<>();
        for (int i : new int[]{180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65}) {
            KEYList.add(Integer.valueOf(i));
        }
        System.out.println("Result:");
        if (Resultlist.equals(KEYList)) {
            System.out.println("Congratulations!");
        } else {
            System.err.println("Error!");
        }
    }
}

显而易见,直接写EXP

#include<stdio.h>
#include<windows.h>
#include<string.h>
int main(){
char enflag[]={180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65};
int len = strlen(enflag);
char flag[len + 1];
flag[len] = '\0';
int i;
for(i = 0; i < len; i++){
  flag[i] = enflag[i]-'@'^32;
}
puts(flag);
}
//flag{This_is_the_flag_!}

第十二题[GXYCTF2019]luck_guy

定位关键代码

 v5 = __readfsqword(0x28u);
  v0 = time(0LL);
  srand(v0);
  for ( i = 0; i <= 4; ++i )
  {
    switch ( rand() % 200 )
    {
      case 1:
        puts("OK, it's flag:");
        memset(s, 0, sizeof(s));
        strcat((char *)s, f1);                  // GXY{do_not_
        strcat((char *)s, &f2);
        printf("%s", (const char *)s);
        break;
      case 2:
        printf("Solar not like you");
        break;
      case 3:
        printf("Solar want a girlfriend");
        break;
      case 4:
        strcpy((char *)s, "icug`of\x7F");
        strcat(&f2, (const char *)s);
        break;
      case 5:
        for ( j = 0; j <= 7; ++j )
        {
          if ( j % 2 == 1 )
            *(&f2 + j) -= 2;
          else
            --*(&f2 + j);
        }
        break;
      default:
        puts("emmm,you can't find flag 23333");
        break;
    }

逻辑简单,我们直接拿到上半部分GXY{do_not_

下半部分直接写EXP

#include<stdio.h>
#include<windows.h>
#include<string.h>
int main(){
char s[]="icug`of\x7F";
int j;
int len = strlen(s);
   for ( j = 0; j <= 7; ++j )
        {
          if ( j % 2 == 1 )
           s[j]-= 2;
          else
            s[j] -=1;
        }
        puts( s );
}
//hate_me}

flag{do_not_hate_me}

第十三题刮开有奖

定位到关键代码

INT_PTR __stdcall DialogFunc(HWND hDlg, UINT a2, WPARAM a3, LPARAM a4)
{
  const char *v4; // esi
  const char *v5; // edi
  int v7[10]; // [esp+8h] [ebp-20030h] BYREF
  int v8; // [esp+30h] [ebp-20008h]
  CHAR String[65536]; // [esp+34h] [ebp-20004h] BYREF
  char v10[65536]; // [esp+10034h] [ebp-10004h] BYREF
​
  if ( a2 == 272 )
    return 1;
  if ( a2 != 273 )
    return 0;
  if ( (_WORD)a3 == 1001 )
  {
    memset(String, 0, 0xFFFFu);
    GetDlgItemTextA(hDlg, 1000, String, 0xFFFF);
    if ( strlen(String) == 8 )
    {
      v7[0] = 90;
      v7[1] = 74;
      v7[2] = 83;
      v7[3] = 69;
      v7[4] = 67;
      v7[5] = 97;
      v7[6] = 78;
      v7[7] = 72;
      v7[8] = 51;
      v7[9] = 110;
      v8 = 103;
      sub_4010F0(v7, 0, 10);
      memset(v10, 0, 0xFFFFu);
      v10[0] = String[5];
      v10[2] = String[7];
      v10[1] = String[6];
      v4 = (const char *)sub_401000(v10, strlen(v10));
      memset(v10, 0, 0xFFFFu);
      v10[1] = String[3];
      v10[0] = String[2];
      v10[2] = String[4];
      v5 = (const char *)sub_401000(v10, strlen(v10));
      if ( String[0] == v7[0] + 34
        && String[1] == v7[4]
        && 4 * String[2] - 141 == 3 * v7[2]
        && String[3] / 4 == 2 * (v7[7] / 9)
        && !strcmp(v4, "ak1w")
        && !strcmp(v5, "V1Ax") )
      {
        MessageBoxA(hDlg, "U g3t 1T!", "@_@", 0);
      }
    }
    return 0;
  }
  if ( (_WORD)a3 != 1 && (_WORD)a3 != 2 )
    return 0;
  EndDialog(hDlg, (unsigned __int16)a3);
  return 1;
}

这道题让我学会了,如果动态调试调不了,可以把代码copy下来,自己跑。

先说说思路String的后6位很简单,解base64就出来了,但前2位是要进过sub_4010F0函数变化得到的,重点就到了加密上。太多太复杂,我动态调试,结果跑不到我的断点。看到大佬的WP让我感悟到可以直接copy代码,自己跑

我们得知道加密后的v7

#include<stdio.h> 
void sub_7310F0(int *v7, int a2, int a3)
{
  int v3; // eax
  int i; // esi
  int v5; // ecx
  int v6; // edx
​
  v3 = a3;
  for ( i = a2; i <= a3; a2 = i )
  {
    v5 = i;
    v6 = v7[i];
    if ( a2 < v3 && i < v3 )
    {
      do
      {
        if ( v6 > v7[v3] )
        {
          if ( i >= v3 )
            break;
          ++i;
          v7[v5] = v7[v3];
          if ( i >= v3 )
            break;
          while ( v7[i] <= v6 )
          {
            if ( ++i >= v3 )
              goto LABEL_13;
          }
          if ( i >= v3 )
            break;
          v5 = i;
          v7[v3] = v7[i];
        }
        --v3;
      }
      while ( i < v3 );
    }
LABEL_13:
    v7[v3] = v6;
    sub_7310F0(v7, a2, i - 1);
    v3 = a3;
    ++i;
  }
}
int main()
{
    int v7[11];
     v7[0] = 90;
      v7[1] = 74;
      v7[2] = 83;
      v7[3] = 69;
      v7[4] = 67;
      v7[5] = 97;
      v7[6] = 78;
      v7[7] = 72;
      v7[8] = 51;
      v7[9] = 110;
      v7[10] = 103;
      sub_7310F0(v7,0,10);
      for ( int i = 0; i <10;i++)
      {
          printf("%c",v7[i]);
      }
      //3CEHJNSZag
​
}
​

然后直接解

#include<stdio.h>
#include<windows.h>
#include<string.h>
int main(){
char v7[11]="3CEHJNSZag";
char String[9];
  String[0] = v7[0] + 34;
  String[1] = v7[4];
  String[5]='j';
  String[6]='M';
  String[7]='p';
  String[2]= 'W';
  String[3]='P';
  String[4]='1';
  String[8]='\0';
  puts(String);
//UJWP1jMp
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值