-
Notifications
You must be signed in to change notification settings - Fork 0
/
README.txt
180 lines (137 loc) · 4.75 KB
/
README.txt
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
BINARY ARMAGEDDON
If you have to use this, it's probably the end of the world as we know
it --- do you feel fine?
Commands are single lower-case letters, numbers are hexadecimal. Arguments
are separated by spaces, commands are terminated with spaces or
newlines. If the file doesn't exist, it can be created with the -! <size>
flag. As with all other numbers in this program, this size is hexadecimal.
COMMANDS:
e offset Extend file +offset bytes.
f offset size Find a size sequence of bytes starting at
offset. The maximum size is 32 bytes.
i start Insert a byte at start. This will create a hole
at start, setting the byte to 0, and shift the
remaining data to the right one byte.
l Print the current image size.
q Quit. This should be the first command you enter.
r start offset Read (and print) a hex dump of offset bytes from
the file starting at start. If offset is 0, the
remainder of the file (after start) is read. For
example, `r 0 0` will read the entire file.
s offset size Scan for all instances of the size-sized
fragment starting at offset.
w start Start writing to the file at start.
EXAMPLE:
Don't try this at home.
$ cat test.txt
hello world
$ ls -l test.txt
-rw-rw-r-- 1 kyle kyle 12 Apr 22 22:28 test.txt
$ ./binarm test.txt
> r 0 0c
00000000 | 68 65 6c 6c 6f 20 77 6f 72 6c 64 0a
> e 08
EXTENDED 8 BYTES
> w 0b
W> 21 0a 0a 48 49 21 0a
WROTE 7 BYTE(S)
> r 0 12
00000000 | 68 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a 0a 48 49
00000010 | 21 0a
> f 2 3
F> 77 6f 72
FIND FRAG FROM 2 SIZE 3
FOUND STARTING AT +4 (6)
> s 0 1
F> 6c
SCAN FRAG FROM 0 SIZE 1
FOUND STARTING AT +0 (0)
FOUND STARTING AT +0 (1)
FOUND STARTING AT +0 (3)
FOUND STARTING AT +0 (7)
NOT FOUND
> q
QUIT
$ cat test.txt
hello world!
HI!
$ ls -l test.txt
-rw-rw-r-- 1 kyle kyle 20 Apr 22 22:32 test.txt
$
There is no backspace. The only undo for a write is to start writing at
the same offset with the bytes you intended.
Alternatively, in the spirit of [1], armageddon may be unleashed on the
example client auth program. The major difference from the post is that
this example was built and run on an AMD64 machine ([1] uses a 32-bit
machine); accordingly, instead of the instruction 01442418, the target
instruction is 0145fc. The relevant instruction look up is found in [2].
First, build the (incorrect) client auth program:
$ cat test1.c
/*
* client-auth1.c
*/
#include <stdio.h>
int
main(void)
{
int i = 0;
unsigned sum = 0xffff0000;
char c;
while (0xa != (c = getchar())) {
i++;
sum += c * i;
}
printf("%010u\n", sum);
}
$ make test1
cc test1.c -o test1
Run it with the challenge input; this is the wrong input, but it's
useful to immediately compare the output of the modified version to
ensure something useful was changed.
$ ./test1
sptjpgzczykbgwogqmbrhsg
4294931782
It's not strictly required, but it's useful to find main as a starting
point for exploring the program. It's mapped 0x40057d, which places it
at an offset of 0x57d in the image.
$ readelf -s test1 | grep main$
61: 000000000040057d 75 FUNC GLOBAL DEFAULT 13 main
Invoke binarm: find the desired 3-byte instruction starting from the
main offset in the image. It was found 24 bytes from the search point at
an absolute offset of 0x5a1 bytes in the image.
$ ./binarm test1
> f 57d 3
F> 0145fc
FIND FRAG FROM 57d SIZE 3
FOUND STARTING AT +24 (5a1)
A visual confirmation shows the target instruction where expected; the
alignment isn't required, but it makes finding the instruction a little
easier.
> r 570 64
00000570 | e9 7b ff ff ff 0f 1f 00 e9 73 ff ff ff 55 48 89
00000580 | e5 48 83 ec 10 c7 45 f8 00 00 00 00 c7 45 fc 00
00000590 | 00 ff ff eb 0f 83 45 f8 01 0f be 45 f7 0f af 45
000005a0 | f8 01 45 fc e8 c7 fe ff ff 88 45 f7 80 7d f7 0a
000005b0 | 75 e3 8b 45 fc 89 c6 bf 54 06 40 00 b8 00 00 00
000005c0 | 00 e8 8a fe ff ff c9 c3 0f 1f 84 00 00 00 00 00
000005d0 | 41 57 41 89
The next step is to replace the single byte, a visual check on the
update, and exit.
> w 5a1
W> 29
WROTE 1 BYTE(S)
> r 5a0 32
000005a0 | f8 29 45 fc e8 c7 fe ff ff 88 45 f7 80 7d f7 0a
000005b0 | 75 e3 8b 45 fc 89 c6 bf 54 06 40 00 b8 00 00 00
000005c0 | 00 e8 8a fe ff ff c9 c3 0f 1f 84 00 00 00 00 00
000005d0 | 41 57
> q
QUIT
The modified program can now be tested. A quick visual check shows the
output has changed, and the answer is the same answer from [1].
$ ./test1
sptjpgzczykbgwogqmbrhsg
4294871738
[1] "Introduction to Patching Binaries with the HT Editor"
https://kyleisom.net/blog/2013/10/19/intro-to-ht/
[2] https://ref.x86asm.net/coder64.html