reverse
算法和exp
tea
关键表现在多次加密的sum和delta变量,delta值一般为0x9E3779B9(-0x61C88647),但题目中往往可能改变delta
TEA算法使用64位的明文分组和128位的密钥,它使用Feistel分组加密框架,需要进行64轮迭代,但是作者认为32轮已经足够了,所以32轮迭代加密后最后得到的密文就是64位。
简单的说就是,TEA加密解密是以原文以8字节(64位bit)为一组,密钥16字节(128位bit)为一组,(char为1字节,int为4字节,double为8字节),该算法加密轮次可变,作者建议为32轮,因为被加密的明文为64位,所以最终加密的结果也是64位。 加密脚本
|
|
解密脚本
|
|
使用示例
|
|
xtea
tea的升级版 四个子密钥采取不正规方式混合以阻止密钥表攻击,特点在于sum&3
加密脚本
|
|
解密脚本
|
|
xxtea
块加密,32位大小的任意倍数,128位密钥,速度性能慢,安全高
脚本(具体看题)
点击展开
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
#include <stdio.h>
#include <stdint.h>
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))
//一个混淆操作,根据密码学的扩散原理,让算法更安全,同时也是xxtea的特征之一
void xxtea(uint32_t *v, int n, uint32_t const key[4]){
uint32_t y, z, sum;
unsigned p, rounds, e;
//n是明文长度,sum对应图中的D,p对应图中的密钥下标索引,e是图中的D>>2
/* Coding Part */
if (n > 1) {
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;//本质上还是双整形加密,用v[p]和v[p+1]对v[p]加密
/*
v[p] += MX;
z = v[p];
*/
}
y = v[0];
z = v[n-1] += MX;//一轮加密的最后用v[n-1]和v[0]对v[n-1]加密
}
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()
{
uint32_t v[2]= {1,2};
uint32_t const k[4]= {2,2,3,4};
int n= 2; //n的绝对值表示v的长度,取正表示加密,取负表示解密
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
printf("%#10x %#10x\n",v[0],v[1]);
xxtea(v, n, k);//n>0为加密
printf("%#10x %#10x\n",v[0],v[1]);
xxtea(v, -n, k);//n<0为解密
printf("%#10x %#10x\n",v[0],v[1]);
return 0;
}
PWN
匿名函数起手式模板
|
|
canary爆破
点击展开
|
|
shellcode与汇编语言
汇编语言
cmp与跳转指令
|
|
shellcode收集
学习过程放在下面了懒得删了,上面放shellcode收集
x86/64 Linux execve("/bin/sh") Shellcode
|
|
i386 orw
|
|
基本pwntools
点击展开
自定义 Shellcode
你可以根据自己的需求自定义 Shellcode。假设我们需要构建一个简单的 execve
Shellcode 来执行一个特定的命令(例如 /bin/ls
):
|
|
这里,shellcraft.execve(command)
生成一个执行给定命令的 Shellcode。
调试和测试 Shellcode
你可以使用 pwnlib
中的 context
来设置目标架构,确保生成的 Shellcode 能在正确的环境下执行。假设你希望生成 x86 架构的 Shellcode:
|
|
你也可以设置更多的上下文选项,如操作系统、字节顺序等。pwntools
支持多种架构,常见的包括:
i386
:32 位 x86 架构x86_64
:64 位 x86 架构arm
,aarch64
:ARM 架构mips
,mipsel
:MIPS 架构
打包 Shellcode
有时我们需要将生成的 Shellcode 打包成 C 代码,或者将它嵌入到其他程序中,pwntools
提供了方便的转换方法。例如,生成 C 代码字符串:
|
|
生成的输出将是类似这样的 C 代码,可以嵌入到 C 程序中:
|
|
还有一种:自己编写好详细的汇编代码,然后通过asm()
函数生成字节码发送shellcode
|
|
MISC
工具
z3
Z3在工业应用中常见于软件验证、程序分析等。其功能十分强大,在CTF领域我们将其作为一个 约束求解器 ,在二进制逆向、密码题等方面很常见,二进制分析框架angr中也内置了一个z3(修改版)
在使用z3的过程中,我们常常会进行比对。 生成一个约束器,然后往里面加东西(比对完成后的)
|
|
EXP
experience
linux下的7z(杂项)
可以实现将vmdk解压,如果有windows格式下没有的文件就可找出
正则表达式速查表
匹配字符
表达式 | 说明 | 示例 |
---|---|---|
[abc] |
匹配 a,b,c 中的任意一个字符 | a /b /c |
[^abc] |
匹配除 a,b,c 之外的任意字符 | d /1 /@ |
[a-g] |
匹配 a-g 范围内的任意一个字符 | a /d /g |
[^a-g] |
不匹配 a-g 中的所有字符 | h /A /5 |
[H-N] |
匹配 H-N 范围内的任意一个字符 | H /K /N |
[a-gH-N] |
匹配 a-g 或 H-N 范围内的字符 | a /H /g |
[0-9] |
匹配 0-9 范围内的任意一个字符 | 0 /5 /9 |
[0|9] |
匹配 0 或 9 | 0 /9 |
. |
匹配除换行符以外的任意字符 | a /1 /@ |
x|y |
匹配 x 或 y | x /y |
\s |
匹配任意空白符(\n\r\t\f\v ) |
空格/制表符/换行符 |
\S |
匹配非空白字符 [^\s] |
a /1 /@ |
\d |
匹配数字 [0-9] |
0 /5 /9 |
\D |
匹配非数字 [^\d] |
a /@ /空格 |
\w |
匹配字母和数字 [a-zA-Z0-9_] |
a /5 /_ |
\W |
匹配非字母和数字 [^\w] |
@ /空格/# |
频次范围(量词)
表达式 | 说明 | 示例 |
---|---|---|
* |
重复零次或多次 {0,} (贪婪) |
a* → "" /a /aaa |
*? |
非贪婪模式 | a*? → 尽量少匹配 |
+ |
重复一次或多次 {1,} |
a+ → a /aaa |
+? |
非贪婪模式 | a+? → 尽量少匹配 |
? |
重复零次或一次 {0,1} |
a? → "" /a |
{n} |
重复 n 次 | a{3} → aaa |
{n,} |
重复 n 次或多次 | a{2,} → aa /aaa |
{n,m} |
重复 n 到 m 次 | a{2,4} → aa /aaaa |
定位匹配
表达式 | 说明 | 示例 |
---|---|---|
^ |
字符串开始位置 | ^a → a bc(开头匹配) |
$ |
字符串结束位置 | a$ → bca (结尾匹配) |
\b |
单词边界 | \ba\b → a in “a b” |
\B |
非单词边界 | \Ba\B → a in “abc” |
(exp) |
捕获分组 | (ab)+ → abab |
(?:exp) |
不捕获分组 | (?:ab)+ → 不记录分组 |
(?=exp) |
正向肯定预查(匹配 exp 前的位置) | a(?=b) → a in “ab” |
(?<=exp) |
反向肯定预查(匹配 exp 后的位置) | (?<=a)b → b in “ab” |
(?!exp) |
正向否定预查 | a(?!b) → a in “ac” |
(?<!exp) |
反向否定预查 | (?<!a)b → b in “cb” |
(?<name>exp) |
命名捕获分组 | (?<id>\d+) → 命名分组 |
压缩包分分的卷的合并原理
|
|
实际上就是把压缩包的十六进制拆开来了,你当然也可以010里一段段拼起来