ctfshow - Reverse

【逆向签到题】 

 逆向题的hello world

用ida打开,可以看到就是读取输入作为s2,然后和flag比较,成功则输出flag

比较简单,flag就是

flag{7ujm8ikhy6}

CTF之逆向Reverse入门推荐学习知识点总结面向新手小白_ctf reverse-CSDN博客

CTF比赛 Reverse 逆向方向:入门规划精讲_ctfhub reverse-CSDN博客

Reverse入门[不断记录]_ctf reverse入门-CSDN博客

https://blog.51cto.com/u_15288224/3241826

CTF Reverse_reverse ctf-CSDN博客

[ctf.show.reverse] 卷王杯 简单的re,sigin_keys,逆向签到_ctf re input key-CSDN博客

CTF-逆向刷题记录_逆向题 非常简单的签到题-CSDN博客

【re2】 - RC4流密码加密

感谢@W22提供的题目

1、解压运行

解压打开有两个文件,打开enflag.txt,发现是乱码

用010重新打开,猜测可能是会用到十六进制

运行一下勒索病毒.exe,输入即闪退

2、ida分析

用PEiD查了下壳,没有壳,直接拖入ida中,sub_401037点进去一看应该是个format格式化类似功能的函数,sub_401073函数看一下给的参数和下面对v10的判断,可以推断是个输入函数,改名成scanf,下面就是对两个文件读取,不存在则退出

2.1 str异或

sub_401069函数,看参数就感觉不简单,有点可疑,点进去以后返回sub_401A70函数的返回值,继续步入,可以看到对Str进行逐位异或,得到Str1,然后和给定的字符串进行比较,成功返回

这个地方插一句,根据if-else语句可以推断format应该是print输出的功能,重命名为print

先写个脚本,异或回来,这里异或的是0x1f,再异或一次,就可以得到原始的Str,也就是输入的内容,定死了,就是[Warnning]Access_Unauthorized

str = "DH~mqqvqxB^||zll@Jq~jkwpmvez{"
flag = ""
for s in str:
    flag += chr(ord(s) ^ 31)
print(flag)

# [Warnning]Access_Unauthorized

2.2 sub_4014E0函数

接下来步入下一个函数sub_401028,可以看到传入了5个参数,然后返回sub_4014E0函数返回值

可以简单看一下,取了str的长度,通过4个函数的操作,最后close了flag和enflag两个文件指针

2.2.1 sub_4010F0函数

返回sub_401800函数返回值,继续步入,先根据上一个函数传入的参数重命名一下

转换成python代码为:

def get_result(a2, str, len):
    result = 0
    if len <= 256:
        for i in range(256):
            a2[i] = str[i % len]
            result = i + 1

    if len > 256:
        for j in range(256):
            a2[j] = str[j]
            result = j + 1
    return result

2.2.2 sub_4010C8函数

这个函数主要是针对a3进行操作,返回sub_401780函数返回值,重命名一下

转换成python代码:

def init_a3(a3):
    result = 0
    for i in range(256):
        a3[i] = i
        result = i + 1
    return result

2.2.3 sub_40116D函数

返回sub_4018E0函数返回值,简单重命名一下

转为Python代码:

def replace(a3, a2):
    key, result = 0, 0
    for i in range(256):
        key = (a2[i] + key + a3[i]) % 256
        tmp = a3[i]
        a3[i] = a3[key]
        a3[key] = tmp
        result = i+1
    return result

2.2.4 sub_4010EB函数

返回sub_4015E0函数返回值,简单重命名一下,这个地方主要是处理了以后输出

转换成python代码:

def write(a3, in_file, out_file):
    v6, v7, result = 0, 0, 0
    i = in_file.read(1)
    while i != "":
        result = ord(i)
        if result == -1:
            break

        v7 = (v7 + 1) % 256
        v6 = (v6 + a3[v7]) % 256
        v4 = a3[v7]
        a3[v7] = a3[v6]
        a3[v6] = v4

        xor_value = a3[(a3[v6] + a3[v7]) % 256] ^ result
        out_file.write(chr(xor_value))

        i = in_file.read(1)

    return result

整合一下,然后进行代码重构,得到完整的代码:

def init(a3, key, len_key):
    if len_key <= 256:
        for i in range(256):
            a2[i] = key[i % len_key]
            a3[i] = i
    # else:  # 输入的key固定,长度不超过256
    #     for j in range(256):
    #         a2[j] = key[j]
    #         a3[j] = j

    k = 0
    for i in range(256):
        k = (a2[i] + k + a3[i]) % 256
        tmp = a3[i]
        a3[i] = a3[k]
        a3[k] = tmp


def write(a3, data):
    i, j, result = 0, 0, 0
    for k in range(len(data)):
        i = (i + 1) % 256
        j = (j + a3[i]) % 256
        tmp = a3[i]
        a3[i] = a3[j]
        a3[j] = tmp

        t = (a3[j] + a3[i]) % 256
        data[k] = data[k] ^ a3[t]


if __name__ == '__main__':
    key = b"[Warnning]Access_Unauthorized"
    len_key = len(key)
    a2, a3 = [0]*256, [0]*256
    init(a3, key, len_key)

    data = bytearray([
        0xC3, 0x82, 0xA3, 0x25, 0xF6, 0x4C, 0x36, 0x3B, 0x59, 0xCC, 0xC4, 0xE9,
        0xF1, 0xB5, 0x32, 0x18, 0xB1, 0x96, 0xAE, 0xBF, 0x08, 0x35
    ])
    write(a3, data)
    for i in data:
        print(chr(i), end="")

看了下有个大佬的代码更加精简:https://www.cnblogs.com/sk2rw/p/15091304.html#

key3 = [0xC3, 0x82, 0xA3, 0x25, 0xF6, 0x4C, 0x36, 0x3B, 0x59, 0xCC, 0xC4, 0xE9, 0xF1, 0xB5, 0x32, 0x18, 0xB1, 0x96, 0xAE, 0xBF, 0x08, 0x355]

c = key3
t = []
key = '[Warnning]Access_Unauthorized'
ch = ''
j = 0  # 初始化
s = list(range(256))  # 创建有序列表
for i in range(256):
    j = (j + s[i] + ord(key[i % len(key)])) % 256
    s[i], s[j] = s[j], s[i]
i = 0  # 初始化
j = 0  # 初始化
for r in c:
    i = (i + 1) % 256
    j = (j + s[i]) % 256
    s[i], s[j] = s[j], s[i]
    x = (s[i] + (s[j] % 256)) % 256
    ch += chr(r ^ s[x])
print(ch)

还有一种更简单一点的解法,就是把enflag.txt重命名为flag.txt,因为对flag.txt是读,要求文件必须存在,而对enflag.txt是写,不要求必须存在,不存在会自动创建

然后整个程序的功能就是从flag.txt中读入flag字符串,然后做一个异或检测一下,然后进行某种加密得到enflag,再写入enflag.txt

最后在enflag.txt文件中就可以得到flag,但是对具体的加密并不是很了解,且若不是对称加密,也并不能依靠这种方法进行解密

可以参考这篇博客[ctf.show.reverse] re2_ctfshow reverse re2-CSDN博客

最终flag为:

flag{RC4&->ENc0d3F1le}

https://www.cnblogs.com/sk2rw/p/15091304.html#

[ctf.show.reverse] re2_ctfshow reverse re2-CSDN博客

https://blog.51cto.com/u_15127693/3946413


看了下flag,又去找了找RC4加密

RC4是流密码,生成伪随机比特流(密钥流)。与任何流密码一样,它们可以通过使用按位异或将其与明文组合来用于加密;解密以相同的方式执行(因为互斥或给定数据是对合)。这与一次性填充类似,只是使用生成的伪随机位而不是准备好的流

RC4加密的特点

如果输入的是明文,输出的就是密文;如果输入的是密文,输出的就是明文

RC4的工作原理

加密程序
  1. 用户输入纯文本文件和密钥。
  2. 然后加密引擎使用 KSA 和 PRGA 算法生成密钥流。
  3. 现在,该密钥流与纯文本进行异或,该异或运算是逐字节完成的,以生成加密文本。
  4. 然后将加密的文本发送给预期的接收者,预期的接收者将解密该文本,解密后,接收者将得到原始的明文。
解密程序

解密是通过对密文执行相同的字节异或运算来实现的。 

示例:设 A 为纯文本,B 为密钥流 (A xor B) xor B = A 

What is RC4 Encryption? - GeeksforGeeks

https://zh.wikipedia.org/wiki/RC4

1 Nowhere (feat. Gervs) Shaker / COBRA / Gervs
2 Bubble STAYC
3 어푸 IU
4 花日 CMJ
5 If We're Being Honest Novo Amor
6 春色悠悠不及你荡漾 陈婧霏
7 足够 银河快递
8 Satisfaction KSHMR
9 April 伍嘉成
10 Alone Shaker
11 happy for you Alex Porat
12 I Feel Better Novo Amor
13 Normal No More TYSM
14 Bubble Gum noli
15 だから僕は音楽を辞めた 他城 / 鏡音リン
16 银河流浪 打扰一下乐团
17 I GOT YOU TWICE
18 Welcome to the Show DAY6
19 有你的快乐 王若琳
20 Run For Roses NMIXX
21 내 손을 잡아 IU
22 玫瑰往事 陶薏点
23 안녕,네버랜드 (Bye My Neverland) KISS OF LIFE
24 人生是旷野 苏运莹 / Kui Kui
25 来吧,占领我的无私 银河快递
26 One Minute Hauskey / Hope Tala
27 FREAK YU琦
28 봄눈(Spring Snow春雪)-背着善宰跑ost 初九
29 Teddy Bear STAYC
30 The Kids Are All Dying FINNEAS
31 Tell Me It's Not a Dream (Eng ver.) 10cm
32 Hey KONG KEY.L刘聪 / c0de731
33 청혼 金秀贤
34 일기 金娜英
35 泪桥(AI杨丞琳) AI小妖


안녕,네버랜드 (Bye My Neverland) - KISS OF LIFE
01:11 / 03:23   
   
An audio error has occurred, player will skip forward in 2 seconds.
作词 : Ondine, 진솔, Strawberrybananaclub, Julie
作曲 : 진솔, Ondine, Strawberrybananaclub, Julie, Haneul
Going round and round (不停地转啊转啊)
저태엽을더감지않아 (直到我的发条再也拧不动了)
오르골은닫고전부치워 (关上八音盒 全部丢掉吧)
Feel like Im an old toy (感觉我就像一个坏掉的玩具)
더자라지않는내흉터 (我的伤痕没有再变得更大)
아플바엔잊혀지려했어Wait (与其痛苦 不如忘却 等等)
Why am I afraid Oh Why (为什么我会害怕 为什么啊)
Got me feeling it yeah (让我感受到了它)
벽장속에든상처 (藏在壁橱里的伤口)
먼지쌓인밤 (灰尘堆积的夜晚)
난더숨고싶거나 (我更想躲起来 或是)
감추지않아 (再也不去隐藏)
Dont wanna stay more (不想再停滞不前了)
I dont care what you say (我不在乎你说的是什么)
I burned my neverland (我烧毁了我的梦幻岛)
시계위로 달려 장면을넘겨 (时过境迁 画面闪过)
멈추고싶지않아 (我不想停下来)
Yeah We dont care what you say (是的 我们不在乎你说什么)
I burned my neverland (我烧毁了我的梦幻岛)
돌아보지 않아 긴밤을지나 (不回头 漫漫长夜过去)
후회따윈없어 (没有丝毫悔意)
Ill never comeback (我永远不会回头)
Leave the hometown (离开了家乡)
Different somehow (不知怎的 有些不同)
멈췄던일기속을Fix it (在停下来的日记中 修复好它)
겁많던아이뒤에사라진꿈 (消失在曾经那个胆小的孩子身后的梦想)
눈감지마Now I can make it new (不要闭眼 现在我可以让一切焕然一新)
No more regrets (不再后悔)
Im tryna play a fair game (我只是想要公平竞争)
내벽지위로변치않던아픔의키를재 (在我的墙纸上测量着从未改变的令人痛苦的身高)
두려웠던Yesterday (曾害怕过的昨天)
Dont recall it passed away (不要回忆了 它已经逝去)
My fairy tale wont be beautiful as starlight (我的童话不会像星光一样美丽)
벽장속에든상처 (藏在壁橱里的伤口)
먼지쌓인밤 (灰尘堆积的夜晚)
난더숨고싶거나 (我更想躲起来 或是)
감추지않아 (再也不去隐藏)
Dont wanna stay more (不想再停滞不前了)
I dont care what you say (我不在乎你说的是什么)
I burned my neverland (我烧毁了我的梦幻岛)
시계위로 달려 장면을넘겨 (时过境迁 画面闪过)
멈추고싶지않아 (我不想停下来)
Yeah We dont care what you say (是的 我们不在乎你说什么)
I burned my neverland (我烧毁了我的梦幻岛)
돌아보지 않아 긴밤을지나 (不回头 漫漫长夜过去)
후회따윈없어 (没有丝毫悔意)
Ill never comeback (我永远不会回头)
And they all lived happily ever after (在那之后他们都过得很幸福)
그딴건없어 (没有那样的事)
뻔한행복을바라지는않아 (我不奢望显而易见的幸福)
So I wont stop my time (所以我不会让我的时间停下来)
아파도자라고싶어난 (即使疼痛 我也想要长大)
I get a little bit lonely (我变得有点孤独)
어른이돼 Now now now now (长大成人 就是现在)
I dont care what you say (我不在乎你说的是什么)
I'm gonna take a train (我要乘火车远行)
비어버린 Playground 나의모래성 (空荡荡的游乐场 我的沙堡)
두고가려해Bye bye (被我留在了身后 再见吧)
Yeah We dont care what you say (是的 我们不在乎你说什么)
I burned my neverland (我烧毁了我的梦幻岛)
이제정말떠나 긴밤을지나 (现在真的要离开 度过漫漫长夜)
후회따윈없어 (没有丝毫悔意)
Ill never comeback (我永远不会回头)
Im leaving my hometown (我要离开我的家乡了)
Why is it sad I dont know (为什么 这很悲伤吗 我不知道)
La la Finally its over (啦 啦 最终一切结束了)
인사를 건네 (我作个告别)
Im leaving my hometown (我要离开我的家乡了)
Why is it sad I dont know (为什么 这很悲伤吗 我不知道)
La la Finally its over (啦 啦 最终一切结束了)
Im sorry (我很抱歉)

【re3】

 感谢@shimly清风师傅提供的题目

提交最小解即可,4位值

下载下来一个r3.r3文件,拖到ida中运行,是64位的,main函数并不是很复杂

strncpy(dest, v19, len - 6);

前面看着都还行,就是简单的赋值输入打印,但是strncpy这个地方让我有点奇怪,前面也没给v19赋值,这里怎么copy啊,回去看下地址,这里s的长度限制为5*sizeof(char),那么scanf多出来的就会覆盖到v19上

那么这行代码就可以这么转换,也就是取出了flag{}包裹的字符串

# v19就相当于是
v19 = s[5:]
# len(v19) = len(s)-5
# len - 6 = len(s) - 6  = len(v19) - 1
# strncpy(dest, v19, len - 6);就相当于
dest = s[5:-1]

__isoc99_sscanf(dest, "%x", &v5); 

这行代码也不是很懂,问了下gpt,主要作用就是把dest以十六进制转成数字赋值给v5,其实就是把flag转为数字

这行代码是在C语言中使用的,其功能是从字符串dest中按照%x的格式字符串提取一个十六进制的数值,并将这个数值赋给变量v5

具体来说:

  • __isoc99_sscanf 是C语言中的一个函数,它与sscanf函数类似,都是用于从一个字符串中按照指定的格式字符串提取数据的
  • dest 是需要从中提取数据的字符串
  • "%x" 是一个格式字符串,它告诉__isoc99_sscanf函数,从dest字符串中提取的是一个十六进制的数值
  • &v5 是一个指针,指向变量v5的内存地址。这样,提取出的十六进制数值就会被赋值给v5

所以,这行代码的整体含义是:从字符串dest中按照十六进制的格式提取一个数值,并赋给变量v5

赋值

根据上面一步,这个地方的赋值其他都是固定的值,只有v5是变化的

循环

根据上一步得出的结论,可以知道v17前6个值都是固定的,那么循环前五次的结果也是固定的

这个地方建议用ida的动态调试去看,提示中给出值为4位,那么就假设给的flag是flag{0000},调出来发现,i=6时,v16的值是000000000000E560,v17[6]=v5,那么v16+v5结果等于0xFFFF,退出循环,然后判断成功,所以v5=0xFFFF-v16=0x1A9F,提示也要求最小值,成功

提交flag也是成功,flag为:

flag{1a9f}


ida动态调试可能遇到的问题

ida不显示对应的debugger

不知道咋的,ida很久没用,突然debug选项少了remote windows debugger,网上几乎没有找到相关的信息,更多的是利用windbg,比如IDA win10 找不到 windbg 解决方案,不过讲的还行,有知道咋回事的大佬可以评论留言一下,感谢

我看到还支持Remote Linux debugger,就是IDA目录下面,找dbgsrv目录,下面有两个linux的,一般来说选64位的,可以尝试一下,拖到Linux系统下运行就行

zsh: permission denied

执行以下命令后,报错 zsh: permission denied

./linux_server64
# zsh: permission denied: ./linux_server64

这个是因为用户对这个文件没有权限,需要添加权限

chmod u+x linux_server64

chmod是权限管理命令change the permissions mode of a file的缩写
u代表所有者。x代表执行权限。’+’ 表示增加权限
chmod u+x linux_server64 就表示对当前目录下的file.sh文件的所有者增加可执行权限

参考这篇博客zsh: permission denied问题的解决办法 

分析的程序也要放入linux

文件先加载到ida中,debugger没有配置,用的是文件默认的值,然后就会提示报错,但是最后有个框弹出来确认以后,会自动传到虚拟机里,这个不知道为什么

后面再尝试的时候,会提示application和inputfile为空,然后焦点会在parameter上,后面又尝试了一下,又不需要了,有点奇怪的

注意,Hostname要填虚拟机的ip地址

自己在win下用ida分析,分析时间长了,就想用python写脚本跑一下

win下无法执行源程序,就想着换语言重写程序,甚至拖到linux运行写的程序

就是没想到在linux下运行源程序,找了大佬的博客,还奇怪人家怎么写的那么好,跟ida上伪代码几乎一模一样,结果还很快就出来了

REVERSE-PRACTICE-CTFSHOW-2_ctfshow reverse 武穆遗书-CSDN博客

CTFShow re3-CSDN博客

https://www.cnblogs.com/ethan269/p/ctfshow_re3.html

https://blog.51cto.com/u_15127693/3946419

https://www.cnblogs.com/cjjcn/p/16141836.html#r2


自己写了脚本,跑俩小时还在i=3,电脑都发烫了 

#include <stdio.h>
#include <string.h>
#include <stdint.h> // 引入 stdint.h 以便使用 uint64_t

int main() {
    // Initialize variables
    uint32_t v7 = 80;
    uint32_t v8 = 64227;
    uint32_t v9 = 226312059;
    uint32_t v10 = 1540056586; // 将负数转换为正数
    uint32_t v11 = 5;
    uint32_t v12 = 16;
    uint32_t v13 = 3833;
    uint32_t v5 = 0;
    uint64_t v16 = 0; // 使用 uint64_t 类型

    printf("plz input the key:\n");
    char s[100];
    scanf("%s", s);
    // printf("%s\n", s);

    char dest[100];
    strncpy(dest, &s[5], strlen(s) - 6); // 复制从第5个字符开始的部分
    dest[strlen(s) - 6] = '\0'; // 添加字符串结束符
    printf("%s\n", dest);

    // 将十六进制字符串转换为整数
    sscanf(dest, "%x", &v5);
    printf("%u\n", v5);


    uint32_t v17[] = {v7, v8, v9, v10, (v11 << 12) + v12, v13, v5};
    printf("[%u, %u, %u, %u, %u, %u, %u]\n", v17, v17[1], v17[2], v17[3], v17[4], v17[5], v17[6]);

    for (size_t i = 0; i < sizeof(v17); ++i) {
        v16 += v17[i];
        while (v16 > 0xFFFF) {
            uint32_t v15 = v16 >> 16;
            v16 = v15 + v16;
            // v16 = v16 % ((uint64_t)1 << 64); // 对2的64次方取余
            v16 &= 0xFFFFFFFFFFFFFFFF;
        }
        printf("%d: %d\n", i, v16);
    }

    if (v16 == 0xFFFF) {
        printf("OK\n");
    } else {
        printf("Error\n");
    }

    return 0;
}

【re4】

[ctf.show.reverse] 逆向4_ctfshow 逆向4-CSDN博客

CTFSHOW 逆向4-CSDN博客

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CTF Reverse(CTF逆向)是一种在CTF竞赛中涉及到的题目类型,要求参赛选手具备较强的反汇编和反编译技术,并能够进行逆向分析。逆向分析与功能猜测结合,通过逆向分析缩小猜测范围,然后通过逆向验证猜测的思路。 在实际的CTF Reverse练习中,参赛选手可以通过访问特定网页或平台来进行实验和练习。例如,可以尝试进入实验网页[CTF- REVERSE练习之逆向初探](https://www.hetianlab.com/expc.do?ec=ECID172.19.104.182014111410002900001&pk_campaign=freebuf- wemedia)来进行逆向初步探索。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [CTF逆向(reverse)入门脑图](https://download.csdn.net/download/qq_32465127/10744933)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [【完善中】CTF逆向Reverse题的玩法](https://blog.csdn.net/m0_37157335/article/details/123694868)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [CTF-REVERSE练习之逆向初探](https://blog.csdn.net/text202202/article/details/129824733)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值