Buuctf—— Re题解

文章描述了在不同技术场景下的逆向工程过程,包括在ida中分析、使用指针法判断字节序、字符串处理、Base64解密、ASCII字符操作、加密算法破解等,最终找出隐藏的flag。
摘要由CSDN通过智能技术生成

SimpleRev 

查壳

放ida里面

这里给出的src和v9需要判断一下是大端还是小端

用指针法判断出是小端,故得到的字符串要反着写

后面半段是加密流程, 直接把全部字母尝试一遍即可

flag{KLDQCUDFZO}

Luck-guy

查壳

64位无壳

跟踪进patch_me函数,

继续跟进

跟踪进f1得到flag第一段,

在case 4中s后面的是小端,在读写时要反着写;跟进f2发现f2什么也没有;把s加到f2中,即此时f2里面就是s;在case 5里,对f2进行了一段加密;根据case1里flag=s+f1+f2,s先被初始化为0了,所以flag就是f1和·f2两段。编写函数求出f2加密后的结果:

把f1和f2拼接起来就是flag:GXY{do_not_hate_me},由于Buuctf里面要求用flag{}形式,故把GXY换成flag就行,即flag{do_not_hate_me}

JustRe

查壳

32位,无壳,用ida打开

这里的WinMain函数是程序的入口点函数,在这个函数里面找不到有用的信息,按shift+F12去字符串里面找

在最后一行发现了一个以flag形式的字符串,跟踪进去后交叉引用,打开另一个函数

这里的sprintf函数承担着将字符串复制储存到String数组里,然后用19999和0替换字符串中的%d的作用。SetwindowTextA是起到改变窗口标题栏的文本内容的作用,即作用于运行后的窗口

所以它不会改变String,因此用19999和0替换字符串里的%d后的结果就是flag,即flag{1999902069a45792d233ac}

刮开有奖

查壳

32位,无壳,用ida打开

打开DialogFunc函数

跟进sub_401000函数,

跟进这个byte_407830

是个base64表,由此可知,这个sub函数对数据进行了base64加密。把需要和v4及v5比较的字符串用工具进行base64解密,然后按string[]数组的顺序排列得到“WP1jMp”这就是flag的后六位。因为前面的赋值时连续赋值,所以他们的地址是连续的,跟踪进sub_4010F0函数,这里对前面赋值的数进行了一系列操作。

函数很长,把这个函数复制到编译软件里,稍微修改使之能运行

#include<stdio.h>
#include<string.h> 
int __cdecl sub_C110F0(char* a1, int a2, int a3)
{
  int result; // eax
  int i; // esi
  int v5; // ecx
  int v6; // edx

  result = a3;
  for ( i = a2; i <= a3; a2 = i )
  {
    v5 = i;
    v6 = a1[i];
    if ( a2 < result && i < result )
    {
      do
      {
        if ( v6 > a1 [result] )
        {
          if ( i >= result )
            break;
          ++i;
          a1[v5] = a1[result];
          if ( i >= result )
            break;
          while ( a1[i] <= v6 )
          {
            if ( ++i >= result )
              goto LABEL_13;
          }
          if ( i >= result )
            break;
          v5 = i;
          a1[result] = a1[i];
        }
        --result;
      }
      while ( i < result );
    }
LABEL_13:
    a1[result] = v6;
    sub_C110F0(a1, a2, i - 1);
    result = a3;
    ++i;
  }
  return result;
}
int main()
{ 
	char v7[]="ZJSECaNH3ng";
      sub_C110F0(v7, 0, 10);
      //printf("%s",v7);
      for(int i=0;i<=9;i++)
      {
      	printf("%d ",v7[i]);
	  }
  return 0;
}

运行得到

我们只需要用到v7[0]和v10,即第一个和第5个,

根据条件,可以得知,String[0]=51+34=85=U,String[1]=74=J。所以flag{UJWP1jMp}。

easyre

查壳

32位有壳,进行去壳操作

去壳结束后用ida打开,

由if里面的判断语句可知,flag是以“ACTF{}”形式的,flag就在括号里面,qmemcpy函数就是把后面的字符串复制到v4里面,因为循环是12次的,猜测flag就是12位,

由以上可知v4[i] = _data_start__[v5[i] - 1],也就是说,与v4[i]相同的字符在data数组中的位置+1=v5[i]。编写代码如下:

#include<stdio.h>
#include<string.h>
int main()
{
	char s[]="~}|{zyxwvutsrqponmlkjihgfedcba`_^]\\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)(\'&%$# !\"";
	char v[]="*F'\"N,\"(I?+@";
	for(int i=0;i<strlen(v);i++)
	{
		for(int j=0;j<strlen(s);j++)
		{
			if(v[i]==s[j])
			{
				printf("%c",j+1);
				break;
			}
		}
	}
	return 0;
}

flag{U9X_1S_W6@T?}

pyre

下载后发现是一个pyc文件,将其与pycdc.exe文件放同一个文件夹,在终端中输入“pycdc.exe attachment.pyc”,得到如下伪代码:

D:\逆向\python逆向>pycdc.exe attachment.pyc
# Source Generated with Decompyle++
# File: attachment.pyc (Python 2.7)

print 'Welcome to Re World!'
print 'Your input1 is your flag~'
l = len(input1)
for i in range(l):
    num = ((input1[i] + i) % 128 + 128) % 128
    code += num

for i in range(l - 1):
    code[i] = code[i] ^ code[i + 1]

print code
code = [
    '\x1f',
    '\x12',
    '\x1d',
    '(',
    '0',
    '4',
    '\x01',
    '\x06',
    '\x14',
    '4',
    ',',
    '\x1b',
    'U',
    '?',
    'o',
    '6',
    '*',
    ':',
    '\x01',
    'D',
    ';',
    '%',
    '\x13']

D:\逆向\python逆向>

flag进行了两次加密后等于code,在异或操作中,唯一没有改变的是code的最后一位,所以反向解密,反向异或后得到的数组直接进行暴力解法,由于ASCII表只有0~127这些数字,所以直接遍历一遍找flag:

#include<stdio.h>
#include<string.h>
int main()
{
	char s[]={'\x1f','\x12','\x1d','(','0','4','\x01','\x06','\x14','4',',','\x1b','U','?','o','6','*',':','\x01','D',';','%','\x13'};
    for(int i=strlen(s)-2;i>=0;i--)
    {
    	s[i] = s[i] ^ s[i + 1];
	}
	for(int i=0;i<=strlen(s)-1;i++)
	{
		for(int j=0;j<=127;j++)
		{
			if(s[i] == ((j + i) % 128 + 128) % 128)
			{
				printf("%c",j);
			}
		}
	}
	return 0;
 } 

把GWHT换成flag就是flag了,即flag{Just_Re_1s_Ha66y!}

rome

查壳

32位无壳,用ida打开

跟进func函数:

将v2,v3等数转化为字符,得到了“ACTF{}",是flag的形式,可知flag就是包在括号里的内容,因为括号里的内容赋值给了v1,所以v1就是flag。先分析一下加密函数:

这里*(_DWORD *)&v12[17]就是一个变量,类似循环里的i,所以*((char *)v1 + *(_DWORD *)&v12[17])就是指v1[i],将变量名修改后就更容易看明白加密过程了:

i = 0;
while ( i <= 15 )
{
    if ( v1[i] > 64 && v1[i]  <= 90 )
        v1[i]  = (v1[i]  - 51) % 26 + 65;
    if ( v1[i]  > 96 && v1[i]  <= 122 )
        v1[i]  = (v1[i]  - 79) % 26 + 97;
    ++i;
}
i = 0;
while ( i <= 15 )
{
    result = v12[i];
    if ( v1[i]  !=  result )
        return result;
    ++i;
}
return printf("You are correct!");

因为加密过程进行了取余处理,不好反向推,所以选择直接遍历ASCII为0~127的字符来筛选出符合条件的字符,编写代码如下:

#include<stdio.h>
#include<string.h>
int main()
{
	char s[]="Qsw3sj_lz4_Ujw@l" ;
	int x;
	for(int i=0;i<=15;i++)
	{
		for(int j=0;j<=127;j++)
		{
			x=j;
			if(j>64&&j<=90)
				x=(x-51)%26+65;
			if(j>96&&j<=122) 
				x=(x-79)%26+97;
			if(x==s[i])
			{
				printf("%c",j);
			 } 
		}
	}
	return 0;
 } 

flag{Cae3ar_th4_Gre@t}

login

下载后打开html文件,跳转到了一个网页,按F12获得其源代码

<!DOCTYPE Html />
<html>
    <head>
        <title>FLARE On 2017</title>
    </head>
    <body>
        <input type="text" name="flag" id="flag" value="Enter the flag" />
        <input type="button" id="prompt" value="Click to check the flag" />
        <script type="text/javascript">
            document.getElementById("prompt").onclick = function () {
                var flag = document.getElementById("flag").value;
                var rotFlag = flag.replace(/[a-zA-Z]/g, function(c){return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);});
                if ("PyvragFvqrYbtvafNerRnfl@syner-ba.pbz" == rotFlag) {
                    alert("Correct flag!");
                } else {
                    alert("Incorrect flag, rot again");
                }
            }
        </script>
    </body>
</html>

对flag里面的字符进行了替换操作,替换成的是“(c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26”得到的结果,这一条指令,其实就是分为4种情况:

if(s[i]<='M'&&s[i]>='A')
     printf("%c",s[i]+13);
else if(s[i]<='Z'&&s[i]>='N')
     printf("%c",s[i]-13);
else if(s[i]<='m'&&s[i]>='a')
	 printf("%c",s[i]+13);
else if(s[i]<='z'&&s[i]>='n')
	printf("%c",s[i]-13);

 这一段意思是一个从A~Z(或a~z)的字母,如果它在前半段(即A~M),就把它替换为位次是它后13位的字母;如果在后半段(即N~Z),就把它替换为它前13为的字母。由于英文字母是26个,所以字母往前13位和往后13位对应的字母都是一样的,也就是说,每两个字母一一对应,A和N对应,B和O对应·····M和Z对应。所以这一段加密就是把A换成N,把N换成A,把B换成O,把O换成B······。要解密的话,只需用和加密相同的代码做脚本

#include<stdio.h>
#include<string.h>
int main()
{
	char s[]="PyvragFvqrYbtvafNerRnfl@syner-ba.pbz";
	for(int i=0;i<strlen(s);i++)
	{
		if(s[i]<='M'&&s[i]>='A')
		  printf("%c",s[i]+13);
		else if(s[i]<='Z'&&s[i]>='N')
		  printf("%c",s[i]-13);
		else if(s[i]<='m'&&s[i]>='a')
		  printf("%c",s[i]+13);
		else if(s[i]<='z'&&s[i]>='n')
		  printf("%c",s[i]-13);
		else printf("%c",s[i]);
	 } 
	return 0;
 } 

flag{ClientSideLoginsAreEasy@flare-on.com}

level 1

下载后有两个文件,一个文件叫output,里面是一串数字,对另一个文件查壳

64位,用ida打开

fopen函数是打开文件,fread是读取文件后存放数据到ptr数组里,fclose是关闭文件,所以flag就在ptr数组里面,后面是一堆加密和输出,其中i&1是判断奇偶数:1换为二进制是0000 0001,进行与运算无论最后一位前面是1还是零,与运算后一定是0,所以只需要看最后一位,如果最后一位是0,那么i&1就是0,如果最后一位是1,那么i&1结果是1.如果是奇数,那么最后一位一定是1,而偶数则是0.所以它可以判断奇偶性。

对于ptr这个数组,是20位的,但是循环从ptr[1]开始,也就是ptr[0]是什么不影响后面的输出,从文件名是output可知,输出的结果是文件里面的数字,编写脚本如下

#include<stdio.h> 
#include<string.h>
int main()
{
	int s[]={198,232,816,200,1536,300,6144,984,51200,570,92160,1200,565248,756,1474560,800,6291456,1782 ,65536000 };
	for(int i=0;i<=18;i++)
	{
		if ( ((i+1) & 1) != 0 )
      printf("%c", (s[i] >> i+1));
    else
      printf("%c", s[i]/(i+1));
	 } 
 } 

至于为什么是i+1,这是因为ptr[0]没有参与输出,所以s[0]对标的是ptr[1],对应的是i=1,而不是0

运行这段代码得到flag{d9-dE6-20c}

  • 17
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断
buuctfmisc是一个CTF比赛中的题目,涉及到网络分析工具Wireshark的使用。Wireshark是一款开源的网络协议分析工具,可以用于捕获和分析网络数据包。在buuctfmisc题目中,可能需要使用Wireshark来解析和分析给定的网络数据包,以获取关键信息或者解决问题。 具体的题解步骤可能因题目而异,但通常的解题思路如下: 1. 下载并安装Wireshark:首先需要从Wireshark官网下载并安装适合你操作系统的版本。 2. 打开Wireshark并开始捕获数据包:打开Wireshark后,选择合适的网络接口开始捕获数据包。可以通过点击"Capture"按钮或者使用快捷键Ctrl + E来开始捕获。 3. 分析捕获的数据包:Wireshark会将捕获到的数据包以列表形式展示出来。你可以通过点击每个数据包来查看其详细信息,包括源IP地址、目标IP地址、协议类型等。 4. 过滤数据包:如果题目要求只关注特定的数据包,你可以使用Wireshark提供的过滤功能来筛选出符合条件的数据包。过滤条件可以根据协议、源IP地址、目标IP地址等进行设置。 5. 提取关键信息:根据题目要求,你可能需要从数据包中提取关键信息。Wireshark提供了多种功能来帮助你提取数据,比如导出数据包、导出特定协议的数据等。 6. 分析数据包内容:根据题目要求,你可能需要进一步分析数据包的内容。Wireshark可以解析多种协议,你可以查看每个数据包的协议栈、协议字段等信息。 7. 解决问题或回答题目:根据你对数据包的分析和提取的关键信息,你可以解决问题或者回答题目。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值