攻防世界Reverse(5)

secret-string-400

后缀为gz,第一次见这种压缩包!
在这里插入图片描述
当然我们也可以直接就去用ida看看,是可以发现无法进行逆向的,所以我们解压它!
在这里插入图片描述
有点像web题型,不过它是给了代码的!
我们打开看看!
在这里插入图片描述
这是用火狐打开所显示的内容,用IE打开是没有办法完整显示的,此时我们再来看看另一个html页面!
在这里插入图片描述
有意思!没想到是个这样子的逆向!
然后源代码是没有相关内容的,但是再js里面有,所以我们可以找到js,用记事本打开即可!
然后我们在调试器中进行一系列调试!
在这里插入图片描述
不过调试结果在console显示必须在run函数加上一句话!
在这里插入图片描述
此时我们便可以根据代码写出解密脚本!

WOW_so_EASY
flag就有了!


这道题主要考察了对与网页web上的一些简单登录进行的逆向!主要是加的那句话,将代码给泄露出来!然后根据其进行逆向!

testre

做题来了手感!赶紧再做一题!
EP先探查没有什么东西!
在这里插入图片描述
主要就是这个检查函数,所以我们就进去里面进行一番探查!
在这里插入图片描述
再到函数上面进行细致分析!
在这里插入图片描述
base58不是2的整次幂,所以原理不是base64那样子。
在这里插入图片描述
flag{base58_is_boring}
flag就有了,主要是要理解这个base58是个什么东西!


base58编码,其实源于比特币!
base58编码先将输入转换为ASCLL码值(按256进制算!),然后转换为10进制的数,然后转换为58进制数,此时我们将其按照base58表转换!

deedeedee

这道题还是很难(简单的,flag直接给了)解压有两个文件。

D语言最初由Digital Mars公司就职的Walter Bright于2001年发布,意图改进C++语言。目前最新D语言被简称为D2。最主要的D语言的实现是DMD。

有个后缀名为d的文件,用记事本打开,发现有代码!

import std.stdio;
import std.range;
import std.algorithm;
import std.string;
import std.traits;
import std.conv;

template enc(string key) {
    string enc(string s) pure @safe {
        pragma(msg, "encrypting with key...", key);
        char enc_add = cast(char) (s.length.to!int);
        string output = "";
        foreach(a,b; cycle(key).zip(s)) {
            output ~= a ^ b ^ enc_add;
        }
        return output;
    }
}

mixin template ForeachUnrolled(string F, int N, int MIN=1) {
    pragma(msg, "ForEach...", N, " to ", MIN);
    static if (N > 1) {
        mixin ForeachUnrolled!(F, N-1, MIN); 
    }
    mixin MakeFunction!(F, N);
}
mixin template MakeFunction(string F, alias T) {
    // Convert $ and %
    mixin(translate(F, ['$' : T.to!(string), '%' : (T-1).to!string]));
}

string encrypt(string s) pure @safe {
    const int n = 499; // 500 is DMD's template recursion limit
    //const int n = 30;
    string output_0 = s; // base case with our string
    mixin ForeachUnrolled!("string output_$ = enc!($$$.to!string)(output_%);", n);
    mixin("return output_" ~ n.to!string ~ ";");
}

string hexencode(string s) {
    string encoded = "";
    foreach (c; s) {
        encoded ~= format("%02x", c);
    }
    return encoded;
}

string enc_flag = encrypt("flag{t3mplat3_met4pr0gramming_is_gr8_4_3very0n3}");
void main() {
    writeln("Your hexencoded, encrypted flag is: ", enc_flag.hexencode);
    writeln("I generated it at compile time. :)");
    writeln("Can you decrypt it for me?");
}

这里其实很显眼的可以看到flag的存在!
在这里插入图片描述
如果没有源代码做的话,估计要远程调试!在这里插入图片描述
此时我们接着调试!
调试半天不出来!
这里先空着!等有时间再看看!

zorropub

里面有许多字符,经过翻译是个劝酒喝酒喝饮料的程序。
EP再ida打开去分析里面的一些内容!
在这里插入图片描述
对了,这里有句话说错了,就是v6是在16之上!接着看看!
在这里插入图片描述
大致理解了里面的思路,我便用kali进行运行但是报错了!
在这里插入图片描述
所以这个思路是行不通的!
此时再来列一下各个函数

MD5Init是一个初始化函数,初始化核心变量,装入标准的幻数
MD5Update是MD5的主计算过程
MD5Final整理和填写输出结果
int sprintf(char *str, const char *format, …) 发送格式化输出到 str 所指向的字符串。

好了,就说这么多吧,最简单的思路就是爆破!
首先是用pwntools库来进行爆破,但是这样子没能成功

from pwn import *
a = []
for v6 in range(16,0xffff):
    v9 = 0
    seed = 0
    seed ^= v6
    i = seed
    while(i):
        v9 = v9 + 1
        i &= i - 1
    if v9 == 10:
        a.append(v6)
for i in a:
	try:
	    r = process('./87356aae634e4e0a9a081f30fc81fe16')
 	    r.recv()
  	    r.sendline('1')#这里会出错,不知这么回事?
  	    r.recv()
  	    r.sendline(str(i))
  	    r.recv()
    	if "null" in text:
        	print(text)
        	
        	break
    except:
    	continue
r.close()

这样子总是会出错!
但是不要着急,还有一个重要的库python subprocess模块
通过标准库中的subprocess包来fork一个子进程,并运行一个外部的程序。
在这里插入图片描述
然后我看到它是64位,不能用OD,就想打开xdbg64,但是还是不行,因为他是个ELF文件!dgb又不想用,就放这吧!

nullcon{nu11c0n_s4yz_x0r1n6_1s_4m4z1ng}

BabyXor

这里首先进行EP探查,发现有个壳,但是属于未知壳,所以还是使用OD进行脱壳,进入是会提示说代码有压缩,我们不用管!
在这里插入图片描述
然后使用ODdumop插件进行脱壳!生成一个新的没有壳的文件!然后就可以用ida进行打开了,不过时无法进行运行的!但是我们静态分析已经足够了!
来来分析一波这道题!
在这里插入图片描述
进去!
在这里插入图片描述

memcpy指的是C和C++使用的内存拷贝函数,函数原型为void *memcpy(void *destin, void *source, unsigned n);函数的功能是从源内存地址的起始位置开始拷贝若干个字节到目标内存地址中,即从源source中拷贝n个字节到目标destin中。

sprintf指的是字符串格式化命令,函数声明为 int sprintf(char *string, char *format [,argument,…]);,主要功能是把格式化的数据写入某个字符串中,即发送格式化输出到 string 所指向的字符串。

在这里插入图片描述
我们此时不知道flag是在哪里出现的,所以我们以我们模仿其进下写个脚本,然后将每个过程打印一下就可以了!

array1 = [102,109,99,100,127,55,53,48,48,107,58,60,59,32]
array2 = [55,111,56,98,54,124,55,51,52,118,51,98,100,122]
array3 = [26,0,0,81,5,17,84,86,85,89,29,9,93,18,0,0]

上面是三个数组,此时我再分别看看异或的函数!
在这里插入图片描述
再来看看第二个异或函数!
在这里插入图片描述
和第三个异或函数!
在这里插入图片描述
此时我们再将其整合到一起!
在这里插入图片描述
对了,这个图片了的最后一句话有点毛病,不用管它!
脚本!来来来!

array1 = [102,109,99,100,127,55,53,48,48,107,58,60,59,32]
array2 = [55,111,56,98,54,124,55,51,52,118,51,98,100,122]
array3 = [26,0,0,81,5,17,84,86,85,89,29,9,93,18,0,0]
v3 = ''
for i in range(14):
    v3 += chr(array1[i]^i)
v5 = ''
v5 += (chr(array2[0]))#这里就是整合时候添加进去的一个字符!没有这个字符结果会大不一样
for i in range(1,14):
    v5 += chr(array1[i]^array2[i]^array1[i-1])
v7 = ''
for i in range(13):
    v7 += chr(ord(v5[i])^i^array3[i+1])
byte = chr(array2[0]^array3[0])#这里是在第三个异或函数里面进行添加的字符
print(v3,end='')
print(v5,end='')
print(byte,end='')
print(v7,end='')

在这里插入图片描述


梅津美治郎

这道题的描述确实很激荡人心!
解压后是个exe文间,所以先EP探查!
在这里插入图片描述
然后看下面:
在这里插入图片描述
然后我们找找v8是个啥?
在这里插入图片描述
此时我们就知道了如何通过这一关,但是后面一关看看sub_4015EA这个函数!
在这里插入图片描述
不过此时我们用另一神器OD看看!
在这里插入图片描述

然后进到第二步里面看看!
在这里插入图片描述
正好对着ida里面的函数!
在这里插入图片描述
这里确实陷入了困境!
到这里我改用ida本地调试!
这里用的是远程windows调试(其实也可以再本地调试!因为我就是在本地调试的!)先找!
在这里插入图片描述
此时我们再打开ida去远程连接它!在这里插入图片描述
可能你有点疑惑,它这么没有文件名呢?你直接一路确定到最后回弹出一个窗口让我们选择要调试的程序!
在这里插入图片描述
此时我们来进行调试就很方便了!比OD要方便好多!
在这里插入图片描述
接着调,调它到天荒地老!然后就跳出来了,但是第二个密码是什么呢?
__debugbreak函数,这个是个关键点,在x86中汇编指令就变成了init 3这个断点了,但是还是不能够解决这个问题,所以我又回到ida静态分析了,发现了一个特殊的地方!
在这里插入图片描述

此时我用OD打开,先在运行完跳到该函数里,但是运行着就ret了,所以我们跳到判断语句中也是一条思路!
在这里插入图片描述
此时因为OD和ida远程调试调试不到函数回调!所以我们直接看代码(静态分析)函数回调,这表明这我们可以在ida中找到的,不过位置是不好确定的,只能凭借自己的经验和一步一步分析来了!
此时我们可以进去看看!
但是值我们是找不到的,所以我们还是需要进行函数回调,异常回调函数在汇编中是个init 3断点,我们一般会直接修改它,但是修改了就不会进行异常函数回调了!
在这里插入图片描述
然后我们从栈上追踪数据!找到了函数回调的原始数据!
在这里插入图片描述
这样子我们模拟一个函数回调的异或运算来进行解密!
在这里插入图片描述

a = [0x75,0x31,0x6E,0x6E,0x66,0x32,0x6C,0x67]
for i in a:
    print(chr(i^2),end='')

flag{r0b0RUlez!_w3lld0ne}


easyCpp

这个刚开始看的话,确实有点看不下去!所以我直接动态调试,调试到最后看看能不能出flag!
在这里插入图片描述
所以我又开始了静态分析!
在这里插入图片描述
此时我们可以去fib函数里面看看!
在这里插入图片描述
这里是个递归!最后应该将数列储存在了LODWORD(v29)这里了!

C++的确实这里没有学过!

容器(Containers) 容器是用来管理某一类对象的集合。C++ 提供了各种不同类型的容器,比如 deque、list、vector、map 等。

算法(Algorithms) 算法作用于容器。它们提供了执行各种操作的方式,包括对容器内容执行初始化、排序、搜索和转换等操作。

迭代器(iterators) 迭代器用于遍历对象集合的元素。这些集合可能是容器,也可能是容器的子集。

STL的知识确实没有学习过,这里其实是凭借着经验主义来行事的!
在这里插入图片描述
然后我们进去看看!
在这里插入图片描述
此时我们就需要搞懂这两个函数到底时干什么的!
在这里插入图片描述
然后再经过循环看看结果,从而推导出这里的加密方式!
在这里插入图片描述
还有就是分析的时候要注意是地址还是地址里面的内容!
在这里插入图片描述
那个判断应该就是判断是否输入与斐波那契数列是否一致!
这样的话是可以找到我们要输入什么,知道了输入什么正确也就意味着flag找到了!
在这里插入图片描述
在这里插入图片描述
此时我们就可以开始写脚本了!

def fib(i):#模拟斐波那契数列
    if not i or i == 1:
        return 1
    j = fib(i - 1)
    return j + fib(i - 2)

data = [0] * 16
j = 15
for i in range(16):
    data[j] = fib(i)
    j -= 1
print(data)#模拟逆序
for i in range(1,len(data)):#模拟将其进行斐波那契规律
    print(data[i] - data[0])

然后输入这个数组就可以了!
在这里插入图片描述


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值