BUUCTF

这篇具有很好参考价值的文章主要介绍了BUUCTF。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. easyre

  • exeinfo查壳
    BUUCTF

    64位,无壳,用ida64打开

  • 首先查看字符串表
    BUUCTF

    发现flag

2.reverse1

  • exeinfo查壳
    BUUCTF

    64位,无壳,用ida64打开

  • 首先查看字符串
    BUUCTF

    发现疑似flag的字符串

  • 查看引用该字符串的函数
    BUUCTF

    Str2即是该字符串。注意到有一个strcmp()函数,所以基本确定Str2即是flag。有一个for循环处理了Str2:当Str2中有一个字符的ASCII码等于111(o)时,替换为48(0)
    所以flag为flag

注意:ida是静态调试器,内存中的数据是还没有经过各种代码处理的。例如本题的Str2,只有头几次出现(未被处理)时为hello_world,后面经过处理后就不是hello_world了,虽然在ida中仍然指向hello_world,这是因为Str2是一个指针,指向了保存hello_world的那块内存,在程序没有执行之前那块内存的内容不会改变!

3.reverse2

  • 注意到下载的文件并不是exe可执行文件!

查不了壳,不过仍然用exeinfo打开看看是32位的还是64位的
BUUCTF

64位,用ida64打开

  • 查看字符串表
    BUUCTF
    发现疑似flag的字符串,但是ctrl+x发现没有引用

BUUCTF

但是,这里有一个非常值得注意的点,字符串名是一个指向字符串首位地址的指针,该地址往后的地址也是字符串的一部分,那么字符串在哪里截止呢?C/C++中/0即表示字符串停止,汇编中用
"*** ,0 ***"表示字符串结束。所以在这里变量flag指向了601081处,而601081处存储了78h(“{”),那么flag就是“{”了吗?当然不是,flag指向的字符串并没有这里截止,所以往后的aHackingForFun指向的字符串仍是flag的一部分,直到“,0”为止(db 0(空,nop)、ends(段结束) 也是字符串结尾的标志)

  • 跳转到引用flag变量的函数,F5反编译
    BUUCTF

注意到line 27处有一个strcmp()函数,因此经过处理后的flag即是答案

  • 处理脚本(照抄即可):
    BUUCTF

4.内涵的软件

  • exeinfo查壳
    BUUCTF

32位,无壳,ida32打开

  • 查看字符串
    BUUCTF

疑似flag,查看引用
BUUCTF

进入引用函数,发现并没有处理此字符串,应该这个字符串就是答案(改为题述格式)

5.新年快乐

  • exeinfo查壳
    BUUCTF

32位,用了UPX加壳

  • 脱壳
    BUUCTF

ida32打开

  • 查看字符串表
    BUUCTF

看不出什么

  • 查看带有“flag”的提示字符串,进入引用函数,F5反编译转为C语言
    BUUCTF

注意line 12、13、14、15,说明v5是flag,没有经过程序处理,所以v4即是答案。

6.xor

  • 不是exe文件!
    仍用exeinfo打开
    BUUCTF

64位,用ida64打开

  • 查看字符串
    BUUCTF

发现很奇怪的一串东西,看看引用
BUUCTF

没有函数引用它,只有一个变量_global指向了它

  • 再查看带有“flag”的提示字符串,进入引用函数,F5反编译转为C语言
    BUUCTF

注意line 11、12、18、19,所以v6即是flag。v6经过一系列异或运算等于_global,所以对_global进行逆运算即可获取答案

  • 脚本程序:
    BUUCTF

注意:a ^ b = c,则 a ^ c = b , b ^ c = a

7.helloword

  • 注意是一个apk文件,所以要用apk反编译软件,反编译后打开字符串表搜索flag即可获取答案
    变种的第1题

8.reverse3

  • 查壳
    BUUCTF

32位,无壳,用ida32打开

  • 查看字符串表
    BUUCTF

注意到“ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=”,所以可以确认是进行了base64加密

  • 查看带有“flag”的提示字符串,进入引用函数,F5反编译转为C语言
    BUUCTF

可以看出,Str即是flag,接下来就是还原Str了,即对Str2进行逆向处理

  • 跟踪line 24的sub_4110BE函数
    BUUCTF
    BUUCTF

这个函数即是base64加密函数

  • 处理脚本:
    BUUCTF

9.不一样的flag

  • 查壳
    BUUCTF

32位,无壳,用ida32打开

  • 查看字符串表
    BUUCTF

初步判断应该是一个小游戏,通过不断选择上下左右而获取flag

  • 进入引用函数
    BUUCTF
    BUUCTF

line 51、53中的49、35分别对应1、#
所以应该是一个迷宫程序,将*11110100001010000101111#分成五排五列,不经过1到达#所执行的按键组合即是答案

10.SimpleRev

  • 不是exe文件。
    BUUCTF

64位,用ida64打开

  • 查看字符串
    BUUCTF

看不出什么。

  • 进入提示字符串引用函数
    BUUCTF
    BUUCTF

  • 分析程序流程

    1. 给src(将十进制转为十六进制(0x534C43444E),一个字节一个字节对照ASCII码表(ida快捷键“R”)就可以得到对应字符串为“SLCDN”(不能直接用十进制下的数据两两对照,计算机处理的是16进制!经过十进制化的数据必须要还原成16进制才能对照ASCII码表,除非只是一个字节的数据!),但是,只要是英特尔或AMD的x86/x64架构那么一定是小端序,所以该十六进制数实际处理时是0x4E44434C53,因此程序实际处理的字符串为“NDCLS”)和v9(同理可得程序实际处理的值为“hadow”)赋值
    2. 调用join()函数,参数为key3(存储的值为“kills”,字符串名本身是指针)和v9的指针
      BUUCTF

    可以看出,join()函数的作用是将key3和v9拼接起来,并赋给text("killshadow")(malloc()分配内存,返回指向此内存的指针)
    3. line 24、25将key1(值为“ADSFK”)和src拼接赋给key(“ADSFKNDCLS”)
    4. 处理key,得到v3和新的key
    5. 由line 36、39可以得知v1是flag。通过逐个处理v1的字符修改str2,最后str2的值要与text("killshadow")相等

  • 处理脚本:
    BUUCTF

11.Java逆向解密

  • 使用jd-gui反编译
    BUUCTF

这段程序的意思是:输入的字符串依次+‘@’,然后跟32异或,得到KEY数组里的值
所以只要反过来即可:将KEY数组中的值逐个与32异或,再-‘@’

12.[GXYCTF2019]luck_guy

  • exeinfo打开
    BUUCTF

64位,ida64打开

  • 查看字符串表
    BUUCTF

形似flag

  • 进入引用函数(也可以从main()函数一步步分析过来)
    BUUCTF

  • 分析函数流程
    1.v0接收当前时间戳,以v0为种子,以此产生4个(伪)随机数,对200求余后分别运行子程序
    2.由case 1可知s即为flag,它由f1(GXY{do_not_)和f2拼接而成,而f2由case 4得到并经case 5处理,所以应该按照5——>4——>1的流程即可获取真正的flag
    注意:line 33中给s赋的值是小端序,得到的字符串要逆转过来(“icug`of ”)

  • 处理脚本:
    BUUCTF

13.刮开有奖

  • 查壳
    BUUCTF

32位,无壳,用ida32打开

  • 查看字符串表
    BUUCTF

base64加密
BUUCTF

这种奇奇怪怪的字符串多半跟flag有关

  • 分析程序的函数执行流程
    BUUCTF
    搜索main,发现有个WinMain()函数(主函数),调用了DialogBoxParam()来显示对话框,参数里有个DialogFunc,这是对话框过程函数,用来给对话框处理用户或系统的行为,这应该就是目标了
  • 查看DialogFunc()
BOOL __stdcall DialogFunc(HWND hDlg, UINT a2, WPARAM a3, LPARAM a4)
{
  const char *v4; // esi
  const char *v5; // edi
  int v7; // [esp+8h] [ebp-20030h]
  int v8; // [esp+Ch] [ebp-2002Ch]
  int v9; // [esp+10h] [ebp-20028h]
  int v10; // [esp+14h] [ebp-20024h]
  int v11; // [esp+18h] [ebp-20020h]
  int v12; // [esp+1Ch] [ebp-2001Ch]
  int v13; // [esp+20h] [ebp-20018h]
  int v14; // [esp+24h] [ebp-20014h]
  int v15; // [esp+28h] [ebp-20010h]
  int v16; // [esp+2Ch] [ebp-2000Ch]
  int v17; // [esp+30h] [ebp-20008h]
  CHAR String; // [esp+34h] [ebp-20004h]
  char v19; // [esp+35h] [ebp-20003h]
  char v20; // [esp+36h] [ebp-20002h]
  char v21; // [esp+37h] [ebp-20001h]
  char v22; // [esp+38h] [ebp-20000h]
  char v23; // [esp+39h] [ebp-1FFFFh]
  char v24; // [esp+3Ah] [ebp-1FFFEh]
  char v25; // [esp+3Bh] [ebp-1FFFDh]
  char v26; // [esp+10034h] [ebp-10004h]
  char v27; // [esp+10035h] [ebp-10003h]
  char v28; // [esp+10036h] [ebp-10002h]

  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 = 90;
      v8 = 74;
      v9 = 83;
      v10 = 69;
      v11 = 67;
      v12 = 97;
      v13 = 78;
      v14 = 72;
      v15 = 51;
      v16 = 110;
      v17 = 103;
      sub_4010F0(&v7, 0, 10);
      memset(&v26, 0, 0xFFFFu);
      v26 = v23;
      v28 = v25;
      v27 = v24;
      v4 = (const char *)sub_401000(&v26, strlen(&v26));
      memset(&v26, 0, 0xFFFFu);
      v27 = v21;
      v26 = v20;
      v28 = v22;
      v5 = (const char *)sub_401000(&v26, strlen(&v26));
      if ( String == v7 + 34
        && v19 == v11
        && 4 * v20 - 141 == 3 * v9
        && v21 / 4 == 2 * (v14 / 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;
}

这里注意到有两处连续的变量声明,同时地址也很连续,且使用的时候也比较连续,非常有可能是数组,因此ida-edit-Array对这两处一连串变量创建数组
注意:一定要确定好数组的起始地址和结束地址,可以通过双击ida反汇编伪代码的数组起始/结束变量跳转到相应地址,以此确定数组范围

  • 创建数组后的DialogFunc()
BOOL __stdcall DialogFunc(HWND hDlg, UINT a2, WPARAM a3, LPARAM a4)
{
  const char *v4; // esi
  const char *v5; // edi
  int v7[11]; // [esp+8h] [ebp-20030h]
  char String[8]; // [esp+34h] [ebp-20004h]
  char v9[3]; // [esp+10034h] [ebp-10004h]

  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;
      v7[10] = 103;
      sub_4010F0(v7, 0, 10);//处理v7数组(实际上是排序)
      memset(v9, 0, 0xFFFFu);
      v9[0] = String[5];
      v9[2] = String[7];
      v9[1] = String[6];
      v4 = sub_401000((int)v9, strlen(v9));//base64加密
      memset(v9, 0, 0xFFFFu);
      v9[1] = String[3];
      v9[0] = String[2];
      v9[2] = String[4];
      v5 = sub_401000((int)v9, strlen(v9));//base64加密
      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;
}

较比创建数组前,代码的可读性强了很多
注意到GetDlgItemTextA()函数,这个函数的用处是复制对话框中的字符串到lpString参数(第3个参数)指向的缓冲区,即保存输入到指定变量。再加上后面一系列的对String的比较因此String很有可能就是flag

  • 逐个分析关键函数(sub_4010F0、sub_401000)

    1. sub_4010F0
      这个函数实在是太复杂了,因此直接照抄(注意加上头文件,以及删掉例如(_DWORD *)的汇编表示(取4个字节),然后将各种基址+偏移的表示也换成数组的寻址),跑一下程序看看结果
    2. sub_401000
      BUUCTF

    发现有个byte_407830数组,双击查看
    BUUCTF
    (41h即“A”)
    所以可以确定这是个base64加密函数,而且看一下参数,发现两次都是对v9数组的处理,只是两次对v9数组赋的值不同

接下来只要这个确认String数组中的每一个字符即可获取答案

14.

22.[SUCTF2019]SignIn

  • 例行exeinfo检查
    BUUCTF

64位,用ida64打开

  • 查看字符串表
    BUUCTF

程序调用了__gmpz_init_set_str函数,这是一个GNU高精度算法库,在RSA加密中较为常见,在加上65537这个十分敏感的数据,就可以确定这是一道关于RSA加密的题
rsa加密详解:https://blog.csdn.net/dbs1215/article/details/48953589文章来源地址https://www.toymoban.com/news/detail-746541.html

  • 查看主函数
    BUUCTF

到了这里,关于BUUCTF的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 微信小程序在线打开base64形式的pdf文件

    微信小程序在线打开base64形式的pdf文件 流程: 后台返回base64形式的pdf文件的字符串,在微信小程序端打开 小程序中需要用到的几个方法(按顺序) wx.base64ToArrayBuffer(base64数据) //把base64数据转buffer wx.getFileSystemManager().writeFile //写文件 wx.openDocument //打开文件

    2024年02月16日
    浏览(39)
  • 论如何创建APP打开提示手机框架不兼容(架构:32位和64位)

    1.我目前使用的APP获取安装二维码的方式为谷歌aab分享 通过jenkins打包好APP的aab包,放到play internal app sharing-开发提供的分享地址 参考:https://www.likecs.com/show-203641655.html 将aab文件放入上传栏,生成分享文件后复制链接,进入草料二维码转为二维码(https://cli.im/) 2.用32位手机扫

    2024年02月10日
    浏览(42)
  • 打开游戏提示缺失GFSDK_SSAO.win64.dll文件的解决办法

    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个GFSDK_SSAO.win64.dll文件(挑

    2024年02月10日
    浏览(57)
  • Android Spider ApkScan-PKID 查壳工具下载使用以及相关技术介绍

    1、壳的功能:壳最本质的功能就是实现加载器,壳是指在一个程序的外面再包裹上另外一段代码,保护里面的代码不被非法修改或反编译的程序。它们一般都是先于程序运行,拿到控制权,然后完成它们保护软件的任务,深入点就是在apk外面再套一层壳,在运行的时候这层壳

    2024年01月15日
    浏览(37)
  • MySQL mysql-8.0.35-winx64 下载/配置/初始化/安装/打开/登陆/修改密码/退出/卸载/设置远程连接

    #---------------------------------------------------------------------------------------------------------------------------- [mysqld] #设置3306端口 port=3306 #设置mysql的安装目录 basedir=D:mysql-8.0.35-winx64database #设置mysql数据库的数据的存放目录 datadir=D:mysql-8.0.35-winx64databasedata #允许最大连接数 max_connections

    2024年02月04日
    浏览(47)
  • IDA-逆向分析-工具教程-IDA简介-反汇编工具-功能窗口

    介绍了IDA反汇编原理分为, 线性扫描反汇编和递归下降反汇编 。比较了两者的优点和缺点。线性扫描反汇编算法采用一种非常简单的方法来确定需要反汇编的指令的位置:一条指令结束、另一条指令开始的地方。因此,确定起始位置最为困难。常用的解决办法是,假设程序

    2024年02月10日
    浏览(42)
  • 禁止显示状态 错误 LNK1104 无法打开文件“boost_thread-vc142-mt-gd-x64-1_79.lib”

    别人写的工程用vs2019加载,报错如下: 一个错误: LNK1104 无法打开文件“boost_thread-vc142-mt-gd-x64-1_79.lib” 两个警告 1.警告 MSB8004 Intermediate 目录未以斜杠结尾。 此生成实例将添加斜杠,因为必须有这个斜杠才能正确计算 Intermediate 目录。 NetWorkServer C:Program Files (x86)Microsoft Vi

    2024年02月09日
    浏览(84)
  • IDA脚本

    IDA集成了一个脚本引擎,用户可以通过编程对IDA实现全面控制 1. File-Script File IDA会显示一个选择文件的对话框,让你选择想要运行的脚本 运行一个新的脚本,这个程序会被添加到最近运行的脚本列表 View-Recent Scripts可以查看. 2. File-IDC Command File-Python Command (IDA7.2版本为File-Scr

    2024年02月05日
    浏览(29)
  • IDA调试模式

    1.在IDA安装目录找到dbgsrv目录下的 android_server 2.讲android_server文件放置手机/data/local/tmp下 3.CMD窗口,运行./android_server 4.adb forward tcp:端口号 tcp;:端口号 5.打开DDMS:观察程序的端口号 6.调试模式启动 7.IDA里面勾选三项 ​ 1》打开ida,选择debugger-第二项-Remote ARMlinux(第四项) ​ 2》添加

    2024年02月16日
    浏览(36)
  • ida动态调试dll

    有时候会发现有的dll都是动态获取API,IDA静态分析看不了,因此利用IDA动态调试dll,当API获取完毕后保存,便于分析。 在debug窗口选定windows debug后,在Debugger菜单栏下的Process options里填写参数 第一行填写加载dll的exe路径,除了rundll32.exe,有文章说od下的loaddll.exe也是可以的,但

    2024年02月04日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包